From 34981c30a78e8bbd7791131059a9210f9928b62c Mon Sep 17 00:00:00 2001
From: 刘光辉 <347230014@qq.com>
Date: 星期四, 17 九月 2026 09:24:09 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/master' into master

---
 jnpf-lims/jnpf-lims-biz/src/main/java/jnpf/limsService/impl/LimsSxtQuyangJihuaRenwuServiceImpl.java |  819 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 819 insertions(+), 0 deletions(-)

diff --git a/jnpf-lims/jnpf-lims-biz/src/main/java/jnpf/limsService/impl/LimsSxtQuyangJihuaRenwuServiceImpl.java b/jnpf-lims/jnpf-lims-biz/src/main/java/jnpf/limsService/impl/LimsSxtQuyangJihuaRenwuServiceImpl.java
new file mode 100644
index 0000000..e8469bf
--- /dev/null
+++ b/jnpf-lims/jnpf-lims-biz/src/main/java/jnpf/limsService/impl/LimsSxtQuyangJihuaRenwuServiceImpl.java
@@ -0,0 +1,819 @@
+package jnpf.limsService.impl;
+
+import jnpf.audit.sdk.annotation.AuditLog;
+
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import jnpf.base.UserInfo;
+import jnpf.exception.DataException;
+import jnpf.limsEntity.JianyanXiangmuGuanliEntity;
+import jnpf.limsEntity.LimsQingyandanEntity;
+import jnpf.limsEntity.LimsSxtQingyanXiangmuEntity;
+import jnpf.limsEntity.LimsSxtQingyanXiangmuZixiangEntity;
+import jnpf.limsEntity.LimsSxtQuyangJihuaEntity;
+import jnpf.limsEntity.LimsSxtQuyangJihuaRenwuJianyanXiangKuaizhaoEntity;
+import jnpf.limsEntity.LimsSxtQuyangJihuaRenwuPeizhiKuaizhaoEntity;
+import jnpf.limsEntity.LimsSxtQuyangJihuaRenwuRenyuanKuaizhaoEntity;
+import jnpf.limsEntity.LimsSxtQuyangJihuaRenwuShijianEntity;
+import jnpf.limsEntity.LimsSxtQuyangJihuaRenwuEntity;
+import jnpf.limsEntity.LimsSxtQuyangJihuaZixiangEntity;
+import jnpf.limsEntity.LimsSxtQuyangdianEntity;
+import jnpf.limsEntity.LimsWaterSamplingMessageEvent;
+import jnpf.limsEntity.RenwuTihuanJieguo;
+import jnpf.limsEntity.RenwuTihuanPeizhiMingling;
+import jnpf.limsEntity.YangpinGuanliEntity;
+import jnpf.limsEntity.ZhiliangBiaozhunGuanliEntity;
+import jnpf.limsEntity.ZhiliangBiaozhunGuanliZixiangEntity;
+import jnpf.limsMapper.JianyanXiangmuGuanliMapper;
+import jnpf.limsMapper.LimsSxtQingyanXiangmuMapper;
+import jnpf.limsMapper.LimsSxtQingyanXiangmuZixiangMapper;
+import jnpf.limsMapper.LimsSxtQuyangJihuaMapper;
+import jnpf.limsMapper.LimsSxtQuyangJihuaRenwuJianyanXiangKuaizhaoMapper;
+import jnpf.limsMapper.LimsSxtQuyangJihuaRenwuMapper;
+import jnpf.limsMapper.LimsSxtQuyangJihuaRenwuPeizhiKuaizhaoMapper;
+import jnpf.limsMapper.LimsSxtQuyangJihuaRenwuRenyuanKuaizhaoMapper;
+import jnpf.limsMapper.LimsSxtQuyangJihuaRenwuShijianMapper;
+import jnpf.limsMapper.LimsSxtQuyangJihuaZixiangMapper;
+import jnpf.limsMapper.LimsSxtQuyangdianMapper;
+import jnpf.limsMapper.YangpinGuanliMapper;
+import jnpf.limsMapper.ZhiliangBiaozhunGuanliMapper;
+import jnpf.limsModel.LimsSxtQuyangdianKuaizhaoModel;
+import jnpf.limsService.LimsQingyandanService;
+import jnpf.limsService.LimsSxtQuyangJihuaRenwuService;
+import jnpf.limsService.ZhiliangBiaozhunGuanliZixiangService;
+import jnpf.limsService.support.LimsSxtQuyangJihuaRenwuPlanner;
+import jnpf.limsService.support.LimsSxtPlanStatusResolver;
+import jnpf.limsService.support.LimsSxtQuyangJihuaRenwuStatus;
+import jnpf.util.RandomUtil;
+import jnpf.util.UserProvider;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationEventPublisher;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Propagation;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.StringUtils;
+
+import java.nio.charset.StandardCharsets;
+import java.security.MessageDigest;
+import java.time.LocalDate;
+import java.time.ZoneId;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.UUID;
+
+/**
+ * 鏂� Renwu 浠呬娇鐢ㄥ喕缁撳揩鐓х敓鎴愯楠屽崟锛涗笉璇诲啓鏃� Task 琛ㄣ��
+ */
+@Slf4j
+@Service
+public class LimsSxtQuyangJihuaRenwuServiceImpl implements LimsSxtQuyangJihuaRenwuService {
+
+    private static final Integer FLOW_STATE_APPROVED = 2;
+    private static final String SXT_BIZ_TYPE = "SXT";
+
+    @Autowired
+    private LimsSxtQuyangJihuaMapper jihuaMapper;
+    @Autowired
+    private LimsSxtQuyangJihuaZixiangMapper jihuaZixiangMapper;
+    @Autowired
+    private LimsSxtQuyangJihuaRenwuMapper renwuMapper;
+    @Autowired
+    private LimsSxtQuyangJihuaRenwuPeizhiKuaizhaoMapper peizhiKuaizhaoMapper;
+    @Autowired
+    private LimsSxtQuyangJihuaRenwuJianyanXiangKuaizhaoMapper jianyanKuaizhaoMapper;
+    @Autowired
+    private LimsSxtQuyangJihuaRenwuRenyuanKuaizhaoMapper renyuanKuaizhaoMapper;
+    @Autowired
+    private LimsSxtQuyangJihuaRenwuShijianMapper shijianMapper;
+    @Autowired
+    private LimsSxtQuyangdianMapper quyangdianMapper;
+    @Autowired
+    private YangpinGuanliMapper yangpinGuanliMapper;
+    @Autowired
+    private ZhiliangBiaozhunGuanliMapper zhiliangBiaozhunMapper;
+    @Autowired
+    private ZhiliangBiaozhunGuanliZixiangService zhiliangBiaozhunZixiangService;
+    @Autowired
+    private LimsSxtQingyanXiangmuMapper qingyanPeizhiMapper;
+    @Autowired
+    private LimsSxtQingyanXiangmuZixiangMapper qingyanPeizhiZixiangMapper;
+    @Autowired
+    private JianyanXiangmuGuanliMapper jianyanXiangmuMapper;
+    @Autowired
+    private LimsQingyandanService qingyandanService;
+    @Autowired
+    private ApplicationEventPublisher eventPublisher;
+
+    @Scheduled(cron = "${lims.sxt.jihua.cron:0 0 1 * * ?}")
+    public void dingShiShengchengQingyandan() {
+        try {
+            int shuliang = shengchengDaishengchengQingyandan(LocalDate.now());
+            if (shuliang > 0) {
+                log.info("姘寸郴缁烺enwu鍒版湡鐢熸垚璇烽獙鍗曞畬鎴愶紝鏁伴噺={}", shuliang);
+            }
+        } catch (Exception e) {
+            log.error("姘寸郴缁烺enwu鍒版湡鐢熸垚璇烽獙鍗曞け璐�", e);
+        }
+    }
+
+    @Scheduled(cron = "${lims.sxt.jihua.snapshot-compensation-cron:0 5/15 * * * ?}")
+    public void dingShiBuchangRenwu() {
+        try {
+            buchangYishenpiJihuaRenwu();
+        } catch (Exception e) {
+            log.error("姘寸郴缁烺enwu蹇収琛ュ伩澶辫触", e);
+        }
+    }
+
+    @Override
+    @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
+    public int wuhuaYishenpiJihua(String jihuaId, String tenantId) {
+        LimsSxtQuyangJihuaEntity jihua = chaxunYishenpiKeZhixingJihua(jihuaId, tenantId);
+        return wuhuaYishenpiJihuaCong(jihuaId, toLocalDate(jihua.getKaishiShijian(), "璁″垝寮�濮嬫椂闂翠笉鑳戒负绌�"), tenantId);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public int wuhuaYishenpiJihuaCong(String jihuaId, LocalDate qishiRiqi, String tenantId) {
+        if (qishiRiqi == null) {
+            throw new DataException("浠诲姟鐢熸垚璧峰鏃ユ湡涓嶈兘涓虹┖");
+        }
+        tenantId = normalizeTenantId(tenantId);
+        LimsSxtQuyangJihuaEntity jihua = chaxunYishenpiKeZhixingJihua(jihuaId, tenantId);
+        LocalDate kaishi = toLocalDate(jihua.getKaishiShijian(), "璁″垝寮�濮嬫椂闂翠笉鑳戒负绌�");
+        LocalDate jieshu = toLocalDate(jihua.getJieshuShijian(), "璁″垝缁撴潫鏃堕棿涓嶈兘涓虹┖");
+        LocalDate youxiaoQishi = qishiRiqi.isBefore(kaishi) ? kaishi : qishiRiqi;
+        List<LimsSxtQuyangJihuaZixiangEntity> zixiangList = chaxunYouxiaoJihuaZixiang(jihua.getId(), tenantId);
+        int chenggongShuliang = 0;
+        for (LocalDate jihuaRiqi : executionDates(kaishi, jieshu, jihua.getJihuaZhouqiLeixing(), parseInterval(jihua.getJihuaZhouqiJiange()))) {
+            if (jihuaRiqi.isBefore(youxiaoQishi)) {
+                continue;
+            }
+            for (LimsSxtQuyangJihuaZixiangEntity zixiang : zixiangList) {
+                chenggongShuliang += wuhuaDanTiaoRenwu(jihua, zixiang, jihuaRiqi, tenantId);
+            }
+        }
+        return chenggongShuliang;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public int shengchengDaishengchengQingyandan(LocalDate jihuaRiqi) {
+        requireJihuaRiqi(jihuaRiqi);
+        return shengchengYisuodingRenwu(renwuMapper.lockPendingRenwu(jihuaRiqi));
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public int shengchengDaishengchengQingyandanByJihua(String jihuaId, String tenantId, LocalDate jihuaRiqi) {
+        requireText(jihuaId, "鍙栨牱璁″垝ID涓嶈兘涓虹┖");
+        requireJihuaRiqi(jihuaRiqi);
+        return shengchengYisuodingRenwu(renwuMapper.lockPendingRenwuForJihua(
+                jihuaId, normalizeTenantId(tenantId), jihuaRiqi));
+    }
+
+    @Override
+    @AuditLog(action = "PLAN_COMPENSATE", label = "琛ュ伩姘寸郴缁熷凡瀹℃壒璁″垝浠诲姟", bizType = "SXT",
+            bizCodeExpr = "#result > 0 ? 'SXT_PLAN_COMPENSATE' : ''", targetTable = "lims_sxt_quyang_jihua_renwu")
+    public int buchangYishenpiJihuaRenwu() {
+        QueryWrapper<LimsSxtQuyangJihuaEntity> wrapper = new QueryWrapper<>();
+        wrapper.eq("f_flow_state", FLOW_STATE_APPROVED)
+                .eq("plan_status", LimsSxtPlanStatusResolver.AVAILABLE)
+                .and(item -> item.eq("f_delete_mark", 0).or().isNull("f_delete_mark"));
+        int chenggongShuliang = 0;
+        for (LimsSxtQuyangJihuaEntity jihua : jihuaMapper.selectList(wrapper)) {
+            try {
+                chenggongShuliang += wuhuaYishenpiJihua(jihua.getId(), jihua.getFTenantId());
+                shengchengDaishengchengQingyandanByJihua(jihua.getId(), jihua.getFTenantId(), LocalDate.now());
+            } catch (Exception e) {
+                log.error("姘寸郴缁烺enwu琛ュ伩澶辫触锛宩ihuaId={}, tenantId={}", jihua.getId(), jihua.getFTenantId(), e);
+            }
+        }
+        return chenggongShuliang;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public int quxiaoWeishengchengRenwuByJihua(String jihuaId, String tenantId, String yuanyinDaima) {
+        requireText(jihuaId, "鍙栨牱璁″垝ID涓嶈兘涓虹┖");
+        List<LimsSxtQuyangJihuaRenwuEntity> renwuList = renwuMapper.lockWeishengchengRenwuByJihua(
+                jihuaId, normalizeTenantId(tenantId));
+        int shuliang = 0;
+        for (LimsSxtQuyangJihuaRenwuEntity renwu : renwuList) {
+            if (quxiaoRenwu(renwu, yuanyinDaima)) {
+                shuliang++;
+            }
+        }
+        return shuliang;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void quxiaoWeishengchengWeilaiRenwu(String renwuId, String tenantId, String yuanyinDaima) {
+        requireText(renwuId, "浠诲姟ID涓嶈兘涓虹┖");
+        LimsSxtQuyangJihuaRenwuEntity renwu = renwuMapper.lockRenwuForQuxiao(renwuId, normalizeTenantId(tenantId));
+        if (renwu == null) {
+            throw new DataException("璁″垝浠诲姟涓嶅瓨鍦�");
+        }
+        LocalDate jihuaRiqi = toLocalDate(renwu.getJihuaRiqi(), "浠诲姟璁″垝鏃ユ湡涓嶈兘涓虹┖");
+        if (!jihuaRiqi.isAfter(LocalDate.now())) {
+            throw new DataException("浠呮湭鏉ユ湭鐢熸垚璇烽獙鍗曠殑浠诲姟鍏佽鍙栨秷");
+        }
+        if (!quxiaoRenwu(renwu, yuanyinDaima)) {
+            throw new DataException("浠诲姟鐘舵�佸凡鍙樺寲锛屽彇娑堝け璐�");
+        }
+    }
+
+    @Override
+    public RenwuTihuanJieguo tihuanWeishengchengRenwuPeizhi(String renwuId, RenwuTihuanPeizhiMingling mingling) {
+        throw new DataException("鍙楁帶閰嶇疆鏇夸唬鍔熻兘鏈惎鐢�");
+    }
+
+    private int wuhuaDanTiaoRenwu(LimsSxtQuyangJihuaEntity jihua,
+                                   LimsSxtQuyangJihuaZixiangEntity zixiang,
+                                   LocalDate jihuaRiqi,
+                                   String tenantId) {
+        LimsSxtQuyangdianKuaizhaoModel quyangdian = chaxunWeiyiYouxiaoQuyangdian(jihua, zixiang, tenantId);
+        YangpinGuanliEntity yangpin = chaxunYouxiaoYangpin(jihua.getYangpinLeixing(), tenantId);
+        ZhiliangBiaozhunGuanliEntity biaozhun = chaxunYouxiaoBiaozhun(zixiang.getZhiliangBiaozhun(), tenantId, yangpin.getId());
+        LimsSxtQingyanXiangmuEntity qingyanPeizhi = chaxunYouxiaoQingyanPeizhi(
+                zixiang.getJianyanXiangmu(), tenantId, yangpin.getId(), biaozhun.getId());
+        List<LimsSxtQingyanXiangmuZixiangEntity> peizhiZixiang = chaxunYouxiaoPeizhiZixiang(qingyanPeizhi.getId(), tenantId);
+        Map<String, JianyanXiangmuGuanliEntity> jianyanXiangmuMap = chaxunYouxiaoJianyanXiangmuMap(peizhiZixiang, tenantId);
+        List<LimsSxtQuyangJihuaRenwuJianyanXiangKuaizhaoEntity> jianyanKuaizhao = buildJianyanKuaizhao(
+                tenantId, qingyanPeizhi, peizhiZixiang, biaozhun, jianyanXiangmuMap);
+        if (jianyanKuaizhao.isEmpty()) {
+            throw new DataException("璇烽獙閰嶇疆涓庤川閲忔爣鍑嗘病鏈夊尮閰嶇殑妫�楠岄」鐩�");
+        }
+
+        Date now = new Date();
+        LimsSxtQuyangJihuaRenwuEntity renwu = buildRenwu(jihua, zixiang, jihuaRiqi, quyangdian, now);
+        renwu.setKuaizhaoHaxi(haxi(JSON.toJSONString(jihua) + JSON.toJSONString(zixiang)
+                + JSON.toJSONString(quyangdian) + JSON.toJSONString(yangpin)
+                + JSON.toJSONString(biaozhun) + JSON.toJSONString(jianyanXiangmuMap.values())
+                + JSON.toJSONString(jianyanKuaizhao)));
+        if (renwuMapper.insertIgnoreUnique(renwu) != 1) {
+            return 0;
+        }
+
+        baocunPeizhiKuaizhao(renwu, "quyangdian", quyangdian.getId(), null, quyangdian, now);
+        baocunPeizhiKuaizhao(renwu, "yangpin", yangpin.getId(), null, yangpin, now);
+        baocunPeizhiKuaizhao(renwu, "zhiliang_biaozhun", biaozhun.getId(), biaozhun.getBiaozhunBanben(), biaozhun, now);
+        baocunPeizhiKuaizhao(renwu, "qingyan_peizhi", qingyanPeizhi.getId(), null, qingyanPeizhi, now);
+        for (LimsSxtQingyanXiangmuZixiangEntity item : peizhiZixiang) {
+            baocunPeizhiKuaizhao(renwu, "qingyan_peizhi_zixiang", item.getId(), null, item, now);
+        }
+        for (JianyanXiangmuGuanliEntity xiangmu : jianyanXiangmuMap.values()) {
+            baocunPeizhiKuaizhao(renwu, "jianyan_xiangmu", xiangmu.getId(), null, xiangmu, now);
+        }
+        baocunRenyuanKuaizhao(renwu, "qingyan_shenqingren", jihua.getZhidingren(), null, now);
+        if (hasText(quyangdian.getFuzeGangwei())) {
+            baocunRenyuanKuaizhao(renwu, "quyang_fuze_gangwei", null, quyangdian.getFuzeGangwei(), now);
+        }
+        for (LimsSxtQuyangJihuaRenwuJianyanXiangKuaizhaoEntity item : jianyanKuaizhao) {
+            item.setRenwuId(renwu.getId());
+            item.setFCreatorUserId(renwu.getFCreatorUserId());
+            jianyanKuaizhaoMapper.insert(item);
+        }
+        baocunShijian(renwu, "renwu_chuangjian", null, null, null, null);
+        return 1;
+    }
+
+    private int shengchengYisuodingRenwu(List<LimsSxtQuyangJihuaRenwuEntity> renwuList) {
+        int chenggongShuliang = 0;
+        for (LimsSxtQuyangJihuaRenwuEntity renwu : renwuList) {
+            if (renwuMapper.markGenerating(renwu.getId()) != 1) {
+                continue;
+            }
+            try {
+                boolean chayi = jiaoyanDangqianPeizhi(renwu);
+                List<LimsSxtQuyangJihuaRenwuJianyanXiangKuaizhaoEntity> jianyanKuaizhao = chaxunJianyanKuaizhao(renwu.getId(), renwu.getFTenantId());
+                LimsQingyandanEntity qingyandan = qingyandanService.sxtRenwuKuaizhaoAutoSubmit(
+                        buildQingyandanFromRenwuKuaizhao(renwu), jianyanKuaizhao);
+                if (renwuMapper.markGenerated(renwu.getId(), qingyandan.getId(), qingyandan.getJianyanLiushuihao(),
+                        qingyandan.getBizStatus()) != 1) {
+                    throw new DataException("浠诲姟鐘舵�佸凡鍙樺寲锛屼笉鑳芥爣璁板凡鐢熸垚锛�" + renwu.getId());
+                }
+                baocunShijian(renwu, "qingyandan_chuangjian", null, null, qingyandan.getId(), null);
+                eventPublisher.publishEvent(new LimsWaterSamplingMessageEvent(
+                        renwu.getFTenantId(), renwu.getId(), qingyandan.getId(),
+                        qingyandan.getJianyanLiushuihao(), renwu.getFuzeGangwei(),
+                        renwu.getJihuaMingcheng(), renwu.getYangpinMingcheng(),
+                        qingyandan.getQuyangDidian(), renwu.getJihuaRiqi()));
+                if (chayi) {
+                    baocunShijian(renwu, "peizhi_chayi_faxian", "config_changed", "褰撳墠閰嶇疆涓庡喕缁撳揩鐓т笉鍚�", null, null);
+                }
+                chenggongShuliang++;
+            } catch (PeizhiWuxiaoException e) {
+                if (renwuMapper.markBlockedPeizhiWuxiao(renwu.getId(), e.yuanyinDaima, e.getMessage()) == 1) {
+                    baocunShijian(renwu, "peizhi_wuxiao_zuduan", e.yuanyinDaima, e.getMessage(), null, null);
+                }
+            } catch (Exception e) {
+                renwuMapper.resetPending(renwu.getId());
+                throw e;
+            }
+        }
+        return chenggongShuliang;
+    }
+
+    private boolean jiaoyanDangqianPeizhi(LimsSxtQuyangJihuaRenwuEntity renwu) {
+        boolean chayi = false;
+        LimsSxtQuyangdianEntity quyangdian = quyangdianMapper.selectById(renwu.getQuyangdianId());
+        if (quyangdian == null || isDeleted(quyangdian.getDeleteMark()) || !"enabled".equals(quyangdian.getBizEnabled())) {
+            throw new PeizhiWuxiaoException("config_disabled", "鍙栨牱鐐瑰凡鍒犻櫎鎴栧仠鐢�");
+        }
+        YangpinGuanliEntity yangpin = yangpinGuanliMapper.selectById(renwu.getYangpinLeixing());
+        if (!isYouxiaoYangpin(yangpin, renwu.getFTenantId())) {
+            throw new PeizhiWuxiaoException("config_disabled", "鏍峰搧宸插垹闄ゆ垨鍋滅敤");
+        }
+        ZhiliangBiaozhunGuanliEntity biaozhun = zhiliangBiaozhunMapper.selectById(renwu.getZhiliangBiaozhun());
+        if (!isYouxiaoBiaozhun(biaozhun, renwu.getFTenantId(), renwu.getYangpinLeixing())) {
+            throw new PeizhiWuxiaoException("config_disabled", "璐ㄩ噺鏍囧噯宸插垹闄ゃ�佸仠鐢ㄦ垨涓庢牱鍝佷笉鍖归厤");
+        }
+        LimsSxtQingyanXiangmuEntity peizhi = qingyanPeizhiMapper.selectById(renwu.getJianyanXiangmu());
+        if (!isYouxiaoPeizhi(peizhi, renwu.getFTenantId(), renwu.getYangpinLeixing(), renwu.getZhiliangBiaozhun())) {
+            throw new PeizhiWuxiaoException("config_soft_deleted", "璇烽獙閰嶇疆宸插垹闄ゆ垨涓庝换鍔℃牱鍝併�佽川閲忔爣鍑嗕笉鍖归厤");
+        }
+        for (LimsSxtQuyangJihuaRenwuJianyanXiangKuaizhaoEntity item : chaxunJianyanKuaizhao(renwu.getId(), renwu.getFTenantId())) {
+            LimsSxtQingyanXiangmuZixiangEntity peizhiZixiang = qingyanPeizhiZixiangMapper.selectById(item.getLaiyuanQingyanPeizhiZixiangId());
+            ZhiliangBiaozhunGuanliZixiangEntity biaozhunZixiang = zhiliangBiaozhunZixiangService.getById(item.getLaiyuanZhiliangBiaozhunZixiangId());
+            JianyanXiangmuGuanliEntity jianyanXiangmu = jianyanXiangmuMapper.selectById(item.getJianyanXiangmuId());
+            if (!isYouxiaoPeizhiZixiang(peizhiZixiang, renwu.getFTenantId()) || !isYouxiaoBiaozhunZixiang(biaozhunZixiang, renwu.getFTenantId())
+                    || !isYouxiaoJianyanXiangmu(jianyanXiangmu, renwu.getFTenantId())) {
+                throw new PeizhiWuxiaoException("config_soft_deleted", "妫�楠岄」鐩�佽楠岄厤缃瓙椤规垨璐ㄩ噺鏍囧噯瀛愰」宸插垹闄�");
+            }
+        }
+        for (LimsSxtQuyangJihuaRenwuPeizhiKuaizhaoEntity kuaizhao : chaxunPeizhiKuaizhao(renwu.getId(), renwu.getFTenantId())) {
+            Object dangqian = dangqianPeizhi(
+                    kuaizhao.getPeizhiLeixing(), kuaizhao.getLaiyuanPeizhiId(), renwu.getFTenantId());
+            if (dangqian != null && !peizhiKuaizhaoYizhi(kuaizhao, dangqian)) {
+                chayi = true;
+            }
+        }
+        LambdaUpdateWrapper<LimsSxtQuyangJihuaRenwuEntity> update = new LambdaUpdateWrapper<>();
+        update.eq(LimsSxtQuyangJihuaRenwuEntity::getId, renwu.getId())
+                .set(LimsSxtQuyangJihuaRenwuEntity::getPeizhiJiaoyanShijian, new Date())
+                .set(LimsSxtQuyangJihuaRenwuEntity::getPeizhiJiaoyanZhuangtai, chayi ? "drift_detected" : "valid")
+                .set(LimsSxtQuyangJihuaRenwuEntity::getPeizhiChayiBiaozhi, chayi ? 1 : 0);
+        renwuMapper.update(null, update);
+        return chayi;
+    }
+
+    //閰嶇疆蹇収涓�鑷�
+    private boolean peizhiKuaizhaoYizhi(LimsSxtQuyangJihuaRenwuPeizhiKuaizhaoEntity kuaizhao,
+                                         Object dangqian) {
+        if ("quyangdian".equals(kuaizhao.getPeizhiLeixing())) {
+            LimsSxtQuyangdianKuaizhaoModel dongjie = JSON.parseObject(
+                    kuaizhao.getKuaizhaoShuju(), LimsSxtQuyangdianKuaizhaoModel.class);
+            return haxi(JSON.toJSONString(dongjie)).equals(haxi(JSON.toJSONString(dangqian)));
+        }
+        return haxi(JSON.toJSONString(dangqian)).equals(kuaizhao.getKuaizhaoHaxi());
+    }
+
+    //鏍规嵁绫诲瀷鏌ヨ褰撳墠閰嶇疆
+    private Object dangqianPeizhi(String leixing, String id, String tenantId) {
+        if ("quyangdian".equals(leixing)) return quyangdianMapper.selectForTaskSnapshot(tenantId, id);
+        if ("yangpin".equals(leixing)) return yangpinGuanliMapper.selectById(id);
+        if ("zhiliang_biaozhun".equals(leixing)) return zhiliangBiaozhunMapper.selectById(id);
+        if ("qingyan_peizhi".equals(leixing)) return qingyanPeizhiMapper.selectById(id);
+        if ("qingyan_peizhi_zixiang".equals(leixing)) return qingyanPeizhiZixiangMapper.selectById(id);
+        if ("jianyan_xiangmu".equals(leixing)) return jianyanXiangmuMapper.selectById(id);
+        return null;
+    }
+
+    //浠庝换鍔″揩鐓х敓鎴愯楠屽崟
+    private LimsQingyandanEntity buildQingyandanFromRenwuKuaizhao(LimsSxtQuyangJihuaRenwuEntity renwu) {
+        YangpinGuanliEntity yangpin = JSON.parseObject(chaxunPeizhiKuaizhaoShuju(renwu, "yangpin"), YangpinGuanliEntity.class);
+        ZhiliangBiaozhunGuanliEntity biaozhun = JSON.parseObject(chaxunPeizhiKuaizhaoShuju(renwu, "zhiliang_biaozhun"), ZhiliangBiaozhunGuanliEntity.class);
+        LimsQingyandanEntity qingyandan = new LimsQingyandanEntity();
+        qingyandan.setTenantId(renwu.getFTenantId());
+        qingyandan.setLaiyuanRenwuId(renwu.getId());
+        qingyandan.setRenwuKuaizhaoHaxi(renwu.getKuaizhaoHaxi());
+        qingyandan.setChanpinId(renwu.getYangpinLeixing());
+        qingyandan.setChanpinMingcheng(yangpin.getMingcheng());
+        qingyandan.setChanpinBianma(yangpin.getBianma());
+        qingyandan.setGuige(yangpin.getGuige());
+        qingyandan.setBaozhuangGuige(yangpin.getBaozhuangGuige());
+        qingyandan.setChucunTiaojian(yangpin.getCucunTiaojian());
+        qingyandan.setWeiyiShibiemaEnabled(yangpin.getWeiyiShibiemaEnabled());
+        qingyandan.setJianyanBiaozhun(renwu.getZhiliangBiaozhun());
+        qingyandan.setJianyanLiang(hasText(renwu.getQuyangliang()) ? renwu.getQuyangliang() : biaozhun.getJianceLiang());
+        qingyandan.setQuyangDanwei(hasText(renwu.getQuyangliangDanwei()) ? renwu.getQuyangliangDanwei() : biaozhun.getQuyangDanwei());
+        qingyandan.setJianceLiuyangLiang(biaozhun.getJianceLiuyangLiang());
+        qingyandan.setLiuyangLiang(biaozhun.getLiuyangLiang());
+        qingyandan.setLiuyangDanwei(biaozhun.getLiuyangKaochaDanwei());
+        qingyandan.setShifouShixiaoxingYaoqiu(biaozhun.getShifouShixiaoxingYaoqiu());
+        qingyandan.setBizType(SXT_BIZ_TYPE);
+        qingyandan.setJianceFangshi("quanjian");
+        qingyandan.setQuyangDidian(renwu.getQuyangdianBianhao() + "-" + renwu.getSuoshuChejian() + "-" + renwu.getQuyangDidian());
+        qingyandan.setQingyanRen(renwu.getZhidingren());
+        qingyandan.setQingyanRiqi(renwu.getJihuaRiqi());
+        qingyandan.setCreatorUserId(renwu.getZhidingren());
+        List<String> biaozhunZixiangIds = new ArrayList<>();
+        for (LimsSxtQuyangJihuaRenwuJianyanXiangKuaizhaoEntity item : chaxunJianyanKuaizhao(renwu.getId(), renwu.getFTenantId())) {
+            biaozhunZixiangIds.add(item.getLaiyuanZhiliangBiaozhunZixiangId());
+        }
+        qingyandan.setJianceXiangmu(JSON.toJSONString(biaozhunZixiangIds));
+        return qingyandan;
+    }
+
+    private LimsSxtQuyangJihuaRenwuEntity buildRenwu(LimsSxtQuyangJihuaEntity jihua,
+                                                       LimsSxtQuyangJihuaZixiangEntity zixiang,
+                                                       LocalDate jihuaRiqi,
+                                                       LimsSxtQuyangdianKuaizhaoModel quyangdian,
+                                                       Date now) {
+        LimsSxtQuyangJihuaRenwuEntity renwu = new LimsSxtQuyangJihuaRenwuEntity();
+        renwu.setId(RandomUtil.uuId());
+        renwu.setFTenantId(normalizeTenantId(jihua.getFTenantId()));
+        renwu.setJihuaId(jihua.getId());
+        renwu.setJihuaZixiangId(zixiang.getId());
+        renwu.setJihuaRiqi(Date.from(jihuaRiqi.atStartOfDay(ZoneId.systemDefault()).toInstant()));
+        renwu.setRenwuZhuangtai(LimsSxtQuyangJihuaRenwuStatus.PENDING);
+        renwu.setJihuaMingcheng(jihua.getJihuaMingcheng());
+        renwu.setYangpinLeixing(jihua.getYangpinLeixing());
+        renwu.setYangpinLeixingMingcheng(jihua.getYangpinLeixingMingcheng());
+        renwu.setYangpinMingcheng(jihua.getYangpinMingcheng());
+        renwu.setSuoshuChejian(quyangdian.getChejianMingchengName());
+        renwu.setSuoshuChejianId(quyangdian.getChejianMingcheng());
+        renwu.setQuyangDidian(zixiang.getQuyangDidian());
+        renwu.setQuyangdianBianhao(zixiang.getQuyangdianBianhao());
+        renwu.setFuzeGangwei(quyangdian.getFuzeGangwei());
+        renwu.setQuyangliang(zixiang.getQuyangliang());
+        renwu.setQuyangliangDanwei(zixiang.getQuyangliangDanwei());
+        renwu.setZhiliangBiaozhun(zixiang.getZhiliangBiaozhun());
+        renwu.setJianyanXiangmu(zixiang.getJianyanXiangmu());
+        renwu.setJianyanXiangmuMingcheng(zixiang.getJianyanXiangmuMingcheng());
+        renwu.setZhidingren(jihua.getZhidingren());
+        renwu.setFDeleteMark(0);
+        renwu.setFCreatorTime(now);
+        renwu.setFCreatorUserId(jihua.getFCreatorUserId());
+        renwu.setRenwuShiliId(UUID.nameUUIDFromBytes((renwu.getFTenantId() + "|" + jihua.getId() + "|"
+                + zixiang.getId() + "|" + jihuaRiqi).getBytes(StandardCharsets.UTF_8)).toString());
+        renwu.setRenwuXiudingXuhao(1);
+        renwu.setQuyangdianId(quyangdian.getId());
+        renwu.setKuaizhaoJiegouBanben("1.0");
+        renwu.setKuaizhaoShengchengShijian(now);
+        renwu.setPeizhiChayiBiaozhi(0);
+        renwu.setZhuangtaiBiangengShijian(now);
+        return renwu;
+    }
+
+    private List<LimsSxtQuyangJihuaRenwuJianyanXiangKuaizhaoEntity> buildJianyanKuaizhao(
+            String tenantId, LimsSxtQingyanXiangmuEntity peizhi,
+            List<LimsSxtQingyanXiangmuZixiangEntity> peizhiZixiang,
+            ZhiliangBiaozhunGuanliEntity biaozhun,
+            Map<String, JianyanXiangmuGuanliEntity> xiangmuMap) {
+        Map<String, ZhiliangBiaozhunGuanliZixiangEntity> biaozhunMap = new HashMap<>();
+        for (ZhiliangBiaozhunGuanliZixiangEntity item : zhiliangBiaozhunZixiangService.listByForeignId(biaozhun.getId())) {
+            if (isYouxiaoBiaozhunZixiang(item, tenantId)) biaozhunMap.put(item.getJianyanXiangmuBianma(), item);
+        }
+        List<LimsSxtQuyangJihuaRenwuJianyanXiangKuaizhaoEntity> result = new ArrayList<>();
+        for (LimsSxtQingyanXiangmuZixiangEntity peizhiItem : peizhiZixiang) {
+            JianyanXiangmuGuanliEntity xiangmu = xiangmuMap.get(peizhiItem.getXiangmuId());
+            ZhiliangBiaozhunGuanliZixiangEntity biaozhunItem = biaozhunMap.get(xiangmu.getBianma());
+            if (biaozhunItem == null) {
+                throw new DataException("璇烽獙閰嶇疆妫�楠岄」鐩湭缁存姢璐ㄩ噺鏍囧噯锛�" + xiangmu.getBianma());
+            }
+            result.add(buildJianyanKuaizhaoItem(tenantId, peizhi, peizhiItem, biaozhun, xiangmu, biaozhunItem));
+        }
+        return result;
+    }
+
+    private Map<String, JianyanXiangmuGuanliEntity> chaxunYouxiaoJianyanXiangmuMap(
+            List<LimsSxtQingyanXiangmuZixiangEntity> peizhiZixiang,
+            String tenantId) {
+
+        Set<String> xiangmuBianhaoSet = new LinkedHashSet<>();
+
+        for (LimsSxtQingyanXiangmuZixiangEntity item : peizhiZixiang) {
+            if (!hasText(item.getXiangmuId())) {
+                throw new DataException("璇烽獙閰嶇疆瀛愰」鏈淮鎶よ川閲忔爣鍑嗗瓙椤笽D锛�" + item.getId());
+            }
+            if (!hasText(item.getXiangmuBianhao())) {
+                throw new DataException("璇烽獙閰嶇疆瀛愰」鏈淮鎶ゆ楠岄」鐩紪鐮侊細" + item.getId());
+            }
+            xiangmuBianhaoSet.add(item.getXiangmuBianhao());
+        }
+
+        QueryWrapper<JianyanXiangmuGuanliEntity> wrapper = new QueryWrapper<>();
+        wrapper.in("bianma", xiangmuBianhaoSet)
+                .eq("f_tenant_id", tenantId)
+                .and(item -> item.eq("f_delete_mark", 0)
+                        .or()
+                        .isNull("f_delete_mark"));
+
+        Map<String, JianyanXiangmuGuanliEntity> anBianmaChaxunJieguo = new HashMap<>();
+        for (JianyanXiangmuGuanliEntity item : jianyanXiangmuMapper.selectList(wrapper)) {
+            anBianmaChaxunJieguo.put(item.getBianma(), item);
+        }
+
+        Map<String, JianyanXiangmuGuanliEntity> xiangmuMap = new LinkedHashMap<>();
+        for (LimsSxtQingyanXiangmuZixiangEntity item : peizhiZixiang) {
+            JianyanXiangmuGuanliEntity xiangmu =
+                    anBianmaChaxunJieguo.get(item.getXiangmuBianhao());
+
+            if (xiangmu == null) {
+                throw new DataException(
+                        "璇烽獙閰嶇疆寮曠敤鐨勬楠岄」鐩笉瀛樺湪鎴栧凡鍒犻櫎锛岄」鐩紪鐮侊細"
+                                + item.getXiangmuBianhao());
+            }
+
+            // key 浠嶄娇鐢ㄨ川閲忔爣鍑嗗瓙椤� ID锛屽吋瀹瑰悗缁揩鐓ф瀯寤洪�昏緫
+            xiangmuMap.put(item.getXiangmuId(), xiangmu);
+        }
+
+        return xiangmuMap;
+    }
+
+    private LimsSxtQuyangJihuaRenwuJianyanXiangKuaizhaoEntity buildJianyanKuaizhaoItem(
+            String tenantId, LimsSxtQingyanXiangmuEntity peizhi, LimsSxtQingyanXiangmuZixiangEntity peizhiItem,
+            ZhiliangBiaozhunGuanliEntity biaozhun, JianyanXiangmuGuanliEntity xiangmu,
+            ZhiliangBiaozhunGuanliZixiangEntity biaozhunItem) {
+        LimsSxtQuyangJihuaRenwuJianyanXiangKuaizhaoEntity kuaizhao = new LimsSxtQuyangJihuaRenwuJianyanXiangKuaizhaoEntity();
+        kuaizhao.setId(RandomUtil.uuId());
+        kuaizhao.setFTenantId(tenantId);
+        kuaizhao.setLaiyuanQingyanPeizhiId(peizhi.getId());
+        kuaizhao.setLaiyuanQingyanPeizhiZixiangId(peizhiItem.getId());
+        kuaizhao.setLaiyuanZhiliangBiaozhunId(biaozhun.getId());
+        kuaizhao.setLaiyuanZhiliangBiaozhunZixiangId(biaozhunItem.getId());
+        kuaizhao.setJianyanXiangmuId(xiangmu.getId());
+        kuaizhao.setJianyanXiangmuBianma(biaozhunItem.getJianyanXiangmuBianma());
+        kuaizhao.setJianyanXiangmuMingcheng(biaozhunItem.getJianyanXiangmuMingcheng());
+        kuaizhao.setJianyanXiangmuShifouFenxileixing(xiangmu.getShifouFenxileixing());
+        kuaizhao.setJianyanXiangmuFenxiLeixing(xiangmu.getFenxiLeixing());
+        kuaizhao.setJianyanXiangmuJieguoLeixing(xiangmu.getJieguoLeixing());
+        kuaizhao.setJianyanXiangmuMorenDanwei(xiangmu.getMorenDanwei());
+        kuaizhao.setLilunShangxian(xiangmu.getLilunShangxian());
+        kuaizhao.setLilunXiaxian(xiangmu.getLilunXiaxian());
+        kuaizhao.setJianyanXiangmuBeizhu(xiangmu.getNote());
+        kuaizhao.setBiaozhunBianhao(biaozhun.getBiaozhunBianhao());
+        kuaizhao.setBiaozhunBanben(biaozhun.getBiaozhunBanben());
+        kuaizhao.setBiaozhunGuiding(biaozhunItem.getBiaozhunGuiding());
+        kuaizhao.setBiaozhunShangxian(biaozhunItem.getBiaozhunShangxian());
+        kuaizhao.setBiaozhunXiaxian(biaozhunItem.getBiaozhunXiaxian());
+        kuaizhao.setJianyanDanwei(biaozhunItem.getJianyanDanwei());
+        kuaizhao.setShujuLeixing(biaozhunItem.getShujuLeixing());
+        kuaizhao.setFenxiLeixing(biaozhunItem.getFenxiLeixing());
+        kuaizhao.setJianyanLiang(biaozhunItem.getJianyanLiang());
+        kuaizhao.setJianchaBanzu(biaozhunItem.getJianchaBanzu());
+        kuaizhao.setKuaizhaoHaxi(haxi(JSON.toJSONString(kuaizhao)));
+        kuaizhao.setFDeleteMark(0);
+        kuaizhao.setFCreatorTime(new Date());
+        return kuaizhao;
+    }
+
+    private void baocunPeizhiKuaizhao(LimsSxtQuyangJihuaRenwuEntity renwu, String leixing,
+                                      String laiyuanId, String banben, Object shuju, Date now) {
+        String json = JSON.toJSONString(shuju);
+        LimsSxtQuyangJihuaRenwuPeizhiKuaizhaoEntity kuaizhao = new LimsSxtQuyangJihuaRenwuPeizhiKuaizhaoEntity();
+        kuaizhao.setId(RandomUtil.uuId());
+        kuaizhao.setFTenantId(renwu.getFTenantId());
+        kuaizhao.setRenwuId(renwu.getId());
+        kuaizhao.setPeizhiLeixing(leixing);
+        kuaizhao.setLaiyuanPeizhiId(laiyuanId);
+        kuaizhao.setLaiyuanPeizhiBanben(banben);
+        kuaizhao.setKuaizhaoShuju(json);
+        kuaizhao.setKuaizhaoHaxi(haxi(json));
+        kuaizhao.setFCreatorTime(now);
+        kuaizhao.setFCreatorUserId(renwu.getFCreatorUserId());
+        peizhiKuaizhaoMapper.insertKuaizhao(kuaizhao);
+    }
+
+    private void baocunRenyuanKuaizhao(LimsSxtQuyangJihuaRenwuEntity renwu, String guanxiLeixing,
+                                        String yonghuId, String gangweiId, Date now) {
+        LimsSxtQuyangJihuaRenwuRenyuanKuaizhaoEntity kuaizhao = new LimsSxtQuyangJihuaRenwuRenyuanKuaizhaoEntity();
+        kuaizhao.setId(RandomUtil.uuId());
+        kuaizhao.setFTenantId(renwu.getFTenantId());
+        kuaizhao.setRenwuId(renwu.getId());
+        kuaizhao.setGuanxiLeixing(guanxiLeixing);
+        kuaizhao.setYonghuId(yonghuId);
+        kuaizhao.setGangweiId(gangweiId);
+        kuaizhao.setKuaizhaoHaxi(haxi(guanxiLeixing + "|" + yonghuId + "|" + gangweiId));
+        kuaizhao.setFCreatorTime(now);
+        kuaizhao.setFCreatorUserId(renwu.getFCreatorUserId());
+        renyuanKuaizhaoMapper.insert(kuaizhao);
+    }
+
+    private void baocunShijian(LimsSxtQuyangJihuaRenwuEntity renwu, String leixing,
+                                String yuanyinDaima, String yuanyin, String qingyandanId, String shouquanId) {
+        LimsSxtQuyangJihuaRenwuShijianEntity shijian = new LimsSxtQuyangJihuaRenwuShijianEntity();
+        shijian.setId(RandomUtil.uuId());
+        shijian.setFTenantId(renwu.getFTenantId());
+        shijian.setRenwuId(renwu.getId());
+        shijian.setRenwuShiliId(renwu.getRenwuShiliId());
+        shijian.setShijianLeixing(leixing);
+        shijian.setFashengShijian(new Date());
+        UserInfo user = UserProvider.getUser();
+        shijian.setCaozuoRenId(user == null ? null : user.getUserId());
+        shijian.setCaozuoLeixing(user == null ? "system" : "user");
+        shijian.setYuanyinDaima(yuanyinDaima);
+        shijian.setYuanyin(yuanyin);
+        shijian.setGuanlianQingyandanId(qingyandanId);
+        shijian.setXinKuaizhaoHaxi(renwu.getKuaizhaoHaxi());
+        shijian.setShouquanId(shouquanId);
+        shijian.setShijianShuju("{}");
+        shijianMapper.insertShijian(shijian);
+    }
+
+    private boolean quxiaoRenwu(LimsSxtQuyangJihuaRenwuEntity renwu, String yuanyinDaima) {
+        UserInfo user = UserProvider.getUser();
+        int updated = renwuMapper.quxiaoDangeRenwu(renwu.getId(), user == null ? "0" : user.getUserId(), yuanyinDaima);
+        if (updated == 1) {
+            baocunShijian(renwu, "renwu_quxiao", yuanyinDaima, null, null, null);
+            return true;
+        }
+        return false;
+    }
+
+    private List<LimsSxtQuyangJihuaRenwuJianyanXiangKuaizhaoEntity> chaxunJianyanKuaizhao(String renwuId, String tenantId) {
+        QueryWrapper<LimsSxtQuyangJihuaRenwuJianyanXiangKuaizhaoEntity> wrapper = new QueryWrapper<>();
+        wrapper.eq("renwu_id", renwuId).eq("f_tenant_id", tenantId)
+                .and(item -> item.eq("f_delete_mark", 0).or().isNull("f_delete_mark"));
+        return jianyanKuaizhaoMapper.selectList(wrapper);
+    }
+
+    private List<LimsSxtQuyangJihuaRenwuPeizhiKuaizhaoEntity> chaxunPeizhiKuaizhao(String renwuId, String tenantId) {
+        QueryWrapper<LimsSxtQuyangJihuaRenwuPeizhiKuaizhaoEntity> wrapper = new QueryWrapper<>();
+        wrapper.eq("renwu_id", renwuId).eq("f_tenant_id", tenantId);
+        return peizhiKuaizhaoMapper.selectList(wrapper);
+    }
+
+    private String chaxunPeizhiKuaizhaoShuju(LimsSxtQuyangJihuaRenwuEntity renwu, String leixing) {
+        for (LimsSxtQuyangJihuaRenwuPeizhiKuaizhaoEntity kuaizhao : chaxunPeizhiKuaizhao(renwu.getId(), renwu.getFTenantId())) {
+            if (leixing.equals(kuaizhao.getPeizhiLeixing())) return kuaizhao.getKuaizhaoShuju();
+        }
+        throw new DataException("浠诲姟缂哄皯" + leixing + "閰嶇疆蹇収锛�" + renwu.getId());
+    }
+
+    private LimsSxtQuyangJihuaEntity chaxunYishenpiKeZhixingJihua(String jihuaId, String tenantId) {
+        requireText(jihuaId, "鍙栨牱璁″垝ID涓嶈兘涓虹┖");
+        QueryWrapper<LimsSxtQuyangJihuaEntity> wrapper = new QueryWrapper<>();
+        wrapper.eq("f_id", jihuaId).eq("f_tenant_id", normalizeTenantId(tenantId))
+                .eq("f_flow_state", FLOW_STATE_APPROVED).eq("plan_status", LimsSxtPlanStatusResolver.AVAILABLE)
+                .and(item -> item.eq("f_delete_mark", 0).or().isNull("f_delete_mark"));
+        LimsSxtQuyangJihuaEntity jihua = jihuaMapper.selectOne(wrapper);
+        if (jihua == null) throw new DataException("鍙栨牱璁″垝涓嶅瓨鍦ㄣ�佹湭瀹℃壒閫氳繃鎴栦笉鍙墽琛�");
+        return jihua;
+    }
+
+    private List<LimsSxtQuyangJihuaZixiangEntity> chaxunYouxiaoJihuaZixiang(String jihuaId, String tenantId) {
+        QueryWrapper<LimsSxtQuyangJihuaZixiangEntity> wrapper = new QueryWrapper<>();
+        wrapper.eq("f_foreign_id", jihuaId).eq("f_tenant_id", tenantId)
+                .and(item -> item.eq("f_delete_mark", 0).or().isNull("f_delete_mark"));
+        List<LimsSxtQuyangJihuaZixiangEntity> list = jihuaZixiangMapper.selectList(wrapper);
+        if (list.isEmpty()) throw new DataException("鍙栨牱璁″垝鏈厤缃湁鏁堝瓙椤�");
+        return list;
+    }
+
+    private LimsSxtQuyangdianKuaizhaoModel chaxunWeiyiYouxiaoQuyangdian(
+            LimsSxtQuyangJihuaEntity jihua,
+            LimsSxtQuyangJihuaZixiangEntity zixiang,
+            String tenantId) {
+        if (!hasText(zixiang.getQuyangdianId())) {
+            throw new DataException("鍙栨牱璁″垝瀛愰」鏈繚瀛樺彇鏍风偣ID锛�" + zixiang.getId());
+        }
+        LimsSxtQuyangdianKuaizhaoModel quyangdian = quyangdianMapper.selectForTaskSnapshot(
+                tenantId, zixiang.getQuyangdianId());
+        if (quyangdian == null) {
+            throw new DataException("姘寸郴缁熷彇鏍风偣涓嶅瓨鍦ㄣ�佸凡鍒犻櫎鎴栧凡鍋滅敤锛�" + zixiang.getQuyangdianId());
+        }
+        if (!Objects.equals(jihua.getYangpinLeixing(), quyangdian.getLeiXing())) {
+            throw new DataException("鍙栨牱鐐规牱鍝佺被鍨嬩笌璁″垝涓嶄竴鑷达細" + zixiang.getQuyangdianId());
+        }
+        if (!Objects.equals(zixiang.getSuoshuChejian(), quyangdian.getChejianMingchengName())) {
+            throw new DataException("鍙栨牱鐐规墍灞炶溅闂翠笌璁″垝涓嶄竴鑷达細" + zixiang.getQuyangdianId());
+        }
+        return quyangdian;
+    }
+
+    private YangpinGuanliEntity chaxunYouxiaoYangpin(String yangpinId, String tenantId) {
+        YangpinGuanliEntity yangpin = yangpinGuanliMapper.selectById(yangpinId);
+        if (!isYouxiaoYangpin(yangpin, tenantId)) throw new DataException("鏍峰搧涓嶅瓨鍦ㄣ�佸凡鍒犻櫎鎴栧凡鍋滅敤");
+        return yangpin;
+    }
+
+    private ZhiliangBiaozhunGuanliEntity chaxunYouxiaoBiaozhun(String biaozhunId, String tenantId, String yangpinId) {
+        ZhiliangBiaozhunGuanliEntity biaozhun = zhiliangBiaozhunMapper.selectById(biaozhunId);
+        if (!isYouxiaoBiaozhun(biaozhun, tenantId, yangpinId)) throw new DataException("璐ㄩ噺鏍囧噯涓嶅瓨鍦ㄣ�佸凡鍒犻櫎銆佸凡鍋滅敤鎴栦笌鏍峰搧涓嶅尮閰�");
+        return biaozhun;
+    }
+
+    private LimsSxtQingyanXiangmuEntity chaxunYouxiaoQingyanPeizhi(String peizhiId, String tenantId,
+                                                                     String yangpinId, String biaozhunId) {
+        LimsSxtQingyanXiangmuEntity peizhi = qingyanPeizhiMapper.selectById(peizhiId);
+        if (!isYouxiaoPeizhi(peizhi, tenantId, yangpinId, biaozhunId)) {
+            throw new DataException("姘寸郴缁熻楠岄厤缃笉瀛樺湪銆佸凡鍒犻櫎鎴栦笌鏍峰搧銆佽川閲忔爣鍑嗕笉鍖归厤");
+        }
+        return peizhi;
+    }
+
+    private List<LimsSxtQingyanXiangmuZixiangEntity> chaxunYouxiaoPeizhiZixiang(String peizhiId, String tenantId) {
+        QueryWrapper<LimsSxtQingyanXiangmuZixiangEntity> wrapper = new QueryWrapper<>();
+        wrapper.eq("f_foreign_id", peizhiId).eq("f_tenant_id", tenantId)
+                .and(item -> item.eq("f_delete_mark", 0).or().isNull("f_delete_mark"));
+        List<LimsSxtQingyanXiangmuZixiangEntity> list = qingyanPeizhiZixiangMapper.selectList(wrapper);
+        if (list.isEmpty()) throw new DataException("姘寸郴缁熻楠岄厤缃湭閰嶇疆鏈夋晥妫�楠岄」鐩�");
+        return list;
+    }
+
+    private boolean isYouxiaoYangpin(YangpinGuanliEntity item, String tenantId) {
+        return item != null && tenantId.equals(item.getFTenantId()) && !isDeleted(item.getFDeleteMark())
+                && "enabled".equals(item.getBizEnabled());
+    }
+
+    private boolean isYouxiaoBiaozhun(ZhiliangBiaozhunGuanliEntity item, String tenantId, String yangpinId) {
+        return item != null && tenantId.equals(item.getTenantId()) && !isDeleted(item.getDeleteMark())
+                && "enabled".equals(item.getBizEnabled()) && yangpinId.equals(item.getYangpinId());
+    }
+
+    private boolean isYouxiaoPeizhi(LimsSxtQingyanXiangmuEntity item, String tenantId,
+                                    String yangpinId, String biaozhunId) {
+        return item != null && tenantId.equals(item.getFTenantId()) && !isDeleted(item.getFDeleteMark())
+                && yangpinId.equals(item.getYangpinLeixing()) && biaozhunId.equals(item.getZhiliangBiaozhun());
+    }
+
+    private boolean isYouxiaoPeizhiZixiang(LimsSxtQingyanXiangmuZixiangEntity item, String tenantId) {
+        return item != null && tenantId.equals(item.getFTenantId()) && !isDeleted(item.getFDeleteMark());
+    }
+
+    private boolean isYouxiaoBiaozhunZixiang(ZhiliangBiaozhunGuanliZixiangEntity item, String tenantId) {
+        return item != null && tenantId.equals(item.getTenantId()) && !isDeleted(item.getDeleteMark());
+    }
+
+    private boolean isYouxiaoJianyanXiangmu(JianyanXiangmuGuanliEntity item, String tenantId) {
+        return item != null && tenantId.equals(item.getTenantId()) && !isDeleted(item.getDeleteMark());
+    }
+
+    private boolean isDeleted(Integer deleteMark) {
+        return deleteMark != null && deleteMark == 1;
+    }
+
+    private boolean hasText(String value) {
+        return StringUtils.hasText(value);
+    }
+
+    private int parseInterval(String value) {
+        try {
+            int result = Integer.parseInt(value == null ? "" : value.trim());
+            if (result < 0) throw new NumberFormatException();
+            return result;
+        } catch (NumberFormatException e) {
+            throw new DataException("鍙栨牱璁″垝鍛ㄦ湡闂撮殧蹇呴』涓洪潪璐熸暣鏁�");
+        }
+    }
+
+    private List<LocalDate> executionDates(LocalDate start, LocalDate end, String leixing, int jiange) {
+        try {
+            return LimsSxtQuyangJihuaRenwuPlanner.executionDates(start, end, leixing, jiange);
+        } catch (IllegalArgumentException e) {
+            throw new DataException(e.getMessage());
+        }
+    }
+
+    private String normalizeTenantId(String tenantId) {
+        return hasText(tenantId) ? tenantId : "0";
+    }
+
+    private void requireText(String value, String message) {
+        if (!hasText(value)) throw new DataException(message);
+    }
+
+    private void requireJihuaRiqi(LocalDate jihuaRiqi) {
+        if (jihuaRiqi == null) throw new DataException("浠诲姟鎵ц鏃ユ湡涓嶈兘涓虹┖");
+    }
+
+    private LocalDate toLocalDate(Date value, String message) {
+        if (value == null) throw new DataException(message);
+        return value.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
+    }
+
+    private String haxi(String value) {
+        try {
+            byte[] bytes = MessageDigest.getInstance("SHA-256").digest(value.getBytes(StandardCharsets.UTF_8));
+            StringBuilder result = new StringBuilder(bytes.length * 2);
+            for (byte b : bytes) result.append(String.format("%02x", b));
+            return result.toString();
+        } catch (Exception e) {
+            throw new IllegalStateException("鏃犳硶璁$畻蹇収鍝堝笇", e);
+        }
+    }
+
+    private static class PeizhiWuxiaoException extends RuntimeException {
+        private final String yuanyinDaima;
+
+        private PeizhiWuxiaoException(String yuanyinDaima, String message) {
+            super(message);
+            this.yuanyinDaima = yuanyinDaima;
+        }
+    }
+}

--
Gitblit v1.8.0