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/LimsQingyandanServiceImpl.java | 702 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 702 insertions(+), 0 deletions(-)
diff --git a/jnpf-lims/jnpf-lims-biz/src/main/java/jnpf/limsService/impl/LimsQingyandanServiceImpl.java b/jnpf-lims/jnpf-lims-biz/src/main/java/jnpf/limsService/impl/LimsQingyandanServiceImpl.java
new file mode 100644
index 0000000..beea976
--- /dev/null
+++ b/jnpf-lims/jnpf-lims-biz/src/main/java/jnpf/limsService/impl/LimsQingyandanServiceImpl.java
@@ -0,0 +1,702 @@
+package jnpf.limsService.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import jnpf.audit.sdk.annotation.AuditLog;
+import jnpf.base.ActionResult;
+import jnpf.base.BillRuleApi;
+import jnpf.base.UserInfo;
+import jnpf.base.service.SuperServiceImpl;
+import jnpf.exception.DataException;
+import jnpf.limsEntity.*;
+import jnpf.limsMapper.LimsQingyandanMapper;
+import jnpf.limsService.*;
+import jnpf.util.JsonUtil;
+import jnpf.util.RandomUtil;
+import jnpf.util.StringUtil;
+import jnpf.util.UserProvider;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.math.BigDecimal;
+import java.util.*;
+import java.util.stream.Collectors;
+
+@Service
+public class LimsQingyandanServiceImpl extends SuperServiceImpl<LimsQingyandanMapper, LimsQingyandanEntity>
+ implements LimsQingyandanService {
+
+ /**
+ * 鐣欐牱鎺ユ敹缂栧彿瑙勫垯 enCode
+ */
+ private static final String LIUYANG_JIESHOU_BIANHAO_RULE = "liuyangJieshouBianhaoGuize";
+ private static final String JIANYAN_LIUSHUIHAO_RULE = "jianyan_liushuihao";
+
+ @Autowired
+ private BillRuleApi billRuleApi;
+
+ @Autowired
+ private ZhiliangBiaozhunGuanliService zhiliangBiaozhunGuanliService;
+
+ @Autowired
+ private ZhiliangBiaozhunGuanliZixiangService zhiliangBiaozhunGuanliZixiangService;
+
+ @Autowired
+ private LimsJianyanXiangService limsJianyanXiangService;
+
+ @Autowired
+ private LimsLiuyangJiluService limsLiuyangJiluService;
+
+ @Autowired
+ private LimsSxtRenwuQingyandanZhuangtaiTongbuService renwuQingyandanZhuangtaiTongbuService;
+
+ @Autowired
+ private LimsOperationalMessagePublisher operationalMessagePublisher;
+
+ @Override
+ public LimsQingyandanEntity findByFormData(LimsQingyandanEntity formData) {
+ if (formData.getId() != null && !formData.getId().isEmpty()) {
+ return this.getById(formData.getId());
+ }
+ // JNPF 鍦ㄧ嚎琛ㄥ崟淇濆瓨鍚庝笉杩斿洖璁板綍ID锛岄�氳繃涓氬姟瀛楁鍖归厤
+ QueryWrapper<LimsQingyandanEntity> wrapper = new QueryWrapper<>();
+ wrapper.eq("chanpin_id", formData.getChanpinId());
+ if (formData.getPihao() != null) {
+ wrapper.eq("pihao", formData.getPihao());
+ }
+ wrapper.orderByDesc("f_id");
+ wrapper.last("LIMIT 1");
+ return this.getOne(wrapper);
+ }
+
+ @Override
+ public LimsQingyandanEntity findByLiushuihao(String liushuihao) {
+ QueryWrapper<LimsQingyandanEntity> wrapper = new QueryWrapper<>();
+ wrapper.eq("jianyan_liushuihao", liushuihao);
+ return this.getOne(wrapper);
+ }
+
+ @Override
+ @AuditLog(
+ action = "SUBMIT", label = "璇烽獙鍗� 鎻愪氦", bizType = "QINGYANDAN",
+ bizCodeExpr = "#qingyandan.jianyanLiushuihao",
+ targetTable = "lims_qingyandan", targetIdExpr = "#qingyandan.id",
+ diff = true, entityClass = LimsQingyandanEntity.class
+ )
+ @Transactional(rollbackFor = Exception.class)
+ public void submit(LimsQingyandanEntity qingyandan) {
+ String expectedBizStatus = qingyandan.getBizStatus();
+ ZhiliangBiaozhunGuanliEntity standard = findReadyQualityStandardOrThrow(qingyandan);
+ copyStandardLiangFields(qingyandan, standard);
+ qingyandan.setBizStatus(BizStatus.CONFIRMED.getCode());
+ // 璇烽獙鍗曟彁浜ゅ悗杩涘叆鍙栨牱闃舵锛氬彇鏍风姸鎬佸垵濮嬪寲涓哄緟鍙栨牱
+ qingyandan.setQuyangStatus(BizStatus.PENDING_FETCH.getCode());
+ backfillCreatorTimeIfMissing(qingyandan);
+ UpdateWrapper<LimsQingyandanEntity> submitUpdate = activeRowUpdate(qingyandan.getId());
+ submitUpdate.eq("biz_status", expectedBizStatus);
+ if (!this.update(qingyandan, submitUpdate)) {
+ throw new DataException("璇烽獙鍗曠姸鎬佸凡鍙樻洿锛屾彁浜ゆ湭鐢熸晥");
+ }
+ createJianyanXiang(qingyandan, standard);
+ tongbuRenwuQingyandanZhuangtai(qingyandan);
+ }
+
+ @Override
+ public void wendingxingSubmit(LimsQingyandanEntity qingyandan) {
+ ZhiliangBiaozhunGuanliEntity standard = findReadyQualityStandardOrThrow(qingyandan);
+ createJianyanXiang(qingyandan, standard);
+ }
+
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public LimsQingyandanEntity sxtAutoSubmit(LimsQingyandanEntity qingyandan) {
+ ZhiliangBiaozhunGuanliEntity standard = findReadyQualityStandardOrThrow(qingyandan);
+ String plannedJianyanLiang = qingyandan.getJianyanLiang();
+ String plannedQuyangDanwei = qingyandan.getQuyangDanwei();
+
+ copyStandardLiangFields(qingyandan, standard);
+ if (StringUtil.isNotEmpty(plannedJianyanLiang)) {
+ qingyandan.setJianyanLiang(plannedJianyanLiang);
+ }
+ if (StringUtil.isNotEmpty(plannedQuyangDanwei)) {
+ qingyandan.setQuyangDanwei(plannedQuyangDanwei);
+ }
+ qingyandan.setBizStatus(BizStatus.CONFIRMED.getCode());
+ // 璇烽獙鍗曟彁浜ゅ悗杩涘叆鍙栨牱闃舵锛氬彇鏍风姸鎬佸垵濮嬪寲涓哄緟鍙栨牱
+ qingyandan.setQuyangStatus(BizStatus.PENDING_FETCH.getCode());
+ qingyandan.setJianyanLiushuihao(nextJianyanBianhao());
+ backfillCreatorTimeIfMissing(qingyandan);
+ this.saveOrUpdate(qingyandan);
+ createJianyanXiang(qingyandan, standard);
+ tongbuRenwuQingyandanZhuangtai(qingyandan);
+ return qingyandan;
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public LimsQingyandanEntity sxtRenwuKuaizhaoAutoSubmit(
+ LimsQingyandanEntity qingyandan,
+ List<LimsSxtQuyangJihuaRenwuJianyanXiangKuaizhaoEntity> jianyanKuaizhaoList) {
+ if (jianyanKuaizhaoList == null || jianyanKuaizhaoList.isEmpty()) {
+ throw new DataException("浠诲姟妫�楠岄」蹇収涓嶈兘涓虹┖");
+ }
+ if (StringUtil.isEmpty(qingyandan.getLaiyuanRenwuId())) {
+ throw new DataException("璇烽獙鍗曟潵婧愪换鍔′笉鑳戒负绌�");
+ }
+ if (StringUtil.isEmpty(qingyandan.getId())) {
+ qingyandan.setId(RandomUtil.uuId());
+ }
+ qingyandan.setBizStatus(BizStatus.CONFIRMED.getCode());
+ qingyandan.setQuyangStatus(BizStatus.PENDING_FETCH.getCode());
+ qingyandan.setJianyanLiushuihao(nextJianyanBianhao());
+ backfillCreatorTimeIfMissing(qingyandan);
+ this.save(qingyandan);
+
+ List<LimsJianyanXiangEntity> records = new ArrayList<>(jianyanKuaizhaoList.size());
+ for (LimsSxtQuyangJihuaRenwuJianyanXiangKuaizhaoEntity kuaizhao : jianyanKuaizhaoList) {
+ records.add(buildXiangFromRenwuKuaizhao(qingyandan, kuaizhao));
+ }
+ limsJianyanXiangService.saveBatch(records);
+ return qingyandan;
+ }
+
+ @Override
+ @AuditLog(
+ action = "UPDATE", label = "璇烽獙鍗� 缂栬緫", bizType = "QINGYANDAN",
+ bizCodeExpr = "#qingyandan.jianyanLiushuihao",
+ targetTable = "lims_qingyandan", targetIdExpr = "#qingyandan.id",
+ diff = true, entityClass = LimsQingyandanEntity.class
+ )
+ @Transactional(rollbackFor = Exception.class)
+ public void edit(LimsQingyandanEntity qingyandan, LimsQingyandanEntity formData) {
+ String expectedBizStatus = qingyandan.getBizStatus();
+ String originalId = qingyandan.getId();
+ // 鎺掗櫎鍚庣绠$悊鐨勭姸鎬佸瓧娈碉細鍓嶇 formData 涓嶅甫杩欎簺瀛楁锛孊eanUtils 浼氱敤 null 瑕嗙洊銆�
+ // 灏ゅ叾 quyangStatus 鍔犱簡 updateStrategy=ALWAYS锛岃瑕嗙洊鎴� null 浼氭挒 NOT NULL 绾︽潫銆�
+ BeanUtils.copyProperties(formData, qingyandan,
+ "id", "tenantId", "bizStatus", "quyangStatus", "jieyangStatus",
+ "laiyuanRenwuId", "renwuKuaizhaoHaxi",
+ "deleteMark", "deleteTime",
+ "deleteUserId", "flowId", "version", "flowTaskId", "flowState",
+ "jianyanLiushuihao", "creatorUserId", "creatorTime",
+ "lastModifyUserId", "lastModifyTime");
+ qingyandan.setId(originalId);
+
+ ZhiliangBiaozhunGuanliEntity standard = findReadyQualityStandardOrThrow(qingyandan);
+ copyStandardLiangFields(qingyandan, standard);
+
+ qingyandan.setBizStatus(BizStatus.CONFIRMED.getCode());
+ // 閫�鍥炲悗淇閲嶆柊鎻愪氦锛氬彇鏍风姸鎬侀噸鏂板洖鍒板緟鍙栨牱锛堜笌 submit 涓�鑷达級
+ qingyandan.setQuyangStatus(BizStatus.PENDING_FETCH.getCode());
+ backfillCreatorTimeIfMissing(qingyandan);
+ UpdateWrapper<LimsQingyandanEntity> editUpdate = activeRowUpdate(qingyandan.getId());
+ editUpdate.eq("biz_status", expectedBizStatus);
+ if (!this.update(qingyandan, editUpdate)) {
+ throw new DataException("璇烽獙鍗曠姸鎬佸凡鍙樻洿锛岄噸鏂版彁浜ゆ湭鐢熸晥");
+ }
+
+ // 缂栬緫鍚庨噸鏂版彁浜わ細閲嶅缓妫�楠岄」锛堝厛杞垹鏃х殑锛岄伩鍏嶉噸澶嶏級
+ softDeleteJianyanXiangRecords(qingyandan.getId());
+ createJianyanXiang(qingyandan, standard);
+ tongbuRenwuQingyandanZhuangtai(qingyandan);
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ @AuditLog(
+ action = "FETCH",
+ label = "鍙栨牱",
+ bizType = "QUYANG",
+ bizCodeExpr = "#qingyandan.jianyanLiushuihao",
+ targetTable = "lims_qingyandan",
+ targetIdExpr = "#qingyandan.id",
+ diff = true,
+ entityClass = LimsQingyandanEntity.class
+ )
+ public void fetch(LimsQingyandanEntity qingyandan, LimsQingyandanEntity formData) {
+ String expectedQuyangStatus = qingyandan.getQuyangStatus();
+ // 鍙啓鍙栨牱闃舵褰曞叆瀛楁锛屼笉鐢� BeanUtils 鍏ㄩ噺澶嶅埗锛岄伩鍏嶈鐩� submit 鏃朵粠璐ㄩ噺鏍囧噯
+ // 澶嶅埗鐨勯噺/鍗曚綅瀛楁锛坖ianyan_liang / quyang_danwei / jiance_liuyang_liang /
+ // liuyang_liang / liuyang_danwei / shifou_shixiaoxing_yaoqiu锛夈��
+ qingyandan.setJianyanLiangShiji(formData.getJianyanLiangShiji());
+ qingyandan.setJianceLiuyangLiangShiji(formData.getJianceLiuyangLiangShiji());
+ qingyandan.setLiuyangLiangShiji(formData.getLiuyangLiangShiji());
+ qingyandan.setQuyangren(formData.getQuyangren());
+ qingyandan.setQuyangRiqi(formData.getQuyangRiqi());
+ qingyandan.setQuyangDidian(formData.getQuyangDidian());
+ qingyandan.setQuyangBeizhu(formData.getQuyangBeizhu());
+ qingyandan.setBizSign(formData.getBizSign());
+
+ // 鍙栨牱瀹屾垚锛氬彇鏍风姸鎬� 鈫� 宸插彇鏍凤紝鎺ユ牱鐘舵�� 鈫� 寰呮帴鏍凤紱biz_status 涓荤姸鎬佷繚鎸佷笉鍙�
+ qingyandan.setQuyangStatus(BizStatus.FETCHED.getCode());
+ qingyandan.setJieyangStatus(BizStatus.PENDING_RECEIVE.getCode());
+ LimsLiuyangJiluEntity liuyangJilu = null;
+ if (isPositiveNumber(qingyandan.getLiuyangLiangShiji())) {
+ liuyangJilu = buildLiuyangJiluFromQingyandan(qingyandan);
+ limsLiuyangJiluService.save(liuyangJilu);
+ qingyandan.setLiuyangJiluId(liuyangJilu.getId());
+ }
+ UpdateWrapper<LimsQingyandanEntity> fetchUpdate = activeRowUpdate(qingyandan.getId());
+ fetchUpdate.eq("quyang_status", expectedQuyangStatus);
+ if (!this.update(qingyandan, fetchUpdate)) {
+ throw new DataException("璇烽獙鍗曠姸鎬佸凡鍙樻洿锛屽彇鏍锋湭鐢熸晥");
+ }
+ tongbuRenwuQingyandanZhuangtai(qingyandan);
+ if (liuyangJilu != null) {
+ operationalMessagePublisher.retainSamplePendingReceive(
+ liuyangJilu, qingyandan, UserProvider.getUser());
+ }
+ }
+
+ private boolean isPositiveNumber(String value) {
+ if (value == null || value.trim().isEmpty()) {
+ return false;
+ }
+ try {
+ return new BigDecimal(value.trim()).compareTo(BigDecimal.ZERO) > 0;
+ } catch (NumberFormatException e) {
+ return false;
+ }
+ }
+
+ private LimsLiuyangJiluEntity buildLiuyangJiluFromQingyandan(LimsQingyandanEntity qingyandan) {
+ LimsLiuyangJiluEntity record = new LimsLiuyangJiluEntity();
+ record.setId(RandomUtil.uuId());
+ record.setJieshouBianhao(nextLiuyangJieshouBianhao());
+ record.setYangpinMingcheng(qingyandan.getChanpinMingcheng());
+ record.setYangpinBianma(qingyandan.getChanpinBianma());
+ record.setQingyandanId(qingyandan.getId());
+ record.setBizType(qingyandan.getBizType());
+ record.setGuige(qingyandan.getGuige());
+ record.setBaozhuangGuige(qingyandan.getBaozhuangGuige());
+ record.setPihao(qingyandan.getPihao());
+ record.setLaiyuanBianma(qingyandan.getLaiyuanBianma());
+ record.setShengchanRiqi(qingyandan.getShengchanRiqi());
+ record.setYouxiaoqi(qingyandan.getYouxiaoqi());
+ record.setChucunTiaojian(qingyandan.getChucunTiaojian());
+ record.setSongjianRen(qingyandan.getQingyanRen());
+ record.setSongjianRiqi(qingyandan.getQingyanRiqi());
+ record.setBizSign(qingyandan.getBizSign());
+ record.setBizStatus(LiuyangStatus.PENDING_RECEIVE.getCode());
+ record.setLiuyangLiangShiji(qingyandan.getLiuyangLiangShiji());
+ record.setLiuyangDanwei(qingyandan.getLiuyangDanwei());
+ return record;
+ }
+
+ /**
+ * 鐣欐牱鎺ユ敹缂栧彿鍙栧彿澶辫触鏃剁珛鍗充腑鏂紝閬垮厤鐢熸垚绌虹紪鍙风殑鐣欐牱璁板綍銆�
+ */
+ private String nextLiuyangJieshouBianhao() throws DataException {
+ ActionResult<String> result = billRuleApi.getBillNumber(LIUYANG_JIESHOU_BIANHAO_RULE);
+ String bianhao = result == null ? null : result.getData();
+ if (StringUtil.isEmpty(bianhao)) {
+ throw new DataException("鐣欐牱鎺ユ敹缂栧彿鍙栧彿澶辫触锛氬崟鎹鍒橻" + LIUYANG_JIESHOU_BIANHAO_RULE + "]涓嶅彲鐢紝璇风‘璁よ鍒欏凡閰嶇疆涓旂郴缁熸湇鍔″湪绾�");
+ }
+ return bianhao;
+ }
+
+ /**
+ * 鐢熸垚鏂扮殑妫�楠屾祦姘村彿
+ */
+ private String nextJianyanBianhao() throws DataException {
+ ActionResult<String> result = billRuleApi.getBillNumber(JIANYAN_LIUSHUIHAO_RULE);
+ String bianhao = result == null ? null : result.getData();
+ if (StringUtil.isEmpty(bianhao)) {
+ throw new DataException("妫�楠屾祦姘村彿鍙栧彿澶辫触锛氬崟鎹鍒橻" + JIANYAN_LIUSHUIHAO_RULE + "]涓嶅彲鐢紝璇风‘璁よ鍒欏凡閰嶇疆涓旂郴缁熸湇鍔″湪绾�");
+ }
+ return bianhao;
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ @AuditLog(
+ action = "RECEIVE",
+ label = "鎺ユ牱",
+ bizType = "JIEYANG",
+ bizCodeExpr = "#qingyandan.jianyanLiushuihao",
+ targetTable = "lims_qingyandan",
+ targetIdExpr = "#qingyandan.id",
+ diff = true,
+ entityClass = LimsQingyandanEntity.class
+ )
+ public void jieyangReceive(LimsQingyandanEntity qingyandan, LimsQingyandanEntity formData) {
+ String expectedJieyangStatus = qingyandan.getJieyangStatus();
+ // 鍙啓鎺ユ牱闃舵褰曞叆瀛楁锛涙楠岄」 submit 鏃跺凡鍒涘缓锛坈reated + wei_fenjian锛夛紝
+ // 鏈涓嶅垱寤恒�佷笉鎺ㄨ繘妫�楠岄」鐘舵�侊紙鐢卞悗缁崟鐙殑"鍒嗘"鍔ㄤ綔澶勭悊锛夈��
+ qingyandan.setJieshouren(formData.getJieshouren());
+ qingyandan.setJieshouRiqi(formData.getJieshouRiqi());
+ qingyandan.setJieshouShuliang(formData.getJieshouShuliang());
+ qingyandan.setJieshouShuliangDanwei(formData.getJieshouShuliangDanwei());
+ qingyandan.setCunfangWeizhi(formData.getCunfangWeizhi());
+ qingyandan.setShixiaoxingJianceyuan(formData.getShixiaoxingJianceyuan());
+ qingyandan.setJieyangBeizhu(formData.getJieyangBeizhu());
+ qingyandan.setBizSign(formData.getBizSign());
+
+ // 鎺ユ牱瀹屾垚
+ qingyandan.setJieyangStatus(BizStatus.RECEIVED.getCode());
+ UpdateWrapper<LimsQingyandanEntity> receiveUpdate = activeRowUpdate(qingyandan.getId());
+ receiveUpdate.eq("jieyang_status", expectedJieyangStatus);
+ if (!this.update(qingyandan, receiveUpdate)) {
+ throw new DataException("璇烽獙鍗曠姸鎬佸凡鍙樻洿锛屾帴鏍锋湭鐢熸晥");
+ }
+ tongbuRenwuQingyandanZhuangtai(qingyandan);
+ }
+
+ private UpdateWrapper<LimsQingyandanEntity> activeRowUpdate(String id) {
+ UpdateWrapper<LimsQingyandanEntity> update = new UpdateWrapper<>();
+ update.eq("f_id", id);
+ update.and(w -> w.isNull("f_delete_mark").or().ne("f_delete_mark", 1));
+ return update;
+ }
+
+ /**
+ * 璇烽獙鍗曞垱寤� / 缂栬緫鎻愪氦鏃讹紝浠庤川閲忔爣鍑嗕富琛ㄥ鍒堕噺涓庡崟浣嶉厤缃埌璇烽獙鍗曟湰琛岋細
+ * 鍙栨牱鍗曚綅銆佹楠岄噺锛堚啇 jiance_liang锛夈�佹娴嬬暀鏍烽噺銆佺暀鏍烽噺銆佺暀鏍峰崟浣嶏紙鈫� liuyang_kaocha_danwei锛夈��
+ * 瀵瑰簲鐨� _shiji 瀹為檯鍊煎瓧娈电暀绌猴紝鐢卞悗缁彇鏍� / 鎺ユ牱闃舵褰曞叆銆�
+ */
+ private void copyStandardLiangFields(LimsQingyandanEntity qingyandan, ZhiliangBiaozhunGuanliEntity standard) {
+ qingyandan.setQuyangDanwei(standard.getQuyangDanwei());
+ qingyandan.setJianyanLiang(standard.getJianceLiang());
+ qingyandan.setJianceLiuyangLiang(standard.getJianceLiuyangLiang());
+ qingyandan.setLiuyangLiang(standard.getLiuyangLiang());
+ qingyandan.setLiuyangDanwei(standard.getLiuyangKaochaDanwei());
+ qingyandan.setShifouShixiaoxingYaoqiu(standard.getShifouShixiaoxingYaoqiu());
+ }
+
+ /**
+ * lims_qingyandan 鐢� JNPF 鍦ㄧ嚎琛ㄥ崟 INSERT锛岀粫寮� MyBatis-Plus锛�
+ * MetaObjectHandler 鐨� insertFill 涓嶈Е鍙戯紝瀵艰嚧 f_creator_time 姘歌繙涓� null銆�
+ * 鍦ㄦ垜浠笟鍔′唬鐮侀娆℃帴绠¤繖鏉¤褰曟椂锛坰ubmit / edit锛夛紝濡傛灉杩樻病鍊煎氨琛ュ~褰撳墠鏃堕棿銆�
+ */
+ private void backfillCreatorTimeIfMissing(LimsQingyandanEntity qingyandan) {
+ if (qingyandan.getCreatorTime() == null) {
+ qingyandan.setCreatorTime(new Date());
+ }
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ @AuditLog(
+ action = "CANCEL",
+ label = "璇烽獙鍗� 鎾ゅ洖",
+ bizType = "QINGYANDAN",
+ bizCodeExpr = "#result ? #qingyandan.jianyanLiushuihao : null",
+ targetTable = "lims_qingyandan",
+ targetIdExpr = "#qingyandan.id",
+ diff = true,
+ entityClass = LimsQingyandanEntity.class
+ )
+ public boolean cancel(LimsQingyandanEntity qingyandan) {
+ UpdateWrapper<LimsQingyandanEntity> update = activeRowUpdate(qingyandan.getId());
+ update.eq("biz_status", BizStatus.CONFIRMED.getCode());
+ update.set("biz_status", BizStatus.CANCELLED.getCode());
+ if (!this.update(update)) {
+ return false;
+ }
+
+ softDeleteJianyanXiangRecords(qingyandan.getId());
+ qingyandan.setBizStatus(BizStatus.CANCELLED.getCode());
+ tongbuRenwuQingyandanZhuangtai(qingyandan);
+ return true;
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ @AuditLog(
+ action = "RETURN",
+ label = "鍙栨牱 閫�鍥�",
+ bizType = "QINGYANDAN",
+ bizCodeExpr = "#qingyandan.jianyanLiushuihao",
+ extraExpr = "{'reason': #tuihuiyuanyin}",
+ targetTable = "lims_qingyandan",
+ targetIdExpr = "#qingyandan.id",
+ diff = true,
+ entityClass = LimsQingyandanEntity.class
+ )
+ public boolean reject(LimsQingyandanEntity qingyandan, String tuihuiyuanyin, String bizSign) {
+ UserInfo userInfo = UserProvider.getUser();
+ Date now = new Date();
+ UpdateWrapper<LimsQingyandanEntity> update = new UpdateWrapper<>();
+ update.eq("f_id", qingyandan.getId());
+ update.in("biz_status", BizStatus.PENDING_FETCH.getCode(), BizStatus.CONFIRMED.getCode());
+ update.and(w -> w.isNull("f_delete_mark").or().ne("f_delete_mark", 1));
+ update.set("biz_status", BizStatus.REJECTED.getCode());
+ update.set("quyang_status", "");
+ update.set("quyang_tuihui_ren", userInfo.getUserId());
+ update.set("quyang_tuihui_yuanyin", tuihuiyuanyin);
+ update.set("quyang_tuihui_riqi", now);
+ if (!this.update(update)) {
+ return false;
+ }
+
+ softDeleteJianyanXiangRecords(qingyandan.getId());
+ qingyandan.setBizStatus(BizStatus.REJECTED.getCode());
+ qingyandan.setQuyangStatus("");
+ qingyandan.setQuyangTuihuiRen(userInfo.getUserId());
+ qingyandan.setQuyangTuihuiYuanyin(tuihuiyuanyin);
+ qingyandan.setQuyangTuihuiRiqi(now);
+ tongbuRenwuQingyandanZhuangtai(qingyandan);
+ return true;
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ @AuditLog(
+ action = "RETURN",
+ label = "鎺ユ牱 閫�鍥�",
+ bizType = "JIEYANG",
+ bizCodeExpr = "#qingyandan.jianyanLiushuihao",
+ extraExpr = "{'reason': #tuihuiyuanyin}",
+ targetTable = "lims_qingyandan",
+ targetIdExpr = "#qingyandan.id",
+ diff = true,
+ entityClass = LimsQingyandanEntity.class
+ )
+ public boolean jieyangReject(LimsQingyandanEntity qingyandan, String tuihuiyuanyin, String bizSign) {
+ UserInfo userInfo = UserProvider.getUser();
+ Date now = new Date();
+ UpdateWrapper<LimsQingyandanEntity> update = new UpdateWrapper<>();
+ update.eq("f_id", qingyandan.getId());
+ update.eq("jieyang_status", BizStatus.PENDING_RECEIVE.getCode());
+ update.and(w -> w.isNull("f_delete_mark").or().ne("f_delete_mark", 1));
+ update.set("quyang_status", BizStatus.PENDING_FETCH.getCode());
+ update.set("jieyang_status", "");
+ update.set("jieyang_tuihui_yuanyin", tuihuiyuanyin);
+ update.set("jieyang_tuihui_ren", userInfo.getUserId());
+ update.set("jieyang_tuihui_riqi", now);
+ if (!this.update(update)) {
+ return false;
+ }
+
+ // 鎺ユ牱閫�鍥� 鈫� 閫�鍥炲彇鏍烽樁娈甸噸鏂板彇鏍凤細鍙栨牱鐘舵�佸洖鍒板緟鍙栨牱銆佹帴鏍风姸鎬佹竻绌猴紝
+ // biz_status 涓荤姸鎬佷笉鍙橈紱妫�楠岄」浠嶅湪娴佺▼涓紝涓嶈蒋鍒犮��
+ qingyandan.setQuyangStatus(BizStatus.PENDING_FETCH.getCode());
+ qingyandan.setJieyangStatus("");
+ qingyandan.setJieyangTuihuiYuanyin(tuihuiyuanyin);
+ qingyandan.setJieyangTuihuiRen(userInfo.getUserId());
+ qingyandan.setJieyangTuihuiRiqi(now);
+ tongbuRenwuQingyandanZhuangtai(qingyandan);
+ return true;
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ @AuditLog(
+ action = "DELETE",
+ label = "璇烽獙鍗� 搴熷純",
+ bizType = "QINGYANDAN",
+ bizCodeExpr = "#qingyandan.jianyanLiushuihao",
+ targetTable = "lims_qingyandan",
+ targetIdExpr = "#qingyandan.id",
+ diff = true,
+ entityClass = LimsQingyandanEntity.class
+ )
+ public void delete(LimsQingyandanEntity qingyandan) {
+ softDeleteJianyanXiangRecords(qingyandan.getId());
+ qingyandan.setBizStatus(BizStatus.DELETED.getCode());
+ this.updateById(qingyandan);
+ tongbuRenwuQingyandanZhuangtai(qingyandan);
+ }
+
+ private void tongbuRenwuQingyandanZhuangtai(LimsQingyandanEntity qingyandan) {
+ renwuQingyandanZhuangtaiTongbuService.tongbu(qingyandan, "qingyandan_zhuangtai_tongbu");
+ }
+
+ /**
+ * 鎵归噺杞垹闄よ璇烽獙鍗曚笅鎵�鏈夋湭杞垹鐨勬楠岄」锛坙ims_jianyan_xiang锛夈��
+ * 鎾ゅ洖 / 閫�鍥� / 搴熷純鏃惰皟鐢紝鎾ゆ帀鏈鎻愪氦鐢熸垚鐨勬楠屼换鍔¢」銆�
+ */
+ private void softDeleteJianyanXiangRecords(String qingyandanId) {
+ UserInfo userInfo = UserProvider.getUser();
+ QueryWrapper<LimsJianyanXiangEntity> wrapper = new QueryWrapper<>();
+ wrapper.eq("qingyandan_id", qingyandanId);
+ wrapper.and(w -> w.isNull("f_delete_mark").or().ne("f_delete_mark", 1));
+ List<LimsJianyanXiangEntity> list = limsJianyanXiangService.list(wrapper);
+ for (LimsJianyanXiangEntity item : list) {
+ item.setDeleteMark(1);
+ item.setDeleteTime(new Date());
+ item.setDeleteUserId(userInfo.getUserId());
+ limsJianyanXiangService.updateById(item);
+ }
+ }
+
+ /**
+ * 鎻愪氦璇烽獙鍗曟椂锛屾寜璐ㄩ噺鏍囧噯瀛愯〃锛坺hiliang_biaozhun_guanli_zixiang锛夐�愭潯鐩村啓 lims_jianyan_xiang銆�
+ * 鏇夸唬鏃х殑"鍐� lims_qingyandan_jiancexiang 涓棿琛�"閾捐矾锛氭楠岄」鍒濆 jianyan_zhuangtai = created銆�
+ * fenjian_zhuangtai = wei_fenjian锛岀瓑鍚庣画"鍒嗘"鍔ㄤ綔鎺ㄨ繘鍒� pending_assign 杩涘叆鍒嗛厤/褰曞叆/瀹℃牳娴佺▼銆�
+ *
+ * <p>鍙敓鎴愯楠屽崟 jiance_xiangmu 閫変腑鐨勫瓙椤癸細璇ュ瓧娈靛瓨鍓嶇鍕鹃�夌殑 zixiang.f_id 鏁扮粍
+ * 锛堝叏妫�浼氫紶鍏ㄩ儴 id锛岄儴鍒嗘浼犲瓙闆嗭級銆俲iance_xiangmu 涓虹┖鏃跺厹搴曞彇鍏ㄩ儴瀛愰」锛岄伩鍏嶅紓甯告儏鍐垫紡鐢熸垚銆�
+ */
+ private void createJianyanXiang(LimsQingyandanEntity qingyandan, ZhiliangBiaozhunGuanliEntity standard) {
+ List<ZhiliangBiaozhunGuanliZixiangEntity> zixiangList =
+ zhiliangBiaozhunGuanliZixiangService.listByForeignId(standard.getId());
+ if (zixiangList == null || zixiangList.isEmpty()) {
+ return;
+ }
+
+ // 浠呬繚鐣欏墠绔�変腑鐨勬楠屽瓙椤癸紙jiance_xiangmu 瀛橀�変腑鐨� zixiang.f_id锛�
+ Set<String> selectedIds = parseSelectedXiangmuIds(qingyandan.getJianceXiangmu());
+ if (!selectedIds.isEmpty()) {
+ zixiangList = zixiangList.stream()
+ .filter(z -> selectedIds.contains(z.getId()))
+ .collect(Collectors.toList());
+ }
+ if (zixiangList.isEmpty()) {
+ return;
+ }
+
+ List<LimsJianyanXiangEntity> records = new ArrayList<>(zixiangList.size());
+ for (ZhiliangBiaozhunGuanliZixiangEntity zixiang : zixiangList) {
+ records.add(buildXiangFromQingyandan(qingyandan, zixiang, standard));
+ }
+ limsJianyanXiangService.saveBatch(records);
+ }
+
+ /**
+ * 瑙f瀽璇烽獙鍗� jiance_xiangmu锛堝墠绔嬀閫夌殑妫�楠屽瓙椤� zixiang.f_id锛孞SON 鏁扮粍瀛楃涓插 ["id1","id2"]锛�
+ * 涓� id 闆嗗悎銆傜┖ / null / 瑙f瀽澶辫触杩斿洖绌洪泦锛岃皟鐢ㄦ柟鎹鍏滃簳鍙栧叏閮ㄥ瓙椤广��
+ */
+ private Set<String> parseSelectedXiangmuIds(String jianceXiangmu) {
+ if (jianceXiangmu == null || jianceXiangmu.trim().isEmpty()) {
+ return Collections.emptySet();
+ }
+ try {
+ List<String> ids = JsonUtil.getJsonToList(jianceXiangmu, String.class);
+ if (ids == null) {
+ return Collections.emptySet();
+ }
+ return ids.stream()
+ .filter(s -> s != null && !s.isEmpty())
+ .collect(Collectors.toCollection(LinkedHashSet::new));
+ } catch (Exception e) {
+ // 瀹归敊锛氭牸寮忓紓甯告椂杩斿洖绌洪泦锛屽厹搴曡蛋鍏ㄩ儴瀛愰」锛岄伩鍏嶆紡鐢熸垚
+ return Collections.emptySet();
+ }
+ }
+
+ /**
+ * 浠庤楠屽崟 + 璐ㄩ噺鏍囧噯瀛愰」鏋勯�犱竴琛� lims_jianyan_xiang銆�
+ * 澶翠俊鎭紙浜у搧 / 鎵瑰彿 / 瑙勬牸 / 娴佹按鍙� / 鍌ㄥ瓨鏉′欢锛変粠璇烽獙鍗曞彇锛屾楠岄」閰嶇疆浠庡瓙椤瑰彇銆�
+ */
+ private LimsJianyanXiangEntity buildXiangFromQingyandan(LimsQingyandanEntity qingyandan,
+ ZhiliangBiaozhunGuanliZixiangEntity zixiang,
+ ZhiliangBiaozhunGuanliEntity standard) {
+ LimsJianyanXiangEntity record = new LimsJianyanXiangEntity();
+ record.setTenantId(qingyandan.getTenantId());
+ record.setForeignId(zixiang.getId());
+ record.setQingyandanId(qingyandan.getId());
+ record.setBizType(qingyandan.getBizType());
+ record.setJianyanLiushuihao(qingyandan.getJianyanLiushuihao());
+ record.setChanpinId(qingyandan.getChanpinId());
+ record.setChanpinBianma(qingyandan.getChanpinBianma());
+ record.setChanpinMingcheng(qingyandan.getChanpinMingcheng());
+ record.setPihao(qingyandan.getPihao());
+ record.setGuige(qingyandan.getGuige());
+ record.setJianyanXiangmuBianma(zixiang.getJianyanXiangmuBianma());
+ record.setJianyanXiangmuMingcheng(zixiang.getJianyanXiangmuMingcheng());
+ record.setFenxiLeixing(zixiang.getFenxiLeixing());
+ record.setShifouWaijian(zixiang.getShifouWaijian());
+ record.setShifouChujuBaogao(zixiang.getShifouChujuBaogao());
+ record.setBiaozhunGuiding(zixiang.getBiaozhunGuiding());
+ record.setBiaozhunShangxian(zixiang.getBiaozhunShangxian());
+ record.setBiaozhunXiaxian(zixiang.getBiaozhunXiaxian());
+ record.setShujuLeixing(zixiang.getShujuLeixing());
+ record.setJianchaBanzu(zixiang.getJianchaBanzu());
+ record.setJianyanZhuangtai(JianyanStatus.CREATED.getCode());
+ record.setFenjianZhuangtai(FenjianZhuangtai.WEI_FENJIAN.getCode());
+ record.setFenjianLiang(zixiang.getFenjianLiang());
+ record.setFenjianDanwei(zixiang.getFenjianDanwei());
+ record.setFenjianFenzhuangRongqi(zixiang.getFenjianFenzhuangRongqi());
+ record.setFenjianBaocunTiaojian(zixiang.getFenjianBaocunTiaojian());
+ record.setFenjianHuanjing(zixiang.getFenjianHuanjing());
+ // 鏄惁缁勫悎鍒嗘嫞锛氭牱鍝佺骇閰嶇疆锛屼粠璐ㄩ噺鏍囧噯涓昏〃澶嶅埗
+ record.setShifouZuheFenjian(standard.getShifouZuheFenjian());
+ return record;
+ }
+
+ private LimsJianyanXiangEntity buildXiangFromRenwuKuaizhao(
+ LimsQingyandanEntity qingyandan,
+ LimsSxtQuyangJihuaRenwuJianyanXiangKuaizhaoEntity kuaizhao) {
+ LimsJianyanXiangEntity record = new LimsJianyanXiangEntity();
+ record.setId(RandomUtil.uuId());
+ record.setTenantId(qingyandan.getTenantId());
+ record.setForeignId(kuaizhao.getLaiyuanZhiliangBiaozhunZixiangId());
+ record.setQingyandanId(qingyandan.getId());
+ record.setLaiyuanRenwuId(qingyandan.getLaiyuanRenwuId());
+ record.setRenwuJianyanXiangKuaizhaoId(kuaizhao.getId());
+ record.setBizType(qingyandan.getBizType());
+ record.setJianyanLiushuihao(qingyandan.getJianyanLiushuihao());
+ record.setChanpinId(qingyandan.getChanpinId());
+ record.setChanpinBianma(qingyandan.getChanpinBianma());
+ record.setChanpinMingcheng(qingyandan.getChanpinMingcheng());
+ record.setPihao(qingyandan.getPihao());
+ record.setGuige(qingyandan.getGuige());
+ record.setJianyanXiangmuBianma(kuaizhao.getJianyanXiangmuBianma());
+ record.setJianyanXiangmuMingcheng(kuaizhao.getJianyanXiangmuMingcheng());
+ record.setFenxiLeixing(kuaizhao.getFenxiLeixing());
+ record.setBiaozhunGuiding(kuaizhao.getBiaozhunGuiding());
+ record.setBiaozhunShangxian(kuaizhao.getBiaozhunShangxian());
+ record.setBiaozhunXiaxian(kuaizhao.getBiaozhunXiaxian());
+ record.setShujuLeixing(kuaizhao.getShujuLeixing());
+ record.setJianchaBanzu(kuaizhao.getJianchaBanzu());
+ record.setJianyanZhuangtai(JianyanStatus.CREATED.getCode());
+ record.setFenjianZhuangtai(FenjianZhuangtai.WEI_FENJIAN.getCode());
+ return record;
+ }
+
+ /**
+ * jiance_fangshi 瀛楀吀閲�"鍏嶆"瀵瑰簲鐨� enCode
+ */
+ private static final String JIANCE_FANGSHI_MIANJIAN = "mianjian";
+
+ /**
+ * 鏍¢獙璇烽獙鍗曢�変腑鐨勮川閲忔爣鍑嗘槸鍚﹂綈澶囷細
+ * - qingyandan.jianyan_biaozhun 鐩存帴瀛� zhiliang_biaozhun_guanli.f_id
+ * - 涓昏〃蹇呴』瀛樺湪 / 鏈蒋鍒� / biz_enabled=enabled
+ * - 涓斿叾 yangpin_id 蹇呴』涓� qingyandan.chanpin_id 涓�鑷�
+ * - 闈炲厤妫�鍦烘櫙鍐嶆牎楠屽瓙椤硅嚦灏� 1 鏉�
+ * 浠讳竴鏉′欢涓嶆弧瓒冲垯鎶� DataException銆�
+ */
+ private ZhiliangBiaozhunGuanliEntity findReadyQualityStandardOrThrow(LimsQingyandanEntity qingyandan) {
+ String chanpinId = qingyandan.getChanpinId();
+ String chanpinMingcheng = qingyandan.getChanpinMingcheng();
+ String label = (chanpinMingcheng != null && !chanpinMingcheng.isEmpty())
+ ? chanpinMingcheng : chanpinId;
+
+ if (chanpinId == null || chanpinId.isEmpty()) {
+ throw new DataException("璇烽獙鍗曟湭鍏宠仈鏍峰搧ID锛屾棤娉曟牎楠岃川閲忔爣鍑�");
+ }
+
+ // 璇烽獙鍗曚笂閫変腑鐨勮川閲忔爣鍑嗕富閿�
+ String biaozhunId = qingyandan.getJianyanBiaozhun();
+ if (biaozhunId == null || biaozhunId.isEmpty()) {
+ throw new DataException("璇烽獙鍗曟湭鎸囧畾妫�楠屾爣鍑嗭紝鏃犳硶瀹氫綅璐ㄩ噺鏍囧噯");
+ }
+
+ ZhiliangBiaozhunGuanliEntity standard = zhiliangBiaozhunGuanliService.getById(biaozhunId);
+ if (standard == null
+ || (standard.getDeleteMark() != null && standard.getDeleteMark() == 1)) {
+ throw new DataException("鏍峰搧銆�" + label + "銆戠殑璐ㄩ噺鏍囧噯涓嶅瓨鍦ㄦ垨宸茶鍒犻櫎锛岃鍏堝湪銆愯川閲忔爣鍑嗙鐞嗐�戜腑缁存姢鍚庡啀鎻愪氦");
+ }
+ if (!BizEnabledEnum.ENABLED.getCode().equals(standard.getBizEnabled())) {
+ throw new DataException("鏍峰搧銆�" + label + "銆戞墍閫夌殑璐ㄩ噺鏍囧噯宸插仠鐢紝璇烽噸鏂伴�夋嫨鏈夋晥鐨勮川閲忔爣鍑�");
+ }
+ if (!chanpinId.equals(standard.getYangpinId())) {
+ throw new DataException("鏍峰搧銆�" + label + "銆戜笌鎵�閫夎川閲忔爣鍑嗕笉鍖归厤锛岃閲嶆柊閫夋嫨");
+ }
+
+ // 鍏嶆鏃惰烦杩�"妫�楠岄」鐩嚦灏� 1 鏉�"鐨勬牎楠岋紱鍏朵粬妫�娴嬫柟寮忎粛瑕佹眰鑷冲皯閰嶇疆 1 椤�
+ if (!JIANCE_FANGSHI_MIANJIAN.equals(qingyandan.getJianceFangshi())) {
+ long itemCount = zhiliangBiaozhunGuanliZixiangService.countByForeignId(standard.getId());
+ if (itemCount <= 0) {
+ throw new DataException("鏍峰搧銆�" + label + "銆戠殑璐ㄩ噺鏍囧噯鏈厤缃楠岄」鐩紝璇峰厛琛ュ厖妫�楠岄」鐩悗鍐嶆彁浜�");
+ }
+ }
+
+ return standard;
+ }
+}
--
Gitblit v1.8.0