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/LimsWendingxingChurukuServiceImpl.java | 279 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 279 insertions(+), 0 deletions(-)
diff --git a/jnpf-lims/jnpf-lims-biz/src/main/java/jnpf/limsService/impl/LimsWendingxingChurukuServiceImpl.java b/jnpf-lims/jnpf-lims-biz/src/main/java/jnpf/limsService/impl/LimsWendingxingChurukuServiceImpl.java
new file mode 100644
index 0000000..ad3e5c0
--- /dev/null
+++ b/jnpf-lims/jnpf-lims-biz/src/main/java/jnpf/limsService/impl/LimsWendingxingChurukuServiceImpl.java
@@ -0,0 +1,279 @@
+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.extension.plugins.pagination.Page;
+import jnpf.base.UserInfo;
+import jnpf.exception.DataException;
+import jnpf.limsEntity.LimsWendingxingChurukuEntity;
+import jnpf.limsEntity.LimsWendingxingChurukuSubmitParam;
+import jnpf.limsEntity.LimsWendingxingChurukuZixiangEntity;
+import jnpf.limsMapper.LimsWendingxingChurukuMapper;
+import jnpf.limsMapper.LimsWendingxingChurukuZixiangMapper;
+import jnpf.limsService.LimsWendingxingChurukuService;
+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.math.BigDecimal;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+@Service
+public class LimsWendingxingChurukuServiceImpl implements LimsWendingxingChurukuService {
+
+ private static final String LEIXING_RUKU = "ruku";
+ private static final String LEIXING_CHUKU = "chuku";
+ private static final String ZERO = "0";
+
+ @Autowired
+ private LimsWendingxingChurukuMapper churukuMapper;
+
+ @Autowired
+ private LimsWendingxingChurukuZixiangMapper zixiangMapper;
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ @AuditLog(action = "CREATE", label = "绋冲畾鎬у嚭鍏ュ簱鎻愪氦", bizType = "WENDINGXING",
+ bizCodeExpr = "#result['f_id']", targetTable = "lims_wendingxing_churuku",
+ targetIdExpr = "#result != null ? #result['f_id'] : null", diff = true,
+ entityClass = LimsWendingxingChurukuEntity.class)
+ public Map<String, Object> submit(LimsWendingxingChurukuSubmitParam param) {
+ validateParam(param);
+ UserInfo userInfo = UserProvider.getUser();
+ if (userInfo == null || !StringUtils.hasText(userInfo.getUserId())) {
+ throw new DataException("褰撳墠鏈櫥褰�");
+ }
+
+ Date now = new Date();
+ String churukuId = RandomUtil.uuId();
+ LimsWendingxingChurukuEntity churuku = buildChuruku(param, churukuId, userInfo, now);
+ if (churukuMapper.insert(churuku) != 1) {
+ throw new DataException("绋冲畾鎬у嚭鍏ュ簱涓昏〃淇濆瓨澶辫触");
+ }
+
+ Map<String, BigDecimal> balanceCache = new HashMap<>();
+ for (int i = 0; i < param.getZixiang().size(); i++) {
+ LimsWendingxingChurukuZixiangEntity zixiang = param.getZixiang().get(i);
+ saveZixiang(zixiang, i, churukuId, param.getBeizhu(), userInfo, now, balanceCache);
+ }
+
+ Map<String, Object> result = new LinkedHashMap<>();
+ result.put("f_id", churukuId);
+ result.put("zixiang_count", param.getZixiang().size());
+ return result;
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ @AuditLog(action = "BALANCE_SYNC", label = "鍚屾绋冲畾鎬у嚭鍏ュ簱缁撳瓨", bizType = "WENDINGXING",
+ bizCodeExpr = "#result > 0 ? #flowId : ''", targetTable = "lims_wendingxing_churuku_zixiang",
+ targetIdExpr = "T(jnpf.limsService.support.LimsAuditTargetIds).firstWendingxingChurukuItemByFlow(#flowId, #flowTaskId)",
+ diff = true, entityClass = LimsWendingxingChurukuZixiangEntity.class)
+ public int recalculateByFlow(String flowId, String flowTaskId) {
+ LimsWendingxingChurukuEntity churuku = getChurukuByFlow(flowId, flowTaskId);
+
+ LambdaQueryWrapper<LimsWendingxingChurukuZixiangEntity> currentQuery = new LambdaQueryWrapper<>();
+ currentQuery.eq(LimsWendingxingChurukuZixiangEntity::getForeignId, churuku.getId())
+ .and(wrapper -> wrapper.isNull(LimsWendingxingChurukuZixiangEntity::getDeleteMark)
+ .or().ne(LimsWendingxingChurukuZixiangEntity::getDeleteMark, 1))
+ .orderByAsc(LimsWendingxingChurukuZixiangEntity::getCreatorTime)
+ .orderByAsc(LimsWendingxingChurukuZixiangEntity::getId);
+ List<LimsWendingxingChurukuZixiangEntity> currentRows = zixiangMapper.selectList(currentQuery);
+ if (currentRows.isEmpty()) {
+ throw new DataException("鏈壘鍒板搴旂殑绋冲畾鎬у嚭鍏ュ簱瀛愰」鏁版嵁");
+ }
+
+ Map<String, BigDecimal> balanceCache = new HashMap<>();
+ for (int i = 0; i < currentRows.size(); i++) {
+ recalculateZixiang(currentRows.get(i), i, churuku.getId(), balanceCache);
+ }
+ return currentRows.size();
+ }
+
+ private LimsWendingxingChurukuEntity getChurukuByFlow(String flowId, String flowTaskId) {
+ LambdaQueryWrapper<LimsWendingxingChurukuEntity> query = new LambdaQueryWrapper<>();
+ query.eq(LimsWendingxingChurukuEntity::getFlowId, flowId)
+ .eq(LimsWendingxingChurukuEntity::getFlowTaskId, flowTaskId)
+ .and(wrapper -> wrapper.isNull(LimsWendingxingChurukuEntity::getDeleteMark)
+ .or().ne(LimsWendingxingChurukuEntity::getDeleteMark, 1));
+ LimsWendingxingChurukuEntity churuku = churukuMapper.selectOne(query);
+ if (churuku == null) {
+ throw new DataException("鏈壘鍒板搴旂殑绋冲畾鎬у嚭鍏ュ簱鏁版嵁");
+ }
+ return churuku;
+ }
+
+ private void recalculateZixiang(LimsWendingxingChurukuZixiangEntity row, int index,
+ String currentForeignId, Map<String, BigDecimal> balanceCache) {
+ String zhouqiId = trim(row.getJihuaZhouqiId());
+ if (!StringUtils.hasText(zhouqiId)) {
+ throw new DataException("绗�" + (index + 1) + "鏉″瓙椤圭殑璁″垝鍛ㄦ湡ID(jihua_zhouqi_id)涓嶈兘涓虹┖");
+ }
+ String leixing = trim(row.getChurukuLeixing()).toLowerCase(Locale.ROOT);
+ if (!LEIXING_RUKU.equals(leixing) && !LEIXING_CHUKU.equals(leixing)) {
+ throw new DataException("绗�" + (index + 1) + "鏉″瓙椤圭殑鍑哄叆搴撶被鍨嬪繀椤讳负ruku鎴朿huku");
+ }
+ BigDecimal shuliang = parseQuantity(row.getChurukuShuliang(), index, "鍑哄叆搴撴暟閲�");
+ if (shuliang.signum() < 0) {
+ throw new DataException("绗�" + (index + 1) + "鏉″瓙椤圭殑鍑哄叆搴撴暟閲忎笉鑳藉皬浜�0");
+ }
+
+ BigDecimal previousBalance = balanceCache.get(zhouqiId);
+ if (previousBalance == null) {
+ previousBalance = getLatestBalance(zhouqiId, currentForeignId);
+ }
+ BigDecimal currentBalance = LEIXING_RUKU.equals(leixing)
+ ? previousBalance.add(shuliang) : previousBalance.subtract(shuliang);
+ if (currentBalance.signum() < 0) {
+ throw new DataException("绗�" + (index + 1) + "鏉″瓙椤瑰嚭搴撳悗缁撳瓨閲忓皬浜�0锛屽綋鍓嶇粨瀛橀噺涓�"
+ + format(previousBalance) + "锛屽嚭搴撴暟閲忎负" + format(shuliang));
+ }
+
+ String shouruliang = LEIXING_RUKU.equals(leixing) ? format(shuliang) : ZERO;
+ String fachuliang = LEIXING_CHUKU.equals(leixing) ? format(shuliang) : ZERO;
+ LambdaUpdateWrapper<LimsWendingxingChurukuZixiangEntity> update = new LambdaUpdateWrapper<>();
+ update.eq(LimsWendingxingChurukuZixiangEntity::getId, row.getId())
+ .eq(LimsWendingxingChurukuZixiangEntity::getForeignId, currentForeignId)
+ .set(LimsWendingxingChurukuZixiangEntity::getShouruliang, shouruliang)
+ .set(LimsWendingxingChurukuZixiangEntity::getFachuliang, fachuliang)
+ .set(LimsWendingxingChurukuZixiangEntity::getJiecunliang, format(currentBalance));
+ if (zixiangMapper.update(null, update) != 1) {
+ throw new DataException("绗�" + (index + 1) + "鏉$ǔ瀹氭�у嚭鍏ュ簱瀛愰」鏇存柊澶辫触");
+ }
+ balanceCache.put(zhouqiId, currentBalance);
+ }
+
+ private LimsWendingxingChurukuEntity buildChuruku(LimsWendingxingChurukuSubmitParam param,
+ String churukuId, UserInfo userInfo, Date now) {
+ LimsWendingxingChurukuEntity entity = new LimsWendingxingChurukuEntity();
+ entity.setId(churukuId);
+ entity.setShenqingRen(param.getShenqingRen());
+ entity.setShenqingRiqi(param.getShenqingRiqi());
+ entity.setBeizhu(param.getBeizhu());
+ entity.setBizSign(param.getBizSign());
+ entity.setTenantId("0");
+ entity.setCreatorUserId(userInfo.getUserId());
+ entity.setCreatorTime(now);
+ return entity;
+ }
+
+ private void saveZixiang(LimsWendingxingChurukuZixiangEntity entity, int index,
+ String churukuId, String beizhu, UserInfo userInfo, Date now,
+ Map<String, BigDecimal> balanceCache) {
+ if (entity == null) {
+ throw new DataException("绗�" + (index + 1) + "鏉″瓙椤逛笉鑳戒负绌�");
+ }
+ String zhouqiId = trim(entity.getJihuaZhouqiId());
+ if (!StringUtils.hasText(zhouqiId)) {
+ throw new DataException("绗�" + (index + 1) + "鏉″瓙椤圭殑璁″垝鍛ㄦ湡ID(jihua_zhouqi_id)涓嶈兘涓虹┖");
+ }
+ String leixing = trim(entity.getChurukuLeixing()).toLowerCase(Locale.ROOT);
+ if (!LEIXING_RUKU.equals(leixing) && !LEIXING_CHUKU.equals(leixing)) {
+ throw new DataException("绗�" + (index + 1) + "鏉″瓙椤圭殑鍑哄叆搴撶被鍨嬪繀椤讳负ruku鎴朿huku");
+ }
+ BigDecimal shuliang = parseQuantity(entity.getChurukuShuliang(), index, "鍑哄叆搴撴暟閲�");
+ if (shuliang.signum() < 0) {
+ throw new DataException("绗�" + (index + 1) + "鏉″瓙椤圭殑鍑哄叆搴撴暟閲忎笉鑳藉皬浜�0");
+ }
+
+ BigDecimal previousBalance = balanceCache.get(zhouqiId);
+ if (previousBalance == null) {
+ previousBalance = getLatestBalance(zhouqiId);
+ }
+ BigDecimal currentBalance = LEIXING_RUKU.equals(leixing)
+ ? previousBalance.add(shuliang) : previousBalance.subtract(shuliang);
+ if (currentBalance.signum() < 0) {
+ throw new DataException("绗�" + (index + 1) + "鏉″瓙椤瑰嚭搴撳悗缁撳瓨閲忓皬浜�0锛屽綋鍓嶇粨瀛橀噺涓�"
+ + format(previousBalance) + "锛屽嚭搴撴暟閲忎负" + format(shuliang));
+ }
+
+ entity.setId(RandomUtil.uuId());
+ entity.setJihuaZhouqiId(zhouqiId);
+ entity.setChurukuLeixing(leixing);
+ entity.setChurukuShuliang(format(shuliang));
+ entity.setShouruliang(LEIXING_RUKU.equals(leixing) ? format(shuliang) : ZERO);
+ entity.setFachuliang(LEIXING_CHUKU.equals(leixing) ? format(shuliang) : ZERO);
+ entity.setJiecunliang(format(currentBalance));
+ entity.setForeignId(churukuId);
+ entity.setBeizhu(beizhu);
+ entity.setTenantId(userInfo.getTenantId());
+ entity.setCreatorUserId(userInfo.getUserId());
+ entity.setCreatorTime(now);
+ if (zixiangMapper.insert(entity) != 1) {
+ throw new DataException("绗�" + (index + 1) + "鏉$ǔ瀹氭�у嚭鍏ュ簱瀛愰」淇濆瓨澶辫触");
+ }
+ balanceCache.put(zhouqiId, currentBalance);
+ }
+
+ private BigDecimal getLatestBalance(String zhouqiId) {
+ return getLatestBalance(zhouqiId, null);
+ }
+
+ private BigDecimal getLatestBalance(String zhouqiId, String excludedForeignId) {
+ LambdaQueryWrapper<LimsWendingxingChurukuZixiangEntity> query = new LambdaQueryWrapper<>();
+ query.eq(LimsWendingxingChurukuZixiangEntity::getJihuaZhouqiId, zhouqiId)
+ .and(wrapper -> wrapper.isNull(LimsWendingxingChurukuZixiangEntity::getDeleteMark)
+ .or().ne(LimsWendingxingChurukuZixiangEntity::getDeleteMark, 1));
+ if (StringUtils.hasText(excludedForeignId)) {
+ query.ne(LimsWendingxingChurukuZixiangEntity::getForeignId, excludedForeignId);
+ }
+ query.orderByDesc(LimsWendingxingChurukuZixiangEntity::getCreatorTime)
+ .orderByDesc(LimsWendingxingChurukuZixiangEntity::getId);
+ List<LimsWendingxingChurukuZixiangEntity> rows = zixiangMapper
+ .selectPage(new Page<>(1, 1, false), query)
+ .getRecords();
+ if (rows.isEmpty()) {
+ return BigDecimal.ZERO;
+ }
+ LimsWendingxingChurukuZixiangEntity row = rows.get(0);
+ return parseBalance(row.getJiecunliang(), zhouqiId);
+ }
+
+ private BigDecimal parseBalance(String value, String zhouqiId) {
+ if (!StringUtils.hasText(value)) {
+ return BigDecimal.ZERO;
+ }
+ try {
+ return new BigDecimal(value.trim());
+ } catch (NumberFormatException e) {
+ throw new DataException("璁″垝鍛ㄦ湡" + zhouqiId + "鐨勬渶鏂扮粨瀛橀噺鏍煎紡涓嶆纭細" + value);
+ }
+ }
+
+ private BigDecimal parseQuantity(String value, int index, String fieldName) {
+ if (!StringUtils.hasText(value)) {
+ throw new DataException("绗�" + (index + 1) + "鏉″瓙椤圭殑" + fieldName + "(churuku_shuliang)涓嶈兘涓虹┖");
+ }
+ try {
+ return new BigDecimal(value.trim());
+ } catch (NumberFormatException e) {
+ throw new DataException("绗�" + (index + 1) + "鏉″瓙椤圭殑" + fieldName + "鏍煎紡涓嶆纭細" + value);
+ }
+ }
+
+ private void validateParam(LimsWendingxingChurukuSubmitParam param) {
+ if (param == null) {
+ throw new DataException("鎻愪氦鏁版嵁涓嶈兘涓虹┖");
+ }
+ if (param.getZixiang() == null || param.getZixiang().isEmpty()) {
+ throw new DataException("鍑哄叆搴撳瓙椤�(zixiang)涓嶈兘涓虹┖");
+ }
+ }
+
+ private String trim(String value) {
+ return value == null ? "" : value.trim();
+ }
+
+ private String format(BigDecimal value) {
+ return value.stripTrailingZeros().toPlainString();
+ }
+}
--
Gitblit v1.8.0