1 feat: 添加 QA 消息推送功能并优化消息发送逻辑
3 - 为 MesQaDingtalkService 添加了巡检和入库检消息发送功能
4 - 在 MesQaDingtalkController 中新增统一消息发送接口
5 - 优化了消息格式并添加了 ID 判空处理
6 - 实现了根据 qaType 动态调用不同消息发送方法
已修改5个文件
已添加11个文件
489 ■■■■■ 文件已修改
src/main/java/com/gs/dingtalk/controller/MesQaDingtalkController.java 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/gs/dingtalk/dto/QaMsgDto.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/gs/dingtalk/entity/QaRkj.java 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/gs/dingtalk/entity/QaSj.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/gs/dingtalk/entity/QaXj.java 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/gs/dingtalk/mapper/QaRkjMapper.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/gs/dingtalk/mapper/QaXjMapper.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/gs/dingtalk/service/MesQaDingtalkService.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/gs/dingtalk/service/QaRkjService.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/gs/dingtalk/service/QaXjService.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/gs/dingtalk/service/impl/MesQaDingtalkServiceImpl.java 149 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/gs/dingtalk/service/impl/QaRkjServiceImpl.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/gs/dingtalk/service/impl/QaXjServiceImpl.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/QaRkjMapper.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/QaXjMapper.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/test/java/com/gs/dingtalk/MesQaDingtalkServiceTest.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/gs/dingtalk/controller/MesQaDingtalkController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,85 @@
package com.gs.dingtalk.controller;
import com.gs.dingtalk.config.ResultMessage;
import com.gs.dingtalk.dto.QaMsgDto;
import com.gs.dingtalk.service.MesQaDingtalkService;
import com.gs.dingtalk.dto.Result;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
/**
 * MES QA é’‰é’‰æ¶ˆæ¯æŽ¨é€æŽ§åˆ¶å™¨
 */
@RestController
@RequestMapping("MesQaDingtalk")
@RequiredArgsConstructor
@CrossOrigin(origins = "*") //跨域请求
public class MesQaDingtalkController {
    private final MesQaDingtalkService mesQaDingtalkService;
    /**
     * ç»Ÿä¸€å‘送QA消息
     * æ ¹æ®QaMsgDto.qaType的值来调用相应的方法
     * é¦–件首检完成 -> sendQaMsgSJ
     * å·¡æ£€æ£€éªŒå®Œæˆ -> sendQaMsgXJ
     * å…¥åº“检检验完成 -> sendQaMsgRKJ
     */
    @PostMapping("/sendQaMsg")
    public ResultMessage sendQaMsg(@RequestBody QaMsgDto dto) {
        try {
            String qaType = dto.getQaType();
            if ("首件首检完成".equals(qaType)) {
                mesQaDingtalkService.sendQaMsgSJ(dto);
            } else if ("巡检检验完成".equals(qaType)) {
                mesQaDingtalkService.sendQaMsgXJ(dto);
            } else if ("入库检检验完成".equals(qaType)) {
                mesQaDingtalkService.sendQaMsgRKJ(dto);
            } else {
                return ResultMessage.error("未知的QA类型: " + qaType);
            }
            return ResultMessage.ok();
        } catch (Exception e) {
            return ResultMessage.error("QA消息发送失败: " + e.getMessage());
        }
    }
    /**
     * å‘送首件检验消息
     */
    @PostMapping("/sendQaMsgSJ")
    public ResultMessage sendQaMsgSJ(@RequestBody QaMsgDto dto) {
        try {
            mesQaDingtalkService.sendQaMsgSJ(dto);
            return ResultMessage.ok();
        } catch (Exception e) {
            return ResultMessage.error("首件检验消息发送失败: " + e.getMessage());
        }
    }
    /**
     * å‘送巡检消息
     */
    @PostMapping("/sendQaMsgXJ")
    public ResultMessage sendQaMsgXJ(@RequestBody QaMsgDto dto) {
        try {
            mesQaDingtalkService.sendQaMsgXJ(dto);
            return ResultMessage.ok();
        } catch (Exception e) {
            return ResultMessage.error("巡检消息发送失败: " + e.getMessage());
        }
    }
    /**
     * å‘送入库检消息
     */
    @PostMapping("/sendQaMsgRKJ")
    public ResultMessage sendQaMsgRKJ(@RequestBody QaMsgDto dto) {
        try {
            mesQaDingtalkService.sendQaMsgRKJ(dto);
            return ResultMessage.ok();
        } catch (Exception e) {
            return ResultMessage.error("入库检消息发送失败: " + e.getMessage());
        }
    }
}
src/main/java/com/gs/dingtalk/dto/QaMsgDto.java
@@ -6,8 +6,8 @@
@Data
public class QaMsgDto {
    private String id;
    private String lineName;
    private String workshopName;
    private String qaType;
    private String billNo;
}
src/main/java/com/gs/dingtalk/entity/QaRkj.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,62 @@
package com.gs.dingtalk.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import lombok.Data;
/**
 *
 * @TableName QA_RKJ
 */
