陈昶聿
昨天 16335c0ebdbb00381a7c008ccaa387ceadcfd45b
【景宁】景宁 定时发送异常信息-景宁
已修改7个文件
已添加4个文件
353 ■■■■■ 文件已修改
ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/tools/DingTalkController.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/core/domain/DingAsyncSendMsgReq.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/core/domain/DingAsyncSendMsgResp.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/core/domain/DingTokenResp.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/core/service/IDingTalkService.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/dx/MessageSend.java 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/utils/DingTalkUtils.java 79 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/RyTask.java 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/service/DingTalkService.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/service/impl/DingTalkServiceImpl.java 108 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
smartor/src/main/java/com/smartor/service/impl/ServiceSubtaskAnswerServiceImpl.java 33 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/tools/DingTalkController.java
@@ -48,5 +48,19 @@
        return aBoolean;
    }
    /**
     * å‘送钉钉消息
     *
     * @param dingTalkReqVo å‘送内容
     * @throws ApiException
     */
    @ApiOperation("发送钉钉消息")
    @PostMapping("/sendDingTalkText")
    public void sendDingTalkText(@RequestBody DingTalkReqVo dingTalkReqVo) throws Exception {
//        String userid = dingTalkService.getDingTalkUserByMobile(dingTalkReqVo.getNumber());
        String userid = "214563391024684607";
        dingTalkService.sendDingTalkText("景宁发送钉钉消息测试", userid);
    }
}
ruoyi-common/src/main/java/com/ruoyi/common/core/domain/DingAsyncSendMsgReq.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,18 @@
package com.ruoyi.common.core.domain;
import lombok.Data;
import java.util.Map;
@Data
public class DingAsyncSendMsgReq {
    /** åº”用agentId */
    private Long agent_id;
    /** æŽ¥æ”¶äººuserid列表,多个逗号分隔;与dept_id_list二选一 */
    private String userid_list;
    /** æŽ¥æ”¶éƒ¨é—¨id列表,多个逗号分隔 */
    private String dept_id_list;
    /** æ˜¯å¦å‘送给所有员工,true则userid_list、dept_id_list失效 */
    private Boolean to_all_user;
    /** æ¶ˆæ¯ä½“ */
    private Map<String, Object> msg;
}
ruoyi-common/src/main/java/com/ruoyi/common/core/domain/DingAsyncSendMsgResp.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,11 @@
package com.ruoyi.common.core.domain;
import lombok.Data;
@Data
public class DingAsyncSendMsgResp {
    private Integer errcode;
    private String errmsg;
    /** ä»»åŠ¡id,后续回调会带回这个task_id */
    private Long task_id;
}
ruoyi-common/src/main/java/com/ruoyi/common/core/domain/DingTokenResp.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,11 @@
package com.ruoyi.common.core.domain;
import lombok.Data;
@Data
public class DingTokenResp {
    private Integer errcode;
    private String errmsg;
    private String access_token;
    private Long expires_in;
}
ruoyi-common/src/main/java/com/ruoyi/common/core/service/IDingTalkService.java
@@ -13,4 +13,19 @@
     * @return æ˜¯å¦æˆåŠŸ
     */
    Boolean sendNotification(DingTalkReqVo dingTalkReqVo);
    /**
     * å‘送钉钉消息-景宁
     * @param sMessageContent
     * @throws Exception
     */
    void sendDingTalkText(String sMessageContent, String userId) throws Exception;
    /**
     * æ ¹æ®ç”µè¯èŽ·å–ç”¨æˆ·
     * @param mobile
     * @return
     * @throws Exception
     */
    String getDingTalkUserByMobile(String mobile) throws Exception;
}
ruoyi-common/src/main/java/com/ruoyi/common/dx/MessageSend.java
@@ -1,5 +1,9 @@
package com.ruoyi.common.dx;
import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.OapiMessageCorpconversationAsyncsendV2Request;
import com.dingtalk.api.response.OapiMessageCorpconversationAsyncsendV2Response;
import com.ruoyi.common.utils.uuid.UUID;
import lombok.extern.slf4j.Slf4j;
@@ -31,7 +35,8 @@
                result = soap.i5GSend("202508291634227086", "T202508291635259440", UUID.randomUUID().toString(), sMessageContent, sMessageType, sUserNumber, sScheduleTime);
                log.info("----短信返回的数据为:{},    ----sMessageContent çš„值为:{}", result,UUID.randomUUID().toString());
            } else if ("7".equals(sMessageType)) {
                result = soap.i5GSend("202508291634227086", "T202607211306131891", UUID.randomUUID().toString(), sMessageContent, sMessageType, sUserNumber, sScheduleTime);
                result = soap.i5GSend("202508291634227086", "T202607211306131891",
                        UUID.randomUUID().toString(), sMessageContent, sMessageType, sUserNumber, sScheduleTime);
                log.info("----钉钉返回的原始数据为:{}", result);
            } else {
ruoyi-common/src/main/java/com/ruoyi/common/utils/DingTalkUtils.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,79 @@
package com.ruoyi.common.utils;
import com.alibaba.fastjson2.JSON;
import com.ruoyi.common.core.domain.DingAsyncSendMsgReq;
import com.ruoyi.common.core.domain.DingAsyncSendMsgResp;
import com.ruoyi.common.core.domain.DingTokenResp;
import okhttp3.*;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
public class DingTalkUtils {
    private static final OkHttpClient HTTP_CLIENT = new OkHttpClient.Builder()
            .connectTimeout(10, TimeUnit.SECONDS)
            .readTimeout(10, TimeUnit.SECONDS)
            .build();
    /**
     * èŽ·å–ä¼ä¸šaccess_token
     * @param corpid ä¼ä¸šID
     * @param corpsecret åº”用的凭证密钥
     * @return DingTokenResp
     */
    public static DingTokenResp getAccessToken(String corpid, String corpsecret) throws IOException {
        String url = "https://oapi.dingtalk.com/gettoken?corpid=" + corpid + "&corpsecret=" + corpsecret;
        Request request = new Request.Builder()
                .url(url)
                .get()
                .build();
        try (Response response = HTTP_CLIENT.newCall(request).execute()) {
            String body = response.body().string();
            return JSON.parseObject(body, DingTokenResp.class);
        }
    }
    /**
     * å¼‚步发送企业会话消息 asyncsend_v2
     */
    public static DingAsyncSendMsgResp asyncSendCorpMsg(String accessToken, DingAsyncSendMsgReq req) throws IOException {
        String url = "https://oapi.dingtalk.com/topapi/message/corpconversation/asyncsend_v2?access_token=" + accessToken;
        String jsonBody = JSON.toJSONString(req);
        RequestBody body = RequestBody.create(jsonBody, MediaType.get("application/json; charset=utf-8"));
        Request request = new Request.Builder()
                .url(url)
                .post(body)
                .build();
        try (Response response = HTTP_CLIENT.newCall(request).execute()) {
            String respBody = response.body().string();
            return JSON.parseObject(respBody, DingAsyncSendMsgResp.class);
        }
    }
    // ========== æž„建消息示例:文本消息 ==========
    public static Map<String, Object> buildTextMsg(String content) {
        Map<String, Object> msgMap = new HashMap<>();
        msgMap.put("msgtype", "text");
        Map<String, Object> text = new HashMap<>();
        text.put("content", content);
        msgMap.put("text", text);
        return msgMap;
    }
    // ========== æž„建消息示例:markdown消息 ==========
    public static Map<String, Object> buildMarkdownMsg(String title, String text) {
        Map<String, Object> msgMap = new HashMap<>();
        msgMap.put("msgtype", "markdown");
        Map<String, Object> markdown = new HashMap<>();
        markdown.put("title", title);
        markdown.put("text", text);
        msgMap.put("markdown", markdown);
        return msgMap;
    }
}
ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/RyTask.java
@@ -9,6 +9,7 @@
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.core.service.IDingTalkService;
import com.ruoyi.common.dx.MessageSend;
import com.ruoyi.common.enums.MsgLSEnum;
import com.ruoyi.common.enums.ServiceFromEnum;
@@ -104,6 +105,9 @@
    @Autowired
    private ISysConfigService configService;
    @Autowired
    private IDingTalkService dingTalkService;
    @Value("${localIP}")
@@ -270,6 +274,44 @@
        }
    }
    /**
     * å®šæ—¶å‘送异常信息-景宁
     */
    public void sendExceptInfo() throws Exception {
        //1.获取发送人工号
        ServiceSubtaskDetailTraceVO subtaskDetailTraceVO = new ServiceSubtaskDetailTraceVO();
        subtaskDetailTraceVO.setHandleFlag("0");
        List<ServiceSubtaskDetailTrace> serviceSubtaskDetailTraces =
                serviceSubtaskDetailTraceService.selectServiceSubtaskDetailTtraceList(subtaskDetailTraceVO);
        // æŠŠ dutyDeptPersonCode æ•´ç†åˆ° list ä¸­ï¼ˆå¦‚果多个人用逗号分割,则展开并去重)
        List<String> dutyDeptPersonCodeList = serviceSubtaskDetailTraces.stream()
                .map(ServiceSubtaskDetailTrace::getDutyDeptPersonCode)
                .filter(StringUtils::isNotBlank)
                .flatMap(code -> Arrays.stream(code.split(",")))
                .map(String::trim)
                .filter(StringUtils::isNotBlank).distinct()  // åŽ»é‡
                .collect(Collectors.toList());
        // èŽ·å–â€œå¼‚å¸¸å†…å®¹æé†’"
        SysConfig sysConfig = sysConfigMapper.checkConfigKeyUnique("send.except.content");
        String exceptContent = sysConfig.getConfigValue();
        // èŽ·å–â€œå†…å®¹æé†’æµ‹è¯•äººå·¥å·â€
        String testPerson = sysConfigMapper.checkConfigKeyUnique("send.test.person").getConfigValue();
        if (StringUtils.isNotBlank(testPerson)) {
            String[] split = testPerson.split(",");
            if (CollectionUtils.isEmpty(dutyDeptPersonCodeList)) dutyDeptPersonCodeList = Arrays.asList(split);
            else dutyDeptPersonCodeList.addAll(Arrays.asList(split));
        }
        if (CollectionUtils.isNotEmpty(dutyDeptPersonCodeList)) {
            for (String dutyDeptPersonCode : dutyDeptPersonCodeList) {
                log.info("【sendExceptInfo】发送人工号:{}", dutyDeptPersonCode);
                String dutyDeptPerson = dingTalkService.getDingTalkUserByMobile(dutyDeptPersonCode);
                dingTalkService.sendDingTalkText(exceptContent, dutyDeptPerson);
            }
        }
    }
    /**
     * å®šæ—¶å¤„理外链的数据
smartor/src/main/java/com/smartor/service/DingTalkService.java
@@ -21,4 +21,19 @@
     * @param dingTalkReqVo
     */
    public Boolean sendNotification(DingTalkReqVo dingTalkReqVo);
    /**
     * å‘送钉钉消息-景宁
     * @param sMessageContent
     * @throws Exception
     */
    public void sendDingTalkText(String sMessageContent, String userId) throws Exception;
    /**
     * æ ¹æ®ç”µè¯èŽ·å–ç”¨æˆ·
     * @param mobile
     * @return
     * @throws Exception
     */
    public String getDingTalkUserByMobile(String mobile) throws Exception;
}
smartor/src/main/java/com/smartor/service/impl/DingTalkServiceImpl.java
@@ -12,7 +12,11 @@
import com.dingtalk.api.response.OapiMessageCorpconversationAsyncsendV2Response;
import com.dingtalk.api.response.OapiUserListidResponse;
import com.dingtalk.api.response.OapiV2UserGetbymobileResponse;
import com.ruoyi.common.core.domain.DingAsyncSendMsgReq;
import com.ruoyi.common.core.domain.DingAsyncSendMsgResp;
import com.ruoyi.common.core.domain.DingTalkReqVo;
import com.ruoyi.common.core.domain.DingTokenResp;
import com.ruoyi.common.utils.DingTalkUtils;
import com.ruoyi.common.utils.StringUtils;
import com.smartor.service.DingTalkService;
import com.taobao.api.ApiException;
@@ -40,6 +44,9 @@
    @Value("${dingAppSecret}")
    private String dingAppSecret;
    @Value("${dingAppAgentId}")
    private Long dingAppAgentId;
    @Override
    public Boolean sendNotification(DingTalkReqVo dingTalkReqVo) {
@@ -158,4 +165,105 @@
        OapiGettokenResponse response = client.execute(request);
        return response.getAccessToken();
    }
    /**
     * èŽ·å–post access_token
     */
    private String getAccessTokenPost() throws ApiException {
        DefaultDingTalkClient client = new DefaultDingTalkClient("https://api.dingtalk.com/v1.0/oauth2/{corpId}/token");
        OapiGettokenRequest request = new OapiGettokenRequest();
        //Appkey
        request.setAppkey(dingAppid);
        //Appsecret
        request.setAppsecret(dingAppSecret);
        /*请求方式*/
        request.setHttpMethod("Post");
        OapiGettokenResponse response = client.execute(request);
        return response.getAccessToken();
    }
