cuilei
6 天以前 b0ec9895cde2519bc085ac40acbeea89ae8b6f9d
lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/system/service/impl/ThirdAppWechatEnterpriseServiceImpl.java
@@ -1,5 +1,6 @@
package org.jeecg.modules.system.service.impl;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
@@ -14,6 +15,7 @@
import com.jeecg.qywx.api.user.vo.User;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.flowable.common.engine.impl.util.CollectionUtil;
import org.jeecg.common.api.dto.message.MessageDTO;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.system.util.JwtUtil;
@@ -23,6 +25,9 @@
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.config.JeecgBaseConfig;
import org.jeecg.config.thirdapp.ThirdAppConfig;
import org.jeecg.modules.qywx.message.MessageAPI;
import org.jeecg.modules.qywx.message.vo.TemplateCard;
import org.jeecg.modules.qywx.message.vo.TemplateCardEntity;
import org.jeecg.modules.system.entity.*;
import org.jeecg.modules.system.mapper.SysAnnouncementSendMapper;
import org.jeecg.modules.system.mapper.SysUserMapper;
@@ -31,6 +36,7 @@
import org.jeecg.modules.system.service.*;
import org.jeecg.modules.system.vo.thirdapp.JwDepartmentTreeVo;
import org.jeecg.modules.system.vo.thirdapp.SyncInfoVo;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
@@ -39,6 +45,7 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
/**
@@ -398,10 +405,10 @@
             * 2. 本地表里没有,就先用手机号判断,不通过再用username判断。
             */
            SysThirdAccount sysThirdAccount = sysThirdAccountService.getOneByThirdUserId(qwUser.getUserid(), THIRD_TYPE);
            List<SysUser> collect = sysUsersList.stream().filter(user -> (qwUser.getMobile().equals(user.getPhone()) || qwUser.getUserid().equals(user.getUsername()))
            List<SysUser> collect = sysUsersList.stream().filter(user -> qwUser.getUserid().equals(user.getWorkNo())
                                                                ).collect(Collectors.toList());
            if (collect != null && collect.size() > 0) {
            if (CollectionUtil.isNotEmpty(collect)) {
                SysUser sysUserTemp = collect.get(0);
                // 循环到此说明用户匹配成功,进行更新操作
                SysUser updateSysUser = this.qwUserToSysUser(qwUser, sysUserTemp);
@@ -413,7 +420,7 @@
                    this.syncUserCollectErrInfo(e, qwUser, syncInfo);
                }
                this.thirdAccountSaveOrUpdate(sysThirdAccount, updateSysUser.getId(), qwUser.getUserid());
                this.thirdAccountSaveOrUpdate(sysThirdAccount, updateSysUser.getId(), qwUser);
                // 更新完成,直接跳到下一次外部循环继续
            }else{
                // 没匹配到用户则走新增逻辑
@@ -425,7 +432,7 @@
                } catch (Exception e) {
                    this.syncUserCollectErrInfo(e, qwUser, syncInfo);
                }
                this.thirdAccountSaveOrUpdate(sysThirdAccount, newSysUser.getId(), qwUser.getUserid());
                this.thirdAccountSaveOrUpdate(sysThirdAccount, newSysUser.getId(), qwUser);
            }
        }
        return syncInfo;
@@ -447,6 +454,20 @@
            sysThirdAccount.setThirdType(THIRD_TYPE);
        }
        sysThirdAccount.setThirdUserId(qwUserId);
        sysThirdAccountService.saveOrUpdate(sysThirdAccount);
    }
    private void thirdAccountSaveOrUpdate(SysThirdAccount sysThirdAccount, String sysUserId, User qwUser) {
        if (sysThirdAccount == null) {
            sysThirdAccount = new SysThirdAccount();
            sysThirdAccount.setThirdUserId(qwUser.getUserid());
            sysThirdAccount.setRealname(qwUser.getName());
            sysThirdAccount.setThirdUserUuid(qwUser.getUserid());
            sysThirdAccount.setStatus(1);
            sysThirdAccount.setDelFlag(0);
            sysThirdAccount.setThirdType(THIRD_TYPE);
        }
        sysThirdAccount.setSysUserId(sysUserId);
        sysThirdAccountService.saveOrUpdate(sysThirdAccount);
    }
