Selaa lähdekoodia

add:软通用户同步

caozixuan 1 vuosi sitten
vanhempi
commit
98389c8b28

+ 12 - 0
sop-business/src/main/java/com/qmth/sop/business/entity/SysUser.java

@@ -5,6 +5,7 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize;
 import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
 import com.qmth.sop.common.base.BaseEntity;
 import com.qmth.sop.common.enums.GenderEnum;
+import com.qmth.sop.common.enums.RtzfSyncStatusEnum;
 import com.qmth.sop.common.enums.UserSourceEnum;
 import com.qmth.sop.common.util.Base64Util;
 import io.swagger.annotations.ApiModel;
@@ -75,6 +76,9 @@ public class SysUser extends BaseEntity implements Serializable {
     @ApiModelProperty(value = "来源,SYSTEM:系统自带,ARCHIVES:档案")
     private UserSourceEnum source;
 
+    @ApiModelProperty("软通智服用户同步状态")
+    private RtzfSyncStatusEnum rtzfSyncStatus;
+
     @JsonSerialize(using = ToStringSerializer.class)
     @TableField(exist = false)
     @NotEmpty(message = "请选择角色")
@@ -209,4 +213,12 @@ public class SysUser extends BaseEntity implements Serializable {
     public void setRemark(String remark) {
         this.remark = remark;
     }
+
+    public RtzfSyncStatusEnum getRtzfSyncStatus() {
+        return rtzfSyncStatus;
+    }
+
+    public void setRtzfSyncStatus(RtzfSyncStatusEnum rtzfSyncStatus) {
+        this.rtzfSyncStatus = rtzfSyncStatus;
+    }
 }

+ 18 - 0
sop-business/src/main/java/com/qmth/sop/business/service/SysUserService.java

@@ -8,6 +8,8 @@ import com.qmth.sop.business.bean.dto.OrgUserNameDto;
 import com.qmth.sop.business.bean.dto.UserDto;
 import com.qmth.sop.business.bean.result.*;
 import com.qmth.sop.business.entity.SysUser;
+import com.qmth.sop.business.sync.been.rtzf.RtzfResult;
+import com.qmth.sop.business.sync.been.rtzf.RtzfUserInfo;
 import com.qmth.sop.common.enums.*;
 
 import java.security.NoSuchAlgorithmException;
@@ -189,4 +191,20 @@ public interface SysUserService extends IService<SysUser> {
      * @return
      */
     List<OrgUserNameDto> findOrgUserName(List<Long> userIds);
+
+    /**
+     * 根据用户id查询用户所在公司名称
+     *
+     * @param userId 用户id
+     * @return 公司名称
+     */
+    String findUserCompanyName(Long userId);
+
+    /**
+     * 软通智服更新用户
+     * @param requestUser 请求的用户
+     * @param willUpdateUser 将要更新的用户
+     * @return 更新结果
+     */
+    RtzfResult rtzfUpdateUser(SysUser requestUser, SysUser willUpdateUser);
 }

+ 7 - 5
sop-business/src/main/java/com/qmth/sop/business/service/impl/SsoServiceImpl.java

@@ -9,7 +9,6 @@ import com.qmth.sop.common.contant.SystemConstant;
 import org.springframework.stereotype.Service;
 
 import javax.annotation.Resource;
-import java.util.StringJoiner;
 
 /**
  * @Description: sso单点登录服务实现类
@@ -25,12 +24,15 @@ public class SsoServiceImpl implements SsoService {
 
     @Override
     public String rtzfSsoLogin(SysUser requestUser) {
+        String tenantId = "ceshitanantId";
         String ssoUrl = sysConfigService.findByConfigKey(SystemConstant.RTZF_OSS_LOGIN_URL).getConfigValue();
         String token = rtzfApiUtils.getRtzfToken(requestUser, LoginTypeEnum.SSO_LOGIN);
 
-        StringJoiner redirectUrlJoiner = new StringJoiner("");
-        redirectUrlJoiner.add(ssoUrl);
-        redirectUrlJoiner.add(SystemConstant.GET_UNKNOWN).add(SystemConstant.SIGNATURE).add(SystemConstant.GET_EQUAL).add(token);
-        return redirectUrlJoiner.toString();
+        String eg = "https://xxx.xxx.xxx/tenant/xxxx/xxxx/login?tenantId=xxxxx&token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJjdXJyZW50VGltZU1pbGxpcyI6IjE2OTAxNjI1OTUyNzAiLCJleHAiOjE2OTAxOTg1OTUsImFjY291bnQiOiJUTUMifQ.mCnhQFUouL-LXdQg_xc279HlyeAovGotItitPf_vO3k";
+        return ssoUrl +
+                SystemConstant.GET_UNKNOWN +
+                SystemConstant.RTZF_TENANT_ID + SystemConstant.GET_EQUAL + tenantId +
+                SystemConstant.GET_SYMBOL +
+                SystemConstant.TOKEN + SystemConstant.GET_EQUAL + token;
     }
 }

+ 107 - 14
sop-business/src/main/java/com/qmth/sop/business/service/impl/SysUserServiceImpl.java

@@ -14,6 +14,9 @@ import com.qmth.sop.business.cache.CommonCacheService;
 import com.qmth.sop.business.entity.*;
 import com.qmth.sop.business.mapper.SysUserMapper;
 import com.qmth.sop.business.service.*;
+import com.qmth.sop.business.sync.RtzfApiUtils;
+import com.qmth.sop.business.sync.been.rtzf.RtzfResult;
+import com.qmth.sop.business.sync.been.rtzf.RtzfUserInfo;
 import com.qmth.sop.business.util.AuthUtil;
 import com.qmth.sop.common.contant.SpringContextHolder;
 import com.qmth.sop.common.contant.SystemConstant;
@@ -58,6 +61,9 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
     @Resource
     TBUserArchivesService tbUserArchivesService;
 
+    @Resource
+    RtzfApiUtils rtzfApiUtils;
+
     @Override
     public LoginResult login(String password, SysUser sysUser, AppSourceEnum appSource) throws NoSuchAlgorithmException {
         //停用
@@ -68,7 +74,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
         String deviceId = ServletUtil.getRequestDeviceId();
         //添加用户鉴权缓存
         AuthBean authBean = commonCacheService.userAuthCache(sysUser.getId());
-        Optional.ofNullable(authBean).orElseThrow(() -> ExceptionResultEnum.ROLE_ENABLE_AUTHORIZATION.exception());
+        Optional.ofNullable(authBean).orElseThrow(ExceptionResultEnum.ROLE_ENABLE_AUTHORIZATION::exception);
 
         List<SysRole> sysRoleList = authBean.getRoleList().stream().filter(s -> s.getType() == RoleTypeEnum.EFFECT_ENGINEER || s.getType() == RoleTypeEnum.ASSISTANT_ENGINEER).collect(Collectors.toList());
         if (appSource == AppSourceEnum.WX_APP && CollectionUtils.isEmpty(sysRoleList)) {
@@ -95,7 +101,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
         tbSessionService.saveOrUpdate(tbSession);
         commonCacheService.setUserSession(sessionId, tbSession);
 
-        LoginResult loginResult = new LoginResult(sysUser, sessionId, token, Objects.nonNull(roleTypes) && roleTypes.size() > 0 ? roleTypes : roleNamesSet, appSource, SystemConstant.VERSION_VALUE);
+        LoginResult loginResult = new LoginResult(sysUser, sessionId, token, roleTypes.size() > 0 ? roleTypes : roleNamesSet, appSource, SystemConstant.VERSION_VALUE);
         // 添加档案信息
         if (UserSourceEnum.ARCHIVES.equals(sysUser.getSource())) {
             TBUserArchives tbUserArchives = tbUserArchivesService.findByUserId(sysUser.getId());
@@ -116,7 +122,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
     @Override
     public Boolean removeUserInfo(Long userId, boolean all) throws NoSuchAlgorithmException {
         AuthBean authBean = commonCacheService.userAuthCache(userId);
-        Optional.ofNullable(authBean).orElseThrow(() -> ExceptionResultEnum.NOT_LOGIN.exception());
+        Optional.ofNullable(authBean).orElseThrow(ExceptionResultEnum.NOT_LOGIN::exception);
         if (all) {
             for (Platform p : Platform.values()) {
                 Set<String> roleNamesSet = authBean.getRoleList().stream().map(s -> s.getName()).collect(Collectors.toSet());
@@ -314,17 +320,18 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
             if (Objects.isNull(sysUser.getId())) {//新增用户
                 sysUser.insertInfo(requestUser.getId());
                 sysUser.setPasswordInfo(sysUser.getMobileNumber());
+                sysUser.setRtzfSyncStatus(RtzfSyncStatusEnum.NEED_SYNC);
                 sysUserService.save(sysUser);
                 sysUserRoleService.addUserRolePrivilege(sysUser, sysUser.getRoleIds());
             } else {//修改用户
                 SysUser dbUser = this.getById(sysUser.getId());
-                Optional.ofNullable(dbUser).orElseThrow(() -> ExceptionResultEnum.USER_NO_EXISTS.exception());
-
+                Optional.ofNullable(dbUser).orElseThrow(ExceptionResultEnum.USER_NO_EXISTS::exception);
                 List<SysUserRole> sysUserRoleList = commonCacheService.userRolePrivilegeCache(sysUser.getId());
                 List<Long> userRolesList = Arrays.asList(sysUser.getRoleIds());
                 Set<Long> dbUserRolesList = sysUserRoleList.stream().map(SysUserRole::getRoleId).collect(Collectors.toSet());
                 int count = (int) dbUserRolesList.stream().filter(s -> !userRolesList.contains(s)).count();
-                sysUserService.update(new UpdateWrapper<SysUser>().lambda()
+                UpdateWrapper<SysUser> userUpdateWrapper = new UpdateWrapper<>();
+                userUpdateWrapper.lambda()
                         .eq(SysUser::getId, sysUser.getId())
                         .set(SysUser::getLoginName, sysUser.getLoginName())
                         .set(SysUser::getRealName, sysUser.getRealName())
@@ -333,8 +340,15 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
                         .set(SysUser::getGender, sysUser.getGender())
                         .set(SysUser::getOrgId, sysUser.getOrgId())
                         .set(SysUser::getUpdateId, requestUser.getId())
-                        .set(SysUser::getUpdateTime, System.currentTimeMillis())
-                );
+                        .set(SysUser::getUpdateTime, System.currentTimeMillis());
+
+                RtzfSyncStatusEnum rtzfSyncStatus = dbUser.getRtzfSyncStatus();
+                if (RtzfSyncStatusEnum.ALREADY_SYNC.equals(rtzfSyncStatus)) {
+                    dbUser.setRtzfSyncStatus(RtzfSyncStatusEnum.NEED_UPDATE);
+                    userUpdateWrapper.lambda().set(SysUser::getRtzfSyncStatus, RtzfSyncStatusEnum.NEED_UPDATE);
+                }
+
+                sysUserService.update(userUpdateWrapper);
                 //如果修改了角色,需要重新登录
                 if (count > 0 || dbUserRolesList.size() != userRolesList.size()) {
                     QueryWrapper<SysUserRole> sysUserRoleQueryWrapper = new QueryWrapper<>();
@@ -387,13 +401,21 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
         Optional.ofNullable(sysUser.getEnable()).orElseThrow(() -> ExceptionResultEnum.ERROR.exception("启用/禁用不能为空"));
 
         SysUser sysUserDb = this.getById(sysUser.getId());
-        Optional.ofNullable(sysUserDb).orElseThrow(() -> ExceptionResultEnum.USER_NO_EXISTS.exception());
+        Optional.ofNullable(sysUserDb).orElseThrow(ExceptionResultEnum.USER_NO_EXISTS::exception);
 
         SysUser requestUser = (SysUser) ServletUtil.getRequestUser();
-        boolean success = this.update(new UpdateWrapper<SysUser>().lambda().set(SysUser::getEnable, sysUser.getEnable())
+        UpdateWrapper<SysUser> userUpdateWrapper = new UpdateWrapper<>();
+        userUpdateWrapper.lambda().set(SysUser::getEnable, sysUser.getEnable())
                 .eq(SysUser::getId, sysUser.getId())
                 .set(SysUser::getUpdateId, requestUser.getId())
-                .set(SysUser::getUpdateTime, System.currentTimeMillis()));
+                .set(SysUser::getUpdateTime, System.currentTimeMillis());
+
+        RtzfSyncStatusEnum rtzfSyncStatus = sysUserDb.getRtzfSyncStatus();
+        if (RtzfSyncStatusEnum.ALREADY_SYNC.equals(rtzfSyncStatus)) {
+            userUpdateWrapper.lambda().set(SysUser::getRtzfSyncStatus, RtzfSyncStatusEnum.NEED_UPDATE);
+        }
+        boolean success = this.update(userUpdateWrapper);
+
         if (success) {
             commonCacheService.updateUserCache(sysUser.getId());
             //如果状态为禁用,需要踢下线重新登录
@@ -435,13 +457,21 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
         Optional.ofNullable(sysUser.getNewPassword()).orElseThrow(() -> ExceptionResultEnum.ERROR.exception("新密码不能为空"));
 
         SysUser sysUserDb = this.getById(sysUser.getId());
-        Optional.ofNullable(sysUserDb).orElseThrow(() -> ExceptionResultEnum.USER_NO_EXISTS.exception());
+        Optional.ofNullable(sysUserDb).orElseThrow(ExceptionResultEnum.USER_NO_EXISTS::exception);
 
         SysUser requestUser = (SysUser) ServletUtil.getRequestUser();
-        boolean success = this.update(new UpdateWrapper<SysUser>().lambda().set(SysUser::getPassword, sysUser.getNewPassword())
+        UpdateWrapper<SysUser> updateWrapper = new UpdateWrapper<>();
+        updateWrapper.lambda().set(SysUser::getPassword, sysUser.getNewPassword())
                 .eq(SysUser::getId, sysUser.getId())
                 .set(SysUser::getUpdateId, requestUser.getId())
-                .set(SysUser::getUpdateTime, System.currentTimeMillis()));
+                .set(SysUser::getUpdateTime, System.currentTimeMillis());
+
+        RtzfSyncStatusEnum rtzfSyncStatus = sysUserDb.getRtzfSyncStatus();
+        if (RtzfSyncStatusEnum.ALREADY_SYNC.equals(rtzfSyncStatus)) {
+            updateWrapper.lambda().set(SysUser::getRtzfSyncStatus, RtzfSyncStatusEnum.NEED_UPDATE);
+        }
+
+        boolean success = this.update(updateWrapper);
         if (success) {
             commonCacheService.updateUserCache(sysUser.getId());
             //修改密码后,需要踢下线重新登录
@@ -464,6 +494,10 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
         Optional.ofNullable(sysUser.getId()).orElseThrow(() -> ExceptionResultEnum.ERROR.exception("id不能为空"));
 
         SysUser sysUserDb = this.getById(sysUser.getId());
+        RtzfSyncStatusEnum rtzfSyncStatus = sysUserDb.getRtzfSyncStatus();
+        if (RtzfSyncStatusEnum.ALREADY_SYNC.equals(rtzfSyncStatus)) {
+            sysUserDb.setRtzfSyncStatus(RtzfSyncStatusEnum.NEED_UPDATE);
+        }
         Optional.ofNullable(sysUserDb).orElseThrow(() -> ExceptionResultEnum.USER_NO_EXISTS.exception());
 
         SysUser requestUser = (SysUser) ServletUtil.getRequestUser();
@@ -548,4 +582,63 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
     public List<OrgUserNameDto> findOrgUserName(List<Long> userIds) {
         return this.baseMapper.findOrgUserName(userIds);
     }
+
+    @Override
+    public String findUserCompanyName(Long userId) {
+        String companyName = "";
+        SysUser sysUser = this.getById(userId);
+        UserSourceEnum userSource = sysUser.getSource();
+        switch (userSource) {
+            case SYSTEM:
+                companyName = "启明泰和";
+                break;
+            case ARCHIVES:
+                UserArchivesResult userArchivesResult = tbUserArchivesService.findUserArchivesByArchivesIdORUserId(null, userId);
+                if (Objects.nonNull(userArchivesResult)) {
+                    companyName = userArchivesResult.getSupplierName();
+                }
+                break;
+        }
+        return companyName;
+    }
+
+    @Transactional
+    @Override
+    public RtzfResult rtzfUpdateUser(SysUser requestUser, SysUser willUpdateUser) {
+        Long id = willUpdateUser.getId();
+        RtzfUserInfo rtzfUserInfo = new RtzfUserInfo();
+        rtzfUserInfo.setUserName(String.valueOf(id));
+        rtzfUserInfo.setRealName(willUpdateUser.getRealName());
+
+        String companyName = this.findUserCompanyName(id);
+        if (companyName != null && companyName.length() > 0) {
+            rtzfUserInfo.setCompanyName(companyName);
+        }
+        rtzfUserInfo.setPhoneNo(willUpdateUser.getMobileNumber());
+        // TODO: 2023/11/27 密码要解密再加密
+        String password = willUpdateUser.getPassword();
+        rtzfUserInfo.setPassword(password);
+        rtzfUserInfo.setVerifyPassword(password);
+        GenderEnum gender = willUpdateUser.getGender();
+        rtzfUserInfo.setSex(GenderEnum.MAN.equals(gender) ? 1 : 0);
+        rtzfUserInfo.setWorkNo(String.valueOf(id));
+        rtzfUserInfo.setState(0);
+
+        // 0 为启用,1 为禁用
+        Boolean enable = willUpdateUser.getEnable();
+        rtzfUserInfo.setWorkState(enable ? 0 : 1);
+        List<Long> roleIdList = sysRoleService.listRolesByUserId(id)
+                .stream()
+                .map(RoleDto::getId)
+                .collect(Collectors.toList());
+        if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(roleIdList)) {
+            rtzfUserInfo.setRoleIds(roleIdList);
+        }
+        RtzfResult rtzfResult = rtzfApiUtils.updateUser(requestUser, rtzfUserInfo);
+        if (Objects.nonNull(rtzfResult) && "0".equals(rtzfResult.getCode())) {
+            willUpdateUser.setRtzfSyncStatus(RtzfSyncStatusEnum.ALREADY_SYNC);
+            this.updateById(willUpdateUser);
+        }
+        return rtzfResult;
+    }
 }

+ 23 - 0
sop-business/src/main/java/com/qmth/sop/business/sync/RtzfApiUtils.java

@@ -114,4 +114,27 @@ public class RtzfApiUtils {
             throw ExceptionResultEnum.ERROR.exception(e.getMessage());
         }
     }
+
+    /**
+     * 用户信息更新
+     *
+     * @param requestUser  请求用户
+     * @param rtzfUserInfo 用户信息
+     */
+    public RtzfResult updateUser(SysUser requestUser, RtzfUserInfo rtzfUserInfo) {
+        try {
+            String token = this.getRtzfToken(requestUser, LoginTypeEnum.API_LOGIN);
+
+            Map<String, Object> map = new HashMap<>();
+            map.put("tenantId", commonUtils.validParam(tenantId, null, true, "租户 ID"));
+            map.put("userInfo", rtzfUserInfo);
+            String requestJson = JacksonUtil.parseJson(map);
+
+            String result = HttpUtil.postJson(loginUrl, requestJson, token, null, false);
+            RtzfResult rtzfResult = JSONObject.parseObject(result, RtzfResult.class);
+            return rtzfResult;
+        } catch (Exception e) {
+            throw ExceptionResultEnum.ERROR.exception(e.getMessage());
+        }
+    }
 }