//    /**
//     * å‘送钉钉消息-景宁
//     * @param sMessageContent
//     * @throws Exception
//     */
//    public void sendDingTalkText(String sMessageContent) throws Exception {
//        String CORP_ID = "你的企业corpid";
//        String CORP_SECRET = "企业应用的corpsecret";
//        Long AGENT_ID = 4992829038L; // ä½ çš„应用agentId
//
//        try {
//            // 1. èŽ·å–access_token
//            DingTokenResp tokenResp = DingTalkUtils.getAccessToken(CORP_ID, CORP_SECRET);
//            if (tokenResp.getErrcode() != 0) {
//                System.err.println("获取token失败:" + tokenResp.getErrmsg());
//                return;
//            }
//            String accessToken = tokenResp.getAccess_token();
//            System.out.println("access_token=" + accessToken);
//
//            // 2. ç»„装发送请求
//            DingAsyncSendMsgReq sendReq = new DingAsyncSendMsgReq();
//            sendReq.setAgent_id(AGENT_ID);
//            sendReq.setUserid_list("user01,user02"); // æŽ¥æ”¶äººé’‰é’‰userId,多个逗号
//            sendReq.setTo_all_user(false);
//            // è®¾ç½®æ¶ˆæ¯å†…容,这里用文本消息
//            sendReq.setMsg(DingTalkUtils.buildTextMsg("你好,这是异步发送钉钉消息测试"));
//
//            // 3. è°ƒç”¨å¼‚步发送接口
//            DingAsyncSendMsgResp sendResp = DingTalkUtils.asyncSendCorpMsg(accessToken, sendReq);
//            if (sendResp.getErrcode() == 0) {
//                System.out.println("提交消息任务成功,task_id=" + sendResp.getTask_id());
//                System.out.println("消息实际发送结果,需要在钉钉后台配置回调接收");
//            } else {
//                System.err.println("提交消息任务失败:code=" + sendResp.getErrcode() + ",msg=" + sendResp.getErrmsg());
//            }
//
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//    }
    /**
     * å‘送钉钉消息-景宁
     * @param sMessageContent
     * @throws Exception
     */
    @Override
    public void sendDingTalkText(String sMessageContent, String userId) throws Exception {
        Long agentId = dingAppAgentId;
        String accessToken = getAccessToken();
        DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/message/corpconversation/asyncsend_v2");
        OapiMessageCorpconversationAsyncsendV2Request request = new OapiMessageCorpconversationAsyncsendV2Request();
        request.setAgentId(agentId);
        request.setUseridList(userId);
        request.setToAllUser(false);
        OapiMessageCorpconversationAsyncsendV2Request.Msg msg = new OapiMessageCorpconversationAsyncsendV2Request.Msg();
        msg.setMsgtype("text");
        OapiMessageCorpconversationAsyncsendV2Request.Text text = new OapiMessageCorpconversationAsyncsendV2Request.Text();
        text.setContent(sMessageContent);
        msg.setText(text);
        request.setMsg(msg);
        OapiMessageCorpconversationAsyncsendV2Response rsp = client.execute(request, accessToken);
        System.out.println(rsp.getBody());
    }
    /**
     * æ ¹æ®ç”µè¯èŽ·å–ç”¨æˆ·
     * @param mobile
     * @return
     * @throws Exception
     */
    @Override
    public String getDingTalkUserByMobile(String mobile) throws Exception {
        String accessToken = getAccessToken();
        DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/getbymobile");
        OapiV2UserGetbymobileRequest req = new OapiV2UserGetbymobileRequest();
        req.setMobile(mobile);
        OapiV2UserGetbymobileResponse rsp = client.execute(req, accessToken);
        return rsp.getBody();
    }
}
smartor/src/main/java/com/smartor/service/impl/ServiceSubtaskAnswerServiceImpl.java
@@ -1066,8 +1066,19 @@
            }
        }
        String orgid = selectServiceSubtaskList.get(0).getOrgid();
        //景宁-随访异常提示 å…¶ä»–-异常满意度提示
        boolean addTrace = false;
        if(StringUtils.isNotEmpty(orgid) && orgid.equals("47255004333112711A1001")){
            if (stt != null) {
                addTrace = Long.valueOf(1L).equals(stt.getIsabnormal());
            }
        }else {
            addTrace = StringUtils.isNotEmpty(svyTaskTemplateScriptVO.getIsMydException());
        }
        //判断一下当前的问题是不是满意度问题,并且 dutyDeptCode æ˜¯å¦æœ‰å€¼ï¼Œå¹¶ä¸”选项是不是异常选项,如果全符合,则往满意度问题异常表新增
        if (StringUtils.isNotEmpty(svyTaskTemplateScriptVO.getDutyDeptCode()) && stt != null && Long.valueOf(1L).equals(stt.getIsabnormal()) || StringUtils.isNotEmpty(svyTaskTemplateScriptVO.getDutyDeptCode()) && StringUtils.isNotEmpty(svyTaskTemplateScriptVO.getIsMydException())) {
        if (StringUtils.isNotEmpty(svyTaskTemplateScriptVO.getDutyDeptCode()) && stt != null && Long.valueOf(1L).equals(stt.getIsabnormal()) || StringUtils.isNotEmpty(svyTaskTemplateScriptVO.getDutyDeptCode())
                && addTrace) {
            isabnormalFlag = 1L;
            ServiceSubtaskDetailTrace subtaskDetailTrace = new ServiceSubtaskDetailTrace();
            subtaskDetailTrace.setDetailId(serviceSubtaskDetail.getId());
@@ -1083,17 +1094,19 @@
            //获取所有选项
            subtaskDetailTrace.setTargetid(stt != null ? stt.getId() : null);
            subtaskDetailTrace.setTargetvalue(serviceSubtaskDetailVO.getTargetvalue());
            subtaskDetailTrace.setMatchedtext(stt != null ? stt.getOptioncontent() : svyTaskTemplateScriptVO.getIsMydException());
            subtaskDetailTrace.setGuid(svyTaskTemplateScriptVO.getGuid());
            subtaskDetailTrace.setValueType(serviceSubtaskDetail.getValueType());
            subtaskDetailTrace.setIsMydException(svyTaskTemplateScriptVO.getIsMydException());
            subtaskDetailTrace.setTemplateType(2);
            SvyLibScriptCategory svyLibScriptCategory = svyLibScriptCategoryMapper.selectSvyLibScriptCategoryById(svyTaskTemplateScriptVO.getCategoryid());
            subtaskDetailTrace.setType(svyLibScriptCategory != null ? svyLibScriptCategory.getType() : null);
            subtaskDetailTrace.setScriptid(svyTaskTemplateScriptVO.getId());
            //非满意度意见异常自动填入空
            subtaskDetailTrace.setMatchedtext(stt != null ? stt.getOptioncontent() : svyTaskTemplateScriptVO.getIsMydException());
            subtaskDetailTrace.setAsrtext(stt != null ? stt.getOptioncontent() : svyTaskTemplateScriptVO.getIsMydException());
            subtaskDetailTrace.setIsMydException(svyTaskTemplateScriptVO.getIsMydException());
            subtaskDetailTrace.setRecordpath(null);
            subtaskDetailTrace.setPatid(selectServiceSubtaskList.get(0).getPatid());
            JSONObject patdescJson1 = new JSONObject();
@@ -1341,9 +1354,19 @@
                stt = ivrTaskTemplateTargetoption;
        }
        String orgid = selectServiceSubtaskList.get(0).getOrgid();
        //景宁-随访异常提示 å…¶ä»–-异常满意度提示
        boolean addTrace = false;
        if(StringUtils.isNotEmpty(orgid) && orgid.equals("47255004333112711A1001")){
            if (stt != null) {
                addTrace = Long.valueOf(1L).equals(stt.getIsabnormal());
            }
        }else {
            addTrace = StringUtils.isNotEmpty(ivrTaskTemplateScriptVO.getIsMydException());
        }
        //判断一下当前的问题是不是满意度问题,并且dutyDeptCode是否有值,并且选项是不是异常选项,如果全符合,则往满意度问题异常表新增
        if (StringUtils.isNotEmpty(ivrTaskTemplateScriptVO.getDutyDeptCode()) && 1 == stt.getIsabnormal() || StringUtils.isNotEmpty(ivrTaskTemplateScriptVO.getDutyDeptCode()) && StringUtils.isNotEmpty(ivrTaskTemplateScriptVO.getIsMydException())) {
        if (StringUtils.isNotEmpty(ivrTaskTemplateScriptVO.getDutyDeptCode()) && 1 == stt.getIsabnormal() || StringUtils.isNotEmpty(ivrTaskTemplateScriptVO.getDutyDeptCode())
                && addTrace) {
            isabnormalFlag = "1";
            ServiceSubtaskDetailTrace subtaskDetailTrace = new ServiceSubtaskDetailTrace();
            subtaskDetailTrace.setDetailId(serviceSubtaskDetail.getId());