@@ -622,7 +643,7 @@
        sysUser.setDelFlag(0);
        sysUser.setStatus(1);
        // 通过 username 来关联
        sysUser.setUsername(user.getUserid());
        sysUser.setUsername(user.getUserid().substring(2));
        // 密码默认为 “123456”,随机加盐
        String password = "123456", salt = oConvertUtils.randomGen(8);
        String passwordEncode = PasswordUtil.encrypt(sysUser.getUsername(), password, salt);
@@ -643,22 +664,23 @@
        if (oConvertUtils.isEmpty(sysUser.getWorkNo())) {
            sysUser.setWorkNo(qwUser.getUserid());
        }
        try {
            sysUser.setSex(Integer.parseInt(qwUser.getGender()));
        } catch (NumberFormatException ignored) {
        }
        //企业微信接口更新后,不在返回 性别、邮箱、手机号码 字段
        //try {
        //    sysUser.setSex(Integer.parseInt(qwUser.getGender()));
        //} catch (NumberFormatException ignored) {
        //}
        // 因为唯一键约束的原因,如果原数据和旧数据相同,就不更新
        if (oConvertUtils.isNotEmpty(qwUser.getEmail()) && !qwUser.getEmail().equals(sysUser.getEmail())) {
            sysUser.setEmail(qwUser.getEmail());
        } else {
            sysUser.setEmail(null);
        }
        //if (oConvertUtils.isNotEmpty(qwUser.getEmail()) && !qwUser.getEmail().equals(sysUser.getEmail())) {
        //    sysUser.setEmail(qwUser.getEmail());
        //} else {
        //    sysUser.setEmail(null);
        //}
        // 因为唯一键约束的原因,如果原数据和旧数据相同,就不更新
        if (oConvertUtils.isNotEmpty(qwUser.getMobile()) && !qwUser.getMobile().equals(sysUser.getPhone())) {
            sysUser.setPhone(qwUser.getMobile());
        } else {
            sysUser.setPhone(null);
        }
        //if (oConvertUtils.isNotEmpty(qwUser.getMobile()) && !qwUser.getMobile().equals(sysUser.getPhone())) {
        //    sysUser.setPhone(qwUser.getMobile());
        //} else {
        //    sysUser.setPhone(null);
        //}
        // 启用/禁用成员(状态),规则不同,需要转换
        // 企业微信规则:1表示启用成员,0表示禁用成员
@@ -667,7 +689,9 @@
            sysUser.setStatus(qwUser.getEnable() == 1 ? 1 : 2);
        }
        // 座机号
        sysUser.setTelephone(qwUser.getTelephone());
        if (StringUtils.isNotBlank(qwUser.getTelephone())) {
            sysUser.setTelephone(qwUser.getTelephone());
        }
        // --- 企业微信没有逻辑删除的功能
        // sysUser.setDelFlag()
