From c1c045cad0f39a38409de117e9ddf470804b0d81 Mon Sep 17 00:00:00 2001
From: zhou zhou <3272660260@qq.com>
Date: 星期二, 07 四月 2026 10:22:00 +0800
Subject: [PATCH] #
---
rsf-server/pom.xml | 4 +
rsf-server/src/main/java/com/vincent/rsf/server/common/redis/RedisKeys.java | 23 +++++++
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/WmsRedisLuaService.java | 68 ++++++++++++++++++++++
rsf-server/src/main/resources/wms-lua/inventory-reserve.lua | 20 ++++++
rsf-server/src/main/resources/wms-lua/location-claim.lua | 19 ++++++
rsf-server/src/main/java/com/vincent/rsf/server/common/redis/RedisConstants.java | 12 ++++
6 files changed, 146 insertions(+), 0 deletions(-)
diff --git a/rsf-server/pom.xml b/rsf-server/pom.xml
index d7b7edb..454c873 100644
--- a/rsf-server/pom.xml
+++ b/rsf-server/pom.xml
@@ -46,6 +46,10 @@
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-data-redis</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/common/redis/RedisConstants.java b/rsf-server/src/main/java/com/vincent/rsf/server/common/redis/RedisConstants.java
new file mode 100644
index 0000000..a06854d
--- /dev/null
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/common/redis/RedisConstants.java
@@ -0,0 +1,12 @@
+package com.vincent.rsf.server.common.redis;
+
+public final class RedisConstants {
+
+ private RedisConstants() {
+ }
+
+
+
+ public static final String LUA_MODE_PUTAWAY = "PUTAWAY";
+ public static final String LUA_MODE_PICK = "PICK";
+}
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/common/redis/RedisKeys.java b/rsf-server/src/main/java/com/vincent/rsf/server/common/redis/RedisKeys.java
new file mode 100644
index 0000000..28d6979
--- /dev/null
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/common/redis/RedisKeys.java
@@ -0,0 +1,23 @@
+package com.vincent.rsf.server.common.redis;
+
+public final class RedisKeys {
+
+ private RedisKeys() {
+ }
+
+ public static String locationOccupy(Long locationId) {
+ return "wms:location:occupy:" + locationId;
+ }
+
+ public static String locationTaskOccupy(Long locationId) {
+ return "wms:task:occupy:location:" + locationId;
+ }
+
+ public static String stockAvailable(Long inventoryId) {
+ return "wms:stock:available:" + inventoryId;
+ }
+
+ public static String stockReserve(String orderNo) {
+ return "wms:stock:reserve:" + orderNo;
+ }
+}
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/WmsRedisLuaService.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/WmsRedisLuaService.java
new file mode 100644
index 0000000..9b01001
--- /dev/null
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/WmsRedisLuaService.java
@@ -0,0 +1,68 @@
+package com.vincent.rsf.server.manager.service.impl;
+
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.data.redis.core.StringRedisTemplate;
+import org.springframework.data.redis.core.script.DefaultRedisScript;
+import org.springframework.stereotype.Service;
+
+import java.math.BigDecimal;
+import java.time.Duration;
+import java.util.Arrays;
+
+@Slf4j
+@Service
+@RequiredArgsConstructor
+public class WmsRedisLuaService {
+
+ private static final DefaultRedisScript<Long> LOCATION_CLAIM_SCRIPT = createScript("wms-lua/location-claim.lua");
+ private static final DefaultRedisScript<Long> INVENTORY_RESERVE_SCRIPT = createScript("wms-lua/inventory-reserve.lua");
+
+ private final StringRedisTemplate redisTemplate;
+
+ public boolean claimLocation(String occupyKey, String taskKey, String mode, String occupyValue, String taskValue, Duration ttl) {
+ Long result = redisTemplate.execute(
+ LOCATION_CLAIM_SCRIPT,
+ Arrays.asList(occupyKey, taskKey),
+ mode,
+ occupyValue,
+ taskValue,
+ String.valueOf(ttl.toMillis())
+ );
+ return result != null && result > 0;
+ }
+
+ public boolean reserveInventory(String inventoryKey, String orderKey, BigDecimal initialAvailable, BigDecimal reserveQuantity, Duration ttl) {
+ Long result = redisTemplate.execute(
+ INVENTORY_RESERVE_SCRIPT,
+ Arrays.asList(inventoryKey, orderKey),
+ initialAvailable.toPlainString(),
+ reserveQuantity.toPlainString(),
+ String.valueOf(ttl.toMillis())
+ );
+ return result != null && result > 0;
+ }
+
+ public void releaseKeys(String... keys) {
+ if (keys == null || keys.length == 0) {
+ return;
+ }
+ try {
+ redisTemplate.delete(Arrays.asList(keys));
+ } catch (Exception ex) {
+ log.warn("Release redis keys failed", ex);
+ }
+ }
+
+ public void resetInventoryCache(String inventoryKey, BigDecimal availableQuantity, Duration ttl) {
+ redisTemplate.opsForValue().set(inventoryKey, availableQuantity.toPlainString(), ttl);
+ }
+
+ private static DefaultRedisScript<Long> createScript(String path) {
+ DefaultRedisScript<Long> script = new DefaultRedisScript<>();
+ script.setLocation(new ClassPathResource(path));
+ script.setResultType(Long.class);
+ return script;
+ }
+}
diff --git a/rsf-server/src/main/resources/wms-lua/inventory-reserve.lua b/rsf-server/src/main/resources/wms-lua/inventory-reserve.lua
new file mode 100644
index 0000000..3ccd793
--- /dev/null
+++ b/rsf-server/src/main/resources/wms-lua/inventory-reserve.lua
@@ -0,0 +1,20 @@
+local current = redis.call('get', KEYS[1])
+local initial = tonumber(ARGV[1])
+local reserve = tonumber(ARGV[2])
+local ttl = tonumber(ARGV[3])
+
+if current == false then
+ current = initial
+else
+ current = tonumber(current)
+end
+
+if current < reserve then
+ return 0
+end
+
+local nextValue = current - reserve
+redis.call('psetex', KEYS[1], ttl, tostring(nextValue))
+redis.call('incrbyfloat', KEYS[2], reserve)
+redis.call('pexpire', KEYS[2], ttl)
+return 1
diff --git a/rsf-server/src/main/resources/wms-lua/location-claim.lua b/rsf-server/src/main/resources/wms-lua/location-claim.lua
new file mode 100644
index 0000000..b6e6896
--- /dev/null
+++ b/rsf-server/src/main/resources/wms-lua/location-claim.lua
@@ -0,0 +1,19 @@
+local mode = ARGV[1]
+local occupyValue = ARGV[2]
+local taskValue = ARGV[3]
+local ttl = tonumber(ARGV[4])
+
+if mode == 'PUTAWAY' then
+ if redis.call('exists', KEYS[1]) == 1 or redis.call('exists', KEYS[2]) == 1 then
+ return 0
+ end
+ redis.call('psetex', KEYS[1], ttl, occupyValue)
+ redis.call('psetex', KEYS[2], ttl, taskValue)
+ return 1
+end
+
+if redis.call('exists', KEYS[2]) == 1 then
+ return 0
+end
+redis.call('psetex', KEYS[2], ttl, taskValue)
+return 1
--
Gitblit v1.9.1