|
|
@@ -0,0 +1,349 @@
|
|
|
+package com.dgtly.sync.service;
|
|
|
+
|
|
|
+import com.alibaba.fastjson.JSON;
|
|
|
+import com.alibaba.fastjson.JSONArray;
|
|
|
+import com.alibaba.fastjson.JSONObject;
|
|
|
+import com.dgtly.common.utils.ShiroSaltUtil;
|
|
|
+import com.dgtly.common.utils.UserIdentityUtil;
|
|
|
+import com.dgtly.common.utils.http.HttpUtils;
|
|
|
+import com.dgtly.common.utils.security.EncryptPassWordClass;
|
|
|
+import com.dgtly.sync.domain.Customers;
|
|
|
+import com.dgtly.sync.domain.SyncFailDetail;
|
|
|
+import com.dgtly.sync.domain.SyncLog;
|
|
|
+import com.dgtly.sync.mapper.SyncFailDetailMapper;
|
|
|
+import com.dgtly.sync.utils.CustomerAccessTokenUtil;
|
|
|
+import com.dgtly.system.domain.SysUser;
|
|
|
+import com.dgtly.system.domain.SysUserExt;
|
|
|
+import com.dgtly.system.domain.SysUserShopExt;
|
|
|
+import com.dgtly.system.mapper.*;
|
|
|
+import com.dgtly.system.service.ISysConfigService;
|
|
|
+import com.dgtly.system.service.impl.SysUserServiceImpl;
|
|
|
+import org.slf4j.Logger;
|
|
|
+import org.slf4j.LoggerFactory;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.beans.factory.annotation.Value;
|
|
|
+import org.springframework.core.env.Environment;
|
|
|
+import org.springframework.stereotype.Component;
|
|
|
+import org.springframework.transaction.annotation.Transactional;
|
|
|
+
|
|
|
+import java.text.ParseException;
|
|
|
+import java.text.SimpleDateFormat;
|
|
|
+import java.util.*;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
+@Component
|
|
|
+public class ShopUserTypeComponent {
|
|
|
+
|
|
|
+ private static final Logger log = LoggerFactory.getLogger(ShopUserTypeComponent.class);
|
|
|
+ @Autowired
|
|
|
+ private SysUserMapper sysUserMapper;
|
|
|
+ @Autowired
|
|
|
+ private ISysConfigService configService;
|
|
|
+ @Autowired
|
|
|
+ private ISyncLogService syncLogService;
|
|
|
+ @Autowired
|
|
|
+ private SyncFailDetailMapper syncFailDetailMapper;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private SysUserExtMapper sysUserExtMapper;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private SysUserShopExtMapper userShopExtMapper;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private SysRoleMapper roleMapper;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private SysUserServiceImpl sysUserService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private SysUserRoleMapper userRoleMapper;
|
|
|
+
|
|
|
+ @Value(value = "${shop.appid:none}")
|
|
|
+ private String appid;
|
|
|
+
|
|
|
+ @Value(value = "${shop.appsecret:none}")
|
|
|
+ private String appsecret;
|
|
|
+
|
|
|
+ @Value(value = "${shop.tokenUrl:none}")
|
|
|
+ private String tokenUrl;
|
|
|
+
|
|
|
+ @Value(value = "${spring.esb.XAppId}")
|
|
|
+ private String ssbAppid;
|
|
|
+
|
|
|
+ @Value(value = "${spring.esb.APiKey}")
|
|
|
+ private String ssbApiKey;
|
|
|
+
|
|
|
+ @Value(value = "${spring.esb.shopStoneLikePaint}")
|
|
|
+ private String stoneLikePaintUrl;
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @description: 获取TUC仿石漆服务商人员
|
|
|
+ * @param: []
|
|
|
+ * @return: com.dgtly.sync.domain.SyncLog
|
|
|
+ * @author: njs
|
|
|
+ * @date: 2025/8/18 14:09
|
|
|
+ */
|
|
|
+ public void shopStoneLikePaint() throws ParseException {
|
|
|
+ //获取请求参数
|
|
|
+ Map<String, String> tokenHeaders =this.HeaderToMap();
|
|
|
+ Map<String, Object> params = new HashMap<>();
|
|
|
+ params.put("appid", appid);
|
|
|
+ params.put("appsecret", appsecret);
|
|
|
+ // 发送GET请求,包含URL、请求头和请求参数
|
|
|
+ String token = null;
|
|
|
+ try {
|
|
|
+ token = HttpUtils.get(tokenUrl, tokenHeaders, params);
|
|
|
+ if (token == null || token.isEmpty()) {
|
|
|
+ // 处理空返回值的情况
|
|
|
+ log.error("HTTP请求返回空结果");
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ // 处理HTTP请求异常
|
|
|
+ log.error("HTTP请求失败: " + e.getMessage());
|
|
|
+ // 可以选择重试或抛出异常
|
|
|
+ }
|
|
|
+
|
|
|
+ JSONObject jsonObject = JSON.parseObject(token);
|
|
|
+ if(jsonObject !=null && jsonObject.containsKey("access_token")){
|
|
|
+ String shopToken = jsonObject.getString("access_token");
|
|
|
+ String url = stoneLikePaintUrl;
|
|
|
+ Map<String, String> stoneLikePaintHeaders =this.HeaderToMap();
|
|
|
+ Map<String, Object> stoneParams = new HashMap<>();
|
|
|
+ stoneParams.put("access_token", shopToken);
|
|
|
+ stoneParams.put("page", 1);
|
|
|
+ stoneParams.put("page_size", 100);
|
|
|
+ String dateString = userShopExtMapper.searchRunTime();
|
|
|
+ // 截取前3位毫秒数
|
|
|
+ String truncatedDate = dateString.substring(0, dateString.lastIndexOf('.') + 4);
|
|
|
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
|
|
|
+ Date date = sdf.parse(truncatedDate);
|
|
|
+ String runTime = sdf.format(date);
|
|
|
+ //获取上次同步时间进行增量同步
|
|
|
+ if(runTime !=null && !runTime.isEmpty()){
|
|
|
+ stoneParams.put("datetime_start", runTime);
|
|
|
+ }
|
|
|
+ String stoneLikePaintUser =HttpUtils.get(url, stoneLikePaintHeaders, stoneParams);
|
|
|
+ JSONObject stoneLikeJson = JSONObject.parseObject(stoneLikePaintUser);
|
|
|
+ if(stoneLikeJson !=null && stoneLikeJson.getString("code").equals("0")){
|
|
|
+ Integer count = stoneLikeJson.getInteger("count");
|
|
|
+ //TUC仿石漆服务商人员-0
|
|
|
+ Long roleId = roleMapper.selectRoleIdByRoleKey("shopStoneLikePaint");
|
|
|
+ if(count > 100){
|
|
|
+ int num = 0;
|
|
|
+ if (count % 100 != 0) {
|
|
|
+ num = (count / 100) + 2;
|
|
|
+ } else {
|
|
|
+ num = (count / 100) + 1;
|
|
|
+ }
|
|
|
+ for (int i = 1; i < num; i++) {
|
|
|
+ stoneParams.put("page", i);
|
|
|
+ Map<String, String> headerUuid =this.HeaderToMap();
|
|
|
+ try {
|
|
|
+ String stoneLikeUser =HttpUtils.get(url, headerUuid, stoneParams);
|
|
|
+ JSONObject stoneUserJson = JSONObject.parseObject(stoneLikeUser);
|
|
|
+ if(stoneUserJson !=null && stoneUserJson.getString("code").equals("0")){
|
|
|
+ JSONArray stoneUserArray = stoneUserJson.getJSONArray("data");
|
|
|
+ buildShopUser(stoneUserArray,"0",roleId);
|
|
|
+ }
|
|
|
+ }catch (Exception e) {
|
|
|
+ log.error("循环获取获取TUC仿石漆服务商人员列表接口错误!第" + i + "页");
|
|
|
+ throw e;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }else{
|
|
|
+ JSONArray stoneUserArray = stoneLikeJson.getJSONArray("data");
|
|
|
+ buildShopUser(stoneUserArray,"0",roleId);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @description: 构建门店用户信息
|
|
|
+ * @param: [json, Usertype, roleId, deptId]
|
|
|
+ * @return: void
|
|
|
+ * @author: njs
|
|
|
+ * @date: 2025/8/19 13:40
|
|
|
+ */
|
|
|
+ public void buildShopUser(JSONArray jsonArray,String usertype,Long roleId){
|
|
|
+ int count = 0;
|
|
|
+ List<SyncFailDetail> failDetails = new ArrayList<>();
|
|
|
+ for (int i = 0; i < jsonArray.size(); i++) {
|
|
|
+ JSONObject jo = jsonArray.getJSONObject(i);
|
|
|
+ Set<String> loginNameSet = sysUserService.selectAllUserLoginName();
|
|
|
+ loginNameSet = loginNameSet.stream().map(String::toUpperCase).collect(Collectors.toSet());
|
|
|
+ try {
|
|
|
+ String userName = jo.getString("staff_name");
|
|
|
+ String userPhone = jo.getString("staff_mobile");
|
|
|
+ //是否同步企业微信
|
|
|
+ Boolean isSync = jo.getBoolean("is_synced_to_wecom");
|
|
|
+ //是否有效用户
|
|
|
+ Boolean isActive = jo.getBoolean("is_active");
|
|
|
+ String subOfficeCode = jo.getString("office_code");
|
|
|
+ String subOfficeName = jo.getString("office_name");
|
|
|
+ String shopCode = jo.getString("organization_code");
|
|
|
+ String shopName = jo.getString("organization_name");
|
|
|
+ String dataUpdateTime = jo.getString("update_datetime");
|
|
|
+ String dataUserId = jo.getString("id");
|
|
|
+ /*人员信息是否有效,true有效,false无效。是否同步到企微 */
|
|
|
+ String loginName ="";
|
|
|
+ if(isActive && isSync){
|
|
|
+ loginName = jo.getString("wecom_userid");
|
|
|
+ }else{
|
|
|
+ //先判断该用户是否存在在处理离职和去掉角色,否则直接跳出循环不处理
|
|
|
+ //离职掉该门店和用户关联关系
|
|
|
+ if(!isActive){
|
|
|
+ //用户无效后接口获取不到企微id,需从关联表查询
|
|
|
+ loginName = userShopExtMapper.selectLoginNameByUserId(dataUserId,shopCode,usertype);
|
|
|
+ if(loginName !=null && !loginName.isEmpty()){
|
|
|
+ //查询用户信息
|
|
|
+ SysUser user = sysUserMapper.selectUserByLoginName(loginName);
|
|
|
+ userShopExtMapper.deleteUserShopExt(user.getUserId().toString(),loginName,shopCode,usertype);
|
|
|
+ //去掉该用户和角色的关联关系
|
|
|
+ userRoleMapper.deleteUserRoleByUserIdAndExt(user.getUserId(),roleId,usertype);
|
|
|
+ //离职处理以及用户主信息是否有门店账号处理需要添加
|
|
|
+ //查询门店用户表是否存在用户和其他门店的关联关系,如果存在就不离职,不存在查询是否有经销商的关联关系,如果存在就不离职,不存在就离职
|
|
|
+ SysUserShopExt shop = new SysUserShopExt();
|
|
|
+ shop.setUserId(user.getUserId().toString());
|
|
|
+ shop.setDelFlag("0");
|
|
|
+ List<SysUserShopExt> shopExtList = userShopExtMapper.selectSysUserShopExtList(shop);
|
|
|
+ if(shopExtList == null || shopExtList.size() == 0){
|
|
|
+ //在查用户经销商扩展信息
|
|
|
+ SysUserExt userCustomerExt = sysUserExtMapper.selectSysUserExtById(user.getUserId());
|
|
|
+ if(userCustomerExt != null){
|
|
|
+ //有经销商信息,无门店信息。去掉标记
|
|
|
+ user.setIsShopAccount("0");
|
|
|
+ }else{
|
|
|
+ //没有经销商信息也没有门店信息
|
|
|
+ //离职处理2
|
|
|
+ user.setQuit("2");
|
|
|
+ }
|
|
|
+ //修改用户信息
|
|
|
+ sysUserMapper.updateUser(user);
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ if (!loginNameSet.contains(loginName.toUpperCase().trim())) {
|
|
|
+
|
|
|
+ /** =============用户基本信息构建 start===============*/
|
|
|
+ SysUser user = new SysUser();
|
|
|
+ user.setLoginName(loginName);
|
|
|
+ log.info("门店新用户"+loginName +"门店类型身份"+usertype);
|
|
|
+ user.setUserName(userName);
|
|
|
+ user.setPhonenumber(userPhone);
|
|
|
+ user.setPassword(loginName);
|
|
|
+ user.setSalt(ShiroSaltUtil.randomSalt());
|
|
|
+ user.setPassword(EncryptPassWordClass.encryptPassword(user.getLoginName(), user.getPassword(), user.getSalt()));
|
|
|
+ user.setIsShopAccount("1");
|
|
|
+ user.setRoleId(roleId);
|
|
|
+ /** =============用户基本信息构建 end===============*/
|
|
|
+ insertUserAndExt(user);
|
|
|
+ //查询用户信息
|
|
|
+ SysUser userVoExt = sysUserMapper.selectUserByLoginName(loginName);
|
|
|
+ // 新增用户与角色管理
|
|
|
+ user.setUserId(userVoExt.getUserId());
|
|
|
+ sysUserService.insertShopUserRole(user);
|
|
|
+ /**======== 构建门店用户扩展信息表 start===============*/
|
|
|
+ SysUserShopExt shopExt = new SysUserShopExt();
|
|
|
+ shopExt.setLoginName(loginName);
|
|
|
+ shopExt.setShopCode(shopCode);
|
|
|
+ shopExt.setShopName(shopName);
|
|
|
+ shopExt.setSubofficeCode(subOfficeCode);
|
|
|
+ shopExt.setSubofficeName(subOfficeName);
|
|
|
+ shopExt.setIsShopType(usertype);
|
|
|
+ shopExt.setUserUpdateTime(dataUpdateTime);
|
|
|
+ shopExt.setDelFlag("0");
|
|
|
+ shopExt.setConstraintUserId(dataUserId);
|
|
|
+ //用户id
|
|
|
+ shopExt.setUserId(userVoExt.getUserId().toString());
|
|
|
+ userShopExtMapper.insertSysUserShopExt(shopExt);
|
|
|
+ count++;
|
|
|
+ loginNameSet.add(loginName);
|
|
|
+ } else {
|
|
|
+ /*已经存在的,需增加用户标识,然后增加门店用户扩展信息*/
|
|
|
+ SysUser user = sysUserMapper.selectUserByLoginName(loginName);
|
|
|
+ user.setPhonenumber(userPhone);
|
|
|
+ //允许同步自动用户
|
|
|
+ if (("0").equals(user.getIsSync())) {
|
|
|
+ //查询该用户是否存在该接口返回中
|
|
|
+ user.setPhonenumber(userPhone);
|
|
|
+ user.setUserName(userName);
|
|
|
+ user.setIsShopAccount("1");
|
|
|
+ sysUserService.updateUserInfo(user);
|
|
|
+
|
|
|
+ /**======== 构建门店用户扩展信息表 start===============*/
|
|
|
+ //先删除用户门店扩展表,再插入
|
|
|
+ userShopExtMapper.deletePhysicsUserShopExt(user.getUserId().toString(),loginName,shopCode,usertype);
|
|
|
+ SysUserShopExt shopExt = new SysUserShopExt();
|
|
|
+ shopExt.setLoginName(loginName);
|
|
|
+ shopExt.setShopCode(shopCode);
|
|
|
+ shopExt.setShopName(shopName);
|
|
|
+ shopExt.setSubofficeCode(subOfficeCode);
|
|
|
+ shopExt.setSubofficeName(subOfficeName);
|
|
|
+ shopExt.setIsShopType(usertype);
|
|
|
+ shopExt.setUserUpdateTime(dataUpdateTime);
|
|
|
+ shopExt.setDelFlag("0");
|
|
|
+ shopExt.setConstraintUserId(dataUserId);
|
|
|
+ //用户id
|
|
|
+ shopExt.setUserId(user.getUserId().toString());
|
|
|
+ userShopExtMapper.insertSysUserShopExt(shopExt);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }catch (Exception e){
|
|
|
+ log.error("门店用户数据分析异常"+e.getMessage());
|
|
|
+ e.printStackTrace();
|
|
|
+ SyncFailDetail syncFailDetail = new SyncFailDetail();
|
|
|
+ syncFailDetail.setFailReason(e.getMessage());
|
|
|
+ syncFailDetail.setDataJson(jo.toJSONString());
|
|
|
+ syncFailDetail.setFailLevel("1");
|
|
|
+ syncFailDetail.setExceptionType(e.getClass().getSimpleName());
|
|
|
+ failDetails.add(syncFailDetail);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @description: 新esbq请求头
|
|
|
+ * @param: []
|
|
|
+ * @return: java.util.Map<java.lang.String,java.lang.String>
|
|
|
+ * @author: njs
|
|
|
+ * @date: 2025/8/21 15:55
|
|
|
+ */
|
|
|
+ public Map<String, String> HeaderToMap() {
|
|
|
+ String XAppId = ssbAppid;
|
|
|
+ String APiKey = ssbApiKey;
|
|
|
+ Map<String, String> headers = new HashMap<String, String>(2);
|
|
|
+ headers.put("X-App-Id", XAppId);
|
|
|
+ headers.put("X-Timestamp", new Date().toString());
|
|
|
+ headers.put("X-Sequence-No", UUID.randomUUID().toString());
|
|
|
+ headers.put("APIKey", APiKey);
|
|
|
+ headers.put("Accept-Encoding", "identity");
|
|
|
+ return headers;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @description: 新增用户和角色
|
|
|
+ * @param: [user]
|
|
|
+ * @return: java.lang.Integer
|
|
|
+ * @author: njs
|
|
|
+ * @date: 2025/8/20 9:32
|
|
|
+ */
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public Integer insertUserAndExt(SysUser user) {
|
|
|
+ // 新增用户信息
|
|
|
+ int rows = sysUserMapper.insertUser(user);
|
|
|
+
|
|
|
+ return rows;
|
|
|
+ }
|
|
|
+}
|