From 2f8e173048d22c5b40612c3538b9c1aa5a5397f6 Mon Sep 17 00:00:00 2001
From: zhou zhou <3272660260@qq.com>
Date: 星期五, 27 三月 2026 13:38:05 +0800
Subject: [PATCH] #乐观锁
---
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/OutStockServiceImpl.java | 18
docs/superpowers/plans/2026-03-26-menu-tree-redis-cache.md | 55 ++
rsf-server/src/main/java/com/vincent/rsf/server/manager/schedules/TaskSchedules.java | 8
rsf-server/src/test/java/com/vincent/rsf/server/system/controller/MenuControllerTest.java | 125 ++++
rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/OutStockController.java | 2
rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/WaitPakin.java | 4
rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/ReportMsgServiceImpl.java | 15
rsf-server/src/main/java/com/vincent/rsf/server/manager/schedules/PakinSchedules.java | 10
rsf-server/src/main/java/com/vincent/rsf/server/manager/schedules/ScheduleJobs.java | 11
rsf-server/src/test/java/com/vincent/rsf/server/manager/mapper/MybatisPlusOptimisticLockIntegrationTest.java | 474 +++++++++++++++++
rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/WkOrderController.java | 2
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/TaskServiceImpl.java | 382 +++++++------
rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/Loc.java | 3
rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/Task.java | 3
rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/LocPreviewController.java | 2
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/AsnOrderServiceImpl.java | 34
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/CheckOrderServiceImpl.java | 10
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/LocPreviewServiceImpl.java | 51 +
rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/ReceiveMsgServiceImpl.java | 5
rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/Wave.java | 4
rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/WaveController.java | 35
rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/InBoundServiceImpl.java | 13
rsf-server/src/test/java/com/vincent/rsf/server/system/entity/MenuJsonTest.java | 30 +
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/WaveServiceImpl.java | 95 ++-
rsf-server/src/main/java/com/vincent/rsf/server/common/utils/OptimisticLockUtils.java | 15
rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/MatPreparationController.java | 2
rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/CheckDiffItemController.java | 9
version/db/20260327_optimistic_lock.sql | 14
rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/WcsServiceImpl.java | 33
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/LocServiceImpl.java | 55 +
rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/CheckOrderController.java | 2
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/AsnOrderItemServiceImpl.java | 10
rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/WkOrder.java | 4
rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/LocController.java | 2
rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/TaskController.java | 2
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/OutStockItemServiceImpl.java | 10
rsf-server/src/test/java/com/vincent/rsf/server/common/utils/OptimisticLockUtilsTest.java | 23
37 files changed, 1,258 insertions(+), 314 deletions(-)
diff --git a/docs/superpowers/plans/2026-03-26-menu-tree-redis-cache.md b/docs/superpowers/plans/2026-03-26-menu-tree-redis-cache.md
new file mode 100644
index 0000000..aebbeae
--- /dev/null
+++ b/docs/superpowers/plans/2026-03-26-menu-tree-redis-cache.md
@@ -0,0 +1,55 @@
+# Menu Tree Redis Cache Implementation Plan
+
+> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
+
+**Goal:** Add Redis caching for `/menu/tree` without changing the endpoint contract.
+
+**Architecture:** Cache the full menu tree in Redis behind a single stable key, then apply the existing `condition` filter in memory on the cached tree result. Evict the cache only after successful menu save, update, and remove operations so reads stay fast and behavior stays aligned with the database.
+
+**Tech Stack:** Spring Boot, MyBatis-Plus, Jedis-based `RedisService`, JUnit 5, Mockito
+
+---
+
+### Task 1: Lock behavior with controller tests
+
+**Files:**
+- Create: `rsf-server/src/test/java/com/vincent/rsf/server/system/controller/MenuControllerTest.java`
+- Modify: `rsf-server/src/main/java/com/vincent/rsf/server/system/controller/MenuController.java`
+
+- [ ] **Step 1: Write the failing test**
+
+```java
+@Test
+void treeReturnsCachedTreeBeforeQueryingDatabase() {
+ // arrange cached tree
+ // call controller.tree(...)
+ // assert menuService.list(...) is never called
+}
+```
+
+- [ ] **Step 2: Run test to verify it fails**
+
+Run: `mvn -pl rsf-server -Dtest=MenuControllerTest test`
+Expected: FAIL because `MenuController` does not use Redis for `/menu/tree`
+
+- [ ] **Step 3: Write minimal implementation**
+
+```java
+List<Menu> treeData = redisService.get(MENU_TREE_CACHE_FLAG, MENU_TREE_CACHE_KEY);
+if (treeData == null) {
+ treeData = loadAndBuildTree();
+ redisService.set(MENU_TREE_CACHE_FLAG, MENU_TREE_CACHE_KEY, treeData, MENU_TREE_CACHE_TTL_SECONDS);
+}
+```
+
+- [ ] **Step 4: Run test to verify it passes**
+
+Run: `mvn -pl rsf-server -Dtest=MenuControllerTest test`
+Expected: PASS
+
+- [ ] **Step 5: Commit**
+
+```bash
+git add docs/superpowers/plans/2026-03-26-menu-tree-redis-cache.md rsf-server/src/main/java/com/vincent/rsf/server/system/controller/MenuController.java rsf-server/src/test/java/com/vincent/rsf/server/system/controller/MenuControllerTest.java
+git commit -m "feat: cache menu tree in redis"
+```
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/InBoundServiceImpl.java b/rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/InBoundServiceImpl.java
index bb74163..a6790a1 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/InBoundServiceImpl.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/InBoundServiceImpl.java
@@ -275,8 +275,17 @@
if (!basStationService.updateById(station)) {
throw new CoolException("绔欑偣鐘舵�佹洿鏂板け璐ワ紒锛�");
}
- if (!locService.update(new LambdaUpdateWrapper<Loc>().eq(Loc::getCode, task.getTargLoc())
- .set(Loc::getUseStatus, LocStsType.LOC_STS_TYPE_S.type).set(Loc::getBarcode, param.getContainerNo()))) {
+ Loc taskLoc = locService.getOne(new LambdaQueryWrapper<Loc>()
+ .eq(Loc::getCode, task.getTargLoc())
+ .last("limit 1"), false);
+ if (Objects.isNull(taskLoc)) {
+ throw new CoolException("搴撲綅棰勭害澶辫触锛侊紒");
+ }
+ taskLoc.setUseStatus(LocStsType.LOC_STS_TYPE_S.type)
+ .setBarcode(param.getContainerNo())
+ .setUpdateBy(loginUserId)
+ .setUpdateTime(new Date());
+ if (!locService.updateById(taskLoc)) {
throw new CoolException("搴撲綅棰勭害澶辫触锛侊紒");
}
return R.ok("浠诲姟鐢熸垚瀹屾瘯锛�");
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/ReceiveMsgServiceImpl.java b/rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/ReceiveMsgServiceImpl.java
index 2f739e4..b04895d 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/ReceiveMsgServiceImpl.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/ReceiveMsgServiceImpl.java
@@ -980,9 +980,8 @@
}
} else {
Double sum = orderItems.stream().mapToDouble(WkOrderItem::getAnfme).sum();
- if (!asnOrderService.update(new LambdaUpdateWrapper<WkOrder>()
- .eq(WkOrder::getId, wkOrder.getId())
- .set(WkOrder::getAnfme, sum))) {
+ wkOrder.setAnfme(sum);
+ if (!asnOrderService.updateById(wkOrder)) {
throw new CoolException("涓诲崟鏁伴噺淇敼澶辫触锛侊紒");
}
}
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/ReportMsgServiceImpl.java b/rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/ReportMsgServiceImpl.java
index 026b9bb..1058b83 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/ReportMsgServiceImpl.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/ReportMsgServiceImpl.java
@@ -161,14 +161,17 @@
Map<Long, List<WkOrderItem>> asnIds = wkOrderItems.stream().collect(Collectors.groupingBy(WkOrderItem::getOrderId));
ids.forEach(id -> {
long count = Optional.ofNullable(asnOrderMapper.selectCount(new LambdaQueryWrapper<WkOrder>().in(WkOrder::getId, id))).orElse(0L);
+ WkOrder order = asnOrderMapper.selectById(id);
+ if (Objects.isNull(order)) {
+ throw new CoolException("ASN涓诲崟鐘舵�佷慨鏀瑰け璐ワ紒锛�");
+ }
if (count == asnIds.get(id).size()) {
- if (asnOrderMapper.update(null, new LambdaUpdateWrapper<WkOrder>().eq(WkOrder::getId, id).set(WkOrder::getNtyStatus, 1)) <= 0) {
- throw new CoolException("ASN涓诲崟鐘舵�佷慨鏀瑰け璐ワ紒锛�");
- }
+ order.setNtyStatus(1);
} else {
- if (asnOrderMapper.update(null, new LambdaUpdateWrapper<WkOrder>().eq(WkOrder::getId, id).set(WkOrder::getNtyStatus, 2)) <= 0) {
- throw new CoolException("ASN涓诲崟鐘舵�佷慨鏀瑰け璐ワ紒锛�");
- }
+ order.setNtyStatus(2);
+ }
+ if (asnOrderMapper.updateById(order) <= 0) {
+ throw new CoolException("ASN涓诲崟鐘舵�佷慨鏀瑰け璐ワ紒锛�");
}
});
return true;
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/WcsServiceImpl.java b/rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/WcsServiceImpl.java
index c82f047..3a435cf 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/WcsServiceImpl.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/WcsServiceImpl.java
@@ -234,10 +234,17 @@
* 鏇存柊搴撲綅鐘舵��
*/
private void updateLocStatus(String locCode, String barcode) {
- boolean updated = locService.update(new LambdaUpdateWrapper<Loc>()
- .eq(Loc::getCode, locCode)
- .set(Loc::getUseStatus, LocStsType.LOC_STS_TYPE_S.type)
- .set(Loc::getBarcode, barcode));
+ Loc current = locService.getOne(new LambdaQueryWrapper<Loc>().eq(Loc::getCode, locCode));
+ if (Objects.isNull(current)) {
+ throw new CoolException("搴撲綅棰勭害澶辫触锛侊紒");
+ }
+ Loc update = new Loc();
+ update.setId(current.getId());
+ update.setVersion(current.getVersion());
+ update.setUseStatus(LocStsType.LOC_STS_TYPE_S.type);
+ update.setBarcode(barcode);
+ boolean updated = locService.update(update, new LambdaUpdateWrapper<Loc>()
+ .eq(Loc::getId, current.getId()));
if (!updated) {
throw new CoolException("搴撲綅棰勭害澶辫触锛侊紒");
}
@@ -284,11 +291,19 @@
* 鏇存柊缁勬墭鐘舵��
*/
private void updateWaitPakinStatus(String barcode, Long loginUserId) {
- boolean updated = waitPakinService.update(new LambdaUpdateWrapper<WaitPakin>()
- .eq(WaitPakin::getBarcode, barcode)
- .set(WaitPakin::getUpdateBy, loginUserId)
- .set(WaitPakin::getCreateBy, loginUserId)
- .set(WaitPakin::getIoStatus, PakinIOStatus.PAKIN_IO_STATUS_TASK_EXCE.val));
+ WaitPakin current = waitPakinService.getOne(new LambdaQueryWrapper<WaitPakin>()
+ .eq(WaitPakin::getBarcode, barcode));
+ if (Objects.isNull(current)) {
+ throw new CoolException("缁勬墭鐘舵�佷慨鏀瑰け璐ワ紒锛�");
+ }
+ WaitPakin update = new WaitPakin();
+ update.setId(current.getId());
+ update.setVersion(current.getVersion());
+ update.setUpdateBy(loginUserId);
+ update.setCreateBy(loginUserId);
+ update.setIoStatus(PakinIOStatus.PAKIN_IO_STATUS_TASK_EXCE.val);
+ boolean updated = waitPakinService.update(update, new LambdaUpdateWrapper<WaitPakin>()
+ .eq(WaitPakin::getId, current.getId()));
if (!updated) {
throw new CoolException("缁勬墭鐘舵�佷慨鏀瑰け璐ワ紒锛�");
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/common/utils/OptimisticLockUtils.java b/rsf-server/src/main/java/com/vincent/rsf/server/common/utils/OptimisticLockUtils.java
new file mode 100644
index 0000000..e774043
--- /dev/null
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/common/utils/OptimisticLockUtils.java
@@ -0,0 +1,15 @@
+package com.vincent.rsf.server.common.utils;
+
+import com.vincent.rsf.framework.exception.CoolException;
+
+public final class OptimisticLockUtils {
+
+ private OptimisticLockUtils() {
+ }
+
+ public static void requireVersion(String dataName, Integer version) {
+ if (version == null) {
+ throw new CoolException(dataName + "鐗堟湰鍙蜂笉鑳戒负绌猴紝璇峰埛鏂板悗閲嶈瘯锛侊紒");
+ }
+ }
+}
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/CheckDiffItemController.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/CheckDiffItemController.java
index 4108af5..9a72b3f 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/CheckDiffItemController.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/CheckDiffItemController.java
@@ -102,9 +102,12 @@
// 浠呭湪鏈夊崟鏃舵洿鏂扮洏鐐瑰崟(WkOrder)鎵ц鐘舵�侊紱鏃犲崟鐩樼偣鏃犵洏鐐瑰崟锛屼笉鏇存柊
CheckDiff checkDiff = checkDiffService.getById(checkDiffItem.getCheckId());
if (checkDiff != null && checkDiff.getOrderId() != null) {
- if (!checkOrderService.update(new LambdaUpdateWrapper<WkOrder>()
- .eq(WkOrder::getId, checkDiff.getOrderId())
- .set(WkOrder::getExceStatus, CheckExceStatus.CHECK_ORDER_STATUS_EXCE_DONE.val))) {
+ WkOrder order = checkOrderService.getById(checkDiff.getOrderId());
+ if (order == null) {
+ throw new CoolException("鐩樼偣鍗曚笉瀛樺湪锛侊紒");
+ }
+ order.setExceStatus(CheckExceStatus.CHECK_ORDER_STATUS_EXCE_DONE.val);
+ if (!checkOrderService.updateById(order)) {
throw new CoolException("鐩樼偣鍗曟墽琛岀姸鎬佷慨鏀瑰け璐ワ紒锛�");
}
}
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/CheckOrderController.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/CheckOrderController.java
index bd78f87..ef92ca8 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/CheckOrderController.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/CheckOrderController.java
@@ -11,6 +11,7 @@
import com.vincent.rsf.server.common.domain.KeyValVo;
import com.vincent.rsf.server.common.domain.PageParam;
import com.vincent.rsf.server.common.utils.ExcelUtil;
+import com.vincent.rsf.server.common.utils.OptimisticLockUtils;
import com.vincent.rsf.server.manager.controller.params.*;
import com.vincent.rsf.server.manager.entity.WkOrder;
import com.vincent.rsf.server.manager.entity.WkOrderItem;
@@ -86,6 +87,7 @@
@OperationLog("Update 瀛楀吀鏁版嵁闆�")
@PostMapping("/check/update")
public R update(@RequestBody WkOrder order) {
+ OptimisticLockUtils.requireVersion("鐩樼偣鍗�", order.getVersion());
order.setUpdateTime(null);
order.setUpdateBy(getLoginUserId());
if (!checkOrderService.updateById(order)) {
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/LocController.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/LocController.java
index 70342d6..889bba8 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/LocController.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/LocController.java
@@ -10,6 +10,7 @@
import com.vincent.rsf.server.common.domain.BaseParam;
import com.vincent.rsf.server.common.domain.KeyValVo;
import com.vincent.rsf.server.common.domain.PageParam;
+import com.vincent.rsf.server.common.utils.OptimisticLockUtils;
import com.vincent.rsf.server.manager.controller.params.LocMastInitParam;
import com.vincent.rsf.server.manager.controller.params.LocModifyParams;
import com.vincent.rsf.server.manager.entity.Loc;
@@ -164,6 +165,7 @@
@PostMapping("/loc/update")
@Transactional(rollbackFor = Exception.class)
public R update(@RequestBody Loc loc) {
+ OptimisticLockUtils.requireVersion("搴撲綅", loc.getVersion());
loc.setUpdateBy(getLoginUserId());
String join = StringUtils.join(loc.getTypeIds(), ",");
if (!Objects.isNull(loc.getTypeIds())) {
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/LocPreviewController.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/LocPreviewController.java
index 5c18563..0393c68 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/LocPreviewController.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/LocPreviewController.java
@@ -10,6 +10,7 @@
import com.vincent.rsf.server.common.domain.KeyValVo;
import com.vincent.rsf.server.common.domain.PageParam;
import com.vincent.rsf.server.common.utils.ExcelUtil;
+import com.vincent.rsf.server.common.utils.OptimisticLockUtils;
import com.vincent.rsf.server.manager.controller.params.LocModifyParams;
import com.vincent.rsf.server.manager.entity.Loc;
import com.vincent.rsf.server.manager.enums.LocStsType;
@@ -112,6 +113,7 @@
@PostMapping("/locPreview/update")
@Transactional(rollbackFor = Exception.class)
public R update(@RequestBody Loc loc) {
+ OptimisticLockUtils.requireVersion("搴撲綅", loc.getVersion());
loc.setUpdateBy(getLoginUserId());
String join = StringUtils.join(loc.getTypeIds(), ",");
loc.setType(join);
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/MatPreparationController.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/MatPreparationController.java
index da3ab23..a9f161f 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/MatPreparationController.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/MatPreparationController.java
@@ -15,6 +15,7 @@
import com.vincent.rsf.server.common.domain.PageParam;
import com.vincent.rsf.server.common.utils.ExcelUtil;
import com.vincent.rsf.server.common.utils.FieldsUtils;
+import com.vincent.rsf.server.common.utils.OptimisticLockUtils;
import com.vincent.rsf.server.manager.controller.params.AsnOrderAndItemsParams;
import com.vincent.rsf.server.manager.controller.params.GenWaveParams;
import com.vincent.rsf.server.manager.controller.params.OrderOutTaskParam;
@@ -120,6 +121,7 @@
@PostMapping("/preparation/update")
@ApiOperation("鏇存柊")
public R update(@RequestBody WkOrder wkOrder) {
+ OptimisticLockUtils.requireVersion("澶囨枡鍗�", wkOrder.getVersion());
wkOrder.setType(OrderType.ORDER_OUT.type)
.setUpdateBy(getLoginUserId())
.setUpdateTime(new Date());
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/OutStockController.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/OutStockController.java
index f2c7585..3baa8f2 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/OutStockController.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/OutStockController.java
@@ -22,6 +22,7 @@
import com.vincent.rsf.server.common.domain.KeyValVo;
import com.vincent.rsf.server.common.domain.PageParam;
import com.vincent.rsf.server.common.utils.ExcelUtil;
+import com.vincent.rsf.server.common.utils.OptimisticLockUtils;
import com.vincent.rsf.server.manager.controller.params.AsnOrderAndItemsParams;
import com.vincent.rsf.server.manager.entity.excel.AsnOrderTemplate;
import com.vincent.rsf.server.manager.enums.AsnExceStatus;
@@ -119,6 +120,7 @@
@PostMapping("/outStock/update")
@ApiOperation("鏇存柊")
public R update(@RequestBody WkOrder wkOrder) {
+ OptimisticLockUtils.requireVersion("鍑哄簱鍗�", wkOrder.getVersion());
wkOrder.setType(OrderType.ORDER_OUT.type)
.setUpdateBy(getLoginUserId())
.setUpdateTime(new Date());
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/TaskController.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/TaskController.java
index 4555699..ca127a2 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/TaskController.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/TaskController.java
@@ -15,6 +15,7 @@
import com.vincent.rsf.server.common.domain.BaseParam;
import com.vincent.rsf.server.common.domain.KeyValVo;
import com.vincent.rsf.server.common.domain.PageParam;
+import com.vincent.rsf.server.common.utils.OptimisticLockUtils;
import com.vincent.rsf.server.manager.service.*;
import com.vincent.rsf.server.system.controller.BaseController;
import com.vincent.rsf.server.system.service.impl.ConfigServiceImpl;
@@ -89,6 +90,7 @@
@OperationLog("Update 浠诲姟宸ヤ綔妗�")
@PostMapping("/task/update")
public R update(@RequestBody Task task) {
+ OptimisticLockUtils.requireVersion("浠诲姟", task.getVersion());
task.setUpdateBy(getLoginUserId());
task.setUpdateTime(new Date());
if (!taskService.updateById(task)) {
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/WaveController.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/WaveController.java
index 3b47ed5..160818c 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/WaveController.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/WaveController.java
@@ -9,6 +9,7 @@
import com.vincent.rsf.framework.exception.CoolException;
import com.vincent.rsf.server.common.domain.PageResult;
import com.vincent.rsf.server.common.utils.ExcelUtil;
+import com.vincent.rsf.server.common.utils.OptimisticLockUtils;
import com.vincent.rsf.server.common.annotation.OperationLog;
import com.vincent.rsf.server.common.domain.BaseParam;
import com.vincent.rsf.server.common.domain.KeyValVo;
@@ -91,6 +92,7 @@
@OperationLog("Update 娉㈡鍗曟嵁")
@PostMapping("/wave/update")
public R update(@RequestBody Wave wave) {
+ OptimisticLockUtils.requireVersion("娉㈡", wave.getVersion());
wave.setUpdateBy(getLoginUserId());
wave.setUpdateTime(new Date());
if (!waveService.updateById(wave)) {
@@ -172,9 +174,14 @@
@ApiOperation("鏆傚仠涓嬪彂浠诲姟")
@PostMapping("/wave/pause/pub/{id}")
public R pausePublicTask(@PathVariable Long id) {
- waveService.update(new LambdaUpdateWrapper<Wave>()
- .eq(Wave::getId, id)
- .set(Wave::getExceStatus, WaveExceStatus.WAVE_EXCE_STATUS_PAUSE.val));
+ Wave wave = waveService.getById(id);
+ if (Objects.isNull(wave)) {
+ throw new CoolException("娉㈡鏁版嵁涓嶅瓨鍦紒锛�");
+ }
+ wave.setExceStatus(WaveExceStatus.WAVE_EXCE_STATUS_PAUSE.val);
+ if (!waveService.updateById(wave)) {
+ throw new CoolException("娉㈡鐘舵�佷慨鏀瑰け璐ワ紒锛�");
+ }
return R.ok();
}
@@ -182,9 +189,14 @@
@ApiOperation("缁х画涓嬪彂浠诲姟")
@PostMapping("/wave/continue/pub/{id}")
public R continuePublicTask(@PathVariable Long id) {
- waveService.update(new LambdaUpdateWrapper<Wave>()
- .eq(Wave::getId, id)
- .set(Wave::getExceStatus, WaveExceStatus.WAVE_EXCE_STATUS_EXCING.val));
+ Wave wave = waveService.getById(id);
+ if (Objects.isNull(wave)) {
+ throw new CoolException("娉㈡鏁版嵁涓嶅瓨鍦紒锛�");
+ }
+ wave.setExceStatus(WaveExceStatus.WAVE_EXCE_STATUS_EXCING.val);
+ if (!waveService.updateById(wave)) {
+ throw new CoolException("娉㈡鐘舵�佷慨鏀瑰け璐ワ紒锛�");
+ }
return R.ok();
}
@@ -196,9 +208,14 @@
if (Objects.isNull(id)) {
return R.error("鍙傛暟涓嶈兘涓虹┖锛侊紒");
}
- waveService.update(new LambdaUpdateWrapper<Wave>()
- .eq(Wave::getId, id)
- .set(Wave::getExceStatus, WaveExceStatus.WAVE_EXCE_STATUS_PAUSE.val));
+ Wave wave = waveService.getById(id);
+ if (Objects.isNull(wave)) {
+ throw new CoolException("娉㈡鏁版嵁涓嶅瓨鍦紒锛�");
+ }
+ wave.setExceStatus(WaveExceStatus.WAVE_EXCE_STATUS_PAUSE.val);
+ if (!waveService.updateById(wave)) {
+ throw new CoolException("娉㈡鐘舵�佷慨鏀瑰け璐ワ紒锛�");
+ }
return waveService.stopPubTask(id);
}
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/WkOrderController.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/WkOrderController.java
index 59b6188..d22eb63 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/WkOrderController.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/WkOrderController.java
@@ -16,6 +16,7 @@
import com.vincent.rsf.server.common.domain.BaseParam;
import com.vincent.rsf.server.common.domain.KeyValVo;
import com.vincent.rsf.server.common.domain.PageParam;
+import com.vincent.rsf.server.common.utils.OptimisticLockUtils;
import com.vincent.rsf.server.manager.controller.params.AsnOrderAndItemsParams;
import com.vincent.rsf.server.manager.controller.params.BatchUpdateParam;
import com.vincent.rsf.server.manager.entity.excel.AsnOrderTemplate;
@@ -146,6 +147,7 @@
@PostMapping("/asnOrder/update")
@ApiOperation("鏇存柊")
public R update(@RequestBody WkOrder wkOrder) {
+ OptimisticLockUtils.requireVersion("ASN鍗曟嵁", wkOrder.getVersion());
wkOrder.setUpdateBy(getLoginUserId());
wkOrder.setUpdateTime(new Date());
if (!asnOrderService.updateById(wkOrder)) {
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/Loc.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/Loc.java
index 3e25c35..7e25d1b 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/Loc.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/Loc.java
@@ -218,6 +218,9 @@
@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
private Date updateTime;
+ @Version
+ private Integer version;
+
/**
* 澶囨敞
*/
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/Task.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/Task.java
index c322df8..bf28c73 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/Task.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/Task.java
@@ -198,6 +198,9 @@
@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
private Date updateTime;
+ @Version
+ private Integer version;
+
/**
* 澶囨敞
*/
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/WaitPakin.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/WaitPakin.java
index cb52cf7..b670510 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/WaitPakin.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/WaitPakin.java
@@ -18,6 +18,7 @@
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.annotation.Version;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@@ -120,6 +121,9 @@
@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
private Date updateTime;
+ @Version
+ private Integer version;
+
/**
* 澶囨敞
*/
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/Wave.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/Wave.java
index 59d042e..bccfa67 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/Wave.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/Wave.java
@@ -18,6 +18,7 @@
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.annotation.Version;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@@ -135,6 +136,9 @@
@TableLogic
private Integer deleted;
+ @Version
+ private Integer version;
+
/**
* 澶囨敞
*/
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/WkOrder.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/WkOrder.java
index 135c38f..8a45261 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/WkOrder.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/WkOrder.java
@@ -20,6 +20,7 @@
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.annotation.Version;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import com.vincent.rsf.framework.common.Cools;
@@ -172,6 +173,9 @@
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date updateTime;
+ @Version
+ private Integer version;
+
/**
* 澶囨敞
*/
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/schedules/PakinSchedules.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/schedules/PakinSchedules.java
index 3a13341..43b263f 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/schedules/PakinSchedules.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/schedules/PakinSchedules.java
@@ -15,6 +15,7 @@
import java.util.ArrayList;
import java.util.List;
+import java.util.Objects;
import java.util.stream.Collectors;
@Component
@@ -79,9 +80,12 @@
}
Double sum1 = waitPakinItems.stream().mapToDouble(WaitPakinItem::getAnfme).sum();
if (sum.compareTo(sum1) == 0) {
- if (!asnOrderService.update(new LambdaUpdateWrapper<WkOrder>()
- .eq(WkOrder::getCode, item)
- .set(WkOrder::getExceStatus, AsnExceStatus.ASN_EXCE_STATUS_TASK_DONE.val))) {
+ WkOrder wkOrder = asnOrderService.getOne(new LambdaQueryWrapper<WkOrder>().eq(WkOrder::getCode, item), false);
+ if (Objects.isNull(wkOrder)) {
+ throw new CoolException("鍗曟嵁涓嶅瓨鍦紒锛�");
+ }
+ wkOrder.setExceStatus(AsnExceStatus.ASN_EXCE_STATUS_TASK_DONE.val);
+ if (!asnOrderService.updateById(wkOrder)) {
throw new CoolException("鍗曟嵁淇敼澶辫触锛侊紒");
}
}
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/schedules/ScheduleJobs.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/schedules/ScheduleJobs.java
index 4b8227f..c95cfe7 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/schedules/ScheduleJobs.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/schedules/ScheduleJobs.java
@@ -135,10 +135,13 @@
// throw new CoolException("鏀惰揣鍗曚繚瀛樿嚦鏀惰揣鍖烘墽琛屽け璐ワ紒锛�");
// }
- if (!asnOrderService.update(new LambdaUpdateWrapper<WkOrder>()
- .set(WkOrder::getQty, order.getAnfme())
- .set(WkOrder::getExceStatus, AsnExceStatus.ASN_EXCE_STATUS_RECEIPT_DONE.val)
- .eq(WkOrder::getId, order.getId()))) {
+ WkOrder currentOrder = asnOrderService.getById(order.getId());
+ if (Objects.isNull(currentOrder)) {
+ throw new CoolException("鏀惰揣鍗曚笉瀛樺湪锛侊紒");
+ }
+ currentOrder.setQty(order.getAnfme())
+ .setExceStatus(AsnExceStatus.ASN_EXCE_STATUS_RECEIPT_DONE.val);
+ if (!asnOrderService.updateById(currentOrder)) {
throw new CoolException("鏀惰揣鍗曠姸鎬佷慨鏀瑰け璐ワ紒锛�");
}
}
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/schedules/TaskSchedules.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/schedules/TaskSchedules.java
index 0e7b477..2df0126 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/schedules/TaskSchedules.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/schedules/TaskSchedules.java
@@ -941,8 +941,8 @@
|| task.getTaskType().equals(TaskType.TASK_TYPE_EMPTY_IN.type)
|| task.getTaskType().equals(TaskType.TASK_TYPE_MERGE_IN.type)
|| task.getTaskType().equals(TaskType.TASK_TYPE_LOC_MOVE.type)) {
- if (!taskService.update(new LambdaUpdateWrapper<Task>().eq(Task::getTaskCode, task.getTaskCode())
- .set(Task::getTaskStatus, TaskStsType.WCS_EXECUTE_IN.id))) {
+ task.setTaskStatus(TaskStsType.WCS_EXECUTE_IN.id);
+ if (!taskService.updateById(task)) {
throw new CoolException("浠诲姟鐘舵�佷慨鏀瑰け璐ワ紒锛�");
}
/**鎺掗櫎绉诲簱鍔熻兘*/
@@ -962,8 +962,8 @@
|| task.getTaskType().equals(TaskType.TASK_TYPE_MERGE_OUT.type)
|| task.getTaskType().equals(TaskType.TASK_TYPE_EMPTY_OUT.type)
|| task.getTaskType().equals(TaskType.TASK_TYPE_PICK_AGAIN_OUT.type)) {
- if (!taskService.update(new LambdaUpdateWrapper<Task>().eq(Task::getTaskCode, task.getTaskCode())
- .set(Task::getTaskStatus, TaskStsType.WCS_EXECUTE_OUT.id))) {
+ task.setTaskStatus(TaskStsType.WCS_EXECUTE_OUT.id);
+ if (!taskService.updateById(task)) {
throw new CoolException("浠诲姟鐘舵�佷慨鏀瑰け璐ワ紒锛�");
}
/**濡傛灉鏄櫘閫氱珯鐐癸紝淇敼绔欑偣鐘舵�佷负鍏ュ簱棰勭害*/
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/AsnOrderItemServiceImpl.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/AsnOrderItemServiceImpl.java
index 93e5287..c0b9a88 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/AsnOrderItemServiceImpl.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/AsnOrderItemServiceImpl.java
@@ -202,10 +202,12 @@
if (!items.isEmpty()) {
// double qty = items.stream().mapToDouble(AsnOrderItem::getQty).sum();
double anfme = items.stream().mapToDouble(WkOrderItem::getAnfme).sum();
- if (asnOrderMapper.update(null, new LambdaUpdateWrapper<WkOrder>()
-// .set(AsnOrder::getQty, qty)
- .set(WkOrder::getAnfme, anfme)
- .eq(WkOrder::getId, order.getId())) <= 0) {
+ WkOrder currentOrder = asnOrderMapper.selectById(order.getId());
+ if (Objects.isNull(currentOrder)) {
+ throw new CoolException("鍗曟嵁鏁伴噺淇敼澶辫触锛侊紒");
+ }
+ currentOrder.setAnfme(anfme);
+ if (asnOrderMapper.updateById(currentOrder) <= 0) {
throw new CoolException("鍗曟嵁鏁伴噺淇敼澶辫触锛侊紒");
}
}
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/AsnOrderServiceImpl.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/AsnOrderServiceImpl.java
index 6f1592b..ab223ec 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/AsnOrderServiceImpl.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/AsnOrderServiceImpl.java
@@ -203,14 +203,32 @@
if (Objects.isNull(order)) {
throw new CoolException("淇敼鍙傛暟涓嶈兘涓虹┖锛侊紒");
}
- return this.update(new LambdaUpdateWrapper<WkOrder>()
- .in(WkOrder::getId, params.getIds())
- .set(!Objects.isNull(order.getRleStatus()), WkOrder::getRleStatus, order.getRleStatus())
- .set(!Objects.isNull(order.getNtyStatus()), WkOrder::getNtyStatus, order.getNtyStatus())
- .set(!Objects.isNull(order.getStatus()), WkOrder::getStatus, order.getStatus())
- .set(!Objects.isNull(order.getWkType()), WkOrder::getWkType, order.getWkType())
- .set(!Objects.isNull(order.getExceStatus()), WkOrder::getExceStatus, order.getExceStatus())
- .set(WkOrder::getUpdateBy, userId));
+ List<WkOrder> orders = this.listByIds(params.getIds());
+ if (orders.isEmpty()) {
+ return false;
+ }
+ for (WkOrder current : orders) {
+ if (!Objects.isNull(order.getRleStatus())) {
+ current.setRleStatus(order.getRleStatus());
+ }
+ if (!Objects.isNull(order.getNtyStatus())) {
+ current.setNtyStatus(order.getNtyStatus());
+ }
+ if (!Objects.isNull(order.getStatus())) {
+ current.setStatus(order.getStatus());
+ }
+ if (!Objects.isNull(order.getWkType())) {
+ current.setWkType(order.getWkType());
+ }
+ if (!Objects.isNull(order.getExceStatus())) {
+ current.setExceStatus(order.getExceStatus());
+ }
+ current.setUpdateBy(userId);
+ if (!this.updateById(current)) {
+ throw new CoolException("鎵归噺淇敼澶辫触锛侊紒");
+ }
+ }
+ return true;
}
/**
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/CheckOrderServiceImpl.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/CheckOrderServiceImpl.java
index aadcdc3..f8631b8 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/CheckOrderServiceImpl.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/CheckOrderServiceImpl.java
@@ -116,9 +116,13 @@
}
if (!items.isEmpty()) {
double purQty = items.stream().mapToDouble(WkOrderItem::getAnfme).sum();
- if (!this.update(new LambdaUpdateWrapper<WkOrder>()
- .set(WkOrder::getExceStatus, CheckExceStatus.CHECK_ORDER_STATUS_UN_EXCE.val)
- .set(WkOrder::getAnfme, purQty).eq(WkOrder::getId, order.getId()))) {
+ WkOrder savedOrder = this.getById(order.getId());
+ if (Objects.isNull(savedOrder)) {
+ throw new CoolException("鍗曟嵁涓嶅瓨鍦紒锛�");
+ }
+ savedOrder.setExceStatus(CheckExceStatus.CHECK_ORDER_STATUS_UN_EXCE.val)
+ .setAnfme(purQty);
+ if (!this.updateById(savedOrder)) {
throw new CoolException("鍗曟嵁鏁伴噺淇敼澶辫触锛侊紒");
}
}
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/LocPreviewServiceImpl.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/LocPreviewServiceImpl.java
index b0ac65a..26232f3 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/LocPreviewServiceImpl.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/LocPreviewServiceImpl.java
@@ -55,22 +55,47 @@
if (!Objects.isNull(loc.getTypeIds()) && !loc.getTypeIds().isEmpty()) {
join = StringUtils.join(loc.getTypeIds(), ",");
}
- boolean update = this.update(new LambdaUpdateWrapper<Loc>()
+ List<Loc> existsLocs = this.list(new LambdaQueryWrapper<Loc>()
.in(Loc::getId, locs.getId())
- .eq(Loc::getStatus, 1)
- .set(!Objects.isNull(loc.getAreaId()), Loc::getAreaId, loc.getAreaId())
- .set(!Objects.isNull(loc.getWarehouseId()), Loc::getWarehouseId, loc.getWarehouseId())
- .set(!Objects.isNull(loc.getUseStatus()), Loc::getUseStatus, loc.getUseStatus())
- .set(!Objects.isNull(loc.getTypeIds()) && !loc.getTypeIds().isEmpty(), Loc::getType, join)
- .set(!Objects.isNull(loc.getLength()), Loc::getLength, loc.getLength())
- .set(!Objects.isNull(loc.getWidth()), Loc::getWidth, loc.getWidth())
- .set(!Objects.isNull(loc.getHeight()), Loc::getHeight, loc.getHeight())
- .set(!Objects.isNull(loc.getChannel()), Loc::getChannel, loc.getChannel())
- .set(!Objects.isNull(loc.getFlagLabelMange()), Loc::getFlagLabelMange, loc.getFlagLabelMange())
- .set(!Objects.isNull(loc.getStatus()), Loc::getStatus, loc.getStatus()));
- if (!update) {
+ .eq(Loc::getStatus, 1));
+ if (existsLocs.isEmpty()) {
throw new CoolException("搴撲綅淇℃伅淇敼澶辫触锛侊紒");
}
+ for (Loc currentLoc : existsLocs) {
+ if (!Objects.isNull(loc.getAreaId())) {
+ currentLoc.setAreaId(loc.getAreaId());
+ }
+ if (!Objects.isNull(loc.getWarehouseId())) {
+ currentLoc.setWarehouseId(loc.getWarehouseId());
+ }
+ if (!Objects.isNull(loc.getUseStatus())) {
+ currentLoc.setUseStatus(loc.getUseStatus());
+ }
+ if (!Objects.isNull(loc.getTypeIds()) && !loc.getTypeIds().isEmpty()) {
+ currentLoc.setType(join);
+ }
+ if (!Objects.isNull(loc.getLength())) {
+ currentLoc.setLength(loc.getLength());
+ }
+ if (!Objects.isNull(loc.getWidth())) {
+ currentLoc.setWidth(loc.getWidth());
+ }
+ if (!Objects.isNull(loc.getHeight())) {
+ currentLoc.setHeight(loc.getHeight());
+ }
+ if (!Objects.isNull(loc.getChannel())) {
+ currentLoc.setChannel(loc.getChannel());
+ }
+ if (!Objects.isNull(loc.getFlagLabelMange())) {
+ currentLoc.setFlagLabelMange(loc.getFlagLabelMange());
+ }
+ if (!Objects.isNull(loc.getStatus())) {
+ currentLoc.setStatus(loc.getStatus());
+ }
+ if (!this.updateById(currentLoc)) {
+ throw new CoolException("搴撲綅淇℃伅淇敼澶辫触锛侊紒");
+ }
+ }
return R.ok(loc);
}
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/LocServiceImpl.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/LocServiceImpl.java
index f15800f..2204a2f 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/LocServiceImpl.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/LocServiceImpl.java
@@ -57,23 +57,50 @@
if (!Objects.isNull(loc.getTypeIds()) && !loc.getTypeIds().isEmpty()) {
join = StringUtils.join(loc.getTypeIds(), ",");
}
- boolean update = this.update(new LambdaUpdateWrapper<Loc>()
+ List<Loc> existsLocs = this.list(new LambdaQueryWrapper<Loc>()
.in(Loc::getId, locs.getId())
- .eq(Loc::getStatus, 1)
- .set(!Objects.isNull(loc.getAreaId()), Loc::getAreaId, loc.getAreaId())
- .set(!Objects.isNull(loc.getWarehouseId()), Loc::getWarehouseId, loc.getWarehouseId())
- .set(!Objects.isNull(loc.getUseStatus()), Loc::getUseStatus, loc.getUseStatus())
- .set(!Objects.isNull(loc.getTypeIds()) && !loc.getTypeIds().isEmpty(), Loc::getType, join)
- .set(!Objects.isNull(loc.getLength()), Loc::getLength, loc.getLength())
- .set(!Objects.isNull(loc.getWidth()), Loc::getWidth, loc.getWidth())
- .set(!Objects.isNull(loc.getHeight()), Loc::getHeight, loc.getHeight())
- .set(!Objects.isNull(loc.getChannel()), Loc::getChannel, loc.getChannel())
- .set(!Objects.isNull(loc.getFlagLabelMange()), Loc::getFlagLabelMange, loc.getFlagLabelMange())
- .set(loc.getStatus().equals(CommonStatus.COMMONSTATUS_NO.val), Loc::getUseStatus, LocStsType.LOC_STS_TYPE_X.type)
- .set(!Objects.isNull(loc.getStatus()), Loc::getStatus, loc.getStatus()));
- if (!update) {
+ .eq(Loc::getStatus, 1));
+ if (existsLocs.isEmpty()) {
throw new CoolException("搴撲綅淇℃伅淇敼澶辫触锛侊紒");
}
+ for (Loc currentLoc : existsLocs) {
+ if (!Objects.isNull(loc.getAreaId())) {
+ currentLoc.setAreaId(loc.getAreaId());
+ }
+ if (!Objects.isNull(loc.getWarehouseId())) {
+ currentLoc.setWarehouseId(loc.getWarehouseId());
+ }
+ if (!Objects.isNull(loc.getUseStatus())) {
+ currentLoc.setUseStatus(loc.getUseStatus());
+ }
+ if (!Objects.isNull(loc.getTypeIds()) && !loc.getTypeIds().isEmpty()) {
+ currentLoc.setType(join);
+ }
+ if (!Objects.isNull(loc.getLength())) {
+ currentLoc.setLength(loc.getLength());
+ }
+ if (!Objects.isNull(loc.getWidth())) {
+ currentLoc.setWidth(loc.getWidth());
+ }
+ if (!Objects.isNull(loc.getHeight())) {
+ currentLoc.setHeight(loc.getHeight());
+ }
+ if (!Objects.isNull(loc.getChannel())) {
+ currentLoc.setChannel(loc.getChannel());
+ }
+ if (!Objects.isNull(loc.getFlagLabelMange())) {
+ currentLoc.setFlagLabelMange(loc.getFlagLabelMange());
+ }
+ if (!Objects.isNull(loc.getStatus()) && loc.getStatus().equals(CommonStatus.COMMONSTATUS_NO.val)) {
+ currentLoc.setUseStatus(LocStsType.LOC_STS_TYPE_X.type);
+ }
+ if (!Objects.isNull(loc.getStatus())) {
+ currentLoc.setStatus(loc.getStatus());
+ }
+ if (!this.updateById(currentLoc)) {
+ throw new CoolException("搴撲綅淇℃伅淇敼澶辫触锛侊紒");
+ }
+ }
return R.ok(loc);
}
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/OutStockItemServiceImpl.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/OutStockItemServiceImpl.java
index 367fd19..9f5a9e1 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/OutStockItemServiceImpl.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/OutStockItemServiceImpl.java
@@ -147,9 +147,13 @@
}
if (!items.isEmpty()) {
double purQty = items.stream().mapToDouble(WkOrderItem::getAnfme).sum();
- if (asnOrderMapper.update(null, new LambdaUpdateWrapper<WkOrder>()
- .set(WkOrder::getExceStatus, AsnExceStatus.OUT_STOCK_STATUS_TASK_INIT.val)
- .set(WkOrder::getAnfme, purQty).eq(WkOrder::getId, order.getId())) <= 0) {
+ WkOrder currentOrder = asnOrderMapper.selectById(order.getId());
+ if (Objects.isNull(currentOrder)) {
+ throw new CoolException("鍗曟嵁鏁伴噺淇敼澶辫触锛侊紒");
+ }
+ currentOrder.setExceStatus(AsnExceStatus.OUT_STOCK_STATUS_TASK_INIT.val)
+ .setAnfme(purQty);
+ if (asnOrderMapper.updateById(currentOrder) <= 0) {
throw new CoolException("鍗曟嵁鏁伴噺淇敼澶辫触锛侊紒");
}
}
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/OutStockServiceImpl.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/OutStockServiceImpl.java
index 1cecd7f..e4bc088 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/OutStockServiceImpl.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/OutStockServiceImpl.java
@@ -356,11 +356,10 @@
}
for (WkOrder order : orders) {
Double wkQty = Math.round((order.getWorkQty() + order.getAnfme()) * 10000) / 10000.0;
- if (!this.update(new LambdaUpdateWrapper<WkOrder>()
- .set(WkOrder::getWaveId, wave.getId())
- .set(WkOrder::getWorkQty, wkQty)
- .set(WkOrder::getExceStatus, AsnExceStatus.OUT_STOCK_STATUS_TASK_WAVE.val)
- .eq(WkOrder::getId, order.getId()))) {
+ order.setWaveId(wave.getId())
+ .setWorkQty(wkQty)
+ .setExceStatus(AsnExceStatus.OUT_STOCK_STATUS_TASK_WAVE.val);
+ if (!this.updateById(order)) {
throw new CoolException("鎵ц鐘舵�佷慨鏀逛慨鏀瑰け璐ワ紒锛�");
}
}
@@ -455,11 +454,10 @@
}
for (WkOrder order : orders) {
Double wkQty = Math.round((order.getWorkQty() + order.getAnfme()) * 10000) / 10000.0;
- if (!this.update(new LambdaUpdateWrapper<WkOrder>()
- .set(WkOrder::getWaveId, wave.getId())
- .set(WkOrder::getWorkQty, wkQty)
- .set(WkOrder::getExceStatus, AsnExceStatus.OUT_STOCK_STATUS_TASK_WAVE.val)
- .eq(WkOrder::getId, order.getId()))) {
+ order.setWaveId(wave.getId())
+ .setWorkQty(wkQty)
+ .setExceStatus(AsnExceStatus.OUT_STOCK_STATUS_TASK_WAVE.val);
+ if (!this.updateById(order)) {
throw new CoolException("鎵ц鐘舵�佷慨鏀逛慨鏀瑰け璐ワ紒锛�");
}
}
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/TaskServiceImpl.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/TaskServiceImpl.java
index 06c2c73..875e6d4 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/TaskServiceImpl.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/TaskServiceImpl.java
@@ -169,10 +169,7 @@
if (!this.save(task)) {
throw new CoolException("浠诲姟淇濆瓨澶辫触锛侊紒");
}
- if (!locService.update(new LambdaUpdateWrapper<Loc>().eq(Loc::getCode, task.getTargLoc())
- .set(Loc::getUseStatus, LocStsType.LOC_STS_TYPE_S.type).set(Loc::getBarcode, pakin.getBarcode()))) {
- throw new CoolException("搴撲綅棰勭害澶辫触锛侊紒");
- }
+ updateLocByCode(task.getTargLoc(), LocStsType.LOC_STS_TYPE_S.type, pakin.getBarcode(), null, "搴撲綅棰勭害澶辫触锛侊紒", true);
/**鑾峰彇缁勬嫋鏄庣粏**/
List<WaitPakinItem> waitPakinItems = waitPakinItemService.list(new LambdaQueryWrapper<WaitPakinItem>().eq(WaitPakinItem::getPakinId, pakin.getId()));
if (waitPakinItems.isEmpty()) {
@@ -212,13 +209,7 @@
});
});
- if (!waitPakinService.update(new LambdaUpdateWrapper<WaitPakin>()
- .in(WaitPakin::getId, pakins.getId())
- .set(WaitPakin::getUpdateBy, loginUserId)
- .set(WaitPakin::getCreateBy, loginUserId)
- .set(WaitPakin::getIoStatus, PakinIOStatus.PAKIN_IO_STATUS_TASK_EXCE.val))) {
- throw new CoolException("缁勬墭鐘舵�佷慨鏀瑰け璐ワ紒锛�");
- }
+ updateWaitPakinsStatus(waitPakins, PakinIOStatus.PAKIN_IO_STATUS_TASK_EXCE.val, loginUserId, true, "缁勬墭鐘舵�佷慨鏀瑰け璐ワ紒锛�");
return R.ok("浠诲姟鐢熸垚瀹屾瘯锛�");
}
@@ -261,14 +252,7 @@
if (!this.save(task)) {
throw new CoolException("浠诲姟淇濆瓨澶辫触锛侊紒");
}
- if (!locService.update(new LambdaUpdateWrapper<Loc>()
- .eq(Loc::getCode, task.getTargLoc())
- .set(Loc::getUseStatus, LocStsType.LOC_STS_TYPE_S.type)
- .set(Loc::getUpdateBy, loginUserId)
- .set(Loc::getUpdateTime, new Date())
- .set(Loc::getBarcode, pakin.getBarcode()))) {
- throw new CoolException("搴撲綅棰勭害澶辫触锛侊紒");
- }
+ updateLocByCode(task.getTargLoc(), LocStsType.LOC_STS_TYPE_S.type, pakin.getBarcode(), loginUserId, "搴撲綅棰勭害澶辫触锛侊紒", true);
/**鑾峰彇缁勬嫋鏄庣粏**/
List<WaitPakinItem> waitPakinItems = waitPakinItemService.list(new LambdaQueryWrapper<WaitPakinItem>().eq(WaitPakinItem::getPakinId, pakin.getId()));
if (waitPakinItems.isEmpty()) {
@@ -303,13 +287,7 @@
});
});
- if (!waitPakinService.update(new LambdaUpdateWrapper<WaitPakin>()
- .in(WaitPakin::getId, pakins.getId())
- .set(WaitPakin::getUpdateBy, loginUserId)
- .set(WaitPakin::getCreateBy, loginUserId)
- .set(WaitPakin::getIoStatus, PakinIOStatus.PAKIN_IO_STATUS_TASK_EXCE.val))) {
- throw new CoolException("缁勬嫋鐘舵�佷慨鏀瑰け璐ワ紒锛�");
- }
+ updateWaitPakinsStatus(waitPakins, PakinIOStatus.PAKIN_IO_STATUS_TASK_EXCE.val, loginUserId, true, "缁勬嫋鐘舵�佷慨鏀瑰け璐ワ紒锛�");
return R.ok("浠诲姟鐢熸垚瀹屾瘯锛�");
}
@@ -415,10 +393,7 @@
}
- if (!locService.update(new LambdaUpdateWrapper<Loc>().eq(Loc::getCode, task.getTargLoc())
- .set(Loc::getUseStatus, LocStsType.LOC_STS_TYPE_S.type).set(Loc::getBarcode, pakin.getBarcode()))) {
- throw new CoolException("搴撲綅棰勭害澶辫触锛侊紒");
- }
+ updateLocByCode(task.getTargLoc(), LocStsType.LOC_STS_TYPE_S.type, pakin.getBarcode(), null, "搴撲綅棰勭害澶辫触锛侊紒", true);
/**鑾峰彇缁勬嫋鏄庣粏**/
List<WaitPakinItem> waitPakinItems = waitPakinItemService.list(new LambdaQueryWrapper<WaitPakinItem>().eq(WaitPakinItem::getPakinId, pakin.getId()));
if (waitPakinItems.isEmpty()) {
@@ -461,13 +436,7 @@
});
});
- if (!waitPakinService.update(new LambdaUpdateWrapper<WaitPakin>()
- .in(WaitPakin::getId, ids)
- .set(WaitPakin::getUpdateBy, loginUserId)
- .set(WaitPakin::getCreateBy, loginUserId)
- .set(WaitPakin::getIoStatus, PakinIOStatus.PAKIN_IO_STATUS_TASK_EXCE.val))) {
- throw new CoolException("缁勬嫋鐘舵�佷慨鏀瑰け璐ワ紒锛�");
- }
+ updateWaitPakinsStatus(waitPakins, PakinIOStatus.PAKIN_IO_STATUS_TASK_EXCE.val, loginUserId, true, "缁勬嫋鐘舵�佷慨鏀瑰け璐ワ紒锛�");
return R.ok("浠诲姟鐢熸垚瀹屾瘯锛�");
}
@@ -691,10 +660,7 @@
throw new CoolException("浠诲姟淇濆瓨澶辫触锛侊紒");
}
- if (!locService.update(new LambdaUpdateWrapper<Loc>().eq(Loc::getCode, task.getTargLoc())
- .set(Loc::getUseStatus, LocStsType.LOC_STS_TYPE_S.type).set(Loc::getBarcode, pakin.getBarcode()))) {
- throw new CoolException("搴撲綅棰勭害澶辫触锛侊紒");
- }
+ updateLocByCode(task.getTargLoc(), LocStsType.LOC_STS_TYPE_S.type, pakin.getBarcode(), null, "搴撲綅棰勭害澶辫触锛侊紒", true);
/**鑾峰彇缁勬嫋鏄庣粏**/
List<WaitPakinItem> waitPakinItems = waitPakinItemService.list(new LambdaQueryWrapper<WaitPakinItem>().eq(WaitPakinItem::getPakinId, pakin.getId()));
if (waitPakinItems.isEmpty()) {
@@ -736,13 +702,7 @@
continue;
}
- if (!waitPakinService.update(new LambdaUpdateWrapper<WaitPakin>()
- .in(WaitPakin::getId, ids)
- .set(WaitPakin::getUpdateBy, loginUserId)
- .set(WaitPakin::getCreateBy, loginUserId)
- .set(WaitPakin::getIoStatus, PakinIOStatus.PAKIN_IO_STATUS_TASK_EXCE.val))) {
- throw new CoolException("缁勬嫋鐘舵�佷慨鏀瑰け璐ワ紒锛�");
- }
+ updateWaitPakinsStatus(waitPakins, PakinIOStatus.PAKIN_IO_STATUS_TASK_EXCE.val, loginUserId, true, "缁勬嫋鐘舵�佷慨鏀瑰け璐ワ紒锛�");
return R.ok("浠诲姟鐢熸垚瀹屾瘯锛�");
}
String msg = "鏈壘搴撲綅" + Arrays.toString(errMsg);
@@ -1060,30 +1020,11 @@
}
/**淇敼搴撲綅鐘舵�佷负F.鍦ㄥ簱*/
- if (!locService.update(new LambdaUpdateWrapper<Loc>()
- .set(Loc::getBarcode, task.getBarcode())
- .set(Loc::getUseStatus, type)
- .set(Loc::getUpdateBy, loginUserId)
- .set(Loc::getUpdateTime, new Date())
- .eq(Loc::getCode, task.getTargLoc()))) {
- throw new CoolException("搴撲綅鐘舵�佷慨鏀瑰け璐ワ紒锛�");
- }
+ updateLocByCode(task.getTargLoc(), type, task.getBarcode(), loginUserId, "搴撲綅鐘舵�佷慨鏀瑰け璐ワ紒锛�", true);
- if (!locService.update(new LambdaUpdateWrapper<Loc>()
- .set(Loc::getBarcode, null)
- .set(Loc::getUpdateBy, loginUserId)
- .set(Loc::getUpdateTime, new Date())
- .set(Loc::getUseStatus, LocStsType.LOC_STS_TYPE_O.type)
- .eq(Loc::getCode, task.getOrgLoc()))) {
- throw new CoolException("搴撲綅鐘舵�佷慨鏀瑰け璐ワ紒锛�");
- }
+ updateLocByCode(task.getOrgLoc(), LocStsType.LOC_STS_TYPE_O.type, null, loginUserId, "搴撲綅鐘舵�佷慨鏀瑰け璐ワ紒锛�", true);
- if (!this.update(new LambdaUpdateWrapper<Task>().eq(Task::getId, task.getId())
- .set(Task::getUpdateBy, loginUserId)
- .set(Task::getUpdateTime, new Date())
- .set(Task::getTaskStatus, TaskStsType.UPDATED_IN.id))) {
- throw new CoolException("浠诲姟鐘舵�佷慨鏀瑰け璐ワ紒锛�");
- }
+ updateTaskSnapshot(task, TaskStsType.UPDATED_IN.id, loginUserId, "浠诲姟鐘舵�佷慨鏀瑰け璐ワ紒锛�");
}
@@ -1324,16 +1265,8 @@
for (Task task : tasks) {
//鍙栨秷绉诲簱浠诲姟
if (task.getTaskType().equals(TaskType.TASK_TYPE_LOC_MOVE.type) && task.getTaskStatus().equals(TaskStsType.GENERATE_IN.id)) {
- if (!locService.update(new LambdaUpdateWrapper<Loc>()
- .eq(Loc::getCode, task.getOrgLoc())
- .set(Loc::getUseStatus, LocStsType.LOC_STS_TYPE_F.type))) {
- throw new CoolException("婧愬簱浣嶇姸鎬佷慨鏀瑰け璐ワ紒锛�");
- }
- if (!locService.update(new LambdaUpdateWrapper<Loc>()
- .eq(Loc::getCode, task.getTargLoc())
- .set(Loc::getUseStatus, LocStsType.LOC_STS_TYPE_O.type))) {
- throw new CoolException("绉诲簱鐩爣搴撲綅鐘舵�佷慨鏀瑰け璐ワ紒锛�");
- }
+ updateLocByCode(task.getOrgLoc(), LocStsType.LOC_STS_TYPE_F.type, null, null, "婧愬簱浣嶇姸鎬佷慨鏀瑰け璐ワ紒锛�", false);
+ updateLocByCode(task.getTargLoc(), LocStsType.LOC_STS_TYPE_O.type, null, null, "绉诲簱鐩爣搴撲綅鐘舵�佷慨鏀瑰け璐ワ紒锛�", false);
Task outTask = this.getById(task.getParentId());
if (!Objects.isNull(outTask)) {
@@ -1360,11 +1293,7 @@
throw new CoolException("鏄庣粏鏁伴噺淇敼澶辫触锛侊紒");
}
- if (!checkOrderService.update(new LambdaUpdateWrapper<WkOrder>()
- .eq(WkOrder::getId, taskItem.getOrderId())
- .setSql("work_qty = work_qty - " + taskItem.getAnfme()))) {
- throw new CoolException("鐩樼偣鍗曟墽琛屾暟閲忎慨鏀瑰け璐ワ紒锛�");
- }
+ updateWkOrderWorkQty(taskItem.getOrderId(), -taskItem.getAnfme(), null, "鐩樼偣鍗曟墽琛屾暟閲忎慨鏀瑰け璐ワ紒锛�");
CheckDiffItem serviceOne = checkDiffItemService.getOne(new LambdaQueryWrapper<CheckDiffItem>().eq(CheckDiffItem::getTaskItemId, taskItem.getId()));
@@ -1383,17 +1312,11 @@
.distinct()
.collect(Collectors.toList());
for (Long orderId : orderIds) {
- checkOrderService.update(new LambdaUpdateWrapper<WkOrder>()
- .eq(WkOrder::getId, orderId)
- .set(WkOrder::getExceStatus, CheckExceStatus.CHECK_ORDER_STATUS_UN_EXCE.val));
+ updateWkOrderExceStatus(orderId, CheckExceStatus.CHECK_ORDER_STATUS_UN_EXCE.val, null, "鐩樼偣鍗曠姸鎬佷慨鏀瑰け璐ワ紒锛�");
}
}
- if (!locService.update(new LambdaUpdateWrapper<Loc>()
- .eq(Loc::getCode, task.getOrgLoc())
- .set(Loc::getUseStatus, LocStsType.LOC_STS_TYPE_F.type))) {
- throw new CoolException("婧愬簱浣嶇姸鎬佷慨鏀瑰け璐ワ紒锛�");
- }
+ updateLocByCode(task.getOrgLoc(), LocStsType.LOC_STS_TYPE_F.type, null, null, "婧愬簱浣嶇姸鎬佷慨鏀瑰け璐ワ紒锛�", false);
}
// 鍑哄簱绫讳换鍔″彇娑堟椂锛屽洖閫�璺緞瑙勫垝闃舵鍗犵敤鐨勭洰鏍囩珯鐐癸紙S鈫扥锛�
@@ -1804,22 +1727,9 @@
}
/**淇敼涓哄簱浣嶇姸鎬佷负O.绌哄簱*/
- if (!locService.update(new LambdaUpdateWrapper<Loc>()
- .set(Loc::getUseStatus, LocStsType.LOC_STS_TYPE_O.type)
- .set(Loc::getBarcode, null)
- .set(Loc::getUpdateBy, loginUserId)
- .set(Loc::getUpdateTime, new Date())
- .eq(Loc::getId, loc.getId()))) {
- throw new CoolException("搴撲綅鐘舵�佷慨鏀瑰け璐ワ紒锛�");
- }
+ updateLocSnapshot(loc, LocStsType.LOC_STS_TYPE_O.type, null, loginUserId, "搴撲綅鐘舵�佷慨鏀瑰け璐ワ紒锛�", true);
- if (!this.update(new LambdaUpdateWrapper<Task>()
- .eq(Task::getId, task.getId())
- .set(Task::getUpdateBy, loginUserId)
- .set(Task::getUpdateTime, new Date())
- .set(Task::getTaskStatus, TaskStsType.WAVE_SEED.id))) {
- throw new CoolException("搴撳瓨鐘舵�佹洿鏂板け璐ワ紒锛�");
- }
+ updateTaskSnapshot(task, TaskStsType.WAVE_SEED.id, loginUserId, "搴撳瓨鐘舵�佹洿鏂板け璐ワ紒锛�");
// if (task.getTaskType().equals(TaskType.TASK_TYPE_PICK_AGAIN_OUT.type) || task.getTaskType().equals(TaskType.TASK_TYPE_CHECK_OUT.type)) {
// if (!this.update(new LambdaUpdateWrapper<Task>()
@@ -1952,22 +1862,9 @@
}
/**淇敼涓哄簱浣嶇姸鎬佷负O.绌哄簱*/
- if (!locService.update(new LambdaUpdateWrapper<Loc>()
- .set(Loc::getUseStatus, LocStsType.LOC_STS_TYPE_O.type)
- .set(Loc::getBarcode, null)
- .set(Loc::getUpdateBy, loginUserId)
- .set(Loc::getUpdateTime, new Date())
- .eq(Loc::getId, loc.getId()))) {
- throw new CoolException("搴撲綅鐘舵�佷慨鏀瑰け璐ワ紒锛�");
- }
+ updateLocSnapshot(loc, LocStsType.LOC_STS_TYPE_O.type, null, loginUserId, "搴撲綅鐘舵�佷慨鏀瑰け璐ワ紒锛�", true);
- if (!this.update(new LambdaUpdateWrapper<Task>()
- .eq(Task::getId, task.getId())
- .set(Task::getUpdateBy, loginUserId)
- .set(Task::getUpdateTime, new Date())
- .set(Task::getTaskStatus, TaskStsType.UPDATED_OUT.id))) {
- throw new CoolException("搴撳瓨鐘舵�佹洿鏂板け璐ワ紒锛�");
- }
+ updateTaskSnapshot(task, TaskStsType.UPDATED_OUT.id, loginUserId, "搴撳瓨鐘舵�佹洿鏂板け璐ワ紒锛�");
// if (task.getTaskType().equals(TaskType.TASK_TYPE_PICK_AGAIN_OUT.type) || task.getTaskType().equals(TaskType.TASK_TYPE_CHECK_OUT.type)) {
// if (!this.update(new LambdaUpdateWrapper<Task>()
@@ -2068,22 +1965,24 @@
}
/**淇敼涓哄簱浣嶇姸鎬佷负O.绌哄簱*/
- if (!locService.update(new LambdaUpdateWrapper<Loc>()
- .set(Loc::getUseStatus, LocStsType.LOC_STS_TYPE_S.type)
- .set(Loc::getBarcode, loc.getBarcode())
- .set(Loc::getUpdateBy, loginUserId)
- .set(Loc::getUpdateTime, new Date())
- .eq(Loc::getId, loc.getId()))) {
- throw new CoolException("搴撲綅鐘舵�佷慨鏀瑰け璐ワ紒锛�");
- }
+ updateLocSnapshot(loc, LocStsType.LOC_STS_TYPE_S.type, loc.getBarcode(), loginUserId, "搴撲綅鐘舵�佷慨鏀瑰け璐ワ紒锛�", true);
- if (!this.update(new LambdaUpdateWrapper<Task>()
- .eq(Task::getId, task.getId())
- .set(Task::getUpdateBy, loginUserId)
- .set(Task::getUpdateTime, new Date())
- .set(Task::getTargLoc, task.getOrgLoc())
- .set(Task::getTaskStatus, TaskStsType.COMPLETE_IN.id))) {
+ Task update = new Task();
+ update.setId(task.getId());
+ update.setVersion(task.getVersion());
+ update.setUpdateBy(loginUserId);
+ update.setUpdateTime(new Date());
+ update.setTargLoc(task.getOrgLoc());
+ update.setTaskStatus(TaskStsType.COMPLETE_IN.id);
+ if (!this.updateById(update)) {
throw new CoolException("搴撳瓨鐘舵�佹洿鏂板け璐ワ紒锛�");
+ }
+ task.setUpdateBy(loginUserId);
+ task.setUpdateTime(update.getUpdateTime());
+ task.setTargLoc(task.getOrgLoc());
+ task.setTaskStatus(TaskStsType.COMPLETE_IN.id);
+ if (update.getVersion() != null) {
+ task.setVersion(update.getVersion());
}
}
@@ -2108,22 +2007,9 @@
}
/**淇敼涓哄簱浣嶇姸鎬佷负O.绌哄簱*/
- if (!locService.update(new LambdaUpdateWrapper<Loc>()
- .set(Loc::getUseStatus, LocStsType.LOC_STS_TYPE_O.type)
- .set(Loc::getBarcode, null)
- .set(Loc::getUpdateBy, loginUserId)
- .set(Loc::getUpdateTime, new Date())
- .eq(Loc::getId, loc.getId()))) {
- throw new CoolException("搴撲綅鐘舵�佷慨鏀瑰け璐ワ紒锛�");
- }
+ updateLocSnapshot(loc, LocStsType.LOC_STS_TYPE_O.type, null, loginUserId, "搴撲綅鐘舵�佷慨鏀瑰け璐ワ紒锛�", true);
- if (!this.update(new LambdaUpdateWrapper<Task>()
- .eq(Task::getId, task.getId())
- .set(Task::getUpdateBy, loginUserId)
- .set(Task::getUpdateTime, new Date())
- .set(Task::getTaskStatus, TaskStsType.UPDATED_OUT.id))) {
- throw new CoolException("搴撳瓨鐘舵�佹洿鏂板け璐ワ紒锛�");
- }
+ updateTaskSnapshot(task, TaskStsType.UPDATED_OUT.id, loginUserId, "搴撳瓨鐘舵�佹洿鏂板け璐ワ紒锛�");
}
/**
@@ -2357,10 +2243,7 @@
throw new CoolException("绔欑偣涓嶅瓨鍦紒锛�");
}
- if (!this.update(new LambdaUpdateWrapper<Task>().eq(Task::getTaskCode, task.getTaskCode())
- .set(Task::getTaskStatus, TaskStsType.WCS_EXECUTE_IN.id))) {
- throw new CoolException("浠诲姟鐘舵�佷慨鏀瑰け璐ワ紒锛�");
- }
+ updateTaskSnapshot(task, TaskStsType.WCS_EXECUTE_IN.id, null, "浠诲姟鐘舵�佷慨鏀瑰け璐ワ紒锛�");
/**鎺掗櫎绉诲簱鍔熻兘*/
if (!task.getTaskType().equals(TaskType.TASK_TYPE_LOC_MOVE.type)) {
/**濡傛灉鏄櫘閫氱珯鐐癸紝淇敼绔欑偣鐘舵�佷负鍑哄簱棰勭害*/
@@ -2381,10 +2264,7 @@
throw new CoolException("绔欑偣涓嶅瓨鍦紒锛�");
}
- if (!this.update(new LambdaUpdateWrapper<Task>().eq(Task::getTaskCode, task.getTaskCode())
- .set(Task::getTaskStatus, TaskStsType.WCS_EXECUTE_OUT.id))) {
- throw new CoolException("浠诲姟鐘舵�佷慨鏀瑰け璐ワ紒锛�");
- }
+ updateTaskSnapshot(task, TaskStsType.WCS_EXECUTE_OUT.id, null, "浠诲姟鐘舵�佷慨鏀瑰け璐ワ紒锛�");
/**濡傛灉鏄櫘閫氱珯鐐癸紝淇敼绔欑偣鐘舵�佷负鍏ュ簱棰勭害*/
if (curSta.getType().equals(StationTypeEnum.STATION_TYPE_NORMAL.type)) {
curSta.setUseStatus(LocStsType.LOC_STS_TYPE_S.type);
@@ -2462,12 +2342,8 @@
removeReceiptStock(pakinItem, loginUserId);
});
/**淇敼搴撲綅鐘舵�佷负F.鍦ㄥ簱*/
- if (!locService.update(new LambdaUpdateWrapper<Loc>().set(Loc::getUseStatus, LocStsType.LOC_STS_TYPE_F.type).eq(Loc::getCode, task.getTargLoc()))) {
- throw new CoolException("搴撲綅鐘舵�佷慨鏀瑰け璐ワ紒锛�");
- }
- if (!this.update(new LambdaUpdateWrapper<Task>().eq(Task::getId, task.getId()).set(Task::getTaskStatus, TaskStsType.UPDATED_IN.id))) {
- throw new CoolException("浠诲姟鐘舵�佷慨鏀瑰け璐ワ紒锛�");
- }
+ updateLocByCode(task.getTargLoc(), LocStsType.LOC_STS_TYPE_F.type, null, null, "搴撲綅鐘舵�佷慨鏀瑰け璐ワ紒锛�", false);
+ updateTaskSnapshot(task, TaskStsType.UPDATED_IN.id, null, "浠诲姟鐘舵�佷慨鏀瑰け璐ワ紒锛�");
}
/**
@@ -2492,12 +2368,8 @@
}
/**淇敼搴撲綅鐘舵�佷负"D", "绌烘澘"*/
- if (!locService.update(new LambdaUpdateWrapper<Loc>().set(Loc::getUseStatus, LocStsType.LOC_STS_TYPE_D.type).eq(Loc::getCode, task.getTargLoc()))) {
- throw new CoolException("搴撲綅鐘舵�佷慨鏀瑰け璐ワ紒锛�");
- }
- if (!this.update(new LambdaUpdateWrapper<Task>().eq(Task::getId, task.getId()).set(Task::getTaskStatus, TaskStsType.UPDATED_IN.id))) {
- throw new CoolException("浠诲姟鐘舵�佷慨鏀瑰け璐ワ紒锛�");
- }
+ updateLocByCode(task.getTargLoc(), LocStsType.LOC_STS_TYPE_D.type, null, null, "搴撲綅鐘舵�佷慨鏀瑰け璐ワ紒锛�", false);
+ updateTaskSnapshot(task, TaskStsType.UPDATED_IN.id, null, "浠诲姟鐘舵�佷慨鏀瑰け璐ワ紒锛�");
}
/**
@@ -2511,12 +2383,7 @@
@Transactional(rollbackFor = Exception.class)
public synchronized void removeReceiptStock(WaitPakinItem pakinItem, Long loginUserId) {
if (pakinItem.getType().equals(OrderType.ORDER_PRE.type)){
- if (!waitPakinService.update(new LambdaUpdateWrapper<WaitPakin>()
- .set(WaitPakin::getIoStatus, PakinIOStatus.PAKIN_IO_STATUS_TASK_DONE.val)
- .set(WaitPakin::getUpdateBy, loginUserId)
- .eq(WaitPakin::getId, pakinItem.getPakinId()))) {
- throw new CoolException("缁勬嫋鐘舵�佷慨鏀瑰け璐ワ紒锛�");
- }
+ updateWaitPakinById(pakinItem.getPakinId(), PakinIOStatus.PAKIN_IO_STATUS_TASK_DONE.val, loginUserId, "缁勬嫋鐘舵�佷慨鏀瑰け璐ワ紒锛�");
}else {
WarehouseAreasItem itemServiceOne = warehouseAreasItemService.getOne(new LambdaQueryWrapper<WarehouseAreasItem>()
.eq(WarehouseAreasItem::getId, pakinItem.getSource()));
@@ -2530,12 +2397,7 @@
Double qty = Math.round((itemServiceOne.getQty() + pakinItem.getAnfme()) * 1000000) / 1000000.0;
itemServiceOne.setWorkQty(workQty).setQty(qty);
- if (!waitPakinService.update(new LambdaUpdateWrapper<WaitPakin>()
- .set(WaitPakin::getIoStatus, PakinIOStatus.PAKIN_IO_STATUS_TASK_DONE.val)
- .set(WaitPakin::getUpdateBy, loginUserId)
- .eq(WaitPakin::getId, pakinItem.getPakinId()))) {
- throw new CoolException("缁勬嫋鐘舵�佷慨鏀瑰け璐ワ紒锛�");
- }
+ updateWaitPakinById(pakinItem.getPakinId(), PakinIOStatus.PAKIN_IO_STATUS_TASK_DONE.val, loginUserId, "缁勬嫋鐘舵�佷慨鏀瑰け璐ワ紒锛�");
if (qty.compareTo(itemServiceOne.getAnfme()) == 0.00) {
if (!warehouseAreasItemService.removeById(itemServiceOne.getId())) {
@@ -2665,4 +2527,156 @@
}
}
}
+
+ private void updateLocByCode(String locCode, String useStatus, String barcode, Long loginUserId, String errorMessage, boolean updateBarcode) {
+ Loc loc = locService.getOne(new LambdaQueryWrapper<Loc>().eq(Loc::getCode, locCode), false);
+ if (Objects.isNull(loc)) {
+ throw new CoolException("搴撲綅涓嶅瓨鍦紒锛�");
+ }
+ updateLocSnapshot(loc, useStatus, barcode, loginUserId, errorMessage, updateBarcode);
+ }
+
+ private void updateLocSnapshot(Loc loc, String useStatus, String barcode, Long loginUserId, String errorMessage, boolean updateBarcode) {
+ Loc update = new Loc();
+ update.setId(loc.getId());
+ update.setVersion(loc.getVersion());
+ update.setUseStatus(useStatus);
+ if (updateBarcode) {
+ update.setBarcode(barcode);
+ }
+ if (loginUserId != null) {
+ update.setUpdateBy(loginUserId);
+ update.setUpdateTime(new Date());
+ }
+ if (!locService.updateById(update)) {
+ throw new CoolException(errorMessage);
+ }
+ loc.setUseStatus(useStatus);
+ if (updateBarcode) {
+ loc.setBarcode(barcode);
+ }
+ if (loginUserId != null) {
+ loc.setUpdateBy(loginUserId);
+ loc.setUpdateTime(update.getUpdateTime());
+ }
+ if (update.getVersion() != null) {
+ loc.setVersion(update.getVersion());
+ }
+ }
+
+ private void updateWaitPakinById(Long pakinId, Short ioStatus, Long loginUserId, String errorMessage) {
+ WaitPakin waitPakin = waitPakinService.getById(pakinId);
+ if (Objects.isNull(waitPakin)) {
+ throw new CoolException("缁勬嫋涓嶅瓨鍦紒锛�");
+ }
+ updateWaitPakinSnapshot(waitPakin, ioStatus, loginUserId, false, errorMessage);
+ }
+
+ private void updateWaitPakinsStatus(List<WaitPakin> waitPakins, Short ioStatus, Long loginUserId, boolean updateCreateBy, String errorMessage) {
+ for (WaitPakin waitPakin : waitPakins) {
+ updateWaitPakinSnapshot(waitPakin, ioStatus, loginUserId, updateCreateBy, errorMessage);
+ }
+ }
+
+ private void updateWaitPakinSnapshot(WaitPakin waitPakin, Short ioStatus, Long loginUserId, boolean updateCreateBy, String errorMessage) {
+ WaitPakin update = new WaitPakin();
+ update.setId(waitPakin.getId());
+ update.setVersion(waitPakin.getVersion());
+ update.setIoStatus(ioStatus);
+ if (updateCreateBy && loginUserId != null) {
+ update.setCreateBy(loginUserId);
+ }
+ if (loginUserId != null) {
+ update.setUpdateBy(loginUserId);
+ update.setUpdateTime(new Date());
+ }
+ if (!waitPakinService.updateById(update)) {
+ throw new CoolException(errorMessage);
+ }
+ waitPakin.setIoStatus(ioStatus);
+ if (loginUserId != null) {
+ waitPakin.setUpdateBy(loginUserId);
+ waitPakin.setUpdateTime(update.getUpdateTime());
+ }
+ if (update.getVersion() != null) {
+ waitPakin.setVersion(update.getVersion());
+ }
+ }
+
+ private void updateWkOrderExceStatus(Long orderId, Short exceStatus, Long loginUserId, String errorMessage) {
+ WkOrder order = checkOrderService.getById(orderId);
+ if (Objects.isNull(order)) {
+ return;
+ }
+ WkOrder update = new WkOrder();
+ update.setId(order.getId());
+ update.setVersion(order.getVersion());
+ update.setExceStatus(exceStatus);
+ if (loginUserId != null) {
+ update.setUpdateBy(loginUserId);
+ update.setUpdateTime(new Date());
+ }
+ if (!checkOrderService.updateById(update)) {
+ throw new CoolException(errorMessage);
+ }
+ order.setExceStatus(exceStatus);
+ if (loginUserId != null) {
+ order.setUpdateBy(loginUserId);
+ order.setUpdateTime(update.getUpdateTime());
+ }
+ if (update.getVersion() != null) {
+ order.setVersion(update.getVersion());
+ }
+ }
+
+ private void updateWkOrderWorkQty(Long orderId, Double delta, Long loginUserId, String errorMessage) {
+ WkOrder order = checkOrderService.getById(orderId);
+ if (Objects.isNull(order)) {
+ throw new CoolException("鐩樼偣鍗曚笉瀛樺湪锛侊紒");
+ }
+ double currentWorkQty = Objects.isNull(order.getWorkQty()) ? 0.0 : order.getWorkQty();
+ double nextWorkQty = Math.round((currentWorkQty + delta) * 10000) / 10000.0;
+
+ WkOrder update = new WkOrder();
+ update.setId(order.getId());
+ update.setVersion(order.getVersion());
+ update.setWorkQty(nextWorkQty);
+ if (loginUserId != null) {
+ update.setUpdateBy(loginUserId);
+ update.setUpdateTime(new Date());
+ }
+ if (!checkOrderService.updateById(update)) {
+ throw new CoolException(errorMessage);
+ }
+ order.setWorkQty(nextWorkQty);
+ if (loginUserId != null) {
+ order.setUpdateBy(loginUserId);
+ order.setUpdateTime(update.getUpdateTime());
+ }
+ if (update.getVersion() != null) {
+ order.setVersion(update.getVersion());
+ }
+ }
+
+ private void updateTaskSnapshot(Task task, Integer taskStatus, Long loginUserId, String errorMessage) {
+ Task update = new Task();
+ update.setId(task.getId());
+ update.setVersion(task.getVersion());
+ update.setTaskStatus(taskStatus);
+ if (loginUserId != null) {
+ update.setUpdateBy(loginUserId);
+ update.setUpdateTime(new Date());
+ }
+ if (!this.updateById(update)) {
+ throw new CoolException(errorMessage);
+ }
+ task.setTaskStatus(taskStatus);
+ if (loginUserId != null) {
+ task.setUpdateBy(loginUserId);
+ task.setUpdateTime(update.getUpdateTime());
+ }
+ if (update.getVersion() != null) {
+ task.setVersion(update.getVersion());
+ }
+ }
}
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/WaveServiceImpl.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/WaveServiceImpl.java
index b3ad570..218fa07 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/WaveServiceImpl.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/WaveServiceImpl.java
@@ -96,11 +96,7 @@
}
List<Long> orderIds = waveItems.stream().map(WaveItem::getOrderId).collect(Collectors.toList());
/**淇敼鍑哄簱鍗曠姸鎬�*/
- if (!asnOrderService.update(new LambdaUpdateWrapper<WkOrder>()
- .set(WkOrder::getExceStatus, AsnExceStatus.OUT_STOCK_STATUS_TASK_WORKING.val)
- .in(WkOrder::getId, orderIds))) {
- throw new CoolException("鍑哄簱鍗曟嵁鐘舵�佷慨鏀瑰け璐ワ紒锛�");
- }
+ updateAsnOrders(orderIds, null, AsnExceStatus.OUT_STOCK_STATUS_TASK_WORKING.val, null, "鍑哄簱鍗曟嵁鐘舵�佷慨鏀瑰け璐ワ紒锛�");
return R.ok();
}
@@ -203,25 +199,9 @@
Double sum = taskItems.stream().mapToDouble(TaskItem::getAnfme).sum();
Double v = Math.round((wave.getWorkQty() + sum) * 1000000) / 1000000.0;
if (wave.getAnfme().compareTo(v) == 0) {
- if (!this.update(new LambdaUpdateWrapper<Wave>()
- .set(Wave::getExceStatus, WaveExceStatus.WAVE_EXCE_STATUS_TASK.val)
- .set(Wave::getWorkQty, v)
- .set(Wave::getUpdateBy, loginUserId)
- .set(Wave::getMemo, null)
- .set(Wave::getUpdateTime, new Date())
- .eq(Wave::getId, wave.getId()))) {
- throw new CoolException("娉㈡鐘舵�佷慨鏀瑰け璐ワ紒锛�");
- }
+ updateWaveSnapshot(wave, WaveExceStatus.WAVE_EXCE_STATUS_TASK.val, v, loginUserId, null, "娉㈡鐘舵�佷慨鏀瑰け璐ワ紒锛�");
} else {
- if (!this.update(new LambdaUpdateWrapper<Wave>()
- .set(Wave::getExceStatus, WaveExceStatus.WAVE_EXCE_STATUS_EXCING.val)
- .set(Wave::getWorkQty, v)
- .set(Wave::getUpdateBy, loginUserId)
- .set(Wave::getMemo, null)
- .set(Wave::getUpdateTime, new Date())
- .eq(Wave::getId, wave.getId()))) {
- throw new CoolException("娉㈡鐘舵�佷慨鏀瑰け璐ワ紒锛�");
- }
+ updateWaveSnapshot(wave, WaveExceStatus.WAVE_EXCE_STATUS_EXCING.val, v, loginUserId, null, "娉㈡鐘舵�佷慨鏀瑰け璐ワ紒锛�");
}
}
@@ -263,20 +243,71 @@
});
List<Long> orders = orderRelas.stream().map(WaveOrderRela::getOrderId).collect(Collectors.toList());
- if (!asnOrderService.update(new LambdaUpdateWrapper<WkOrder>()
- .set(WkOrder::getWorkQty, 0.0)
- .set(WkOrder::getExceStatus, AsnExceStatus.OUT_STOCK_STATUS_TASK_INIT.val)
- .in(WkOrder::getId, orders))) {
- throw new CoolException("鍗曟嵁鏇存柊澶辫触锛�!");
- }
+ updateAsnOrders(orders, 0.0, AsnExceStatus.OUT_STOCK_STATUS_TASK_INIT.val, null, "鍗曟嵁鏇存柊澶辫触锛侊紒");
- this.update(new LambdaUpdateWrapper<Wave>()
- .eq(Wave::getId, id)
- .set(Wave::getExceStatus, WaveExceStatus.WAVE_EXCE_STATUS_TASK.val));
+ updateWaveSnapshot(wave, WaveExceStatus.WAVE_EXCE_STATUS_TASK.val, null, null, null, "娉㈡鐘舵�佷慨鏀瑰け璐ワ紒锛�");
return R.ok();
}
+ private void updateWaveSnapshot(Wave wave, Short exceStatus, Double workQty, Long loginUserId, String memo, String errorMessage) {
+ Wave update = new Wave();
+ update.setId(wave.getId());
+ update.setVersion(wave.getVersion());
+ update.setExceStatus(exceStatus);
+ update.setWorkQty(workQty);
+ update.setUpdateBy(loginUserId);
+ update.setMemo(memo);
+ update.setUpdateTime(loginUserId == null ? null : new Date());
+ if (!this.updateById(update)) {
+ throw new CoolException(errorMessage);
+ }
+ wave.setExceStatus(exceStatus);
+ wave.setWorkQty(workQty);
+ wave.setUpdateBy(loginUserId);
+ if (loginUserId != null) {
+ wave.setUpdateTime(update.getUpdateTime());
+ }
+ wave.setMemo(memo);
+ if (update.getVersion() != null) {
+ wave.setVersion(update.getVersion());
+ }
+ }
+
+ private void updateAsnOrders(List<Long> orderIds, Double workQty, Short exceStatus, Long loginUserId, String errorMessage) {
+ if (Cools.isEmpty(orderIds)) {
+ return;
+ }
+ List<WkOrder> orders = asnOrderService.listByIds(orderIds.stream().distinct().collect(Collectors.toList()));
+ for (WkOrder order : orders) {
+ WkOrder update = new WkOrder();
+ update.setId(order.getId());
+ update.setVersion(order.getVersion());
+ if (workQty != null) {
+ update.setWorkQty(workQty);
+ }
+ update.setExceStatus(exceStatus);
+ if (loginUserId != null) {
+ update.setUpdateBy(loginUserId);
+ update.setUpdateTime(new Date());
+ }
+ if (!asnOrderService.updateById(update)) {
+ throw new CoolException(errorMessage);
+ }
+ if (workQty != null) {
+ order.setWorkQty(workQty);
+ }
+ order.setExceStatus(exceStatus);
+ if (loginUserId != null) {
+ order.setUpdateBy(loginUserId);
+ order.setUpdateTime(update.getUpdateTime());
+ }
+ if (update.getVersion() != null) {
+ order.setVersion(update.getVersion());
+ }
+ }
+ }
+
/**
* @param
* @param loginUserId
diff --git a/rsf-server/src/test/java/com/vincent/rsf/server/common/utils/OptimisticLockUtilsTest.java b/rsf-server/src/test/java/com/vincent/rsf/server/common/utils/OptimisticLockUtilsTest.java
new file mode 100644
index 0000000..7126a30
--- /dev/null
+++ b/rsf-server/src/test/java/com/vincent/rsf/server/common/utils/OptimisticLockUtilsTest.java
@@ -0,0 +1,23 @@
+package com.vincent.rsf.server.common.utils;
+
+import com.vincent.rsf.framework.exception.CoolException;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+class OptimisticLockUtilsTest {
+
+ @Test
+ void requireVersionRejectsMissingVersion() {
+ CoolException exception = assertThrows(CoolException.class,
+ () -> OptimisticLockUtils.requireVersion("浠诲姟", null));
+ assertEquals("浠诲姟鐗堟湰鍙蜂笉鑳戒负绌猴紝璇峰埛鏂板悗閲嶈瘯锛侊紒", exception.getMessage());
+ }
+
+ @Test
+ void requireVersionAllowsExistingVersion() {
+ assertDoesNotThrow(() -> OptimisticLockUtils.requireVersion("浠诲姟", 0));
+ }
+}
diff --git a/rsf-server/src/test/java/com/vincent/rsf/server/manager/mapper/MybatisPlusOptimisticLockIntegrationTest.java b/rsf-server/src/test/java/com/vincent/rsf/server/manager/mapper/MybatisPlusOptimisticLockIntegrationTest.java
new file mode 100644
index 0000000..1b016a0
--- /dev/null
+++ b/rsf-server/src/test/java/com/vincent/rsf/server/manager/mapper/MybatisPlusOptimisticLockIntegrationTest.java
@@ -0,0 +1,474 @@
+package com.vincent.rsf.server.manager.mapper;
+
+import com.baomidou.mybatisplus.core.MybatisConfiguration;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
+import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
+import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
+import com.vincent.rsf.server.manager.entity.Loc;
+import com.vincent.rsf.server.manager.entity.Task;
+import com.vincent.rsf.server.manager.entity.WaitPakin;
+import com.vincent.rsf.server.manager.entity.WkOrder;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.jdbc.datasource.DriverManagerDataSource;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+
+import javax.sql.DataSource;
+import java.util.Date;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+@ExtendWith(SpringExtension.class)
+@ContextConfiguration(classes = MybatisPlusOptimisticLockIntegrationTest.TestConfig.class)
+class MybatisPlusOptimisticLockIntegrationTest {
+
+ @Autowired
+ private WaitPakinMapper waitPakinMapper;
+
+ @Autowired
+ private LocMapper locMapper;
+
+ @Autowired
+ private AsnOrderMapper asnOrderMapper;
+
+ @Autowired
+ private TaskMapper taskMapper;
+
+ @Autowired
+ private JdbcTemplate jdbcTemplate;
+
+ @BeforeEach
+ void setUpSchema() {
+ jdbcTemplate.execute("drop table if exists man_wait_pakin");
+ jdbcTemplate.execute("drop table if exists man_loc");
+ jdbcTemplate.execute("drop table if exists man_asn_order");
+ jdbcTemplate.execute("drop table if exists man_task");
+ jdbcTemplate.execute("""
+ create table man_wait_pakin (
+ id bigint auto_increment primary key,
+ code varchar(64),
+ barcode varchar(64),
+ anfme double,
+ io_status smallint,
+ flag_defect smallint,
+ status integer,
+ deleted integer,
+ tenant_id integer,
+ create_by bigint,
+ create_time timestamp,
+ update_by bigint,
+ update_time timestamp,
+ memo varchar(255),
+ version integer not null default 0
+ )
+ """);
+ jdbcTemplate.execute("""
+ create table man_loc (
+ id bigint auto_increment primary key,
+ area_id bigint,
+ code varchar(64),
+ warehouse_id bigint,
+ `type` varchar(64),
+ flag_logic smallint,
+ fuc_atrrs varchar(255),
+ barcode varchar(64),
+ unit varchar(64),
+ `length` double,
+ height double,
+ width double,
+ `row` integer,
+ device_no integer,
+ col integer,
+ lev integer,
+ `channel` integer,
+ max_parts integer,
+ max_pack integer,
+ use_status varchar(8),
+ flag_label_mange smallint,
+ loc_attrs varchar(255),
+ status integer,
+ deleted integer,
+ tenant_id integer,
+ create_by bigint,
+ create_time timestamp,
+ update_by bigint,
+ update_time timestamp,
+ memo varchar(255),
+ version integer not null default 0
+ )
+ """);
+ jdbcTemplate.execute("""
+ create table man_asn_order (
+ id bigint auto_increment primary key,
+ code varchar(64),
+ po_code varchar(64),
+ po_id bigint,
+ `type` varchar(64),
+ wk_type varchar(64),
+ check_type integer,
+ anfme double,
+ work_qty double,
+ qty double,
+ logis_no varchar(64),
+ wave_id bigint,
+ arr_time timestamp,
+ nty_status integer,
+ report_once integer,
+ rle_status smallint,
+ exce_status smallint,
+ status integer,
+ deleted integer,
+ tenant_id integer,
+ create_by bigint,
+ create_time timestamp,
+ update_by bigint,
+ update_time timestamp,
+ version integer not null default 0,
+ memo varchar(255),
+ warehouse_id bigint,
+ ware_area_id bigint,
+ business_time timestamp,
+ station_id varchar(64),
+ shipper_id bigint,
+ order_internal_code varchar(64),
+ stock_direct varchar(64),
+ customer_id varchar(64),
+ customer_name varchar(255),
+ supplier_id varchar(64),
+ supplier_name varchar(255),
+ stock_org_id varchar(64),
+ stock_org_name varchar(255),
+ purchase_org_id varchar(64),
+ purchase_org_name varchar(255),
+ purchase_user_id varchar(64),
+ purchase_user_name varchar(255),
+ prd_org_id varchar(64),
+ prd_org_name varchar(255),
+ sale_org_id varchar(64),
+ sale_org_name varchar(255),
+ sale_user_id varchar(64),
+ sale_user_name varchar(255)
+ )
+ """);
+ jdbcTemplate.execute("""
+ create table man_task (
+ id bigint auto_increment primary key,
+ task_code varchar(64),
+ resource smallint,
+ task_status integer,
+ parent_id bigint,
+ wareh_type varchar(64),
+ task_type integer,
+ org_loc varchar(64),
+ targ_loc varchar(64),
+ org_site varchar(64),
+ targ_site varchar(64),
+ barcode varchar(64),
+ robot_code varchar(64),
+ exce_status smallint,
+ exp_desc varchar(255),
+ sort integer,
+ exp_code varchar(64),
+ start_time timestamp,
+ end_time timestamp,
+ status integer,
+ task_origin varchar(64),
+ deleted integer,
+ tenant_id integer,
+ create_by bigint,
+ create_time timestamp,
+ update_by bigint,
+ update_time timestamp,
+ version integer not null default 0,
+ memo varchar(255),
+ device_site_id bigint,
+ sou_step varchar(64),
+ end_step varchar(64),
+ targ_site_area varchar(255),
+ targ_loc_area varchar(255),
+ targ_site_area_now varchar(255)
+ )
+ """);
+ }
+
+ @Test
+ void updateByIdRejectsStaleSnapshot() {
+ WaitPakin seed = waitPakin();
+ waitPakinMapper.insert(seed);
+
+ WaitPakin firstSnapshot = waitPakinMapper.selectById(seed.getId());
+ WaitPakin secondSnapshot = waitPakinMapper.selectById(seed.getId());
+
+ firstSnapshot.setIoStatus((short) 1);
+ firstSnapshot.setUpdateBy(2L);
+ firstSnapshot.setUpdateTime(new Date());
+ assertEquals(1, waitPakinMapper.updateById(firstSnapshot));
+ assertEquals(1, firstSnapshot.getVersion());
+
+ secondSnapshot.setIoStatus((short) 2);
+ secondSnapshot.setUpdateBy(3L);
+ secondSnapshot.setUpdateTime(new Date());
+ assertEquals(0, waitPakinMapper.updateById(secondSnapshot));
+
+ WaitPakin latest = waitPakinMapper.selectById(seed.getId());
+ assertEquals((short) 1, latest.getIoStatus());
+ assertEquals(1, latest.getVersion());
+ }
+
+ @Test
+ void updateWithEntityAndWrapperRejectsStaleSnapshot() {
+ WaitPakin seed = waitPakin();
+ waitPakinMapper.insert(seed);
+
+ WaitPakin firstSnapshot = waitPakinMapper.selectById(seed.getId());
+ WaitPakin secondSnapshot = waitPakinMapper.selectById(seed.getId());
+
+ WaitPakin firstUpdate = new WaitPakin();
+ firstUpdate.setId(firstSnapshot.getId());
+ firstUpdate.setVersion(firstSnapshot.getVersion());
+ firstUpdate.setIoStatus((short) 1);
+ firstUpdate.setUpdateBy(2L);
+ firstUpdate.setUpdateTime(new Date());
+ assertEquals(1, waitPakinMapper.update(firstUpdate,
+ new LambdaUpdateWrapper<WaitPakin>().eq(WaitPakin::getId, firstSnapshot.getId())));
+ assertEquals(1, firstUpdate.getVersion());
+
+ WaitPakin secondUpdate = new WaitPakin();
+ secondUpdate.setId(secondSnapshot.getId());
+ secondUpdate.setVersion(secondSnapshot.getVersion());
+ secondUpdate.setIoStatus((short) 2);
+ secondUpdate.setUpdateBy(3L);
+ secondUpdate.setUpdateTime(new Date());
+ assertEquals(0, waitPakinMapper.update(secondUpdate,
+ new LambdaUpdateWrapper<WaitPakin>().eq(WaitPakin::getId, secondSnapshot.getId())));
+
+ WaitPakin latest = waitPakinMapper.selectById(seed.getId());
+ assertEquals((short) 1, latest.getIoStatus());
+ assertEquals(1, latest.getVersion());
+ }
+
+ @Test
+ void locUpdateWithEntityAndWrapperRejectsStaleSnapshot() {
+ Loc seed = loc();
+ locMapper.insert(seed);
+
+ Loc firstSnapshot = locMapper.selectById(seed.getId());
+ Loc secondSnapshot = locMapper.selectById(seed.getId());
+
+ Loc firstUpdate = new Loc();
+ firstUpdate.setId(firstSnapshot.getId());
+ firstUpdate.setVersion(firstSnapshot.getVersion());
+ firstUpdate.setUseStatus("S");
+ firstUpdate.setBarcode("BC-LOC-001");
+ firstUpdate.setUpdateBy(2L);
+ firstUpdate.setUpdateTime(new Date());
+ assertEquals(1, locMapper.update(firstUpdate,
+ new LambdaUpdateWrapper<Loc>().eq(Loc::getId, firstSnapshot.getId())));
+ assertEquals(1, firstUpdate.getVersion());
+
+ Loc secondUpdate = new Loc();
+ secondUpdate.setId(secondSnapshot.getId());
+ secondUpdate.setVersion(secondSnapshot.getVersion());
+ secondUpdate.setUseStatus("F");
+ secondUpdate.setBarcode("BC-LOC-002");
+ secondUpdate.setUpdateBy(3L);
+ secondUpdate.setUpdateTime(new Date());
+ assertEquals(0, locMapper.update(secondUpdate,
+ new LambdaUpdateWrapper<Loc>().eq(Loc::getId, secondSnapshot.getId())));
+
+ Loc latest = locMapper.selectById(seed.getId());
+ assertEquals("S", latest.getUseStatus());
+ assertEquals("BC-LOC-001", latest.getBarcode());
+ assertEquals(1, latest.getVersion());
+ }
+
+ @Test
+ void wkOrderUpdateByIdRejectsStaleSnapshot() {
+ WkOrder seed = wkOrder();
+ asnOrderMapper.insert(seed);
+
+ WkOrder firstSnapshot = asnOrderMapper.selectById(seed.getId());
+ WkOrder secondSnapshot = asnOrderMapper.selectById(seed.getId());
+
+ firstSnapshot.setExceStatus((short) 1);
+ firstSnapshot.setUpdateBy(2L);
+ firstSnapshot.setUpdateTime(new Date());
+ assertEquals(1, asnOrderMapper.updateById(firstSnapshot));
+ assertEquals(1, firstSnapshot.getVersion());
+
+ secondSnapshot.setExceStatus((short) 2);
+ secondSnapshot.setUpdateBy(3L);
+ secondSnapshot.setUpdateTime(new Date());
+ assertEquals(0, asnOrderMapper.updateById(secondSnapshot));
+
+ WkOrder latest = asnOrderMapper.selectById(seed.getId());
+ assertEquals((short) 1, latest.getExceStatus());
+ assertEquals(1, latest.getVersion());
+ }
+
+ @Test
+ void wkOrderWorkQtyUpdateRejectsStaleSnapshot() {
+ WkOrder seed = wkOrder();
+ asnOrderMapper.insert(seed);
+
+ WkOrder firstSnapshot = asnOrderMapper.selectById(seed.getId());
+ WkOrder secondSnapshot = asnOrderMapper.selectById(seed.getId());
+
+ firstSnapshot.setWorkQty(2.5);
+ firstSnapshot.setUpdateBy(2L);
+ firstSnapshot.setUpdateTime(new Date());
+ assertEquals(1, asnOrderMapper.updateById(firstSnapshot));
+ assertEquals(1, firstSnapshot.getVersion());
+
+ secondSnapshot.setWorkQty(1.0);
+ secondSnapshot.setUpdateBy(3L);
+ secondSnapshot.setUpdateTime(new Date());
+ assertEquals(0, asnOrderMapper.updateById(secondSnapshot));
+
+ WkOrder latest = asnOrderMapper.selectById(seed.getId());
+ assertEquals(2.5, latest.getWorkQty());
+ assertEquals(1, latest.getVersion());
+ }
+
+ @Test
+ void taskUpdateByIdRejectsStaleSnapshot() {
+ Task seed = task();
+ taskMapper.insert(seed);
+
+ Task firstSnapshot = taskMapper.selectById(seed.getId());
+ Task secondSnapshot = taskMapper.selectById(seed.getId());
+
+ firstSnapshot.setTaskStatus(1);
+ firstSnapshot.setUpdateBy(2L);
+ firstSnapshot.setUpdateTime(new Date());
+ assertEquals(1, taskMapper.updateById(firstSnapshot));
+ assertEquals(1, firstSnapshot.getVersion());
+
+ secondSnapshot.setTaskStatus(2);
+ secondSnapshot.setUpdateBy(3L);
+ secondSnapshot.setUpdateTime(new Date());
+ assertEquals(0, taskMapper.updateById(secondSnapshot));
+
+ Task latest = taskMapper.selectById(seed.getId());
+ assertEquals(1, latest.getTaskStatus());
+ assertEquals(1, latest.getVersion());
+ }
+
+ private WaitPakin waitPakin() {
+ return new WaitPakin()
+ .setCode("PK-001")
+ .setBarcode("BC-001")
+ .setAnfme(1.0)
+ .setIoStatus((short) 0)
+ .setFlagDefect((short) 0)
+ .setStatus(1)
+ .setDeleted(0)
+ .setTenantId(1)
+ .setCreateBy(1L)
+ .setCreateTime(new Date())
+ .setUpdateBy(1L)
+ .setUpdateTime(new Date())
+ .setMemo("seed");
+ }
+
+ private Loc loc() {
+ return new Loc()
+ .setCode("LOC-001")
+ .setBarcode(null)
+ .setUseStatus("O")
+ .setStatus(1)
+ .setDeleted(0)
+ .setTenantId(1)
+ .setCreateBy(1L)
+ .setCreateTime(new Date())
+ .setUpdateBy(1L)
+ .setUpdateTime(new Date())
+ .setMemo("seed");
+ }
+
+ private WkOrder wkOrder() {
+ return new WkOrder()
+ .setCode("ASN-001")
+ .setType("CHECK")
+ .setWkType("IN")
+ .setAnfme(1.0)
+ .setWorkQty(0.0)
+ .setQty(0.0)
+ .setRleStatus((short) 0)
+ .setExceStatus((short) 0)
+ .setStatus(1)
+ .setDeleted(0)
+ .setTenantId(1)
+ .setCreateBy(1L)
+ .setCreateTime(new Date())
+ .setUpdateBy(1L)
+ .setUpdateTime(new Date())
+ .setMemo("seed");
+ }
+
+ private Task task() {
+ return new Task()
+ .setTaskCode("TASK-001")
+ .setTaskStatus(0)
+ .setTaskType(1)
+ .setOrgLoc("ORG-001")
+ .setTargLoc("TARG-001")
+ .setBarcode("BC-TASK-001")
+ .setExceStatus((short) 0)
+ .setStatus(1)
+ .setDeleted(0)
+ .setTenantId(1)
+ .setCreateBy(1L)
+ .setCreateTime(new Date())
+ .setUpdateBy(1L)
+ .setUpdateTime(new Date())
+ .setMemo("seed");
+ }
+
+ @Configuration
+ @MapperScan(basePackageClasses = {WaitPakinMapper.class, LocMapper.class, AsnOrderMapper.class, TaskMapper.class})
+ static class TestConfig {
+
+ @Bean
+ DataSource dataSource() {
+ DriverManagerDataSource dataSource = new DriverManagerDataSource();
+ dataSource.setDriverClassName("org.h2.Driver");
+ dataSource.setUrl("jdbc:h2:mem:optimistic-lock;MODE=MySQL;DB_CLOSE_DELAY=-1");
+ dataSource.setUsername("sa");
+ dataSource.setPassword("");
+ return dataSource;
+ }
+
+ @Bean
+ JdbcTemplate jdbcTemplate(DataSource dataSource) {
+ return new JdbcTemplate(dataSource);
+ }
+
+ @Bean
+ MybatisPlusInterceptor mybatisPlusInterceptor() {
+ MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
+ interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
+ return interceptor;
+ }
+
+ @Bean
+ MybatisSqlSessionFactoryBean sqlSessionFactory(DataSource dataSource,
+ MybatisPlusInterceptor mybatisPlusInterceptor) {
+ MybatisSqlSessionFactoryBean factoryBean = new MybatisSqlSessionFactoryBean();
+ factoryBean.setDataSource(dataSource);
+ factoryBean.setPlugins(mybatisPlusInterceptor);
+ MybatisConfiguration configuration = new MybatisConfiguration();
+ configuration.setMapUnderscoreToCamelCase(true);
+ factoryBean.setConfiguration(configuration);
+ return factoryBean;
+ }
+ }
+}
diff --git a/rsf-server/src/test/java/com/vincent/rsf/server/system/controller/MenuControllerTest.java b/rsf-server/src/test/java/com/vincent/rsf/server/system/controller/MenuControllerTest.java
new file mode 100644
index 0000000..e529b25
--- /dev/null
+++ b/rsf-server/src/test/java/com/vincent/rsf/server/system/controller/MenuControllerTest.java
@@ -0,0 +1,125 @@
+package com.vincent.rsf.server.system.controller;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.vincent.rsf.framework.common.R;
+import com.vincent.rsf.server.common.service.RedisService;
+import com.vincent.rsf.server.system.entity.Menu;
+import com.vincent.rsf.server.system.service.MenuService;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.springframework.test.util.ReflectionTestUtils;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+@ExtendWith(MockitoExtension.class)
+class MenuControllerTest {
+
+ private static final String MENU_TREE_CACHE_FLAG = "MENU_TREE";
+ private static final String MENU_TREE_CACHE_KEY = "FULL_TREE";
+
+ @Mock
+ private MenuService menuService;
+ @Mock
+ private RedisService redisService;
+
+ private MenuController menuController;
+
+ @BeforeEach
+ void setUp() {
+ menuController = new MenuController();
+ ReflectionTestUtils.setField(menuController, "menuService", menuService);
+ ReflectionTestUtils.setField(menuController, "redisService", redisService);
+ }
+
+ @Test
+ void treeReturnsCachedTreeBeforeQueryingDatabase() {
+ List<Menu> cachedTree = List.of(menu(1L, 0L, "System"));
+ when(redisService.get(MENU_TREE_CACHE_FLAG, MENU_TREE_CACHE_KEY)).thenReturn(cachedTree);
+
+ R result = menuController.tree(new HashMap<>());
+
+ assertEquals(cachedTree, result.get("data"));
+ verify(menuService, never()).list(any(LambdaQueryWrapper.class));
+ }
+
+ @Test
+ void treeLoadsFromDatabaseAndCachesFullTreeWhenCacheMissing() {
+ when(redisService.get(MENU_TREE_CACHE_FLAG, MENU_TREE_CACHE_KEY)).thenReturn(null);
+ when(menuService.list(any(LambdaQueryWrapper.class))).thenReturn(List.of(
+ menu(1L, 0L, "System"),
+ menu(2L, 1L, "User")
+ ));
+
+ R result = menuController.tree(new HashMap<>());
+
+ List<Menu> tree = cast(result.get("data"));
+ assertEquals(1, tree.size());
+ assertNotNull(tree.get(0).getChildren());
+ assertEquals(1, tree.get(0).getChildren().size());
+
+ ArgumentCaptor<Object> captor = ArgumentCaptor.forClass(Object.class);
+ verify(redisService).set(eq(MENU_TREE_CACHE_FLAG), eq(MENU_TREE_CACHE_KEY), captor.capture(), anyInt());
+ List<Menu> cachedTree = cast(captor.getValue());
+ assertEquals(1, cachedTree.size());
+ assertEquals(1L, cachedTree.get(0).getId());
+ }
+
+ @Test
+ void saveEvictsMenuTreeCacheAfterSuccessfulSave() {
+ Menu menu = menu(1L, 0L, "System");
+ when(menuService.save(menu)).thenReturn(true);
+
+ menuController.save(menu);
+
+ verify(redisService).delete(MENU_TREE_CACHE_FLAG, MENU_TREE_CACHE_KEY);
+ }
+
+ @Test
+ void updateEvictsMenuTreeCacheAfterSuccessfulUpdate() {
+ Menu menu = menu(1L, 0L, "System");
+ when(menuService.updateById(menu)).thenReturn(true);
+
+ menuController.update(menu);
+
+ verify(redisService).delete(MENU_TREE_CACHE_FLAG, MENU_TREE_CACHE_KEY);
+ }
+
+ @Test
+ void removeEvictsMenuTreeCacheAfterSuccessfulRemove() {
+ when(menuService.removeByIds(List.of(1L, 2L))).thenReturn(true);
+
+ menuController.remove(new Long[]{1L, 2L});
+
+ verify(redisService).delete(MENU_TREE_CACHE_FLAG, MENU_TREE_CACHE_KEY);
+ }
+
+ private Menu menu(Long id, Long parentId, String name) {
+ Menu menu = new Menu();
+ menu.setId(id);
+ menu.setParentId(parentId);
+ menu.setName(name);
+ menu.setChildren(new ArrayList<>());
+ return menu;
+ }
+
+ @SuppressWarnings("unchecked")
+ private List<Menu> cast(Object value) {
+ return (List<Menu>) value;
+ }
+}
diff --git a/rsf-server/src/test/java/com/vincent/rsf/server/system/entity/MenuJsonTest.java b/rsf-server/src/test/java/com/vincent/rsf/server/system/entity/MenuJsonTest.java
new file mode 100644
index 0000000..9026bde
--- /dev/null
+++ b/rsf-server/src/test/java/com/vincent/rsf/server/system/entity/MenuJsonTest.java
@@ -0,0 +1,30 @@
+package com.vincent.rsf.server.system.entity;
+
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.junit.jupiter.api.Test;
+
+import java.util.Map;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+
+class MenuJsonTest {
+
+ private final ObjectMapper objectMapper = new ObjectMapper();
+
+ @Test
+ void serializationShouldIgnoreDatabaseBackedDisplayGetters() {
+ Menu menu = new Menu();
+ menu.setId(1L);
+ menu.setTenantId(2L);
+ menu.setCreateBy(3L);
+ menu.setUpdateBy(4L);
+
+ Map<String, Object> json = objectMapper.convertValue(menu, new TypeReference<Map<String, Object>>() {
+ });
+
+ assertFalse(json.containsKey("tenantId$"));
+ assertFalse(json.containsKey("createBy$"));
+ assertFalse(json.containsKey("updateBy$"));
+ }
+}
diff --git a/version/db/20260327_optimistic_lock.sql b/version/db/20260327_optimistic_lock.sql
new file mode 100644
index 0000000..26acaec
--- /dev/null
+++ b/version/db/20260327_optimistic_lock.sql
@@ -0,0 +1,14 @@
+ALTER TABLE `man_task`
+ ADD COLUMN `version` int NOT NULL DEFAULT 0 COMMENT '涔愯閿佺増鏈�';
+
+ALTER TABLE `man_loc`
+ ADD COLUMN `version` int NOT NULL DEFAULT 0 COMMENT '涔愯閿佺増鏈�';
+
+ALTER TABLE `man_wait_pakin`
+ ADD COLUMN `version` int NOT NULL DEFAULT 0 COMMENT '涔愯閿佺増鏈�';
+
+ALTER TABLE `man_wave`
+ ADD COLUMN `version` int NOT NULL DEFAULT 0 COMMENT '涔愯閿佺増鏈�';
+
+ALTER TABLE `man_asn_order`
+ ADD COLUMN `version` int NOT NULL DEFAULT 0 COMMENT '涔愯閿佺増鏈�';
--
Gitblit v1.9.1