@@ -822,7 +846,7 @@
            String userId = announcement.getUserIds();
            String[] userIds = null;
            if(oConvertUtils.isNotEmpty(userId)){
                userIds = userId.substring(0, (userId.length() - 1)).split(",");
                userIds = userId.substring(0, userId.length()).split(",");
            }else{
                LambdaQueryWrapper<SysAnnouncementSend> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(SysAnnouncementSend::getAnntId, announcement.getId());
@@ -857,7 +881,126 @@
        return JwMessageAPI.sendTextCardMessage(textCard, accessToken);
    }
    private String getTouser(String origin, boolean toAll) {
    /**
     * 发送模板卡片消息(业务流程调用此方法)
     * @param templateCard
     * @param verifyConfig
     * @return
     */
    public JSONObject sendTemplateCardMsg(TemplateCard templateCard, boolean verifyConfig) {
        if (verifyConfig && !thirdAppConfig.isWechatEnterpriseEnabled()) {
            return null;
        }
        String accessToken = this.getAppAccessToken();
        if (accessToken == null) {
            return null;
        }
        templateCard.setAgentid(thirdAppConfig.getWechatEnterprise().getAgentIdInt());
        return MessageAPI.sendTemplateCardMessage(templateCard, accessToken);
    }
    /**
     * 发送模板卡片消息(消息测试调用此方法)
     *
     * @return
     */
    public JSONObject sendTemplateCardMsg(SysAnnouncement announcement, boolean verifyConfig) {
        if (verifyConfig && !thirdAppConfig.isWechatEnterpriseEnabled()) {
            return null;
        }
        String accessToken = this.getAppAccessToken();
        if (accessToken == null) {
            return null;
        }
        TemplateCard templateCard = new TemplateCard();
        templateCard.setAgentid(thirdAppConfig.getWechatEnterprise().getAgentIdInt());
        boolean isToAll = CommonConstant.MSG_TYPE_ALL.equals(announcement.getMsgType());
        String usernameString = "";
        if (!isToAll) {
            // 将userId转为username
            String userId = announcement.getUserIds();
            String[] userIds = null;
            if (oConvertUtils.isNotEmpty(userId)) {
                userIds = userId.substring(0, userId.length()).split(",");
            } else {
                LambdaQueryWrapper<SysAnnouncementSend> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(SysAnnouncementSend::getAnntId, announcement.getId());
                SysAnnouncementSend sysAnnouncementSend = sysAnnouncementSendMapper.selectOne(queryWrapper);
                userIds = new String[]{sysAnnouncementSend.getUserId()};
            }
            LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.in(SysUser::getId, userIds);
            List<SysUser> userList = userMapper.selectList(queryWrapper);
            List<String> usernameList = userList.stream().map(SysUser::getUsername).collect(Collectors.toList());
            usernameString = String.join(",", usernameList);
        }
        templateCard.setTouser(this.getTouser(usernameString, isToAll));
        TemplateCardEntity templateCardEntity = new TemplateCardEntity();
        templateCard.setTemplate_card(templateCardEntity);
        templateCardEntity.setTask_id(UUID.randomUUID().toString().replaceAll("-", ""));
        TemplateCardEntity.Source source = new TemplateCardEntity.Source();
        source.setIcon_url("https://www.jeecg.org/logo.png");
        source.setDesc("设备管理测试");
        templateCardEntity.setSource(source);
        TemplateCardEntity.MainTitle mainTitle = new TemplateCardEntity.MainTitle();
        mainTitle.setTitle("设备周保");
        //mainTitle.setDesc("设备周保信息");
        templateCardEntity.setMain_title(mainTitle);
        templateCardEntity.setSub_title_text("设备周保流程详情");
        List<TemplateCardEntity.HorizontalContent> horizontalContentList = getHorizontalContents();
        templateCardEntity.setHorizontal_content_list(horizontalContentList);
        TemplateCardEntity.CardAction cardAction = new TemplateCardEntity.CardAction();
        cardAction.setType(1);
        cardAction.setUrl("https://houjie.xalxzn.com:8866/h5");
        templateCardEntity.setCard_action(cardAction);
        TemplateCardEntity.ActionMenu actionMenu = new TemplateCardEntity.ActionMenu();
        actionMenu.setDesc("更多");
        actionMenu.setAction_list(cn.hutool.core.collection.CollectionUtil
                .newArrayList(new TemplateCardEntity.ActionMenu.ActionList("接收推送", "A"),
                        new TemplateCardEntity.ActionMenu.ActionList("不再推送", "B")));
        templateCardEntity.setAction_menu(actionMenu);
        //templateCardEntity.setJump_list(cn.hutool.core.collection.CollectionUtil
        //        .newArrayList(new TemplateCardEntity.Jump(1, "企业微信官网", "https://work.weixin.qq.com")));
        //TemplateCardEntity.CardImage cardImage = new TemplateCardEntity.CardImage();
        //cardImage.setUrl("https://www.jeecg.org/logo.png");
        //templateCardEntity.setCard_image(cardImage);
        return MessageAPI.sendTemplateCardMessage(templateCard, accessToken);
    }
    @NotNull
    private static List<TemplateCardEntity.HorizontalContent> getHorizontalContents() {
        List<TemplateCardEntity.HorizontalContent> horizontalContentList = new ArrayList<>();
        TemplateCardEntity.HorizontalContent content1 = new TemplateCardEntity.HorizontalContent();
        content1.setKeyname("流程描述");
        content1.setValue("工单号:WMCR2025050011;设备编号:031-41进行设备周保");
        horizontalContentList.add(content1);
        TemplateCardEntity.HorizontalContent content2 = new TemplateCardEntity.HorizontalContent();
        content2.setKeyname("之前处理人");
        content2.setValue("管理员");
        horizontalContentList.add(content2);
        TemplateCardEntity.HorizontalContent content3 = new TemplateCardEntity.HorizontalContent();
        content3.setKeyname("前驱节点");
        content3.setValue("周保领取");
        horizontalContentList.add(content3);
        TemplateCardEntity.HorizontalContent content4 = new TemplateCardEntity.HorizontalContent();
        content4.setKeyname("当前节点");
        content4.setValue("周保执行");
        horizontalContentList.add(content4);
        TemplateCardEntity.HorizontalContent content5 = new TemplateCardEntity.HorizontalContent();
        content5.setKeyname("工单号");
        content5.setValue("WMCR2025050011");
        horizontalContentList.add(content5);
        TemplateCardEntity.HorizontalContent content6 = new TemplateCardEntity.HorizontalContent();
        content6.setKeyname("设备编号");
        content6.setValue("031-41");
        horizontalContentList.add(content6);
        return horizontalContentList;
    }
    public String getTouser(String origin, boolean toAll) {
        if (toAll) {
            return "@all";
        } else {
@@ -895,7 +1038,17 @@
        if (accessToken == null) {
            return null;
        }
        String appUserId = this.getUserIdByThirdCode(code, accessToken);
        // 通过code获取用户信息(包含user_ticket)
        JSONObject userInfoResult = this.getUserInfoByCode(code, accessToken);
        if (userInfoResult == null || userInfoResult.getInteger("errcode") != 0) {
            log.error("获取企业微信用户信息失败,code: {}", code);
            return null;
        }
        String appUserId = userInfoResult.getString("UserId");
        String userTicket = userInfoResult.getString("user_ticket"); // 手动授权返回的用户票据
        if (appUserId != null) {
            // 判断第三方用户表有没有这个人
            LambdaQueryWrapper<SysThirdAccount> queryWrapper = new LambdaQueryWrapper<>();
@@ -903,18 +1056,63 @@
            queryWrapper.or().eq(SysThirdAccount::getThirdUserId, appUserId);
            queryWrapper.eq(SysThirdAccount::getThirdType, THIRD_TYPE);
            SysThirdAccount thirdAccount = sysThirdAccountService.getOne(queryWrapper);
            // 通过user_ticket获取用户详细信息(包含手机号等敏感信息)
            JSONObject userDetail = this.getUserDetailByTicket(userTicket, accessToken);
            String mobile = userDetail.getString("mobile");
            if (thirdAccount != null) {
                // 更新手机号(如果有)
                if (mobile != null && !mobile.isEmpty()) {
                    thirdAccount.setPhone(mobile);
                    sysThirdAccountService.updateById(thirdAccount);
                }
                return this.getSysUserByThird(thirdAccount, null, appUserId, accessToken);
            } else {
                // 直接创建新账号
                // 直接创建新账号,包含手机号信息
                User appUser = JwUserAPI.getUserByUserid(appUserId, accessToken);
                ThirdLoginModel tlm = new ThirdLoginModel(THIRD_TYPE, appUser.getUserid(), appUser.getName(), appUser.getAvatar());
                ThirdLoginModel tlm = new ThirdLoginModel(THIRD_TYPE, appUser.getUserid(), appUser.getName(), appUser.getAvatar(), mobile);
                thirdAccount = sysThirdAccountService.saveThirdUser(tlm);
                return this.getSysUserByThird(thirdAccount, appUser, null, null);
            }
        }
        return null;
    }
    /**
     * 通过code获取用户信息(包含user_ticket)
     */
    private JSONObject getUserInfoByCode(String code, String accessToken) {
        String url = "https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo" +
                "?access_token=" + accessToken +
                "&code=" + code;
        try {
            String result = String.valueOf(RestUtil.get(url));
            return JSONObject.parseObject(result);
        } catch (Exception e) {
            log.error("获取企业微信用户信息异常", e);
            return null;
        }
    }
    /**
     * 通过user_ticket获取用户详细信息(包含手机号等敏感信息)
     */
    private JSONObject getUserDetailByTicket(String userTicket, String accessToken) {
        String url = "https://qyapi.weixin.qq.com/cgi-bin/user/getuserdetail";
        JSONObject params = new JSONObject();
        params.put("user_ticket", userTicket);
        try {
            String result = String.valueOf(RestUtil.post(url + "?access_token=" + accessToken, JSONObject.parseObject(params.toJSONString())));
//            String result = String.valueOf(RestUtil.post(url + "?access_token=" + accessToken, params.toJSONString()));
            return JSONObject.parseObject(result);
        } catch (Exception e) {
            log.error("获取企业微信用户详细信息异常", e);
            return new JSONObject(); // 返回空对象避免NPE
        }
    }
    /**
     * 根据第三方账号获取本地账号,如果不存在就创建
@@ -928,14 +1126,24 @@
    private SysUser getSysUserByThird(SysThirdAccount thirdAccount, User appUser, String appUserId, String accessToken) {
        String sysUserId = thirdAccount.getSysUserId();
        if (oConvertUtils.isNotEmpty(sysUserId)) {
            return userMapper.selectById(sysUserId);
            SysUser sysUser = userMapper.selectById(sysUserId);
            if (sysUser != null && StringUtils.isBlank(sysUser.getPhone())) {
                //如果有用户,并且没有电话信息,更新进电话号码
                SysUser user = new SysUser()
                        .setId(sysUser.getId())
                        .setPhone(thirdAccount.getPhone());
                userMapper.updateById(user);
            }
            return sysUser;
        } else {
            // 如果没有 sysUserId ,说明没有绑定账号,获取到手机号之后进行绑定
            if (appUser == null) {
                appUser = JwUserAPI.getUserByUserid(appUserId, accessToken);
            }
            // 判断系统里是否有这个手机号的用户
            SysUser sysUser = userMapper.getUserByPhone(appUser.getMobile());
            appUser.setMobile(thirdAccount.getPhone());
            // 判断系统里是否有这个用户,根据工号匹配
            SysUser sysUser = userMapper.getUserByWorkNo(thirdAccount.getThirdUserId());
            //SysUser sysUser = userMapper.getUserByPhone(appUser.getMobile());
            if (sysUser != null) {
                thirdAccount.setAvatar(appUser.getAvatar());
                thirdAccount.setRealname(appUser.getName());
@@ -943,6 +1151,13 @@
                thirdAccount.setThirdUserUuid(appUser.getUserid());
                thirdAccount.setSysUserId(sysUser.getId());
                sysThirdAccountService.updateById(thirdAccount);
                if (StringUtils.isBlank(sysUser.getPhone())) {
                    //如果没有手机号码,更新
                    SysUser user = new SysUser()
                            .setId(sysUser.getId())
                            .setPhone(appUser.getMobile());
                    userMapper.updateById(user);
                }
                return sysUser;
            } else {
                // 没有就走创建逻辑