@TableName(value ="QA_RKJ")
@Data
public class QaRkj implements Serializable {
    /**
     * å•号id
     */
    private Long id;
    /**
     * æ£€éªŒå•号
     */
    private String releaseNo;
    /**
     * ç‰©æ–™ç¼–码
     */
    private String itemNo;
    /**
     * ç‰©æ–™åç§°
     */
    private String itemName;
    /**
     * çº¿ä½“
     */
    private String daa020;
    /**
     * è½¦é—´
     */
    private String departmentname;
    /**
     * æäº¤æ ‡è¯†
     */
    private Long fsubmit;
    /**
     * å·¥å•号
     */
    private String daa001;
    /**
     * æ£€éªŒç»“æžœ
     */
    private String fcheckResu;
    @TableField(exist = false)
    private static final long serialVersionUID = 1L;
}
src/main/java/com/gs/dingtalk/entity/QaSj.java
@@ -13,6 +13,10 @@
@Data
public class QaSj implements Serializable {
    /**
     * æ£€éªŒå•id
     */
    private Long id;
    /**
     * æ£€éªŒå•号
     */
    private String billNo;
src/main/java/com/gs/dingtalk/entity/QaXj.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,62 @@
package com.gs.dingtalk.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import lombok.Data;
/**
 *
 * @TableName QA_XJ
 */
@TableName(value ="QA_XJ")
@Data
public class QaXj implements Serializable {
    /**
     * id
     */
    private Long id;
    /**
     * æ£€éªŒå•号
     */
    private String releaseNo;
    /**
     * ç‰©æ–™ç¼–码
     */
    private String itemNo;
    /**
     * ç‰©æ–™åç§°
     */
    private String itemName;
    /**
     * çº¿ä½“
     */
    private String lineName;
    /**
     * è½¦é—´
     */
    private String departmentname;
    /**
     * æäº¤æ ‡è¯†
     */
    private Long fsubmit;
    /**
     * å·¥å•号
     */
    private String daa001;
    /**
     * æ£€éªŒç»“æžœ
     */
    private String fcheckResu;
    @TableField(exist = false)
    private static final long serialVersionUID = 1L;
}
src/main/java/com/gs/dingtalk/mapper/QaRkjMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,18 @@
package com.gs.dingtalk.mapper;
import com.gs.dingtalk.entity.QaRkj;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* @author Administrator
* @description é’ˆå¯¹è¡¨ã€QA_RKJ】的数据库操作Mapper
* @createDate 2025-12-04 09:49:14
* @Entity com.gs.dingtalk.entity.QaRkj
*/
public interface QaRkjMapper extends BaseMapper<QaRkj> {
}
src/main/java/com/gs/dingtalk/mapper/QaXjMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,18 @@
package com.gs.dingtalk.mapper;
import com.gs.dingtalk.entity.QaXj;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* @author Administrator
* @description é’ˆå¯¹è¡¨ã€QA_XJ】的数据库操作Mapper
* @createDate 2025-12-04 09:49:37
* @Entity com.gs.dingtalk.entity.QaXj
*/
public interface QaXjMapper extends BaseMapper<QaXj> {
}
src/main/java/com/gs/dingtalk/service/MesQaDingtalkService.java
@@ -13,4 +13,8 @@
    void sendQaMsgSJ(QaMsgDto dto);
    void sendQaMsgXJ(QaMsgDto dto);
    void sendQaMsgRKJ(QaMsgDto dto);
}
src/main/java/com/gs/dingtalk/service/QaRkjService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,13 @@
package com.gs.dingtalk.service;
import com.gs.dingtalk.entity.QaRkj;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* @author Administrator
* @description é’ˆå¯¹è¡¨ã€QA_RKJ】的数据库操作Service
* @createDate 2025-12-04 09:49:14
*/
public interface QaRkjService extends IService<QaRkj> {
}
src/main/java/com/gs/dingtalk/service/QaXjService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,13 @@
package com.gs.dingtalk.service;
import com.gs.dingtalk.entity.QaXj;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* @author Administrator
* @description é’ˆå¯¹è¡¨ã€QA_XJ】的数据库操作Service
* @createDate 2025-12-04 09:49:37
*/
public interface QaXjService extends IService<QaXj> {
}
src/main/java/com/gs/dingtalk/service/impl/MesQaDingtalkServiceImpl.java
@@ -5,11 +5,11 @@
import com.gs.dingtalk.dto.DingTalkMessage;
import com.gs.dingtalk.dto.QaMsgDto;
import com.gs.dingtalk.entity.MesQaDingtalk;
import com.gs.dingtalk.entity.QaRkj;
import com.gs.dingtalk.entity.QaSj;
import com.gs.dingtalk.service.MesQaDingtalkService;
import com.gs.dingtalk.entity.QaXj;
import com.gs.dingtalk.service.*;
import com.gs.dingtalk.mapper.MesQaDingtalkMapper;
import com.gs.dingtalk.service.QaSjService;
import com.gs.dingtalk.service.SimpleExample;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -30,13 +30,22 @@
public class MesQaDingtalkServiceImpl extends ServiceImpl<MesQaDingtalkMapper, MesQaDingtalk>
        implements MesQaDingtalkService {
    private final SimpleExample simpleExample;
    private final QaSjService qaSjService;
    private final QaXjService qaXjService;
    private final QaRkjService qaRkjService;
    @Override
    public void sendQaMsgSJ(QaMsgDto dto) {
        // å¯¹dto.getId()进行判空处理
        if (dto.getId() == null) {
            log.warn("检验ID为空,无法发送消息");
            return;
        }
        LambdaQueryWrapper<MesQaDingtalk> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(MesQaDingtalk::getLineName, dto.getLineName())
@@ -52,7 +61,7 @@
        }
        LambdaQueryWrapper<QaSj> qaSjQueryWrapper = new LambdaQueryWrapper<>();
        qaSjQueryWrapper.eq(QaSj::getBillNo, dto.getBillNo());
        qaSjQueryWrapper.eq(QaSj::getId, dto.getId());
        QaSj qaSj = qaSjService.getOne(qaSjQueryWrapper, false);
        if (qaSj == null) {
@@ -60,10 +69,138 @@
            return;
        }
        String message = String.format("首件[检验单号:%s, ç‰©æ–™ç¼–码:%s, ç‰©æ–™åç§°:%s, è½¦é—´:%s, çº¿ä½“:%s, å·¥å•号:%s, æ£€éªŒç»“æžœ:%s],请进行后续操作",
        String message = String.format("首件检验单号:%s, ç‰©æ–™:%s-%s, è½¦é—´:%s线体:%s, å·¥å•:%s, ç»“æžœ:%s, è¯·è¿›è¡ŒåŽç»­å¤„理",
                qaSj.getBillNo(), qaSj.getItemNo(), qaSj.getItemName(), qaSj.getWorkshopName(),
                qaSj.getLineName(), qaSj.getDaa001(), qaSj.getJyjg());
        List<String> sidList = list.stream()
                .map(MesQaDingtalk::getTelephone)
                .collect(Collectors.toList());
        List<String> userIdList = getDingtalkUserIdListByPhones(sidList);
        if (userIdList == null || userIdList.isEmpty()) {
            log.warn("没有有效的钉钉用户ID");
            return;
        }
        String userIdListStr = String.join(",", userIdList);
        DingTalkMessage dingTalkMessage = null;
        try {
            dingTalkMessage = simpleExample.sendMessage(userIdListStr, message);
        } catch (Exception e) {
            throw new RuntimeException("发送钉钉消息失败", e);
        }
        if (dingTalkMessage != null && dingTalkMessage.getErrcode() == 0) {
            System.out.println("发送成功");
        } else {
            System.out.println("发送失败");
        }
    }
    @Override
    public void sendQaMsgXJ(QaMsgDto dto) {
        // å¯¹dto.getId()进行判空处理
        if (dto.getId() == null) {
            log.warn("巡检ID为空,无法发送消息");
            return;
        }
        LambdaQueryWrapper<MesQaDingtalk> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(MesQaDingtalk::getLineName, dto.getLineName())
                .eq(MesQaDingtalk::getDepartmentname, dto.getWorkshopName())
                .eq(MesQaDingtalk::getQaType, dto.getQaType());
        //获取到用户id,当用户没有id时重新获取并更新MesQaDingtalk表
        List<MesQaDingtalk> list = list(wrapper);
        if (list.isEmpty()) {
            // å¦‚果没有找到对应的用户,直接返回
            return;
        }
        LambdaQueryWrapper<QaXj> qaXjQueryWrapper = new LambdaQueryWrapper<>();
        qaXjQueryWrapper.eq(QaXj::getId, dto.getId());
        QaXj qaXj = qaXjService.getOne(qaXjQueryWrapper, false);
        if (qaXj == null) {
            // å¦‚果没有找到对应的巡检信息,直接返回
            return;
        }
        String message = String.format("巡检单号:%s, ç‰©æ–™:%s-%s, è½¦é—´:%s线体:%s, å·¥å•:%s, ç»“æžœ:%s, è¯·è¿›è¡ŒåŽç»­å¤„理",
                qaXj.getReleaseNo(), qaXj.getItemNo(), qaXj.getItemName(), qaXj.getDepartmentname(),
                qaXj.getLineName(), qaXj.getDaa001(), qaXj.getFcheckResu());
        // æŠŠList<MesQaDingtalk>中的userId使用,拼接起来变成userIdList这个变量
        List<String> sidList = list.stream()
                .map(MesQaDingtalk::getTelephone)
                .collect(Collectors.toList());
        List<String> userIdList = getDingtalkUserIdListByPhones(sidList);
        if (userIdList == null || userIdList.isEmpty()) {
            log.warn("没有有效的钉钉用户ID");
            return;
        }
        String userIdListStr = String.join(",", userIdList);
        DingTalkMessage dingTalkMessage = null;
        try {
            dingTalkMessage = simpleExample.sendMessage(userIdListStr, message);
        } catch (Exception e) {
            throw new RuntimeException("发送钉钉消息失败", e);
        }
        if (dingTalkMessage != null && dingTalkMessage.getErrcode() == 0) {
            System.out.println("发送成功");
        } else {
            System.out.println("发送失败");
        }
    }
    @Override
    public void sendQaMsgRKJ(QaMsgDto dto) {
        // å¯¹dto.getId()进行判空处理
        if (dto.getId() == null) {
            log.warn("入库检ID为空,无法发送消息");
            return;
        }
        LambdaQueryWrapper<MesQaDingtalk> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(MesQaDingtalk::getLineName, dto.getLineName())
                .eq(MesQaDingtalk::getDepartmentname, dto.getWorkshopName())
                .eq(MesQaDingtalk::getQaType, dto.getQaType());
        //获取到用户id,当用户没有id时重新获取并更新MesQaDingtalk表
        List<MesQaDingtalk> list = list(wrapper);
        if (list.isEmpty()) {
            // å¦‚果没有找到对应的用户,直接返回
            return;
        }
        LambdaQueryWrapper<QaRkj> qaRkjQueryWrapper = new LambdaQueryWrapper<>();
        qaRkjQueryWrapper.eq(QaRkj::getId, dto.getId());
        QaRkj qaRkj = qaRkjService.getOne(qaRkjQueryWrapper, false);
        if (qaRkj == null) {
            // å¦‚果没有找到对应的入库检信息,直接返回
            return;
        }
        String message = String.format("入库检单号:%s, ç‰©æ–™:%s-%s, è½¦é—´:%s线体:%s, å·¥å•:%s, ç»“æžœ:%s, è¯·è¿›è¡ŒåŽç»­å¤„理",
                qaRkj.getReleaseNo(), qaRkj.getItemNo(), qaRkj.getItemName(), qaRkj.getDepartmentname(),
                qaRkj.getDaa020(), qaRkj.getDaa001(), qaRkj.getFcheckResu());
        // æŠŠList<MesQaDingtalk>中的userId使用,拼接起来变成userIdList这个变量
        List<String> sidList = list.stream()
src/main/java/com/gs/dingtalk/service/impl/QaRkjServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,22 @@
package com.gs.dingtalk.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gs.dingtalk.entity.QaRkj;
import com.gs.dingtalk.service.QaRkjService;
import com.gs.dingtalk.mapper.QaRkjMapper;
import org.springframework.stereotype.Service;
/**
* @author Administrator
* @description é’ˆå¯¹è¡¨ã€QA_RKJ】的数据库操作Service实现
* @createDate 2025-12-04 09:49:14
*/
@Service
public class QaRkjServiceImpl extends ServiceImpl<QaRkjMapper, QaRkj>
    implements QaRkjService{
}
src/main/java/com/gs/dingtalk/service/impl/QaXjServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,22 @@
package com.gs.dingtalk.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gs.dingtalk.entity.QaXj;
import com.gs.dingtalk.service.QaXjService;
import com.gs.dingtalk.mapper.QaXjMapper;
import org.springframework.stereotype.Service;
/**
* @author Administrator
* @description é’ˆå¯¹è¡¨ã€QA_XJ】的数据库操作Service实现
* @createDate 2025-12-04 09:49:37
*/
@Service
public class QaXjServiceImpl extends ServiceImpl<QaXjMapper, QaXj>
    implements QaXjService{
}
src/main/resources/mapper/QaRkjMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.gs.dingtalk.mapper.QaRkjMapper">
</mapper>
src/main/resources/mapper/QaXjMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.gs.dingtalk.mapper.QaXjMapper">
</mapper>
src/test/java/com/gs/dingtalk/MesQaDingtalkServiceTest.java
@@ -29,7 +29,6 @@
        dto.setLineName("注塑3号机");
        dto.setWorkshopName("注塑车间");
        dto.setQaType("首件首检完成");
        dto.setBillNo("SJ202509150022");
        mesQaDingtalkService.sendQaMsgSJ(dto);
    }