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/LimsHuanjingJianceServiceImpl.java | 1093 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 1,093 insertions(+), 0 deletions(-)

diff --git a/jnpf-lims/jnpf-lims-biz/src/main/java/jnpf/limsService/impl/LimsHuanjingJianceServiceImpl.java b/jnpf-lims/jnpf-lims-biz/src/main/java/jnpf/limsService/impl/LimsHuanjingJianceServiceImpl.java
new file mode 100644
index 0000000..6f36895
--- /dev/null
+++ b/jnpf-lims/jnpf-lims-biz/src/main/java/jnpf/limsService/impl/LimsHuanjingJianceServiceImpl.java
@@ -0,0 +1,1093 @@
+package jnpf.limsService.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import jnpf.audit.sdk.annotation.AuditLog;
+import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
+import jnpf.base.UserInfo;
+import jnpf.base.service.SuperServiceImpl;
+import jnpf.exception.DataException;
+import jnpf.limsEntity.LimsHuanjingCaiyangdianEntity;
+import jnpf.limsEntity.LimsHuanjingCaiyangdianZixiangEntity;
+import jnpf.limsEntity.LimsHuanjingCaiyangdianVo;
+import jnpf.limsEntity.LimsHuanjingJianceBaogaoEntity;
+import jnpf.limsEntity.LimsHuanjingJianceBaogaoZixiangEntity;
+import jnpf.limsEntity.LimsHuanjingJianceBiaozhunEntity;
+import jnpf.limsEntity.LimsHuanjingJianceJihuaEntity;
+import jnpf.limsEntity.LimsHuanjingJianceJihuaZhongzhiEntity;
+import jnpf.limsEntity.LimsHuanjingJianceJihuaZixiangEntity;
+import jnpf.limsEntity.LimsHuanjingJianceJiluEntity;
+import jnpf.limsEntity.LimsHuanjingJianceJiluZixiangEntity;
+import jnpf.limsEntity.LimsHuanjingJianceKanbanItemVo;
+import jnpf.limsEntity.LimsHuanjingJianceKanbanRowVo;
+import jnpf.limsEntity.LimsHuanjingJianceQushiDataVo;
+import jnpf.limsEntity.LimsHuanjingJianceQushiRecordVo;
+import jnpf.limsEntity.LimsHuanjingJianceQushiStandardVo;
+import jnpf.limsEntity.LimsHuanjingQuyuEntity;
+import jnpf.limsMapper.LimsHuanjingCaiyangdianMapper;
+import jnpf.limsMapper.LimsHuanjingCaiyangdianZixiangMapper;
+import jnpf.limsMapper.LimsHuanjingJianceBaogaoMapper;
+import jnpf.limsMapper.LimsHuanjingJianceBaogaoZixiangMapper;
+import jnpf.limsMapper.LimsHuanjingJianceBiaozhunMapper;
+import jnpf.limsMapper.LimsHuanjingJianceJihuaMapper;
+import jnpf.limsMapper.LimsHuanjingJianceJihuaZhongzhiMapper;
+import jnpf.limsMapper.LimsHuanjingJianceJihuaZixiangMapper;
+import jnpf.limsMapper.LimsHuanjingJianceJiluMapper;
+import jnpf.limsMapper.LimsHuanjingJianceJiluZixiangMapper;
+import jnpf.limsMapper.LimsHuanjingQuyuMapper;
+import jnpf.limsService.LimsHuanjingJianceService;
+import jnpf.util.JsonUtil;
+import jnpf.util.RandomUtil;
+import jnpf.util.UserProvider;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.StringUtils;
+
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+@Service
+public class LimsHuanjingJianceServiceImpl
+        extends SuperServiceImpl<LimsHuanjingJianceJiluMapper, LimsHuanjingJianceJiluEntity>
+        implements LimsHuanjingJianceService {
+
+    private static final String STATUS_ENABLED = "enabled";
+    private static final String STATUS_DISABLED = "disabled";
+    private static final String STATUS_RECEIVED = "received";
+    private static final String STATUS_PENDING_AUDIT = "pending_audit";
+    private static final String STATUS_AUDITED = "audited";
+    private static final String PLAN_TYPE_TEMPORARY = "temporary";
+    private static final String PLAN_TYPE_YEARLY = "yearly";
+    private static final String ACTION_SUBMIT = "submit";
+    private static final String ACTION_ACCEPT = "accept";
+    private static final String ACTION_REJECT = "reject";
+
+    @Autowired
+    private LimsHuanjingCaiyangdianMapper caiyangdianMapper;
+
+    @Autowired
+    private LimsHuanjingJianceJihuaMapper jihuaMapper;
+
+    @Autowired
+    private LimsHuanjingJianceJihuaZixiangMapper jihuaZixiangMapper;
+
+    @Autowired
+    private LimsHuanjingJianceJihuaZhongzhiMapper jihuaZhongzhiMapper;
+
+    @Autowired
+    private LimsHuanjingCaiyangdianZixiangMapper caiyangdianZixiangMapper;
+
+    @Autowired
+    private LimsHuanjingJianceJiluZixiangMapper jiluZixiangMapper;
+
+    @Autowired
+    private LimsHuanjingJianceBaogaoMapper baogaoMapper;
+
+    @Autowired
+    private LimsHuanjingJianceBaogaoZixiangMapper baogaoZixiangMapper;
+
+    @Autowired
+    private LimsHuanjingJianceBiaozhunMapper biaozhunMapper;
+
+    @Autowired
+    private LimsHuanjingQuyuMapper quyuMapper;
+
+    @Override
+    public List<LimsHuanjingCaiyangdianVo> listCaiyangdian(String jianceQuyuId, String jiejingJibie) {
+        LambdaQueryWrapper<LimsHuanjingCaiyangdianEntity> wrapper = new LambdaQueryWrapper<>();
+        wrapper.select(
+                LimsHuanjingCaiyangdianEntity::getId,
+                LimsHuanjingCaiyangdianEntity::getWeizhiBianhao,
+                LimsHuanjingCaiyangdianEntity::getWeizhiMingcheng);
+        wrapper.eq(LimsHuanjingCaiyangdianEntity::getJianceQuyu, jianceQuyuId);
+        wrapper.eq(LimsHuanjingCaiyangdianEntity::getBizEnabled, STATUS_ENABLED);
+        wrapper.eq(StringUtils.hasText(jiejingJibie),
+                LimsHuanjingCaiyangdianEntity::getJiejingJibie, jiejingJibie);
+        wrapper.and(item -> item.isNull(LimsHuanjingCaiyangdianEntity::getDeleteMark)
+                .or().ne(LimsHuanjingCaiyangdianEntity::getDeleteMark, 1));
+        wrapper.orderByAsc(
+                LimsHuanjingCaiyangdianEntity::getWeizhiBianhao,
+                LimsHuanjingCaiyangdianEntity::getWeizhiMingcheng);
+
+        List<LimsHuanjingCaiyangdianVo> result = new ArrayList<>();
+        for (LimsHuanjingCaiyangdianEntity entity : caiyangdianMapper.selectList(wrapper)) {
+            LimsHuanjingCaiyangdianVo vo = new LimsHuanjingCaiyangdianVo();
+            vo.setCaiyangdianId(entity.getId());
+            vo.setWeizhiBianhao(entity.getWeizhiBianhao());
+            vo.setWeizhiMingcheng(entity.getWeizhiMingcheng());
+            result.add(vo);
+        }
+        return result;
+    }
+
+    @Override
+    public List<LimsHuanjingJianceKanbanRowVo> listKanbanRows(String jianceQuyu, String weizhiBianhao, String jiejingJibie) {
+        LambdaQueryWrapper<LimsHuanjingCaiyangdianEntity> wrapper = new LambdaQueryWrapper<>();
+        wrapper.select(
+                LimsHuanjingCaiyangdianEntity::getId,
+                LimsHuanjingCaiyangdianEntity::getJianceQuyu,
+                LimsHuanjingCaiyangdianEntity::getWeizhiBianhao,
+                LimsHuanjingCaiyangdianEntity::getWeizhiMingcheng,
+                LimsHuanjingCaiyangdianEntity::getJiejingJibie);
+        wrapper.eq(LimsHuanjingCaiyangdianEntity::getBizEnabled, STATUS_ENABLED);
+        wrapper.eq(StringUtils.hasText(jianceQuyu), LimsHuanjingCaiyangdianEntity::getJianceQuyu, jianceQuyu);
+        wrapper.eq(StringUtils.hasText(weizhiBianhao), LimsHuanjingCaiyangdianEntity::getWeizhiBianhao, weizhiBianhao);
+        wrapper.eq(StringUtils.hasText(jiejingJibie), LimsHuanjingCaiyangdianEntity::getJiejingJibie, jiejingJibie);
+        wrapper.and(item -> item.isNull(LimsHuanjingCaiyangdianEntity::getDeleteMark)
+                .or().ne(LimsHuanjingCaiyangdianEntity::getDeleteMark, 1));
+        wrapper.orderByAsc(
+                LimsHuanjingCaiyangdianEntity::getJianceQuyu,
+                LimsHuanjingCaiyangdianEntity::getWeizhiBianhao,
+                LimsHuanjingCaiyangdianEntity::getWeizhiMingcheng);
+
+        List<LimsHuanjingCaiyangdianEntity> entityList = caiyangdianMapper.selectList(wrapper);
+        Set<String> quyuIds = new LinkedHashSet<>();
+        for (LimsHuanjingCaiyangdianEntity entity : entityList) {
+            if (StringUtils.hasText(entity.getJianceQuyu())) {
+                quyuIds.add(entity.getJianceQuyu());
+            }
+        }
+        Map<String, String> quyuMap = getQuyuMap(quyuIds);
+
+        List<LimsHuanjingJianceKanbanRowVo> result = new ArrayList<>();
+        for (LimsHuanjingCaiyangdianEntity entity : entityList) {
+            LimsHuanjingJianceKanbanRowVo vo = new LimsHuanjingJianceKanbanRowVo();
+            vo.setCaiyangdianId(entity.getId());
+            vo.setJianceQuyu(entity.getJianceQuyu());
+            vo.setJianceQuyuMingcheng(quyuMap.getOrDefault(entity.getJianceQuyu(), entity.getJianceQuyu()));
+            vo.setWeizhiBianhao(entity.getWeizhiBianhao());
+            vo.setWeizhiMingcheng(entity.getWeizhiMingcheng());
+            vo.setJiejingJibie(entity.getJiejingJibie());
+            result.add(vo);
+        }
+        return result;
+    }
+
+    @Override
+    public List<LimsHuanjingJianceKanbanItemVo> listKanbanItems(Date startDate, Date endDate, String jianceQuyu, String weizhiBianhao, String jiejingJibie) {
+        LambdaQueryWrapper<LimsHuanjingJianceJiluEntity> jiluWrapper = new LambdaQueryWrapper<>();
+        jiluWrapper.select(
+                LimsHuanjingJianceJiluEntity::getId,
+                LimsHuanjingJianceJiluEntity::getJihuaId,
+                LimsHuanjingJianceJiluEntity::getJihuaMingcheng,
+                LimsHuanjingJianceJiluEntity::getJihuaLeixing,
+                LimsHuanjingJianceJiluEntity::getJihuaRiqi,
+                LimsHuanjingJianceJiluEntity::getJiejingJibie,
+                LimsHuanjingJianceJiluEntity::getJianceQuyu,
+                LimsHuanjingJianceJiluEntity::getJianceZhuangtai,
+                LimsHuanjingJianceJiluEntity::getBizStatus);
+        jiluWrapper.ge(startDate != null, LimsHuanjingJianceJiluEntity::getJihuaRiqi, startDate);
+        jiluWrapper.le(endDate != null, LimsHuanjingJianceJiluEntity::getJihuaRiqi, endDate);
+        jiluWrapper.ne(LimsHuanjingJianceJiluEntity::getBizStatus, STATUS_DISABLED);
+        jiluWrapper.eq(StringUtils.hasText(jianceQuyu), LimsHuanjingJianceJiluEntity::getJianceQuyu, jianceQuyu);
+        jiluWrapper.eq(StringUtils.hasText(jiejingJibie), LimsHuanjingJianceJiluEntity::getJiejingJibie, jiejingJibie);
+        jiluWrapper.and(item -> item.isNull(LimsHuanjingJianceJiluEntity::getDeleteMark)
+                .or().ne(LimsHuanjingJianceJiluEntity::getDeleteMark, 1));
+        jiluWrapper.orderByAsc(LimsHuanjingJianceJiluEntity::getJihuaRiqi);
+
+        List<LimsHuanjingJianceJiluEntity> jiluList = baseMapper.selectList(jiluWrapper);
+        if (jiluList.isEmpty()) {
+            return Collections.emptyList();
+        }
+
+        Map<String, LimsHuanjingJianceJiluEntity> jiluMap = new LinkedHashMap<>();
+        List<String> jiluIds = new ArrayList<>();
+        Set<String> quyuIds = new LinkedHashSet<>();
+        for (LimsHuanjingJianceJiluEntity jilu : jiluList) {
+            jiluMap.put(jilu.getId(), jilu);
+            jiluIds.add(jilu.getId());
+            if (StringUtils.hasText(jilu.getJianceQuyu())) {
+                quyuIds.add(jilu.getJianceQuyu());
+            }
+        }
+
+        LambdaQueryWrapper<LimsHuanjingJianceJiluZixiangEntity> zixiangWrapper = new LambdaQueryWrapper<>();
+        zixiangWrapper.select(
+                LimsHuanjingJianceJiluZixiangEntity::getId,
+                LimsHuanjingJianceJiluZixiangEntity::getForeignId,
+                LimsHuanjingJianceJiluZixiangEntity::getWeizhiBianhao,
+                LimsHuanjingJianceJiluZixiangEntity::getWeizhiMingcheng,
+                LimsHuanjingJianceJiluZixiangEntity::getJianceXiangmu,
+                LimsHuanjingJianceJiluZixiangEntity::getJianceQuyu,
+                LimsHuanjingJianceJiluZixiangEntity::getJiejingJibie);
+        zixiangWrapper.in(LimsHuanjingJianceJiluZixiangEntity::getForeignId, jiluIds);
+        zixiangWrapper.eq(StringUtils.hasText(jianceQuyu), LimsHuanjingJianceJiluZixiangEntity::getJianceQuyu, jianceQuyu);
+        zixiangWrapper.eq(StringUtils.hasText(weizhiBianhao), LimsHuanjingJianceJiluZixiangEntity::getWeizhiBianhao, weizhiBianhao);
+        zixiangWrapper.eq(StringUtils.hasText(jiejingJibie), LimsHuanjingJianceJiluZixiangEntity::getJiejingJibie, jiejingJibie);
+        zixiangWrapper.and(item -> item.isNull(LimsHuanjingJianceJiluZixiangEntity::getDeleteMark)
+                .or().ne(LimsHuanjingJianceJiluZixiangEntity::getDeleteMark, 1));
+        zixiangWrapper.orderByAsc(
+                LimsHuanjingJianceJiluZixiangEntity::getWeizhiBianhao,
+                LimsHuanjingJianceJiluZixiangEntity::getJianceXiangmu);
+        List<LimsHuanjingJianceJiluZixiangEntity> zixiangList = jiluZixiangMapper.selectList(zixiangWrapper);
+
+        for (LimsHuanjingJianceJiluZixiangEntity zixiang : zixiangList) {
+            if (StringUtils.hasText(zixiang.getJianceQuyu())) {
+                quyuIds.add(zixiang.getJianceQuyu());
+            }
+        }
+        Map<String, String> quyuMap = getQuyuMap(quyuIds);
+
+        Map<String, LimsHuanjingJianceKanbanItemVo> resultMap = new LinkedHashMap<>();
+        for (LimsHuanjingJianceJiluZixiangEntity zixiang : zixiangList) {
+            LimsHuanjingJianceJiluEntity jilu = jiluMap.get(zixiang.getForeignId());
+            if (jilu == null) {
+                continue;
+            }
+            LimsHuanjingJianceKanbanItemVo vo = new LimsHuanjingJianceKanbanItemVo();
+            vo.setZixiangId(zixiang.getId());
+            vo.setJiluId(jilu.getId());
+            vo.setJihuaId(jilu.getJihuaId());
+            vo.setJihuaMingcheng(jilu.getJihuaMingcheng());
+            vo.setJihuaLeixing(jilu.getJihuaLeixing());
+            vo.setJihuaRiqi(jilu.getJihuaRiqi());
+            vo.setJiejingJibie(StringUtils.hasText(zixiang.getJiejingJibie()) ? zixiang.getJiejingJibie() : jilu.getJiejingJibie());
+            vo.setJianceQuyu(StringUtils.hasText(zixiang.getJianceQuyu()) ? zixiang.getJianceQuyu() : jilu.getJianceQuyu());
+            vo.setJianceQuyuMingcheng(quyuMap.getOrDefault(vo.getJianceQuyu(), vo.getJianceQuyu()));
+            vo.setWeizhiBianhao(zixiang.getWeizhiBianhao());
+            vo.setWeizhiMingcheng(zixiang.getWeizhiMingcheng());
+            vo.setJianceXiangmu(zixiang.getJianceXiangmu());
+            vo.setJianceZhuangtai(jilu.getJianceZhuangtai());
+            vo.setBizStatus(jilu.getBizStatus());
+            vo.setCanDelete(STATUS_ENABLED.equals(jilu.getBizStatus()));
+            resultMap.putIfAbsent(getKanbanZixiangGroupKey(zixiang), vo);
+        }
+        return new ArrayList<>(resultMap.values());
+    }
+
+    @Override
+    public LimsHuanjingJianceQushiDataVo listQushiData(Date startDate,
+                                                       Date endDate,
+                                                       String jianceQuyu,
+                                                       String jiejingJibie,
+                                                       String weizhiBianhao,
+                                                       String jiancePinci,
+                                                       List<String> jianceXiangmu,
+                                                       String jianceZhuangtai) {
+        LimsHuanjingJianceQushiDataVo result = new LimsHuanjingJianceQushiDataVo();
+        result.setStandards(listQushiStandards(jianceXiangmu, jiejingJibie, jianceZhuangtai));
+
+        LambdaQueryWrapper<LimsHuanjingJianceBaogaoEntity> baogaoWrapper = new LambdaQueryWrapper<>();
+        baogaoWrapper.select(
+                LimsHuanjingJianceBaogaoEntity::getId,
+                LimsHuanjingJianceBaogaoEntity::getJihuaRiqi,
+                LimsHuanjingJianceBaogaoEntity::getJianceQuyu,
+                LimsHuanjingJianceBaogaoEntity::getJiejingJibie,
+                LimsHuanjingJianceBaogaoEntity::getJianceXiangmu);
+        baogaoWrapper.ge(LimsHuanjingJianceBaogaoEntity::getJihuaRiqi, startDate);
+        baogaoWrapper.le(LimsHuanjingJianceBaogaoEntity::getJihuaRiqi, endDate);
+        baogaoWrapper.eq(LimsHuanjingJianceBaogaoEntity::getBizStatus, STATUS_AUDITED);
+        baogaoWrapper.eq(LimsHuanjingJianceBaogaoEntity::getJianceQuyu, jianceQuyu);
+        baogaoWrapper.eq(LimsHuanjingJianceBaogaoEntity::getJiejingJibie, jiejingJibie);
+        baogaoWrapper.in(LimsHuanjingJianceBaogaoEntity::getJianceXiangmu, jianceXiangmu);
+        if ("na".equals(jiancePinci)) {
+            baogaoWrapper.and(item -> item.isNull(LimsHuanjingJianceBaogaoEntity::getJiancePinci)
+                    .or().eq(LimsHuanjingJianceBaogaoEntity::getJiancePinci, "na"));
+        } else {
+            baogaoWrapper.eq(LimsHuanjingJianceBaogaoEntity::getJiancePinci, jiancePinci);
+        }
+        baogaoWrapper.eq(LimsHuanjingJianceBaogaoEntity::getJianceZhuangtai, jianceZhuangtai);
+        baogaoWrapper.and(item -> item.isNull(LimsHuanjingJianceBaogaoEntity::getDeleteMark)
+                .or().ne(LimsHuanjingJianceBaogaoEntity::getDeleteMark, 1));
+        baogaoWrapper.orderByAsc(LimsHuanjingJianceBaogaoEntity::getJihuaRiqi);
+        List<LimsHuanjingJianceBaogaoEntity> baogaoList = baogaoMapper.selectList(baogaoWrapper);
+        if (baogaoList.isEmpty()) {
+            return result;
+        }
+
+        List<String> baogaoIds = new ArrayList<>();
+        Map<String, LimsHuanjingJianceBaogaoEntity> baogaoMap = new LinkedHashMap<>();
+        for (LimsHuanjingJianceBaogaoEntity baogao : baogaoList) {
+            if (!StringUtils.hasText(baogao.getId())) {
+                continue;
+            }
+            baogaoIds.add(baogao.getId());
+            baogaoMap.put(baogao.getId(), baogao);
+        }
+        if (baogaoIds.isEmpty()) {
+            return result;
+        }
+
+        LambdaQueryWrapper<LimsHuanjingJianceBaogaoZixiangEntity> zixiangWrapper = new LambdaQueryWrapper<>();
+        zixiangWrapper.select(
+                LimsHuanjingJianceBaogaoZixiangEntity::getForeignId,
+                LimsHuanjingJianceBaogaoZixiangEntity::getJianceQuyu,
+                LimsHuanjingJianceBaogaoZixiangEntity::getJiejingJibie,
+                LimsHuanjingJianceBaogaoZixiangEntity::getWeizhiBianhao,
+                LimsHuanjingJianceBaogaoZixiangEntity::getWeizhiMingcheng,
+                LimsHuanjingJianceBaogaoZixiangEntity::getQuyangdianMingcheng,
+                LimsHuanjingJianceBaogaoZixiangEntity::getJianceXiangmu,
+                LimsHuanjingJianceBaogaoZixiangEntity::getCeshiJieguo,
+                LimsHuanjingJianceBaogaoZixiangEntity::getCeshiJieguoLijing);
+        zixiangWrapper.in(LimsHuanjingJianceBaogaoZixiangEntity::getForeignId, baogaoIds);
+        zixiangWrapper.eq(LimsHuanjingJianceBaogaoZixiangEntity::getWeizhiBianhao, weizhiBianhao);
+        zixiangWrapper.and(item -> item.isNull(LimsHuanjingJianceBaogaoZixiangEntity::getDeleteMark)
+                .or().ne(LimsHuanjingJianceBaogaoZixiangEntity::getDeleteMark, 1));
+        zixiangWrapper.orderByAsc(
+                LimsHuanjingJianceBaogaoZixiangEntity::getJianceXiangmu,
+                LimsHuanjingJianceBaogaoZixiangEntity::getQuyangdianMingcheng);
+
+        List<LimsHuanjingJianceQushiRecordVo> records = new ArrayList<>();
+        for (LimsHuanjingJianceBaogaoZixiangEntity zixiang : baogaoZixiangMapper.selectList(zixiangWrapper)) {
+            LimsHuanjingJianceBaogaoEntity baogao = baogaoMap.get(zixiang.getForeignId());
+            if (baogao == null) {
+                continue;
+            }
+            LimsHuanjingJianceQushiRecordVo vo = new LimsHuanjingJianceQushiRecordVo();
+            vo.setJianceRiqi(baogao.getJihuaRiqi());
+            vo.setJianceQuyu(StringUtils.hasText(zixiang.getJianceQuyu()) ? zixiang.getJianceQuyu() : baogao.getJianceQuyu());
+            vo.setJiejingJibie(StringUtils.hasText(zixiang.getJiejingJibie()) ? zixiang.getJiejingJibie() : baogao.getJiejingJibie());
+            vo.setWeizhiBianhao(zixiang.getWeizhiBianhao());
+            vo.setWeizhiMingcheng(zixiang.getWeizhiMingcheng());
+            vo.setQuyangdianMingcheng(zixiang.getQuyangdianMingcheng());
+            vo.setJianceXiangmu(StringUtils.hasText(zixiang.getJianceXiangmu()) ? zixiang.getJianceXiangmu() : baogao.getJianceXiangmu());
+            vo.setCeshiJieguo(zixiang.getCeshiJieguo());
+            vo.setCeshiJieguoLijing(zixiang.getCeshiJieguoLijing());
+            records.add(vo);
+        }
+        result.setRecords(records);
+        return result;
+    }
+
+    private List<LimsHuanjingJianceQushiStandardVo> listQushiStandards(List<String> jianceXiangmu, String jiejingJibie, String jianceZhuangtai) {
+        LambdaQueryWrapper<LimsHuanjingJianceBiaozhunEntity> wrapper = new LambdaQueryWrapper<>();
+        wrapper.select(
+                LimsHuanjingJianceBiaozhunEntity::getJianceXiangmu,
+                LimsHuanjingJianceBiaozhunEntity::getJiejingJibie,
+                LimsHuanjingJianceBiaozhunEntity::getJianceZhuangtai,
+                LimsHuanjingJianceBiaozhunEntity::getBiaozhunShangxian,
+                LimsHuanjingJianceBiaozhunEntity::getMorenDanwei,
+                LimsHuanjingJianceBiaozhunEntity::getLijing,
+                LimsHuanjingJianceBiaozhunEntity::getBiaozhunGuiding);
+        wrapper.in(LimsHuanjingJianceBiaozhunEntity::getJianceXiangmu, jianceXiangmu);
+        wrapper.eq(LimsHuanjingJianceBiaozhunEntity::getJiejingJibie, jiejingJibie);
+        wrapper.eq(LimsHuanjingJianceBiaozhunEntity::getJianceZhuangtai, jianceZhuangtai);
+        wrapper.eq(LimsHuanjingJianceBiaozhunEntity::getBizEnabled, STATUS_ENABLED);
+        wrapper.and(item -> item.isNull(LimsHuanjingJianceBiaozhunEntity::getDeleteMark)
+                .or().ne(LimsHuanjingJianceBiaozhunEntity::getDeleteMark, 1));
+        wrapper.orderByAsc(
+                LimsHuanjingJianceBiaozhunEntity::getJianceXiangmu,
+                LimsHuanjingJianceBiaozhunEntity::getLijing);
+
+        List<LimsHuanjingJianceQushiStandardVo> result = new ArrayList<>();
+        for (LimsHuanjingJianceBiaozhunEntity entity : biaozhunMapper.selectList(wrapper)) {
+            LimsHuanjingJianceQushiStandardVo vo = new LimsHuanjingJianceQushiStandardVo();
+            vo.setJianceXiangmu(entity.getJianceXiangmu());
+            vo.setJiejingJibie(entity.getJiejingJibie());
+            vo.setJianceZhuangtai(entity.getJianceZhuangtai());
+            vo.setBiaozhunShangxian(entity.getBiaozhunShangxian());
+            vo.setMorenDanwei(entity.getMorenDanwei());
+            vo.setLijing(entity.getLijing());
+            vo.setBiaozhunGuiding(entity.getBiaozhunGuiding());
+            result.add(vo);
+        }
+        return result;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    @AuditLog(action = "DELETE", label = "鍒犻櫎鐜鐩戞祴璁″垝鐪嬫澘瀛愰」", bizType = "HUANJING_JIANCE",
+            bizCodeExpr = "#result > 0 ? #zixiangId : ''", targetTable = "lims_huanjing_jiance_jilu_zixiang",
+            targetIdExpr = "#zixiangId", diff = true,
+            entityClass = LimsHuanjingJianceJiluZixiangEntity.class)
+    public int deleteKanbanZixiang(String zixiangId) {
+        if (!StringUtils.hasText(zixiangId)) {
+            throw new DataException("璁板綍瀛愰」ID涓嶈兘涓虹┖");
+        }
+
+        LambdaQueryWrapper<LimsHuanjingJianceJiluZixiangEntity> zixiangWrapper = new LambdaQueryWrapper<>();
+        zixiangWrapper.eq(LimsHuanjingJianceJiluZixiangEntity::getId, zixiangId);
+        zixiangWrapper.and(item -> item.isNull(LimsHuanjingJianceJiluZixiangEntity::getDeleteMark)
+                .or().ne(LimsHuanjingJianceJiluZixiangEntity::getDeleteMark, 1));
+        List<LimsHuanjingJianceJiluZixiangEntity> zixiangList = jiluZixiangMapper.selectList(zixiangWrapper);
+        if (zixiangList.isEmpty()) {
+            return 0;
+        }
+
+        LimsHuanjingJianceJiluZixiangEntity target = zixiangList.get(0);
+        LimsHuanjingJianceJiluEntity jilu = findJiluById(target.getForeignId());
+        if (jilu == null) {
+            return 0;
+        }
+        if (!STATUS_ENABLED.equals(jilu.getBizStatus())) {
+            throw new DataException("浠呭凡鍚敤璁板綍鍏佽鍒犻櫎");
+        }
+
+        LambdaUpdateWrapper<LimsHuanjingJianceJiluZixiangEntity> deleteWrapper = new LambdaUpdateWrapper<>();
+        eqNullable(deleteWrapper, LimsHuanjingJianceJiluZixiangEntity::getForeignId, target.getForeignId());
+        eqNullable(deleteWrapper, LimsHuanjingJianceJiluZixiangEntity::getJianceQuyu, target.getJianceQuyu());
+        eqNullable(deleteWrapper, LimsHuanjingJianceJiluZixiangEntity::getWeizhiBianhao, target.getWeizhiBianhao());
+        eqNullable(deleteWrapper, LimsHuanjingJianceJiluZixiangEntity::getJiejingJibie, target.getJiejingJibie());
+        deleteWrapper.and(item -> item.isNull(LimsHuanjingJianceJiluZixiangEntity::getDeleteMark)
+                .or().ne(LimsHuanjingJianceJiluZixiangEntity::getDeleteMark, 1));
+        deleteWrapper.set(LimsHuanjingJianceJiluZixiangEntity::getDeleteMark, 1);
+        int affected = jiluZixiangMapper.update(null, deleteWrapper);
+        if (affected > 0 && !hasActiveJiluZixiang(target.getForeignId())) {
+            disableJilu(target.getForeignId());
+        }
+        return affected;
+    }
+
+    private String getKanbanZixiangGroupKey(LimsHuanjingJianceJiluZixiangEntity zixiang) {
+        return normalizeKeyPart(zixiang.getForeignId()) + "|"
+                + normalizeKeyPart(zixiang.getJianceQuyu()) + "|"
+                + normalizeKeyPart(zixiang.getWeizhiBianhao()) + "|"
+                + normalizeKeyPart(zixiang.getJiejingJibie());
+    }
+
+    private String normalizeKeyPart(String value) {
+        return value == null ? "" : value;
+    }
+
+    private void eqNullable(
+            LambdaUpdateWrapper<LimsHuanjingJianceJiluZixiangEntity> wrapper,
+            SFunction<LimsHuanjingJianceJiluZixiangEntity, ?> column,
+            String value) {
+        if (value == null) {
+            wrapper.isNull(column);
+        } else {
+            wrapper.eq(column, value);
+        }
+    }
+
+    private boolean hasActiveJiluZixiang(String jiluId) {
+        LambdaQueryWrapper<LimsHuanjingJianceJiluZixiangEntity> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(LimsHuanjingJianceJiluZixiangEntity::getForeignId, jiluId);
+        wrapper.and(item -> item.isNull(LimsHuanjingJianceJiluZixiangEntity::getDeleteMark)
+                .or().ne(LimsHuanjingJianceJiluZixiangEntity::getDeleteMark, 1));
+        return jiluZixiangMapper.selectCount(wrapper) > 0;
+    }
+
+    private int disableJilu(String jiluId) {
+        LimsHuanjingJianceJiluEntity update = new LimsHuanjingJianceJiluEntity();
+        update.setBizStatus(STATUS_DISABLED);
+
+        LambdaQueryWrapper<LimsHuanjingJianceJiluEntity> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(LimsHuanjingJianceJiluEntity::getId, jiluId);
+        wrapper.and(item -> item.isNull(LimsHuanjingJianceJiluEntity::getDeleteMark)
+                .or().ne(LimsHuanjingJianceJiluEntity::getDeleteMark, 1));
+        return baseMapper.update(update, wrapper);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    @AuditLog(action = "ENABLE", label = "鍚敤鐜鐩戞祴璁″垝", bizType = "HUANJING_JIANCE",
+            bizCodeExpr = "#result > 0 ? #flowId : ''", targetTable = "lims_huanjing_jiance_jihua",
+            targetIdExpr = "T(jnpf.limsService.support.LimsAuditTargetIds).huanjingJihuaByFlow(#flowId, #taskId)",
+            diff = true,
+            entityClass = LimsHuanjingJianceJihuaEntity.class)
+    public int acceptJianceJihua(String flowId, String taskId) {
+        LimsHuanjingJianceJihuaEntity jihua = getJianceJihua(flowId, taskId);
+        if (jihua == null) {
+            return 0;
+        }
+
+        int updated = updateJianceJihuaStatus(flowId, taskId, STATUS_ENABLED);
+        if (updated <= 0) {
+            return 0;
+        }
+        if (!hasGeneratedJilu(jihua.getId())) {
+            generateJiluAndZixiang(jihua);
+        } else {
+            syncJiancePinciToJilu(jihua);
+            generateJiluZixiangByJihuaId(jihua.getId());
+        }
+        return updated;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    @AuditLog(action = "TERMINATE", label = "缁堟鐜鐩戞祴璁″垝", bizType = "HUANJING_JIANCE",
+            bizCodeExpr = "#result > 0 ? #flowId : ''", targetTable = "lims_huanjing_jiance_jihua",
+            targetIdExpr = "T(jnpf.limsService.support.LimsAuditTargetIds).huanjingJihuaByTerminateFlow(#flowId, #taskId)",
+            diff = true, entityClass = LimsHuanjingJianceJihuaEntity.class)
+    public int terminateJianceJihua(String flowId, String taskId) {
+        LimsHuanjingJianceJihuaZhongzhiEntity zhongzhi = getJihuaZhongzhi(flowId, taskId);
+        if (zhongzhi == null || !StringUtils.hasText(zhongzhi.getJihuaId())) {
+            return 0;
+        }
+
+        LimsHuanjingJianceJihuaEntity jihuaUpdate = new LimsHuanjingJianceJihuaEntity();
+        jihuaUpdate.setZhongzhiYuanyin(zhongzhi.getZhongzhiYuanyin());
+        jihuaUpdate.setZhongzhiRen(zhongzhi.getZhongzhiRen());
+        jihuaUpdate.setZhongzhiRiqi(zhongzhi.getZhongzhiRiqi());
+        jihuaUpdate.setZhongzhiPizhunRen(zhongzhi.getZhongzhiPizhunRen());
+        jihuaUpdate.setZhongzhiPizhunRiqi(zhongzhi.getZhongzhiPizhunRiqi());
+        jihuaUpdate.setBizStatus(STATUS_DISABLED);
+
+        LambdaQueryWrapper<LimsHuanjingJianceJihuaEntity> jihuaWrapper = new LambdaQueryWrapper<>();
+        jihuaWrapper.eq(LimsHuanjingJianceJihuaEntity::getId, zhongzhi.getJihuaId());
+        jihuaWrapper.and(item -> item.isNull(LimsHuanjingJianceJihuaEntity::getDeleteMark)
+                .or().ne(LimsHuanjingJianceJihuaEntity::getDeleteMark, 1));
+        int updated = jihuaMapper.update(jihuaUpdate, jihuaWrapper);
+        if (updated <= 0) {
+            return 0;
+        }
+
+        disableEnabledJilu(zhongzhi.getJihuaId());
+        return updated;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    @AuditLog(action = "SAMPLE", label = "鐜鐩戞祴璁板綍鍙栨牱", bizType = "HUANJING_JIANCE",
+            bizCodeExpr = "#result > 0 ? #jiluId : ''", targetTable = "lims_huanjing_jiance_jilu",
+            targetIdExpr = "#jiluId", diff = true, entityClass = LimsHuanjingJianceJiluEntity.class)
+    public int quyangJilu(String jiluId, String bizSign) {
+        UserInfo userInfo = UserProvider.getUser();
+        if (userInfo == null || !StringUtils.hasText(userInfo.getUserId())) {
+            throw new DataException("褰撳墠鏈櫥褰�");
+        }
+
+        LimsHuanjingJianceJiluEntity jilu = findJiluById(jiluId);
+        if (jilu == null) {
+            return 0;
+        }
+
+        Date quyangRiqi = new Date();
+        LimsHuanjingJianceJiluEntity update = new LimsHuanjingJianceJiluEntity();
+        update.setBizStatus(STATUS_RECEIVED);
+        update.setQuyangRen(userInfo.getUserId());
+        update.setQuyangRiqi(quyangRiqi);
+        update.setQuyangRenSign(bizSign);
+
+        LambdaQueryWrapper<LimsHuanjingJianceJiluEntity> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(LimsHuanjingJianceJiluEntity::getId, jiluId);
+        wrapper.and(item -> item.isNull(LimsHuanjingJianceJiluEntity::getDeleteMark)
+                .or().ne(LimsHuanjingJianceJiluEntity::getDeleteMark, 1));
+        int updated = baseMapper.update(update, wrapper);
+        if (updated > 0) {
+            updateJiluZixiangQuyangInfo(jiluId, userInfo.getUserId(), quyangRiqi);
+        }
+        return updated;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    @AuditLog(action = "SAMPLE_TERMINATE", label = "鐜鐩戞祴璁板綍缁堟鍙栨牱", bizType = "HUANJING_JIANCE",
+            bizCodeExpr = "#result > 0 ? #jiluId : ''", targetTable = "lims_huanjing_jiance_jilu",
+            targetIdExpr = "#jiluId", diff = true, entityClass = LimsHuanjingJianceJiluEntity.class)
+    public int terminateQuyangJilu(String jiluId, String bizSign) {
+        UserInfo userInfo = UserProvider.getUser();
+        if (userInfo == null || !StringUtils.hasText(userInfo.getUserId())) {
+            throw new DataException("褰撳墠鏈櫥褰�");
+        }
+
+        LimsHuanjingJianceJiluEntity update = new LimsHuanjingJianceJiluEntity();
+        update.setBizStatus(STATUS_DISABLED);
+        update.setZhongzhiQuyangRen(userInfo.getUserId());
+        update.setZhongzhiQuyangRiqi(new Date());
+        update.setZhongzhiQuyangRenSign(bizSign);
+
+        LambdaQueryWrapper<LimsHuanjingJianceJiluEntity> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(LimsHuanjingJianceJiluEntity::getId, jiluId);
+        wrapper.and(item -> item.isNull(LimsHuanjingJianceJiluEntity::getDeleteMark)
+                .or().ne(LimsHuanjingJianceJiluEntity::getDeleteMark, 1));
+        return baseMapper.update(update, wrapper);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    @AuditLog(action = "REPORT_ACTION", label = "鐜鐩戞祴鎶ュ憡鎿嶄綔", bizType = "HUANJING_JIANCE",
+            bizCodeExpr = "#result > 0 ? #flowId : ''", targetTable = "lims_huanjing_jiance_baogao",
+            targetIdExpr = "T(jnpf.limsService.support.LimsAuditTargetIds).huanjingBaogaoByFlow(#flowId, #taskId)",
+            extraExpr = "{'action': #action}", diff = true,
+            entityClass = LimsHuanjingJianceBaogaoEntity.class)
+    public int baogaoAction(String flowId, String taskId, String action) {
+        LimsHuanjingJianceBaogaoEntity baogao = getBaogao(flowId, taskId);
+        if (baogao == null) {
+            return 0;
+        }
+
+        String status;
+        if (ACTION_SUBMIT.equals(action)) {
+            status = STATUS_PENDING_AUDIT;
+        } else if (ACTION_ACCEPT.equals(action)) {
+            status = STATUS_AUDITED;
+        } else if (ACTION_REJECT.equals(action)) {
+            status = STATUS_RECEIVED;
+        } else {
+            throw new DataException("涓嶆敮鎸佺殑鎿嶄綔: " + action);
+        }
+
+        int updated = updateBaogaoStatus(baogao.getId(), status);
+        if (updated <= 0) {
+            return 0;
+        }
+        if (ACTION_SUBMIT.equals(action)) {
+            syncBaogaoZixiangFromBaogao(baogao);
+        }
+        if (updateJiluByBaogaoAction(baogao, action, status) <= 0) {
+            throw new DataException("鐜鐩戞祴璁板綍鏁版嵁涓嶅瓨鍦�");
+        }
+        return updated;
+    }
+
+    private Map<String, String> getQuyuMap(Set<String> quyuIds) {
+        if (quyuIds == null || quyuIds.isEmpty()) {
+            return Collections.emptyMap();
+        }
+
+        LambdaQueryWrapper<LimsHuanjingQuyuEntity> wrapper = new LambdaQueryWrapper<>();
+        wrapper.select(LimsHuanjingQuyuEntity::getId, LimsHuanjingQuyuEntity::getJianceQuyu);
+        wrapper.in(LimsHuanjingQuyuEntity::getId, quyuIds);
+        wrapper.and(item -> item.isNull(LimsHuanjingQuyuEntity::getDeleteMark)
+                .or().ne(LimsHuanjingQuyuEntity::getDeleteMark, 1));
+
+        Map<String, String> result = new LinkedHashMap<>();
+        for (LimsHuanjingQuyuEntity entity : quyuMapper.selectList(wrapper)) {
+            result.put(entity.getId(), entity.getJianceQuyu());
+        }
+        return result;
+    }
+
+    private LimsHuanjingJianceJihuaEntity getJianceJihua(String flowId, String taskId) {
+        LambdaQueryWrapper<LimsHuanjingJianceJihuaEntity> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(LimsHuanjingJianceJihuaEntity::getFlowId, flowId);
+        wrapper.eq(LimsHuanjingJianceJihuaEntity::getFlowTaskId, taskId);
+        wrapper.and(item -> item.isNull(LimsHuanjingJianceJihuaEntity::getDeleteMark)
+                .or().ne(LimsHuanjingJianceJihuaEntity::getDeleteMark, 1));
+        wrapper.orderByDesc(LimsHuanjingJianceJihuaEntity::getId);
+        List<LimsHuanjingJianceJihuaEntity> list = jihuaMapper.selectList(wrapper);
+        return list.isEmpty() ? null : list.get(0);
+    }
+
+    private LimsHuanjingJianceBaogaoEntity getBaogao(String flowId, String taskId) {
+        LambdaQueryWrapper<LimsHuanjingJianceBaogaoEntity> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(LimsHuanjingJianceBaogaoEntity::getFlowId, flowId);
+        wrapper.eq(LimsHuanjingJianceBaogaoEntity::getFlowTaskId, taskId);
+        wrapper.and(item -> item.isNull(LimsHuanjingJianceBaogaoEntity::getDeleteMark)
+                .or().ne(LimsHuanjingJianceBaogaoEntity::getDeleteMark, 1));
+        wrapper.orderByDesc(LimsHuanjingJianceBaogaoEntity::getId);
+        List<LimsHuanjingJianceBaogaoEntity> list = baogaoMapper.selectList(wrapper);
+        return list.isEmpty() ? null : list.get(0);
+    }
+
+    private int updateBaogaoStatus(String baogaoId, String status) {
+        LimsHuanjingJianceBaogaoEntity update = new LimsHuanjingJianceBaogaoEntity();
+        update.setBizStatus(status);
+
+        LambdaQueryWrapper<LimsHuanjingJianceBaogaoEntity> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(LimsHuanjingJianceBaogaoEntity::getId, baogaoId);
+        wrapper.and(item -> item.isNull(LimsHuanjingJianceBaogaoEntity::getDeleteMark)
+                .or().ne(LimsHuanjingJianceBaogaoEntity::getDeleteMark, 1));
+        return baogaoMapper.update(update, wrapper);
+    }
+
+    private int syncBaogaoZixiangFromBaogao(LimsHuanjingJianceBaogaoEntity baogao) {
+        if (baogao == null || !StringUtils.hasText(baogao.getId())) {
+            return 0;
+        }
+        LambdaUpdateWrapper<LimsHuanjingJianceBaogaoZixiangEntity> wrapper = new LambdaUpdateWrapper<>();
+        wrapper.eq(LimsHuanjingJianceBaogaoZixiangEntity::getForeignId, baogao.getId());
+        wrapper.and(item -> item.isNull(LimsHuanjingJianceBaogaoZixiangEntity::getDeleteMark)
+                .or().ne(LimsHuanjingJianceBaogaoZixiangEntity::getDeleteMark, 1));
+        wrapper.set(LimsHuanjingJianceBaogaoZixiangEntity::getJianceQuyu, baogao.getJianceQuyu());
+        wrapper.set(LimsHuanjingJianceBaogaoZixiangEntity::getJianceXiangmu, baogao.getJianceXiangmu());
+        return baogaoZixiangMapper.update(null, wrapper);
+    }
+
+    private int updateJiluByBaogaoAction(LimsHuanjingJianceBaogaoEntity baogao, String action, String status) {
+        if (baogao == null || !StringUtils.hasText(baogao.getJiluId())) {
+            return 0;
+        }
+
+        LambdaUpdateWrapper<LimsHuanjingJianceJiluEntity> wrapper = new LambdaUpdateWrapper<>();
+        wrapper.eq(LimsHuanjingJianceJiluEntity::getId, baogao.getJiluId());
+        wrapper.and(item -> item.isNull(LimsHuanjingJianceJiluEntity::getDeleteMark)
+                .or().ne(LimsHuanjingJianceJiluEntity::getDeleteMark, 1));
+        wrapper.set(LimsHuanjingJianceJiluEntity::getBizStatus, status);
+
+        if (ACTION_SUBMIT.equals(action)) {
+            wrapper.set(LimsHuanjingJianceJiluEntity::getBaogaoId, baogao.getId());
+            wrapper.set(LimsHuanjingJianceJiluEntity::getJianceRen, baogao.getJianceRen());
+            wrapper.set(LimsHuanjingJianceJiluEntity::getJianceRiqi, baogao.getJianceRiqi());
+            wrapper.set(LimsHuanjingJianceJiluEntity::getBiaozhunGuiding, baogao.getBiaozhunGuiding());
+        } else if (ACTION_ACCEPT.equals(action)) {
+            wrapper.set(LimsHuanjingJianceJiluEntity::getFuheRen, baogao.getFuheRen());
+            wrapper.set(LimsHuanjingJianceJiluEntity::getFuheRiqi, baogao.getFuheRiqi());
+        }
+
+        return baseMapper.update(null, wrapper);
+    }
+
+    @Override
+    public LimsHuanjingJianceJiluEntity findJiluById(String jiluId) {
+        if (!StringUtils.hasText(jiluId)) {
+            return null;
+        }
+        LambdaQueryWrapper<LimsHuanjingJianceJiluEntity> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(LimsHuanjingJianceJiluEntity::getId, jiluId);
+        wrapper.and(item -> item.isNull(LimsHuanjingJianceJiluEntity::getDeleteMark)
+                .or().ne(LimsHuanjingJianceJiluEntity::getDeleteMark, 1));
+        List<LimsHuanjingJianceJiluEntity> list = baseMapper.selectList(wrapper);
+        return list.isEmpty() ? null : list.get(0);
+    }
+
+    private void generateJiluZixiang(LimsHuanjingJianceJiluEntity jilu) {
+        if (jilu == null || !StringUtils.hasText(jilu.getId())
+                || !StringUtils.hasText(jilu.getJihuaId())
+                || !StringUtils.hasText(jilu.getJianceXiangmu())) {
+            return;
+        }
+        if (hasJiluZixiang(jilu.getId())) {
+            return;
+        }
+
+        LimsHuanjingJianceJihuaEntity jihua = getJianceJihuaById(jilu.getJihuaId());
+        if (jihua == null) {
+            return;
+        }
+
+        List<LimsHuanjingJianceJihuaZixiangEntity> jihuaZixiangList =
+                listMatchedJihuaZixiang(jilu.getJihuaId(), jilu.getJianceXiangmu());
+        if (jihuaZixiangList.isEmpty()) {
+            return;
+        }
+
+        Map<String, List<LimsHuanjingCaiyangdianZixiangEntity>> quyangdianMap =
+                listQuyangdianMap(jihuaZixiangList);
+        if (quyangdianMap.isEmpty()) {
+            return;
+        }
+
+        List<LimsHuanjingJianceJiluZixiangEntity> insertList = new ArrayList<>();
+        for (LimsHuanjingJianceJihuaZixiangEntity jihuaZixiang : jihuaZixiangList) {
+            List<LimsHuanjingCaiyangdianZixiangEntity> quyangdianList =
+                    quyangdianMap.get(jihuaZixiang.getCaiyangdianId());
+            if (quyangdianList == null || quyangdianList.isEmpty()) {
+                continue;
+            }
+            for (LimsHuanjingCaiyangdianZixiangEntity quyangdian : quyangdianList) {
+                insertList.add(buildJiluZixiang(jilu, jihua, jihuaZixiang, quyangdian));
+            }
+        }
+
+        for (LimsHuanjingJianceJiluZixiangEntity entity : insertList) {
+            jiluZixiangMapper.insert(entity);
+        }
+    }
+
+    private void updateJiluZixiangQuyangInfo(String jiluId, String quyangRen, Date quyangRiqi) {
+        LambdaUpdateWrapper<LimsHuanjingJianceJiluZixiangEntity> wrapper = new LambdaUpdateWrapper<>();
+        wrapper.eq(LimsHuanjingJianceJiluZixiangEntity::getForeignId, jiluId);
+        wrapper.and(item -> item.isNull(LimsHuanjingJianceJiluZixiangEntity::getDeleteMark)
+                .or().ne(LimsHuanjingJianceJiluZixiangEntity::getDeleteMark, 1));
+        wrapper.set(LimsHuanjingJianceJiluZixiangEntity::getQuyangRen, quyangRen);
+        wrapper.set(LimsHuanjingJianceJiluZixiangEntity::getQuyangRiqi, quyangRiqi);
+        jiluZixiangMapper.update(null, wrapper);
+    }
+
+    private boolean hasJiluZixiang(String jiluId) {
+        LambdaQueryWrapper<LimsHuanjingJianceJiluZixiangEntity> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(LimsHuanjingJianceJiluZixiangEntity::getForeignId, jiluId);
+        wrapper.and(item -> item.isNull(LimsHuanjingJianceJiluZixiangEntity::getDeleteMark)
+                .or().ne(LimsHuanjingJianceJiluZixiangEntity::getDeleteMark, 1));
+        return jiluZixiangMapper.selectCount(wrapper) > 0;
+    }
+
+    private LimsHuanjingJianceJihuaEntity getJianceJihuaById(String jihuaId) {
+        LambdaQueryWrapper<LimsHuanjingJianceJihuaEntity> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(LimsHuanjingJianceJihuaEntity::getId, jihuaId);
+        wrapper.and(item -> item.isNull(LimsHuanjingJianceJihuaEntity::getDeleteMark)
+                .or().ne(LimsHuanjingJianceJihuaEntity::getDeleteMark, 1));
+        List<LimsHuanjingJianceJihuaEntity> list = jihuaMapper.selectList(wrapper);
+        return list.isEmpty() ? null : list.get(0);
+    }
+
+    private List<LimsHuanjingJianceJihuaZixiangEntity> listMatchedJihuaZixiang(String jihuaId, String jianceXiangmu) {
+        String targetJianceXiangmu = jianceXiangmu.trim();
+        LambdaQueryWrapper<LimsHuanjingJianceJihuaZixiangEntity> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(LimsHuanjingJianceJihuaZixiangEntity::getForeignId, jihuaId);
+        wrapper.and(item -> item.isNull(LimsHuanjingJianceJihuaZixiangEntity::getDeleteMark)
+                .or().ne(LimsHuanjingJianceJihuaZixiangEntity::getDeleteMark, 1));
+        wrapper.orderByAsc(LimsHuanjingJianceJihuaZixiangEntity::getId);
+
+        List<LimsHuanjingJianceJihuaZixiangEntity> result = new ArrayList<>();
+        for (LimsHuanjingJianceJihuaZixiangEntity zixiang : jihuaZixiangMapper.selectList(wrapper)) {
+            if (parseJianceXiangmu(zixiang.getJianceXiangmu()).contains(targetJianceXiangmu)
+                    && StringUtils.hasText(zixiang.getCaiyangdianId())) {
+                result.add(zixiang);
+            }
+        }
+        return result;
+    }
+
+    private Map<String, List<LimsHuanjingCaiyangdianZixiangEntity>> listQuyangdianMap(
+            List<LimsHuanjingJianceJihuaZixiangEntity> jihuaZixiangList) {
+        Set<String> caiyangdianIds = new LinkedHashSet<>();
+        for (LimsHuanjingJianceJihuaZixiangEntity zixiang : jihuaZixiangList) {
+            if (StringUtils.hasText(zixiang.getCaiyangdianId())) {
+                caiyangdianIds.add(zixiang.getCaiyangdianId());
+            }
+        }
+        if (caiyangdianIds.isEmpty()) {
+            return Collections.emptyMap();
+        }
+
+        LambdaQueryWrapper<LimsHuanjingCaiyangdianZixiangEntity> wrapper = new LambdaQueryWrapper<>();
+        wrapper.in(LimsHuanjingCaiyangdianZixiangEntity::getForeignId, caiyangdianIds);
+        wrapper.and(item -> item.isNull(LimsHuanjingCaiyangdianZixiangEntity::getDeleteMark)
+                .or().ne(LimsHuanjingCaiyangdianZixiangEntity::getDeleteMark, 1));
+        wrapper.orderByAsc(
+                LimsHuanjingCaiyangdianZixiangEntity::getForeignId,
+                LimsHuanjingCaiyangdianZixiangEntity::getId);
+
+        Map<String, List<LimsHuanjingCaiyangdianZixiangEntity>> result = new LinkedHashMap<>();
+        for (LimsHuanjingCaiyangdianZixiangEntity quyangdian : caiyangdianZixiangMapper.selectList(wrapper)) {
+            if (!StringUtils.hasText(quyangdian.getForeignId())) {
+                continue;
+            }
+            if (!result.containsKey(quyangdian.getForeignId())) {
+                result.put(quyangdian.getForeignId(), new ArrayList<>());
+            }
+            result.get(quyangdian.getForeignId()).add(quyangdian);
+        }
+        return result;
+    }
+
+    private LimsHuanjingJianceJiluZixiangEntity buildJiluZixiang(LimsHuanjingJianceJiluEntity jilu,
+                                                                  LimsHuanjingJianceJihuaEntity jihua,
+                                                                  LimsHuanjingJianceJihuaZixiangEntity jihuaZixiang,
+                                                                  LimsHuanjingCaiyangdianZixiangEntity quyangdian) {
+        LimsHuanjingJianceJiluZixiangEntity entity = new LimsHuanjingJianceJiluZixiangEntity();
+        entity.setId(RandomUtil.uuId());
+        entity.setForeignId(jilu.getId());
+        entity.setTenantId(getTenantId(jilu.getTenantId(), jihua.getTenantId()));
+        entity.setWeizhiBianhao(jihuaZixiang.getWeizhiBianhao());
+        entity.setWeizhiMingcheng(jihuaZixiang.getWeizhiMingcheng());
+        entity.setJianceXiangmu(jilu.getJianceXiangmu());
+        entity.setJiluId(jilu.getId());
+        entity.setQuyangdianId(quyangdian.getId());
+        entity.setQuyangdianMingcheng(quyangdian.getQuyangdianMingcheng());
+        entity.setJianceQuyu(jihua.getJianceQuyu());
+        entity.setJiejingJibie(jihua.getJiejingJibie());
+        entity.setQuyangRen(jilu.getQuyangRen());
+        entity.setQuyangRiqi(jilu.getQuyangRiqi());
+        return entity;
+    }
+
+    private String getTenantId(String first, String second) {
+        if (StringUtils.hasText(first)) {
+            return first;
+        }
+        if (StringUtils.hasText(second)) {
+            return second;
+        }
+        return "0";
+    }
+
+    private int updateJianceJihuaStatus(String flowId, String taskId, String status) {
+        LimsHuanjingJianceJihuaEntity update = new LimsHuanjingJianceJihuaEntity();
+        update.setBizStatus(status);
+
+        LambdaQueryWrapper<LimsHuanjingJianceJihuaEntity> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(LimsHuanjingJianceJihuaEntity::getFlowId, flowId);
+        wrapper.eq(LimsHuanjingJianceJihuaEntity::getFlowTaskId, taskId);
+        wrapper.and(item -> item.isNull(LimsHuanjingJianceJihuaEntity::getDeleteMark)
+                .or().ne(LimsHuanjingJianceJihuaEntity::getDeleteMark, 1));
+        return jihuaMapper.update(update, wrapper);
+    }
+
+    private LimsHuanjingJianceJihuaZhongzhiEntity getJihuaZhongzhi(String flowId, String taskId) {
+        LambdaQueryWrapper<LimsHuanjingJianceJihuaZhongzhiEntity> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(LimsHuanjingJianceJihuaZhongzhiEntity::getFlowId, flowId);
+        wrapper.eq(LimsHuanjingJianceJihuaZhongzhiEntity::getFlowTaskId, taskId);
+        wrapper.and(item -> item.isNull(LimsHuanjingJianceJihuaZhongzhiEntity::getDeleteMark)
+                .or().ne(LimsHuanjingJianceJihuaZhongzhiEntity::getDeleteMark, 1));
+        wrapper.orderByDesc(LimsHuanjingJianceJihuaZhongzhiEntity::getId);
+        List<LimsHuanjingJianceJihuaZhongzhiEntity> list = jihuaZhongzhiMapper.selectList(wrapper);
+        return list.isEmpty() ? null : list.get(0);
+    }
+
+    private boolean hasGeneratedJilu(String jihuaId) {
+        if (!StringUtils.hasText(jihuaId)) {
+            return false;
+        }
+        LambdaQueryWrapper<LimsHuanjingJianceJiluEntity> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(LimsHuanjingJianceJiluEntity::getJihuaId, jihuaId);
+        wrapper.and(item -> item.isNull(LimsHuanjingJianceJiluEntity::getDeleteMark)
+                .or().ne(LimsHuanjingJianceJiluEntity::getDeleteMark, 1));
+        return baseMapper.selectCount(wrapper) > 0;
+    }
+
+    private void generateJiluAndZixiang(LimsHuanjingJianceJihuaEntity jihua) {
+        List<String> jianceXiangmuList = getJianceXiangmuUnion(jihua.getId());
+        List<Date> jihuaRiqiList = buildJihuaRiqiList(jihua);
+        if (jianceXiangmuList.isEmpty() || jihuaRiqiList.isEmpty()) {
+            return;
+        }
+
+        List<LimsHuanjingJianceJiluEntity> jiluList = new ArrayList<>();
+        for (String jianceXiangmu : jianceXiangmuList) {
+            for (Date jihuaRiqi : jihuaRiqiList) {
+                jiluList.add(buildJilu(jihua, jianceXiangmu, jihuaRiqi));
+            }
+        }
+        saveBatch(jiluList);
+        for (LimsHuanjingJianceJiluEntity jilu : jiluList) {
+            generateJiluZixiang(jilu);
+        }
+    }
+
+    private void generateJiluZixiangByJihuaId(String jihuaId) {
+        if (!StringUtils.hasText(jihuaId)) {
+            return;
+        }
+
+        LambdaQueryWrapper<LimsHuanjingJianceJiluEntity> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(LimsHuanjingJianceJiluEntity::getJihuaId, jihuaId);
+        wrapper.and(item -> item.isNull(LimsHuanjingJianceJiluEntity::getDeleteMark)
+                .or().ne(LimsHuanjingJianceJiluEntity::getDeleteMark, 1));
+        wrapper.orderByAsc(LimsHuanjingJianceJiluEntity::getId);
+        for (LimsHuanjingJianceJiluEntity jilu : baseMapper.selectList(wrapper)) {
+            generateJiluZixiang(jilu);
+        }
+    }
+
+    private List<String> getJianceXiangmuUnion(String jihuaId) {
+        LambdaQueryWrapper<LimsHuanjingJianceJihuaZixiangEntity> wrapper = new LambdaQueryWrapper<>();
+        wrapper.select(LimsHuanjingJianceJihuaZixiangEntity::getJianceXiangmu);
+        wrapper.eq(LimsHuanjingJianceJihuaZixiangEntity::getForeignId, jihuaId);
+        wrapper.and(item -> item.isNull(LimsHuanjingJianceJihuaZixiangEntity::getDeleteMark)
+                .or().ne(LimsHuanjingJianceJihuaZixiangEntity::getDeleteMark, 1));
+        wrapper.orderByAsc(LimsHuanjingJianceJihuaZixiangEntity::getId);
+
+        Set<String> result = new LinkedHashSet<>();
+        for (LimsHuanjingJianceJihuaZixiangEntity zixiang : jihuaZixiangMapper.selectList(wrapper)) {
+            result.addAll(parseJianceXiangmu(zixiang.getJianceXiangmu()));
+        }
+        return new ArrayList<>(result);
+    }
+
+    private List<String> parseJianceXiangmu(String raw) {
+        if (!StringUtils.hasText(raw)) {
+            return Collections.emptyList();
+        }
+        String value = raw.trim();
+        try {
+            List<String> list = JsonUtil.getJsonToList(value, String.class);
+            if (list == null) {
+                return Collections.emptyList();
+            }
+            return trimNonEmptyItems(list);
+        } catch (Exception ignored) {
+            List<String> items = new ArrayList<>();
+            Collections.addAll(items, value.split(","));
+            return trimNonEmptyItems(items);
+        }
+    }
+
+    private List<String> trimNonEmptyItems(List<String> items) {
+        List<String> result = new ArrayList<>();
+        for (String item : items) {
+            if (StringUtils.hasText(item)) {
+                result.add(item.trim());
+            }
+        }
+        return result;
+    }
+
+    private List<Date> buildJihuaRiqiList(LimsHuanjingJianceJihuaEntity jihua) {
+        Date start = jihua.getJihuaRiqi();
+        if (start == null) {
+            return Collections.emptyList();
+        }
+        if (PLAN_TYPE_TEMPORARY.equals(jihua.getJihuaLeixing())) {
+            return Collections.singletonList(start);
+        }
+        if (!PLAN_TYPE_YEARLY.equals(jihua.getJihuaLeixing())) {
+            return Collections.emptyList();
+        }
+
+        LocalDateTime current = LocalDateTime.ofInstant(start.toInstant(), ZoneId.systemDefault());
+        LocalDateTime endExclusive = current.plusYears(1);
+        List<Date> result = new ArrayList<>();
+        while (current.isBefore(endExclusive)) {
+            result.add(Date.from(current.atZone(ZoneId.systemDefault()).toInstant()));
+            LocalDateTime next = nextJihuaRiqi(current, jihua.getJiancePinci());
+            if (next == null) {
+                return Collections.emptyList();
+            }
+            current = next;
+        }
+        return result;
+    }
+
+    private LocalDateTime nextJihuaRiqi(LocalDateTime current, String jiancePinci) {
+        if ("weekly".equals(jiancePinci)) {
+            return current.plusWeeks(1);
+        }
+        if ("monthly".equals(jiancePinci)) {
+            return current.plusMonths(1);
+        }
+        if ("bimonthly".equals(jiancePinci)) {
+            return current.plusMonths(2);
+        }
+        if ("quarterly".equals(jiancePinci)) {
+            return current.plusMonths(3);
+        }
+        if ("semiannual".equals(jiancePinci)) {
+            return current.plusMonths(6);
+        }
+        if ("annual".equals(jiancePinci)) {
+            return current.plusYears(1);
+        }
+        return null;
+    }
+
+    private LimsHuanjingJianceJiluEntity buildJilu(LimsHuanjingJianceJihuaEntity jihua,
+                                                    String jianceXiangmu,
+                                                    Date jihuaRiqi) {
+        LimsHuanjingJianceJiluEntity jilu = new LimsHuanjingJianceJiluEntity();
+        jilu.setId(RandomUtil.uuId());
+        jilu.setTenantId(StringUtils.hasText(jihua.getTenantId()) ? jihua.getTenantId() : "0");
+        jilu.setJihuaId(jihua.getId());
+        jilu.setJihuaMingcheng(jihua.getJihuaMingcheng());
+        jilu.setJihuaRiqi(jihuaRiqi);
+        jilu.setJihuaLeixing(jihua.getJihuaLeixing());
+        jilu.setJiejingJibie(jihua.getJiejingJibie());
+        jilu.setJianceQuyu(jihua.getJianceQuyu());
+        jilu.setJianceZhuangtai(jihua.getJianceZhuangtai());
+        jilu.setJianceXiangmu(jianceXiangmu);
+        jilu.setJiancePinci(jihua.getJiancePinci());
+        jilu.setBizStatus(STATUS_ENABLED);
+        return jilu;
+    }
+
+    private void syncJiancePinciToJilu(LimsHuanjingJianceJihuaEntity jihua) {
+        if (jihua == null || !StringUtils.hasText(jihua.getId())) {
+            return;
+        }
+
+        LimsHuanjingJianceJiluEntity update = new LimsHuanjingJianceJiluEntity();
+        update.setJiancePinci(jihua.getJiancePinci());
+
+        LambdaQueryWrapper<LimsHuanjingJianceJiluEntity> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(LimsHuanjingJianceJiluEntity::getJihuaId, jihua.getId());
+        wrapper.and(item -> item.isNull(LimsHuanjingJianceJiluEntity::getDeleteMark)
+                .or().ne(LimsHuanjingJianceJiluEntity::getDeleteMark, 1));
+        baseMapper.update(update, wrapper);
+    }
+
+    private void disableEnabledJilu(String jihuaId) {
+        LimsHuanjingJianceJiluEntity update = new LimsHuanjingJianceJiluEntity();
+        update.setBizStatus(STATUS_DISABLED);
+
+        LambdaQueryWrapper<LimsHuanjingJianceJiluEntity> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(LimsHuanjingJianceJiluEntity::getJihuaId, jihuaId);
+        wrapper.eq(LimsHuanjingJianceJiluEntity::getBizStatus, STATUS_ENABLED);
+        wrapper.and(item -> item.isNull(LimsHuanjingJianceJiluEntity::getDeleteMark)
+                .or().ne(LimsHuanjingJianceJiluEntity::getDeleteMark, 1));
+        baseMapper.update(update, wrapper);
+    }
+}

--
Gitblit v1.8.0