2601b5f18d4464a6848b399c034e8266180725c8..b839bdc85e784e545cb5d371ed3f638747fb6a06
16 小时以前 tjx
新增企业微信的接口
b839bd 对比 | 目录
16 小时以前 tjx
新增企业微信的接口
b00edf 对比 | 目录
已添加1个文件
已修改11个文件
923 ■■■■■ 文件已修改
pom.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/gs/xky/config/DataAcquisitionConfiguration.java 13 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/gs/xky/entity/DingtalkMsg.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/gs/xky/service/DingtalkInfoService.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/gs/xky/service/Impl/DingtalkInfoServiceImpl.java 281 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/gs/xky/service/Impl/MesQaItemsDetect01ServiceImpl.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/gs/xky/service/XkyService.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/gs/xky/task/PurchaseOrderSyncTask.java 96 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/gs/xky/task/ScheduledTasks.java 230 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application.yml 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/VwCjScSjTsBbMonthMapper.xml 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/test/java/com/gs/xky/XkyApplicationTests.java 245 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pom.xml
@@ -96,13 +96,6 @@
            <artifactId>hutool-all</artifactId>
            <version>5.8.18</version>
        </dependency>
        <!-- Apache POI for Excel (required by Hutool) -->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>5.2.3</version>
        </dependency>
    </dependencies>
    <build>
src/main/java/com/gs/xky/config/DataAcquisitionConfiguration.java
@@ -25,26 +25,19 @@
    /**
     * åº”用的 AgentId
     */
    public static final Long AGENT_ID = 4104598880L;
    public static final Long AGENT_ID = 3303296035L;
    /**
     * åº”用的 AppKey
     */
    public static final String TALK_APP_KEY = "dinggglb3pttl1x0gn0c";
    public static final String TALK_APP_KEY = "dingnpc4kma0t19nphhd";
    /**
     * åº”用的 AppSecret
     */
    public static final String TALK_APP_SECRET = "Zc7r0Mb7bPsC_xy7ryrWoEnE5OzHEXibUMPDCA2LBusJ9pYzIolRk_OdZuLvNExf";
    public static final String TALK_APP_SECRET = "uMecvKIfErf9htigYIyjI3svHpXEEDWROy2v1cXw7V6EXIG09oQI5N5e-EMqBo4r";
    //群聊机器人相关
    public static final String CUSTOM_ROBOT_TOKEN = "c2849e46cb0d91b0721c377742938b8ac5ef57e3c9eeab918e2cd5dd9c3aad2a";
    public static final String SECRET = "SEC382027a5c81ea5152b71b687fb2c1ebf26acbde035355da6ab2fb37306454134";
    //企业微信
    public static final String CORPID = "wwabe21b935901a7d8";
    public static final String CORPSECRET = "Z-7fNbZjrd80ypz69U14j8FMxI_fpUxcT6PksxlvKaY";
    public static final String TXL_CORPSECRET = "T64bdcV7fo0hvW10W3NJYmGUmlBYxYMfiW6EiUJ9VPM";
}
src/main/java/com/gs/xky/entity/DingtalkMsg.java
@@ -51,4 +51,8 @@
     * å®¡æ ¸äºº
     */
    private String modify1By;
    /**
     * æ–™å“åç§°
     */
    private String itemName;
}
src/main/java/com/gs/xky/service/DingtalkInfoService.java
@@ -11,15 +11,4 @@
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,13 +14,11 @@
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;
@@ -132,95 +130,6 @@
        }
    }
    @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<String> sidList = fixedList.stream()
                    .map(DingtalkInfo::getPhone)
                    .collect(Collectors.toList());
            List<String> userIdList = getDingtalkUserIdListByPhones(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列表
     *
@@ -285,72 +194,13 @@
        }
    }
    private List<String> getDingtalkUserIdListByPhones(List<String> phoneList) {
        try {
            if (phoneList == null || phoneList.isEmpty()) {
                return new ArrayList<>();
            }
            // åŽ»é‡
            phoneList = phoneList.stream().distinct().collect(Collectors.toList());
            // æ ¹æ®sid查询DingtalkInfo
            List<DingtalkInfo> list = baseMapper.selectList(
                    new LambdaQueryWrapper<DingtalkInfo>().in(DingtalkInfo::getPhone, phoneList)
            );
            if (list == null || list.isEmpty()) {
                return new ArrayList<>();
            }
            // ä½¿ç”¨stream流过滤出list中dingtalkId为空的数据
            List<DingtalkInfo> emptyDingtalkIdList = list.stream()
                    .filter(info -> !StringUtils.hasText(info.getDingtalkId()))
                    .collect(Collectors.toList());
            // å¦‚果存在为空的数据就通过钉钉的接口获取,为dingtalkId赋值,并且更新数据库
            if (!emptyDingtalkIdList.isEmpty()) {
                String accessToken = simpleExample.getAccessToken();
                for (DingtalkInfo info : emptyDingtalkIdList) {
                    if (StringUtils.hasText(info.getPhone())) {
                        try {
                            // é€šè¿‡æ‰‹æœºå·èŽ·å–é’‰é’‰ç”¨æˆ·ID
                            com.dingtalk.api.response.OapiV2UserGetbymobileResponse response =
                                    simpleExample.getOapiV2UserGetbymobileResponse(info.getPhone(), accessToken);
                            if (response != null && response.getResult() != null) {
                                info.setDingtalkId(response.getResult().getUserid());
                                // æ›´æ–°æ•°æ®åº“
                                updateById(info);
                            }
                        } catch (Exception e) {
                            log.error("获取钉钉用户ID失败,手机号:{}", info.getPhone(), e);
                        }
                    }
                }
            }
            // ä¸å­˜åœ¨ä¸ºç©ºçš„æ•°æ®æˆ–者处理完空数据后,返回所有有效的dingtalkId列表
            return list.stream()
                    .map(DingtalkInfo::getDingtalkId)
                    .filter(StringUtils::hasText)
                    .distinct()
                    .collect(Collectors.toList());
        } catch (Exception e) {
            log.error("获取钉钉用户列表失败", e);
            return new ArrayList<>();
        }
    }
    private OapiMessageCorpconversationAsyncsendV2Response sendMessage(String userIdListStr, String message) 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.setAgentId(3917187842L);
        request.setUseridList(userIdListStr);
        request.setToAllUser(false);