+ 11 - 0
sop-business/src/main/java/com/qmth/sop/business/sync/been/rtzf/RtzfUserInfo.java

@@ -15,6 +15,9 @@ public class RtzfUserInfo {
     @ApiModelProperty("账号名称")
     private String userName;
 
+    @ApiModelProperty("真实姓名")
+    private String realName;
+
     @ApiModelProperty("邮箱")
     private String email;
 
@@ -65,6 +68,14 @@ public class RtzfUserInfo {
         this.userName = userName;
     }
 
+    public String getRealName() {
+        return realName;
+    }
+
+    public void setRealName(String realName) {
+        this.realName = realName;
+    }
+
     public String getEmail() {
         return email;
     }

+ 71 - 0
sop-business/src/main/java/com/qmth/sop/business/templete/execute/AsyncRtzfUserPushService.java

@@ -0,0 +1,71 @@
+package com.qmth.sop.business.templete.execute;
+
+import cn.hutool.core.date.DateUtil;
+import com.qmth.boot.api.exception.ApiException;
+import com.qmth.sop.business.entity.TBTask;
+import com.qmth.sop.business.service.TBTaskService;
+import com.qmth.sop.business.templete.service.TaskLogicService;
+import com.qmth.sop.business.templete.syncData.AsyncSyncDataTaskTemplate;
+import com.qmth.sop.common.contant.SystemConstant;
+import com.qmth.sop.common.enums.TaskResultEnum;
+import com.qmth.sop.common.enums.TaskStatusEnum;
+import com.qmth.sop.common.util.Result;
+import com.qmth.sop.common.util.ResultUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.text.MessageFormat;
+import java.util.Date;
+import java.util.Map;
+import java.util.StringJoiner;
+
+/**
+ * @Description: 软通智服用户同步定时任务
+ * @Author: CaoZixuan
+ * @Date: 2023-11-27
+ */
+@Service
+public class AsyncRtzfUserPushService extends AsyncSyncDataTaskTemplate {
+    private final static Logger log = LoggerFactory.getLogger(AsyncRtzfUserPushService.class);
+
+    @Resource
+    TaskLogicService taskLogicService;
+
+    @Resource
+    TBTaskService tbTaskService;
+
+    public static final String OBJ_TITLE = "软通智服用户推送";
+
+    @Override
+    public Result syncData(Map<String, Object> map) throws Exception {
+        TBTask tbTask = (TBTask) map.get(SystemConstant.TASK);
+        StringJoiner stringJoinerSummary = new StringJoiner("\n").add(MessageFormat.format("{0}{1}{2}", DateUtil.format(new Date(), SystemConstant.DEFAULT_DATE_PATTERN), BEGIN_TITLE, OBJ_TITLE));
+        tbTask.setStatus(TaskStatusEnum.RUNNING);
+        tbTask.setSummary(stringJoinerSummary.toString());
+        tbTaskService.updateById(tbTask);
+        try {
+            // 执行软通智服用户推送任务
+            Map<String, Object> result = taskLogicService.executeSyncRtzfUserPush(map);
+            int successSize = Integer.parseInt(String.valueOf(result.get(SystemConstant.SUCCESS)));
+            int errorSize = Integer.parseInt(String.valueOf(result.get(SystemConstant.RESULT_ERROR)));
+            stringJoinerSummary.add(MessageFormat.format("{0}{1}{2}{3}{4}{5}{6}{7}", DateUtil.format(new Date(), SystemConstant.DEFAULT_DATE_PATTERN), FINISH_TITLE, (successSize + errorSize), FINISH_TOTAL_SIZE, successSize, FINISH_SUCCESS_SIZE, errorSize, FINISH_ERROR_SIZE));
+            tbTask.setResult(TaskResultEnum.SUCCESS);
+        } catch (Exception e) {
+            log.error(SystemConstant.LOG_ERROR, e);
+            stringJoinerSummary.add(MessageFormat.format("{0}{1}{2}{3}", DateUtil.format(new Date(), SystemConstant.DEFAULT_DATE_PATTERN), EXCEPTION_TITLE, EXCEPTION_DATA, e.getMessage()));
+            tbTask.setResult(TaskResultEnum.ERROR);
+            if (e instanceof ApiException) {
+                ResultUtil.error((ApiException) e, ((ApiException) e).getCode(), e.getMessage());
+            } else {
+                ResultUtil.error(e.getMessage());
+            }
+            tbTask.setResult(TaskResultEnum.ERROR);
+        } finally {//生成txt文件
+            tbTask.setSummary(stringJoinerSummary.toString());
+            super.createTxt(tbTask);
+        }
+        return ResultUtil.ok(map);
+    }
+}

+ 71 - 0
sop-business/src/main/java/com/qmth/sop/business/templete/execute/AsyncRtzfUserUpdateBatchService.java

@@ -0,0 +1,71 @@
+package com.qmth.sop.business.templete.execute;
+
+import cn.hutool.core.date.DateUtil;
+import com.qmth.boot.api.exception.ApiException;
+import com.qmth.sop.business.entity.TBTask;
+import com.qmth.sop.business.service.TBTaskService;
+import com.qmth.sop.business.templete.service.TaskLogicService;
+import com.qmth.sop.business.templete.syncData.AsyncSyncDataTaskTemplate;
+import com.qmth.sop.common.contant.SystemConstant;
+import com.qmth.sop.common.enums.TaskResultEnum;
+import com.qmth.sop.common.enums.TaskStatusEnum;
+import com.qmth.sop.common.util.Result;
+import com.qmth.sop.common.util.ResultUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.text.MessageFormat;
+import java.util.Date;
+import java.util.Map;
+import java.util.StringJoiner;
+
+/**
+ * @Description: 软通智服用户批量更新
+ * @Author: CaoZixuan
+ * @Date: 2023-11-27
+ */
+@Service
+public class AsyncRtzfUserUpdateBatchService extends AsyncSyncDataTaskTemplate {
+    private final static Logger log = LoggerFactory.getLogger(AsyncRtzfUserUpdateBatchService.class);
+
+    @Resource
+    TaskLogicService taskLogicService;
+
+    @Resource
+    TBTaskService tbTaskService;
+
+    public static final String OBJ_TITLE = "软通智服用户更新";
+
+    @Override
+    public Result syncData(Map<String, Object> map) throws Exception {
+        TBTask tbTask = (TBTask) map.get(SystemConstant.TASK);
+        StringJoiner stringJoinerSummary = new StringJoiner("\n").add(MessageFormat.format("{0}{1}{2}", DateUtil.format(new Date(), SystemConstant.DEFAULT_DATE_PATTERN), BEGIN_TITLE, OBJ_TITLE));
+        tbTask.setStatus(TaskStatusEnum.RUNNING);
+        tbTask.setSummary(stringJoinerSummary.toString());
+        tbTaskService.updateById(tbTask);
+        try {
+            // 执行软通智服用户推送任务
+            Map<String, Object> result = taskLogicService.executeSyncRtzfUserUpdate(map);
+            int successSize = Integer.parseInt(String.valueOf(result.get(SystemConstant.SUCCESS)));
+            int errorSize = Integer.parseInt(String.valueOf(result.get(SystemConstant.RESULT_ERROR)));
+            stringJoinerSummary.add(MessageFormat.format("{0}{1}{2}{3}{4}{5}{6}{7}", DateUtil.format(new Date(), SystemConstant.DEFAULT_DATE_PATTERN), FINISH_TITLE, (successSize + errorSize), FINISH_TOTAL_SIZE, successSize, FINISH_SUCCESS_SIZE, errorSize, FINISH_ERROR_SIZE));
+            tbTask.setResult(TaskResultEnum.SUCCESS);
+        } catch (Exception e) {
+            log.error(SystemConstant.LOG_ERROR, e);
+            stringJoinerSummary.add(MessageFormat.format("{0}{1}{2}{3}", DateUtil.format(new Date(), SystemConstant.DEFAULT_DATE_PATTERN), EXCEPTION_TITLE, EXCEPTION_DATA, e.getMessage()));
+            tbTask.setResult(TaskResultEnum.ERROR);
+            if (e instanceof ApiException) {
+                ResultUtil.error((ApiException) e, ((ApiException) e).getCode(), e.getMessage());
+            } else {
+                ResultUtil.error(e.getMessage());
+            }
+            tbTask.setResult(TaskResultEnum.ERROR);
+        } finally {//生成txt文件
+            tbTask.setSummary(stringJoinerSummary.toString());
+            super.createTxt(tbTask);
+        }
+        return ResultUtil.ok(map);
+    }
+}

+ 18 - 0
sop-business/src/main/java/com/qmth/sop/business/templete/service/TaskLogicService.java

@@ -92,4 +92,22 @@ public interface TaskLogicService {
      * @throws Exception 异常
      */
     Map<String, Object> executeSyncFxxkData(Map<String, Object> map) throws Exception;
+
+    /**
+     * 执行软通智服同步用户
+     *
+     * @param map 数据
+     * @return 结果
+     * @throws Exception 异常
+     */
+    Map<String, Object> executeSyncRtzfUserPush(Map<String, Object> map) throws Exception;
+
+    /**
+     * 执行软通智服用户更新
+     *
+     * @param map 数据
+     * @return 结果
+     * @throws Exception 异常
+     */
+    Map<String, Object> executeSyncRtzfUserUpdate(Map<String, Object> map) throws Exception;
 }

+ 94 - 1
sop-business/src/main/java/com/qmth/sop/business/templete/service/impl/TaskLogicServiceImpl.java

@@ -11,6 +11,9 @@ import com.qmth.sop.business.bean.result.TBDingAttendanceResult;
 import com.qmth.sop.business.bean.result.TBDingSubmitQueryResult;
 import com.qmth.sop.business.entity.*;
 import com.qmth.sop.business.service.*;
+import com.qmth.sop.business.sync.RtzfApiUtils;
+import com.qmth.sop.business.sync.been.rtzf.RtzfResult;
+import com.qmth.sop.business.sync.been.rtzf.RtzfUserInfo;
 import com.qmth.sop.business.templete.service.TaskLogicService;
 import com.qmth.sop.business.util.ImportExportUtil;
 import com.qmth.sop.business.util.excel.BasicExcelListener;
@@ -33,6 +36,7 @@ import java.util.*;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 /**
  * @Description: 任务处理逻辑impl
@@ -92,6 +96,9 @@ public class TaskLogicServiceImpl implements TaskLogicService {
     @Resource
     private TBCrmService tbCrmService;
 
+    @Resource
+    private RtzfApiUtils rtzfApiUtils;
+
     /**
      * 处理导入人员档案数据
      *
@@ -362,7 +369,7 @@ public class TaskLogicServiceImpl implements TaskLogicService {
         File fileTemp = null;
         try {
             fileTemp = SystemConstant.getFileTempVar(SystemConstant.XLSX_PREFIX);
-            List<TBDingAttendanceResult> tbDingAttendanceResults = tbDingService.attendanceQuery((Long) map.get("serviceId"), (String) map.get("userName"), (Long) map.get("startTime"), (Long) map.get("endTime"), (Long) map.get("supplierId"), (String) map.get("custom"), (String) map.get("sopNo"), (InOutTypeEnum) map.get("type"), (DingResultEnum) map.get("status"),(Long) map.get("abnormal"));
+            List<TBDingAttendanceResult> tbDingAttendanceResults = tbDingService.attendanceQuery((Long) map.get("serviceId"), (String) map.get("userName"), (Long) map.get("startTime"), (Long) map.get("endTime"), (Long) map.get("supplierId"), (String) map.get("custom"), (String) map.get("sopNo"), (InOutTypeEnum) map.get("type"), (DingResultEnum) map.get("status"), (Long) map.get("abnormal"));
 
 //            tbDingAttendanceResults.forEach(e -> {
 //                //e.setStatus(FlowStatusEnum.convertToEnum(e.getStatus()).getTitle());
@@ -552,4 +559,90 @@ public class TaskLogicServiceImpl implements TaskLogicService {
     public Map<String, Object> executeSyncFxxkData(Map<String, Object> map) {
         return tbCrmService.syncCrmFromFxxk(map);
     }
+
+    @Transactional
+    @Override
+    public Map<String, Object> executeSyncRtzfUserPush(Map<String, Object> map) {
+        // 需要同步的用户
+        List<SysUser> sysUserList = sysUserService.list(new QueryWrapper<SysUser>().lambda().eq(SysUser::getRtzfSyncStatus, RtzfSyncStatusEnum.NEED_SYNC));
+        List<RtzfUserInfo> rtzfUserInfoList = sysUserList.stream().flatMap(e -> {
+            Long id = e.getId();
+            RtzfUserInfo rtzfUserInfo = new RtzfUserInfo();
+            rtzfUserInfo.setUserName(String.valueOf(id));
+            rtzfUserInfo.setRealName(e.getRealName());
+
+            String companyName = sysUserService.findUserCompanyName(id);
+            if (companyName != null && companyName.length() > 0) {
+                rtzfUserInfo.setCompanyName(companyName);
+            }
+            rtzfUserInfo.setPhoneNo(e.getMobileNumber());
+            // TODO: 2023/11/27 密码要解密再加密
+            String password = e.getPassword();
+            rtzfUserInfo.setPassword(password);
+            rtzfUserInfo.setVerifyPassword(password);
+            GenderEnum gender = e.getGender();
+            rtzfUserInfo.setSex(GenderEnum.MAN.equals(gender) ? 1 : 0);
+            rtzfUserInfo.setWorkNo(String.valueOf(id));
+            rtzfUserInfo.setState(0);
+
+            // 0 为启用,1 为禁用
+            Boolean enable = e.getEnable();
+            rtzfUserInfo.setWorkState(enable ? 0 : 1);
+            List<Long> roleIdList = sysRoleService.listRolesByUserId(id)
+                    .stream()
+                    .map(RoleDto::getId)
+                    .collect(Collectors.toList());
+            if (CollectionUtils.isNotEmpty(roleIdList)) {
+                rtzfUserInfo.setRoleIds(roleIdList);
+            }
+            return Stream.of(rtzfUserInfo);
+        }).collect(Collectors.toList());
+        SysUser requestUser = (SysUser) map.get(SystemConstant.USER);
+        rtzfApiUtils.pushUserBatch(requestUser, rtzfUserInfoList);
+        sysUserList = sysUserList
+                .stream()
+                .peek(e -> e.setRtzfSyncStatus(RtzfSyncStatusEnum.ALREADY_SYNC))
+                .collect(Collectors.toList());
+        sysUserService.updateBatchById(sysUserList);
+
+        map.put(SystemConstant.SUCCESS, sysUserList.size());
+        map.put(SystemConstant.RESULT_ERROR, 0);
+        return map;
+    }
+
+    @Override
+    public Map<String, Object> executeSyncRtzfUserUpdate(Map<String, Object> map) {
+        SysUser requestUser = (SysUser) map.get(SystemConstant.USER);
+        List<SysUser> sysUserList = sysUserService.list(new QueryWrapper<SysUser>()
+                .lambda().eq(SysUser::getRtzfSyncStatus, RtzfSyncStatusEnum.NEED_UPDATE));
+        int successCount = 0;
+        int errorCount = 0;
+        List<String> errorList = new ArrayList<>();
+        for (SysUser sysUser : sysUserList) {
+            RtzfResult rtzfResult = null;
+            try {
+                rtzfResult = sysUserService.rtzfUpdateUser(requestUser, sysUser);
+                if (Objects.isNull(rtzfResult)) {
+                    errorCount++;
+                    throw ExceptionResultEnum.ERROR.exception("用户更新无返回结果");
+                }
+            } catch (Exception e) {
+                log.error("软通智服用户更新接口同步失败 :用户id : {}", sysUser.getId());
+            }
+            if (Objects.nonNull(rtzfResult) && !"0".equals(rtzfResult.getCode())) {
+                String msg = rtzfResult.getMsg();
+                String error = String.format("用户[%s]账号信息更新失败 : [%s]" + sysUser.getRealName(), msg);
+                errorList.add(error);
+                errorCount++;
+            } else {
+                successCount++;
+            }
+        }
+        if (CollectionUtils.isNotEmpty(errorList)) {
+            throw ExceptionResultEnum.ERROR.exception(String.join("\n", errorList));
+        }
+        map.put(SystemConstant.SUCCESS, successCount);
+        map.put(SystemConstant.RESULT_ERROR, errorCount);
+        return map;
+    }
 }

+ 5 - 0
sop-business/src/main/resources/db/log/caozixuan_update_log.sql

@@ -387,3 +387,8 @@ INSERT INTO sys_privilege (id, name, url, type, parent_id, sequence, property, e
 UPDATE sys_privilege SET related = '2055' WHERE (id = '2054');
 UPDATE sys_privilege SET url = '/api/sso/rtzf/login' WHERE (id = '2055');
 
+
+-- 2023-11-24
+ALTER TABLE sys_user
+    ADD COLUMN rtzf_sync_status VARCHAR(20) NULL COMMENT '软通智服同步状态' AFTER source;
+

+ 1 - 0
sop-common/src/main/java/com/qmth/sop/common/contant/SystemConstant.java

@@ -109,6 +109,7 @@ public class SystemConstant {
     public static final String SYSTEM_AUTO_APPROVE = "系统自动审批";
     public static final String VALUE = "value";
     public static final String SOP = "SOP";
+    public static final String RTZF_TENANT_ID = "tenantId";
 
     /**
      * 微信app

+ 30 - 0
sop-common/src/main/java/com/qmth/sop/common/enums/RtzfSyncStatusEnum.java

@@ -0,0 +1,30 @@
+package com.qmth.sop.common.enums;
+
+/**
+ * @Description: 用户推送软通智服状态
+ * @Author: CaoZixuan
+ * @Date: 2023-11-24
+ */
+public enum RtzfSyncStatusEnum {
+    WITHOUT_SYNC("不需要同步","不需要同步"),
+    NEED_SYNC("需要同步","还从未成功执行用户同步定时任务的"),
+    ALREADY_SYNC("已经同步","成功执行用户同步定时任务或用户信息更新定时任务的"),
+    NEED_UPDATE("需要更新同步","用户在成功执行同步任务后又进行了编辑操作")
+    ;
+
+    RtzfSyncStatusEnum(String title, String desc) {
+        this.title = title;
+        this.desc = desc;
+    }
+
+    private final String title;
+    private final String desc;
+
+    public String getTitle() {
+        return title;
+    }
+
+    public String getDesc() {
+        return desc;
+    }
+}

+ 5 - 1
sop-common/src/main/java/com/qmth/sop/common/enums/TaskTypeEnum.java

@@ -27,7 +27,11 @@ public enum TaskTypeEnum {
 
     DEVICE_IMPORT("设备导入"),
 
-    CRM_SYNC("派单同步");
+    CRM_SYNC("派单同步"),
+
+    RTZF_USER_PUSH_SYNC("软通智服用户推送同步任务"),
+
+    RTZF_USER_UPDATE_SYNC("软通智服用户更新同步任务");
 
     private String title;
 

+ 0 - 1
sop-task/src/main/java/com/qmth/sop/task/start/StartRunning.java

@@ -61,7 +61,6 @@ public class StartRunning implements CommandLineRunner {
         quartzService.addJob(FlowTaskRemindJob.class, JobEnum.FLOW_TASK_REMIND_JOB.name(), JobEnum.FLOW_TASK_REMIND_JOB_GROUP.name(), sysConfig.getConfigValue(), flowTaskRemindJobMap);
         log.info("增加流程任务提醒定时任务 end");
 
-
         log.info("fxxk派单同步定时任务 start");
         Map<Object,Object> fxxkCrmSyncMap = new HashMap<>();
         fxxkCrmSyncMap.put(SystemConstant.NAME, FxxkCrmSyncJob.class.getName());