tjx
2025-11-12 9958f44867a201bb14b3efd3f4506c9714937ea6
添加钉钉推送消息的接口
已修改3个文件
300 ■■■■■ 文件已修改
src/main/java/com/gs/xky/service/DingtalkInfoService.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/gs/xky/service/Impl/DingtalkInfoServiceImpl.java 222 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/test/java/com/gs/xky/XkyApplicationTests.java 67 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/gs/xky/service/DingtalkInfoService.java
@@ -11,4 +11,15 @@
public interface DingtalkInfoService extends IService<DingtalkInfo> {
    boolean sendMessage(String releaseNo);
    boolean sendActionCardMessage() throws Exception;
    /**
     * 发送文件消息
     *
     * @param filePath 本地文件路径
     * @return 是否发送成功
     * @throws Exception 异常
     */
    boolean sendFileMessage(String filePath) throws Exception;
}
src/main/java/com/gs/xky/service/Impl/DingtalkInfoServiceImpl.java
@@ -14,11 +14,13 @@
import com.gs.xky.mapper.MesStaffMapper;
import com.gs.xky.service.DingtalkInfoService;
import com.gs.xky.service.SimpleExample;
import com.taobao.api.FileItem;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
@@ -130,6 +132,95 @@
        }
    }
    @Override
    public boolean sendActionCardMessage() {
        try {
            // 1. 获取需要推送的用户列表(可以是固定推送用户)
            List<DingtalkInfo> fixedList = baseMapper.selectList(
                    new LambdaQueryWrapper<DingtalkInfo>().eq(DingtalkInfo::getIsHead, 1)
            );
            List<Long> sidList = fixedList.stream()
                    .map(DingtalkInfo::getSid)
                    .collect(Collectors.toList());
            List<String> userIdList = getDingtalkUserIdListBySids(sidList);
            if (userIdList == null || userIdList.isEmpty()) {
                log.warn("没有需要发送钉钉消息的用户");
                return false;
            }
            String userIdListStr = String.join(",", userIdList);
            // 2. 构建消息内容
            String title = "生产数据看板";
            String markdown = "请点击下方按钮查看详细BI报表";
            String singleTitle = "查看报表";
            String singleUrl = "http://192.168.1.22:8081/design?fid=rpte6045ab079b211f0824bd3cfd50c6b93&fserid=4b198960bedd11f09f6f792bfe147b64&fsharetype=3";
            // 3. 发送消息
            OapiMessageCorpconversationAsyncsendV2Response rsp =
                    sendActionCardMessage(userIdListStr, title, markdown, singleTitle, singleUrl);
            log.info("成功发送ActionCard消息: {}", rsp.getBody());
            return true;
        } catch (Exception e) {
            log.error("发送ActionCard消息失败", e);
            return false;
        }
    }
    @Override
    public boolean sendFileMessage(String filePath) throws Exception {
        try {
            // 1. 检查文件是否存在
            File file = new File(filePath);
            if (!file.exists()) {
                log.error("文件不存在: {}", filePath);
                return false;
            }
            // 2. 获取需要推送的用户列表(可根据实际需求调整,这里使用isHead=1的用户)
            List<DingtalkInfo> fixedList = baseMapper.selectList(
                    new LambdaQueryWrapper<DingtalkInfo>().eq(DingtalkInfo::getIsHead, 1)
            );
            if (fixedList == null || fixedList.isEmpty()) {
                log.warn("没有需要发送文件的用户(isHead=1)");
                return false;
            }
            List<Long> sidList = fixedList.stream()
                    .map(DingtalkInfo::getSid)
                    .collect(Collectors.toList());
            List<String> userIdList = getDingtalkUserIdListBySids(sidList);
            if (userIdList == null || userIdList.isEmpty()) {
                log.warn("没有有效的钉钉用户ID");
                return false;
            }
            String userIdListStr = String.join(",", userIdList);
            // 3. 上传文件到钉钉服务器
            log.info("开始上传文件: {}", filePath);
            String mediaId = uploadMedia(filePath, "file");
            // 4. 发送文件消息
            log.info("开始发送文件消息,mediaId: {}", mediaId);
            OapiMessageCorpconversationAsyncsendV2Response response = sendFileMessageByMediaId(userIdListStr, mediaId);
            log.info("文件消息发送响应: {}", response.getBody());
            return response.getErrcode() == 0;
        } catch (Exception e) {
            log.error("发送文件消息失败", e);
            throw e;
        }
    }
    /**
     * 根据指定的sid列表获取钉钉用户ID列表
     *
@@ -200,7 +291,7 @@
        DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/message/corpconversation/asyncsend_v2");
        OapiMessageCorpconversationAsyncsendV2Request request = new OapiMessageCorpconversationAsyncsendV2Request();
        request.setAgentId(3917187842L);
        request.setAgentId(4104598880L);
        request.setUseridList(userIdListStr);
        request.setToAllUser(false);
@@ -215,6 +306,135 @@
    }
    /**
     * 发送link消息(在钉钉内置浏览器中打开)
     *
     * @param userIdListStr 用户ID列表,逗号分隔
     * @param title         消息标题
     * @param text          消息内容
     * @param messageUrl    点击消息后跳转的URL
     * @param picUrl        图片URL(可选)
     * @return 响应结果
     * @throws Exception 异常
     */
    private OapiMessageCorpconversationAsyncsendV2Response sendLinkMessage(String userIdListStr, String title, String text, String messageUrl, String picUrl) throws Exception {
        String accessToken = simpleExample.getAccessToken();
        DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/message/corpconversation/asyncsend_v2");
        OapiMessageCorpconversationAsyncsendV2Request request = new OapiMessageCorpconversationAsyncsendV2Request();
        request.setAgentId(4104598880L);
        request.setUseridList(userIdListStr);
        request.setToAllUser(false);
        OapiMessageCorpconversationAsyncsendV2Request.Msg msg = new OapiMessageCorpconversationAsyncsendV2Request.Msg();
        msg.setMsgtype("link");
        msg.setLink(new OapiMessageCorpconversationAsyncsendV2Request.Link());
        msg.getLink().setTitle(title);
        msg.getLink().setText(text);
        msg.getLink().setMessageUrl(messageUrl);
        if (StringUtils.hasText(picUrl)) {
            msg.getLink().setPicUrl(picUrl);
        }
        request.setMsg(msg);
        return client.execute(request, accessToken);
    }
    /**
     * 发送ActionCard消息(在外部浏览器中打开链接,适合BI等外部系统)
     *
     * @param userIdListStr 用户ID列表,逗号分隔
     * @param title         消息标题
     * @param markdown      消息内容(支持Markdown格式)
     * @param singleTitle   按钮文字,例如:"查看详情"
     * @param singleUrl     点击按钮后跳转的URL(外部链接)
     * @return 响应结果
     * @throws Exception 异常
     */
    private OapiMessageCorpconversationAsyncsendV2Response sendActionCardMessage(String userIdListStr, String title, String markdown, String singleTitle, String singleUrl) throws Exception {
        String accessToken = simpleExample.getAccessToken();
        DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/message/corpconversation/asyncsend_v2");
        OapiMessageCorpconversationAsyncsendV2Request request = new OapiMessageCorpconversationAsyncsendV2Request();
        request.setAgentId(4104598880L);
        request.setUseridList(userIdListStr);
        request.setToAllUser(false);
        OapiMessageCorpconversationAsyncsendV2Request.Msg msg = new OapiMessageCorpconversationAsyncsendV2Request.Msg();
        msg.setMsgtype("action_card");
        msg.setActionCard(new OapiMessageCorpconversationAsyncsendV2Request.ActionCard());
        msg.getActionCard().setTitle(title);
        msg.getActionCard().setMarkdown(markdown);
        msg.getActionCard().setSingleTitle(singleTitle);
        msg.getActionCard().setSingleUrl(singleUrl);
        request.setMsg(msg);
        return client.execute(request, accessToken);
    }
    /**
     * 上传文件到钉钉服务器,获取media_id
     *
     * @param filePath 本地文件路径
     * @param fileType 文件类型:file(普通文件), voice(语音文件), video(视频文件), image(图片文件)
     * @return media_id
     * @throws Exception 异常
     */
    private String uploadMedia(String filePath, String fileType) throws Exception {
        String accessToken = simpleExample.getAccessToken();
        DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/media/upload");
        com.dingtalk.api.request.OapiMediaUploadRequest request = new com.dingtalk.api.request.OapiMediaUploadRequest();
        request.setType(fileType);
        // 使用 FileItem 包装文件
        File file = new File(filePath);
        FileItem fileItem = new FileItem(file);
        request.setMedia(fileItem);
        com.dingtalk.api.response.OapiMediaUploadResponse response = client.execute(request, accessToken);
        if (response.getErrcode() == 0) {
            log.info("文件上传成功,media_id: {}", response.getMediaId());
            return response.getMediaId();
        } else {
            log.error("文件上传失败,错误码: {}, 错误信息: {}", response.getErrcode(), response.getErrmsg());
            throw new Exception("文件上传失败: " + response.getErrmsg());
        }
    }
    /**
     * 通过media_id发送文件消息
     *
     * @param userIdListStr 用户ID列表,逗号分隔
     * @param mediaId       文件的media_id(通过uploadMedia方法获取)
     * @return 响应结果
     * @throws Exception 异常
     */
    private OapiMessageCorpconversationAsyncsendV2Response sendFileMessageByMediaId(String userIdListStr, String mediaId) throws Exception {
        String accessToken = simpleExample.getAccessToken();
        DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/message/corpconversation/asyncsend_v2");
        OapiMessageCorpconversationAsyncsendV2Request request = new OapiMessageCorpconversationAsyncsendV2Request();
        request.setAgentId(4104598880L);
        request.setUseridList(userIdListStr);
        request.setToAllUser(false);
        OapiMessageCorpconversationAsyncsendV2Request.Msg msg = new OapiMessageCorpconversationAsyncsendV2Request.Msg();
        msg.setMsgtype("file");
        msg.setFile(new OapiMessageCorpconversationAsyncsendV2Request.File());
        msg.getFile().setMediaId(mediaId);
        request.setMsg(msg);
        return client.execute(request, accessToken);
    }
    /**
     * 获取isSendDingtalk=1的用户的钉钉用户ID列表(保留原有方法,向后兼容)
     */
    private List<String> getDingtalkUserIdList() {
src/test/java/com/gs/xky/XkyApplicationTests.java
@@ -1,11 +1,9 @@
package com.gs.xky;
import com.alibaba.fastjson.JSON;
import com.gs.xky.config.ApiResponse;
import com.gs.xky.config.BodyParam;
import com.gs.xky.config.DataAcquisitionConfiguration;
import com.gs.xky.config.XkyCommonParam;
import com.gs.xky.config.*;
import com.gs.xky.dto.BarcodeDeliveryNo;
import com.gs.xky.dto.EmployeeInfo;
import com.gs.xky.dto.XkyDetail;
import com.gs.xky.dto.XkyEntity;
import com.gs.xky.entity.MesInvItemArn;
@@ -16,6 +14,7 @@
import java.io.IOException;
import java.util.List;
import java.util.stream.Collectors;
@SpringBootTest
class XkyApplicationTests {
@@ -160,12 +159,62 @@
    @Test
    void cs3() throws Exception {
//        dingtalkInfoService.sendMessage("CGJY20250412166");
        DingTalkParam dingTalkParam = new DingTalkParam(1);
        DingTalkResponse<EmployeeInfo> employeeInfoDingTalkResponse =
                apiService.sendListRequest(dingTalkParam, EmployeeInfo.class,
                        "http://192.168.1.64/eHR/eHRExternalService/Service.ashx");
//        XkyEntity xkyEntity = new XkyEntity();
//        xkyEntity.setDeliveryNo("222505057541");
//        xkyService.remove1(xkyEntity);
        List<EmployeeInfo> collect = employeeInfoDingTalkResponse.getData().stream()
                .filter(s -> "造梦者(浙江)科技有限公司".equals(s.getCUnitName()))
                .collect(Collectors.toList());
        deliveryNoticeService.setDeliveryNotice();
    }
    /**
     * 测试发送ActionCard消息(在外部浏览器中打开链接)
     * 适用场景:BI报表、外部系统链接等需要在外部浏览器打开的场景
     */
    @Test
    void testSendActionCardMessage() throws Exception {
        System.out.println("=== 开始测试发送ActionCard消息 ===");
        boolean result = dingtalkInfoService.sendActionCardMessage();
        if (result) {
            System.out.println("✓ ActionCard消息发送成功");
        } else {
            System.out.println("✗ ActionCard消息发送失败");
        }
        System.out.println("=== 测试结束 ===");
    }
    /**
     * 测试发送文件消息
     * 适用场景:发送Excel报表、PDF文档、Word文档等各类文件
     */
    @Test
    void testSendFileMessage() throws Exception {
        System.out.println("=== 开始测试发送文件消息 ===");
        // 指定要发送的文件路径(请修改为实际存在的文件路径)
        String filePath = "D:\\test\\report.xlsx";  // 示例:Excel报表文件
        // String filePath = "D:\\test\\document.pdf";  // 示例:PDF文档
        // String filePath = "D:\\test\\data.docx";     // 示例:Word文档
        try {
            boolean result = dingtalkInfoService.sendFileMessage(filePath);
            if (result) {
                System.out.println("✓ 文件消息发送成功");
            } else {
                System.out.println("✗ 文件消息发送失败");
            }
        } catch (Exception e) {
            System.out.println("✗ 发送文件时发生异常: " + e.getMessage());
            e.printStackTrace();
        }
        System.out.println("=== 测试结束 ===");
    }
}