@@ -358,135 +208,6 @@
        msg.setMsgtype("text");
        msg.setText(new OapiMessageCorpconversationAsyncsendV2Request.Text());
        msg.getText().setContent(message);
        request.setMsg(msg);
        return client.execute(request, accessToken);
    }
    /**
     * å‘送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);
src/main/java/com/gs/xky/service/Impl/MesQaItemsDetect01ServiceImpl.java
@@ -47,6 +47,11 @@
        List<String> collect = list.stream().filter(s -> !StrUtil.isNotEmpty(s.getFcheckResu())).map(MesQaItemsDetect01::getReleaseNo).collect(Collectors.toList());
        if (CollUtil.isEmpty(collect)) {
            return true;
        }
        LambdaUpdateWrapper<MesQaItemsDetect01> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.in(MesQaItemsDetect01::getReleaseNo, collect);
        if (remove(wrapper)) {
src/main/java/com/gs/xky/service/XkyService.java
@@ -97,7 +97,7 @@
    private void processBatchDeliveries(List<XkyEntity> batchDeliveries) {
        batchDeliveries.forEach(deliveryNo -> {
            try {
                if ("6".equals(deliveryNo.getStatus()) || "0".equals(deliveryNo.getLogisticsStatus())) {
                if ("6".equals(deliveryNo.getStatus()) || "8".equals(deliveryNo.getStatus()) || "0".equals(deliveryNo.getLogisticsStatus())) {
                    log.info("【processBatchDeliveries】移除送货单: {}", deliveryNo.getDeliveryNo());
                    remove1(deliveryNo);
                } else if ("1".equals(deliveryNo.getStatus()) && ("2".equals(deliveryNo.getLogisticsStatus()) || "1".equals(deliveryNo.getLogisticsStatus()))) {
src/main/java/com/gs/xky/task/PurchaseOrderSyncTask.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,96 @@
package com.gs.xky.task;
import com.gs.xky.service.PurchaseService;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicBoolean;
/**
 * é‡‡è´­è®¢å•同步定时任务
 */
@Component
@RequiredArgsConstructor
public class PurchaseOrderSyncTask {
    private static final Logger log = LoggerFactory.getLogger(PurchaseOrderSyncTask.class);
    private final PurchaseService purchaseService;
    private final Executor purchaseTaskExecutor; // æ³¨å…¥ä¸“用线程池
    // ç”¨äºŽæ ‡è®°ä»»åŠ¡æ˜¯å¦æ­£åœ¨æ‰§è¡Œ
    private final AtomicBoolean isRunning = new AtomicBoolean(false);
    /**
     * å®šæ—¶æ‰§è¡Œé‡‡è´­è®¢å•同步任务
     * æ¯å¤©12点整执行一次
     * è®¾ç½®ä¸º12点05分执行,避免与其他定时任务冲突
     * ä½¿ç”¨å¼‚步执行,防止阻塞其他定时任务
     */
    @Scheduled(cron = "0 5 12 * * ?")
    public void syncPurchaseOrders() {
        // å¦‚果任务已经在运行,则跳过本次执行
        if (!isRunning.compareAndSet(false, true)) {
            log.info("【syncPurchaseOrders】上一次任务还在执行中,跳过本次执行");
            return;
        }
        log.info("【syncPurchaseOrders】开始执行采购订单同步任务");
        // ä½¿ç”¨ä¸“用线程池执行异步任务
        CompletableFuture.runAsync(() -> {
            try {
                log.info("【syncPurchaseOrders】异步线程开始执行采购订单同步");
                purchaseService.syncPurchaseOrderDetails();
                log.info("【syncPurchaseOrders】采购订单同步任务执行成功");
            } catch (IOException e) {
                log.error("【syncPurchaseOrders】采购订单同步任务执行异常: {}", e.getMessage(), e);
            } finally {
                // æ— è®ºæˆåŠŸè¿˜æ˜¯å¤±è´¥ï¼Œéƒ½å°†è¿è¡ŒçŠ¶æ€é‡ç½®
                isRunning.set(false);
                log.info("【syncPurchaseOrders】任务状态已重置,可以接受新的任务");
            }
        }, purchaseTaskExecutor);
        // ä¸ç­‰å¾…任务完成,立即返回,避免阻塞调度线程
        log.info("【syncPurchaseOrders】采购订单同步任务已提交到异步线程执行");
    }
    /**
     * æ‰‹åŠ¨è§¦å‘é‡‡è´­è®¢å•åŒæ­¥ä»»åŠ¡
     * ç”¨äºŽç³»ç»Ÿç®¡ç†å‘˜æ‰‹åŠ¨è§¦å‘åŒæ­¥
     *
     * @return ä»»åŠ¡æ˜¯å¦å·²æäº¤æ‰§è¡Œ
     */
    public boolean manualSyncPurchaseOrders() {
        // å¦‚果任务已经在运行,则拒绝本次执行
        if (!isRunning.compareAndSet(false, true)) {
            log.info("【manualSyncPurchaseOrders】上一次任务还在执行中,拒绝本次执行");
            return false;
        }
        log.info("【manualSyncPurchaseOrders】手动触发采购订单同步任务");
        // ä½¿ç”¨ä¸“用线程池执行异步任务
        CompletableFuture.runAsync(() -> {
            try {
                log.info("【manualSyncPurchaseOrders】异步线程开始执行采购订单同步");
                purchaseService.syncPurchaseOrderDetails();
                log.info("【manualSyncPurchaseOrders】采购订单同步任务执行成功");
            } catch (IOException e) {
                log.error("【manualSyncPurchaseOrders】采购订单同步任务执行异常: {}", e.getMessage(), e);
            } finally {
                // æ— è®ºæˆåŠŸè¿˜æ˜¯å¤±è´¥ï¼Œéƒ½å°†è¿è¡ŒçŠ¶æ€é‡ç½®
                isRunning.set(false);
                log.info("【manualSyncPurchaseOrders】任务状态已重置,可以接受新的任务");
            }
        }, purchaseTaskExecutor);
        return true;
    }
}
src/main/java/com/gs/xky/task/ScheduledTasks.java
@@ -1,157 +1,133 @@
package com.gs.xky.task;
import com.gs.xky.service.VwCjScSjTsBbService;
import cn.hutool.core.collection.ListUtil;
import com.gs.xky.config.DingTalkParam;
import com.gs.xky.config.DingTalkResponse;
import com.gs.xky.dto.EmployeeInfo;
import com.gs.xky.entity.MesInvItemArn;
import com.gs.xky.service.*;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;
@Component
@RequiredArgsConstructor
public class ScheduledTasks {
    private static final Logger log = LoggerFactory.getLogger(ScheduledTasks.class);
    private final VwCjScSjTsBbService vwCjScSjTsBbService;
    private final AtomicBoolean exportTaskRunning = new AtomicBoolean(false);
//    private final XkyService xkyService;
//    private final ApiService apiService;
//    private final MesStaffService staffService;
//    private final DeliveryNoticeService deliveryNoticeService;
//    private final MesInvItemArnService invItemArnService;
//    private final Executor taskExecutor; // æ³¨å…¥é€šç”¨çº¿ç¨‹æ± 
    private final XkyService xkyService;
    private final ApiService apiService;
    private final MesStaffService staffService;
    private final DeliveryNoticeService deliveryNoticeService;
    private final MesInvItemArnService invItemArnService;
    private final Executor taskExecutor; // æ³¨å…¥é€šç”¨çº¿ç¨‹æ± 
    // ç”¨äºŽæ ‡è®°å„任务是否正在执行
//    private final AtomicBoolean isDeviceDataRunning = new AtomicBoolean(false);
//    private final AtomicBoolean isCompensateRunning = new AtomicBoolean(false);
//    private final AtomicBoolean isDingTalkRunning = new AtomicBoolean(false);
    private final AtomicBoolean isDeviceDataRunning = new AtomicBoolean(false);
    private final AtomicBoolean isCompensateRunning = new AtomicBoolean(false);
    private final AtomicBoolean isDingTalkRunning = new AtomicBoolean(false);
    /**
     * æ¯å¤©ä¸Šåˆ9点执行
     * å¯¼å‡ºç”Ÿäº§æ•°æ®å¹¶å‘送钉钉消息
     * æ¯äº”分钟执行一次
     * èŽ·å–è®¾å¤‡æœ€è¿‘çš„ä¸€æ¡è®°å½•
     */
    @Async("taskExecutor")
    @Scheduled(cron = "0 0 12,16 * * ?")
    public void exportAndSendProductionDataTask() {
        if (!exportTaskRunning.compareAndSet(false, true)) {
            log.warn("生产数据导出任务正在执行中,跳过本次执行");
    @Scheduled(cron = "0 0/5 * * * ?")
    public void getDeviceRealTimeData() {
        // å¦‚果任务已经在运行,则跳过本次执行
        if (!isDeviceDataRunning.compareAndSet(false, true)) {
            log.info("【getDeviceRealTimeData】上一次任务还在执行中,跳过本次执行");
            return;
        }
        try {
            log.info("开始执行生产数据导出并发送钉钉任务");
            boolean result = vwCjScSjTsBbService.exportAndSendToDingtalk();
        log.info("【getDeviceRealTimeData】开始获取设备实时数据");
            if (result) {
                log.info("生产数据导出并发送钉钉任务执行成功");
            } else {
                log.error("生产数据导出并发送钉钉任务执行失败");
        // ä½¿ç”¨å¼‚步执行,避免阻塞调度线程
        CompletableFuture.runAsync(() -> {
            try {
                xkyService.GetSaveDetail();
                log.info("【getDeviceRealTimeData】获取设备实时数据成功");
            } catch (IOException e) {
                log.error("【getDeviceRealTimeData】获取设备实时数据异常: {}", e.getMessage(), e);
            } finally {
                isDeviceDataRunning.set(false);
            }
        } catch (Exception e) {
            log.error("生产数据导出并发送钉钉任务执行异常", e);
        } finally {
            exportTaskRunning.set(false);
        }
        }, taskExecutor);
    }
//    /**
//     * æ¯äº”分钟执行一次
//     * èŽ·å–åå®¢äº‘æœ€è¿‘çš„ä¸€æ¡è®°å½•
//     */
//    @Scheduled(cron = "0 0/5 * * * ?")
//    public void getDeviceRealTimeData() {
//        // å¦‚果任务已经在运行,则跳过本次执行
//        if (!isDeviceDataRunning.compareAndSet(false, true)) {
//            log.info("【getDeviceRealTimeData】上一次任务还在执行中,跳过本次执行");
//            return;
//        }
//
//        log.info("【getDeviceRealTimeData】开始获取设备实时数据");
//
//        // ä½¿ç”¨å¼‚步执行,避免阻塞调度线程
//        CompletableFuture.runAsync(() -> {
//            try {
//                xkyService.GetSaveDetail();
//                log.info("【getDeviceRealTimeData】获取设备实时数据成功");
//            } catch (IOException e) {
//                log.error("【getDeviceRealTimeData】获取设备实时数据异常: {}", e.getMessage(), e);
//            } finally {
//                isDeviceDataRunning.set(false);
//            }
//        }, taskExecutor);
//    }
//
//    /**
//     * å®šæ—¶æ‰§è¡Œè¡¥å¿é€»è¾‘
//     */
//    @Scheduled(cron = "10 3,8,13,18,23,28,33,38,43,48,53,58 * * * ?")
//    public void compensateMethod() {
//        // å¦‚果任务已经在运行,则跳过本次执行
//        if (!isCompensateRunning.compareAndSet(false, true)) {
//            log.info("【compensateMethod】上一次任务还在执行中,跳过本次执行");
//            return;
//        }
//
//        log.info("【compensateMethod】开始执行补偿逻辑");
//
//        // ä½¿ç”¨å¼‚步执行,避免阻塞调度线程
//        CompletableFuture.runAsync(() -> {
//            try {
//                // è¡¥å¿é€»è¾‘
//                List<MesInvItemArn> itemArnMinus = invItemArnService.getItemArnMinus();
//                deliveryNoticeService.processMesInvItemArnStatusAsync(itemArnMinus);
//                log.info("【compensateMethod】补偿逻辑执行成功");
//            } catch (Exception e) {
//                log.error("【compensateMethod】补偿逻辑执行异常: {}", e.getMessage(), e);
//            } finally {
//                isCompensateRunning.set(false);
//            }
//        }, taskExecutor);
//    }
//
//    /**
//     * å®šæ—¶èŽ·å–é’‰é’‰æ•°æ®
//     */
//    @Scheduled(cron = "0 0/53 * * * ?")
//    public void getDinTalkData() {
//        // å¦‚果任务已经在运行,则跳过本次执行
//        if (!isDingTalkRunning.compareAndSet(false, true)) {
//            log.info("【getDinTalkData】上一次任务还在执行中,跳过本次执行");
//            return;
//        }
//
//        log.info("【getDinTalkData】开始获取钉钉数据");
//
//        // ä½¿ç”¨å¼‚步执行,避免阻塞调度线程
//        CompletableFuture.runAsync(() -> {
//            try {
//                DingTalkParam dingTalkParam = new DingTalkParam(1);
//                DingTalkResponse<EmployeeInfo> employeeInfoDingTalkResponse =
//                        apiService.sendListRequest(dingTalkParam, EmployeeInfo.class,
//                                "http://192.168.1.64/eHR/eHRExternalService/Service.ashx");
//
//                List<EmployeeInfo> collect = employeeInfoDingTalkResponse.getData().stream()
//                        .filter(s -> "造梦者(浙江)科技有限公司".equals(s.getCUnitName()))
//                        .collect(Collectors.toList());
//
//                log.info("【getDinTalkData】获取到{}条员工数据", collect.size());
//
//                List<List<EmployeeInfo>> partition = ListUtil.partition(collect, 100);
//                partition.forEach(staffService::UpdateStaff);
//
//                log.info("【getDinTalkData】钉钉数据处理完成");
//            } catch (IOException e) {
//                log.error("【getDinTalkData】获取钉钉数据异常: {}", e.getMessage(), e);
//            } finally {
//                isDingTalkRunning.set(false);
//            }
//        }, taskExecutor);
//    }
    /**
     * å®šæ—¶æ‰§è¡Œè¡¥å¿é€»è¾‘
     */
    @Scheduled(cron = "10 3,8,13,18,23,28,33,38,43,48,53,58 * * * ?")
    public void compensateMethod() {
        // å¦‚果任务已经在运行,则跳过本次执行
        if (!isCompensateRunning.compareAndSet(false, true)) {
            log.info("【compensateMethod】上一次任务还在执行中,跳过本次执行");
            return;
        }
        log.info("【compensateMethod】开始执行补偿逻辑");
        // ä½¿ç”¨å¼‚步执行,避免阻塞调度线程
        CompletableFuture.runAsync(() -> {
            try {
                // è¡¥å¿é€»è¾‘
                List<MesInvItemArn> itemArnMinus = invItemArnService.getItemArnMinus();
                deliveryNoticeService.processMesInvItemArnStatusAsync(itemArnMinus);
                log.info("【compensateMethod】补偿逻辑执行成功");
            } catch (Exception e) {
                log.error("【compensateMethod】补偿逻辑执行异常: {}", e.getMessage(), e);
            } finally {
                isCompensateRunning.set(false);
            }
        }, taskExecutor);
    }
    /**
     * å®šæ—¶èŽ·å–é’‰é’‰æ•°æ®
     */
    @Scheduled(cron = "0 0/53 * * * ?")
    public void getDinTalkData() {
        // å¦‚果任务已经在运行,则跳过本次执行
        if (!isDingTalkRunning.compareAndSet(false, true)) {
            log.info("【getDinTalkData】上一次任务还在执行中,跳过本次执行");
            return;
        }
        log.info("【getDinTalkData】开始获取钉钉数据");
        // ä½¿ç”¨å¼‚步执行,避免阻塞调度线程
        CompletableFuture.runAsync(() -> {
            try {
                DingTalkParam dingTalkParam = new DingTalkParam(1);
                DingTalkResponse<EmployeeInfo> employeeInfoDingTalkResponse =
                        apiService.sendListRequest(dingTalkParam, EmployeeInfo.class,
                                "http://192.168.1.64/eHR/eHRExternalService/Service.ashx");
                List<EmployeeInfo> collect = employeeInfoDingTalkResponse.getData().stream()
                        .filter(s -> "造梦者(浙江)科技有限公司".equals(s.getCUnitName()))
                        .collect(Collectors.toList());
                log.info("【getDinTalkData】获取到{}条员工数据", collect.size());
                List<List<EmployeeInfo>> partition = ListUtil.partition(collect, 100);
                partition.forEach(staffService::UpdateStaff);
                log.info("【getDinTalkData】钉钉数据处理完成");
            } catch (IOException e) {
                log.error("【getDinTalkData】获取钉钉数据异常: {}", e.getMessage(), e);
            } finally {
                isDingTalkRunning.set(false);
            }
        }, taskExecutor);
    }
}
src/main/resources/application.yml
@@ -5,9 +5,9 @@
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: oracle.jdbc.OracleDriver
    url: jdbc:oracle:thin:@192.168.1.22:1521/ORCL
    username: hm_prd
    password: hmprd
    url: jdbc:oracle:thin:@192.168.1.104:1521/ORCL
    username: zmz_prd
    password: zmzprd
    druid:
      initialSize: 5
      minIdle: 5
src/main/resources/mapper/VwCjScSjTsBbMonthMapper.xml
@@ -4,27 +4,4 @@
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.gs.xky.mapper.VwCjScSjTsBbMonthMapper">
    <resultMap id="BaseResultMap" type="com.gs.xky.entity.VwCjScSjTsBbMonth">
            <result property="itemName" column="ITEM_NAME" />
            <result property="itemNo" column="ITEM_NO" />
            <result property="departmentname" column="DEPARTMENTNAME" />
            <result property="departmentcode" column="DEPARTMENTCODE" />
            <result property="daa001" column="DAA001" />
            <result property="lineName" column="LINE_NAME" />
            <result property="lineNo" column="LINE_NO" />
            <result property="daa008" column="DAA008" />
            <result property="yjkg" column="YJKG" />
            <result property="sjkg" column="SJKG" />
            <result property="sq" column="SQ" />
            <result property="rk" column="RK" />
            <result property="sqwwg" column="SQWWG" />
            <result property="rkwwg" column="RKWWG" />
            <result property="sqwrk" column="SQWRK" />
    </resultMap>
    <sql id="Base_Column_List">
        ITEM_NAME,ITEM_NO,DEPARTMENTNAME,DEPARTMENTCODE,DAA001,LINE_NAME,
        LINE_NO,DAA008,YJKG,SJKG,SQ,
        RK,SQWWG,RKWWG,SQWRK
    </sql>
</mapper>
src/test/java/com/gs/xky/XkyApplicationTests.java
@@ -1,7 +1,14 @@
package com.gs.xky;
import com.gs.xky.service.VwCjScSjTsBbService;
import com.gs.xky.service.WorkWXService;
import com.alibaba.fastjson.JSONObject;
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.dto.BarcodeDeliveryNo;
import com.gs.xky.dto.XkyDetail;
import com.gs.xky.dto.XkyEntity;
import com.gs.xky.service.*;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@@ -13,126 +20,168 @@
class XkyApplicationTests {
    public static final String URL = "http://192.168.1.64/eHR/eHRExternalService/Service.ashx";
    @Autowired
    private VwCjScSjTsBbService vwCjScSjTsBbService;
    private XkyService xkyService;
    @Autowired
    private WorkWXService workWXService;
    private ApiService apiService;
    /**
     * æµ‹è¯•导出生产数据并发送钉钉消息
     * åŠŸèƒ½ï¼šæŸ¥è¯¢VW_CJ_SC_SJ_TS_BB表数据 -> å¯¼å‡ºExcel -> å‘送钉钉文件消息
     */
    @Autowired
    private MesStaffService staffService;
    @Autowired
    private DeliveryNoticeService deliveryNoticeService;
    @Autowired
    private TblBarcodeInformationService barcodeInformationService;
    @Autowired
    private MesInvItemArnService invItemArnService;
    @Autowired
    private PurchaseService service;
    @Autowired
    private DingtalkInfoService dingtalkInfoService;
    @Test
    void testExportAndSendProductionData() throws Exception {
        System.out.println("=== å¼€å§‹æµ‹è¯•导出生产数据并发送钉钉 ===");
    void contextLoads() throws IOException {
//        try {
//            boolean result = vwCjScSjTsBbService.exportAndSendToDingtalk();
//        List<MesInvItemArn> itemArnMinus = invItemArnService.getItemArnMinus();
//
//            if (result) {
//                System.out.println("✓ ç”Ÿäº§æ•°æ®å¯¼å‡ºå¹¶å‘送成功");
//                System.out.println("  - æ•°æ®å·²ä»Ž VW_CJ_SC_SJ_TS_BB è¡¨æŸ¥è¯¢");
//                System.out.println("  - Excel æ–‡ä»¶å·²ç”Ÿæˆå¹¶ä¿å­˜åˆ° D:\\BIFile\\");
//                System.out.println("  - é’‰é’‰æ–‡ä»¶æ¶ˆæ¯å·²å‘送");
//            } else {
//                System.out.println("✗ ç”Ÿäº§æ•°æ®å¯¼å‡ºæˆ–发送失败");
//            }
//        } catch (Exception e) {
//            System.out.println("✗ å¯¼å‡ºå¹¶å‘送时发生异常: " + e.getMessage());
//            e.printStackTrace();
//        }
//        deliveryNoticeService.processMesInvItemArnStatusAsync(itemArnMinus);
        System.out.println("=== æµ‹è¯•结束 ===");
    }
    @Test
    void testGetCheckinDataByQwStaff() {
        System.out.println("=== å¼€å§‹æµ‹è¯•通过QW_STAFF表获取打卡数据 ===");
        try {
            long currentTime = System.currentTimeMillis() / 1000;
            long oneDaySeconds = 86400;
            long endTime = (currentTime / oneDaySeconds) * oneDaySeconds - 1;
            long startTime = endTime - oneDaySeconds + 1;
            System.out.println("  - å¼€å§‹æ—¶é—´: " + new java.util.Date(startTime * 1000));
            System.out.println("  - ç»“束时间: " + new java.util.Date(endTime * 1000));
            List<WorkWXService.CheckinData> checkinDataList = workWXService.getCheckinDataByQwStaff(startTime, endTime);
            if (checkinDataList != null && !checkinDataList.isEmpty()) {
                System.out.println("✓ æˆåŠŸèŽ·å–æ‰“å¡æ•°æ®");
                System.out.println("  - æ‰“卡记录总数: " + checkinDataList.size());
                System.out.println("  - å‰5条数据:");
                checkinDataList.stream().limit(5).forEach(data -> {
                    System.out.println("    * userid: " + data.getUserid() +
                            ", æ‰“卡时间: " + new java.util.Date(data.getCheckinTime() * 1000) +
                            ", æ‰“卡类型: " + data.getCheckinType() +
                            ", å¼‚常类型: " + data.getExceptionType() +
                            ", åœ°ç‚¹: " + data.getLocationDetail());
                });
            } else {
                System.out.println("✗ èŽ·å–çš„æ‰“å¡æ•°æ®ä¸ºç©ºï¼ˆå¯èƒ½QW_STAFF表无数据或时间范围内无打卡记录)");
            }
        } catch (IOException e) {
            System.out.println("✗ èŽ·å–æ‰“å¡æ•°æ®å¤±è´¥: " + e.getMessage());
            e.printStackTrace();
        }
        System.out.println("=== æµ‹è¯•结束 ===");
    public void getDeviceRealTimeData() throws IOException {
//        xkyService.GetSaveDetail();
    }
    @Test
    void testGetWorkWXUserList() {
        System.out.println("=== å¼€å§‹æµ‹è¯•获取企业微信用户列表 ===");
    void cs() throws IOException {
        try {
            List<WorkWXService.WorkWXUser> userList = workWXService.getUserList();
        String str = "22251123LM3X";
            if (userList != null && !userList.isEmpty()) {
                System.out.println("✓ æˆåŠŸèŽ·å–ä¼ä¸šå¾®ä¿¡ç”¨æˆ·åˆ—è¡¨");
                System.out.println("  - ç”¨æˆ·æ€»æ•°: " + userList.size());
                System.out.println("  - å‰10条数据:");
                userList.stream().limit(10).forEach(user -> {
                    System.out.println("    * userid: " + user.getUserid() +
                            ", å§“名: " + user.getName() +
                            ", éƒ¨é—¨: " + user.getDepartment());
                });
            } else {
                System.out.println("✗ èŽ·å–çš„ç”¨æˆ·åˆ—è¡¨ä¸ºç©º");
        String[] split = str.split(";");
        for (String s : split) {
            XkyCommonParam param = XkyCommonParam.GetInit();
            // åˆ›å»º BodyParam å¯¹è±¡å¹¶èµ‹å€¼
            BodyParam bodyParam = new BodyParam();
            bodyParam.setErpCode(DataAcquisitionConfiguration.TEST_ERP_CODE);
            bodyParam.setDeliveryNo(s);
            param.setBody(bodyParam);
            ApiResponse<XkyDetail> detail = apiService.sendListRequest(param, XkyDetail.class, "https://openapi.xiekeyun.com/delivery/getDetail.json");
            XkyDetail deliveryNo = detail.getData();
            System.out.println((JSONObject) JSONObject.toJSON(deliveryNo));
            if (deliveryNo == null) {
                System.out.println("为空的送货单号" + s);
                return;
            }
        } catch (IOException e) {
            System.out.println("✗ èŽ·å–ç”¨æˆ·åˆ—è¡¨å¤±è´¥: " + e.getMessage());
            e.printStackTrace();
            System.out.println("送货单状态" + deliveryNo.getStatus());
            if ("6".equals(deliveryNo.getStatus()) || "8".equals(deliveryNo.getStatus()) || "0".equals(deliveryNo.getLogisticsStatus())) {
                XkyEntity xkyEntity = new XkyEntity();
                xkyEntity.setDeliveryNo(deliveryNo.getDeliveryNo());
                xkyService.remove1(xkyEntity);
            } else if ("1".equals(deliveryNo.getStatus()) && ("2".equals(deliveryNo.getLogisticsStatus()) || "1".equals(deliveryNo.getLogisticsStatus()))) {
                XkyDetail detail1 = deliveryNo;
                deliveryNoticeService.saveDeliveryNotice(detail1);
                List<BarcodeDeliveryNo> barcodeDeliveryNos = GetBarcodeInformation(deliveryNo.getDeliveryNo());
                barcodeInformationService.SaveBarcodeInformation(barcodeDeliveryNos, deliveryNo.getDeliveryNo());
                if ("2".equals(deliveryNo.getLogisticsStatus())) {
                    deliveryNoticeService.callPdaReceiptBtn("送货单签收[BTNOK[PL017[" + deliveryNo.getDeliveryNo(), "");
                }
            }
        }
    }
        System.out.println("=== æµ‹è¯•结束 ===");
    private List<BarcodeDeliveryNo> GetBarcodeInformation(String deliveryNo) throws IOException {
        XkyCommonParam param = XkyCommonParam.GetInit();
        // åˆ›å»º BodyParam å¯¹è±¡å¹¶èµ‹å€¼
        BodyParam bodyParam = new BodyParam();
        bodyParam.setErpCode(DataAcquisitionConfiguration.TEST_ERP_CODE);
        bodyParam.setDeliveryNo(deliveryNo);
        param.setBody(bodyParam);
        ApiResponse<BarcodeDeliveryNo> noList = apiService.sendListRequest(param, BarcodeDeliveryNo.class, "https://openapi.xiekeyun.com/barcode/byDeliveryNo.json");
        return noList.getDataList();
    }
    @Test
    void testGetUserDetail() {
        System.out.println("=== å¼€å§‹æµ‹è¯•获取用户详情 ===");
    void cs1() throws IOException {
//        DingTalkParam dingTalkParam = new DingTalkParam(0);
//
//        DingTalkResponse<EmployeeInfo> employeeInfoDingTalkResponse = apiService.sendListRequest(dingTalkParam, EmployeeInfo.class, "http://192.168.1.64/eHR/eHRExternalService/Service.ashx");
//
//        //造梦者(浙江)科技有限公司 cUnitName
//        //http://192.168.1.64/eHR
//        List<EmployeeInfo> collect = employeeInfoDingTalkResponse.getData().stream().filter(s -> "造梦者(浙江)科技有限公司".equals(s.getCUnitName())).collect(Collectors.toList());
//        //System.out.println(collect.size());
//
//        collect.stream().filter(s->s.getEmployeeId().equals("2025130028")).forEach(System.out::println);
//
//        List<List<EmployeeInfo>> partition = ListUtil.partition(collect, 500);
        try {
            String userid = "ShenJuanYue";
            WorkWXService.WorkWXUserDetail userDetail = workWXService.getUserDetail(userid);
//        partition.forEach(list -> {
//            staffService.SaveStaff(list);
//        });
//        XkyCommonParam param = XkyCommonParam.GetInit();
//        String jsonString = JSON.toJSONString(param);
//        System.out.println(jsonString);
    }
            if (userDetail != null && userDetail.getErrcode() == 0) {
                System.out.println("✓ æˆåŠŸèŽ·å–ç”¨æˆ·è¯¦æƒ…");
                System.out.println("  - userid: " + userDetail.getUserid());
                System.out.println("  - å§“名: " + userDetail.getName());
                System.out.println("  - æ‰‹æœºå·: " + userDetail.getMobile());
                System.out.println("  - èŒä½: " + userDetail.getPosition());
            } else {
                System.out.println("✗ èŽ·å–ç”¨æˆ·è¯¦æƒ…å¤±è´¥");
            }
        } catch (IOException e) {
            System.out.println("✗ èŽ·å–ç”¨æˆ·è¯¦æƒ…å¤±è´¥: " + e.getMessage());
            e.printStackTrace();
        }
    @Test
    void cs2() throws IOException {
//        DingTalkParam dingTalkParam = new DingTalkParam(1);
//
//        DingTalkResponse<EmployeeInfo> employeeInfoDingTalkResponse = apiService.sendListRequest(dingTalkParam, EmployeeInfo.class, "http://192.168.1.64/eHR/eHRExternalService/Service.ashx");
//
//        //造梦者(浙江)科技有限公司 cUnitName
//        //http://192.168.1.64/eHR
//        List<EmployeeInfo> collect = employeeInfoDingTalkResponse.getData().stream().filter(s -> "造梦者(浙江)科技有限公司".equals(s.getCUnitName())).collect(Collectors.toList());
//        System.out.println(collect.size());
//
//        List<List<EmployeeInfo>> partition = ListUtil.partition(collect, 100);
//
//        partition.forEach(list -> {
//            staffService.UpdateStaff(list);
//
//
//        });
        System.out.println("=== æµ‹è¯•结束 ===");
    }
    @Test
    void cs113() throws Exception {
//        DingTalkParam dingTalkParam = new DingTalkParam(1);
//        DingTalkResponse<EmployeeInfo> employeeInfoDingTalkResponse =
//                apiService.sendListRequest(dingTalkParam, EmployeeInfo.class,
//                        "http://192.168.1.64/eHR/eHRExternalService/Service.ashx");
//
//        List<EmployeeInfo> collect = employeeInfoDingTalkResponse.getData().stream()
//                .filter(s -> "造梦者(浙江)科技有限公司".equals(s.getCUnitName()))
//                .collect(Collectors.toList());
    }
    @Test
    void cs3() throws Exception {
//        dingtalkInfoService.sendMessage("CGJY20250412166");
//        XkyEntity xkyEntity = new XkyEntity();
//        xkyEntity.setDeliveryNo("222505057541");
//        xkyService.remove1(xkyEntity);
    }
}