mirror of
http://192.168.1.205:9980/cf_devdept2/cf_imes_server.git
synced 2026-08-12 21:02:08 +08:00
新增排单锁
This commit is contained in:
+1
@@ -24,6 +24,7 @@ public class ErrorCodeConstants {
|
||||
public static final ErrorCode ORDER_PLATE_UPDATE_CONCURRENCY_ERROR = new ErrorCode(1_003_107_012, "order.plate.update.concurrency.error");
|
||||
public static final ErrorCode GOODS_PLATE_UPDATE_CONCURRENCY_ERROR = new ErrorCode(1_003_107_013, "goods.plate.update.concurrency.error");
|
||||
public static final ErrorCode BODY_PLATE_UPDATE_CONCURRENCY_ERROR = new ErrorCode(1_003_107_014, "body.plate.update.concurrency.error");
|
||||
public static final ErrorCode ORDER_PLAN_LOCKED = new ErrorCode(1_003_107_015, "当前排单已锁定,请稍后再试");
|
||||
|
||||
|
||||
// ========== 订单商品 1_003_108_000 ==========
|
||||
|
||||
+2
-2
@@ -72,9 +72,9 @@ public class OptimizePlanController {
|
||||
@PreAuthorize("@ss.hasAnyPermissions('placeorder:optimize','production:manager-list:calculate','manage:order-plan:process-scheme','producePlan:order-plan:process-scheme','producePlan:optimize')")
|
||||
public CommonResult<OrderSource> getOrderSource(@Schema(description = "订单id") @RequestParam(required = false) Long orderId,
|
||||
@Schema(description = "排单id") @RequestParam(required = false) Long planId,
|
||||
@Schema(description = "机台Id") @RequestParam(required = false) Long machineId
|
||||
@Schema(description = "排单值") @RequestParam(required = false) String val
|
||||
) {
|
||||
return CommonResult.success(optimizePlanService.getOrderSource(orderId, planId, machineId));
|
||||
return CommonResult.success(optimizePlanService.getOrderSource(orderId, planId, val));
|
||||
|
||||
}
|
||||
|
||||
|
||||
+14
-1
@@ -193,6 +193,19 @@ public class PlanController {
|
||||
}
|
||||
|
||||
|
||||
@PostMapping("/lock")
|
||||
@Operation(summary = "获取排单锁")
|
||||
@PreAuthorize("@ss.hasAnyPermissions('placeorder:optimize','production:manager-list:calculate','manage:order-plan:process-scheme','producePlan:order-plan:process-scheme','producePlan:optimize')")
|
||||
public CommonResult<Boolean> getPlanLock(@RequestBody OrderPlanLockReqVO orderPlanLockReqVO) {
|
||||
planService.getPlanLock(orderPlanLockReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
|
||||
@PostMapping("/release/lock")
|
||||
@Operation(summary = "释放排单锁")
|
||||
@PreAuthorize("@ss.hasAnyPermissions('placeorder:optimize','production:manager-list:calculate','manage:order-plan:process-scheme','producePlan:order-plan:process-scheme','producePlan:optimize')")
|
||||
public CommonResult<Boolean> releasePlanLock(@RequestBody OrderPlanLockReqVO orderPlanLockReqVO) {
|
||||
planService.releasePlanLock(orderPlanLockReqVO);
|
||||
return success(true);
|
||||
}
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
package com.cf.imes.module.executor.controller.admin.plan.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author Gqr
|
||||
* @since 2026/6/8 16:43
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "排单锁定请求参数")
|
||||
public class OrderPlanLockReqVO {
|
||||
@Schema(description = "排单ID")
|
||||
@NotNull(message = "排单ID不能为空")
|
||||
private Long planId;
|
||||
|
||||
@Schema(description = "排单优化本地值")
|
||||
@NotNull(message = "排单优化本地值不能为空")
|
||||
private String val;
|
||||
}
|
||||
+1
-1
@@ -27,7 +27,7 @@ public interface OptimizePlanService {
|
||||
|
||||
Map<String, Object> getLabelDataSourceValue(GetSourceDataReq req);
|
||||
|
||||
OrderSource getOrderSource(Long orderId, Long planId, Long machineId);
|
||||
OrderSource getOrderSource(Long orderId, Long planId, String val);
|
||||
|
||||
OrderSource getOrderSourceByOrderId(Long orderId);
|
||||
|
||||
|
||||
+7
-1
@@ -71,6 +71,7 @@ import com.cf.imes.module.executor.dal.mysql.plate.PlateMapper;
|
||||
import com.cf.imes.module.executor.dal.mysql.remainplaten.RemainPlateMapper;
|
||||
import com.cf.imes.module.executor.enums.ErrorCodeConstants;
|
||||
import com.cf.imes.module.executor.enums.plan.FlowProcessStatus;
|
||||
import com.cf.imes.module.executor.service.plan.PlanService;
|
||||
import com.cf.imes.module.executor.util.elasticsearch.EsUtils;
|
||||
import com.cf.imes.module.system.api.dataSource.DataSourceApi;
|
||||
import com.cf.imes.module.system.api.machine.MachineApi;
|
||||
@@ -160,6 +161,9 @@ public class OptimizePlanServiceImpl implements OptimizePlanService {
|
||||
@Resource
|
||||
private PlateGoodMapper plateGoodMapper;
|
||||
|
||||
@Resource
|
||||
private PlanService planService;
|
||||
|
||||
@Value("${chenfeng.plan.create.plate-threshold:20000}")
|
||||
private int planCreatePlateThreshold;
|
||||
|
||||
@@ -282,7 +286,7 @@ public class OptimizePlanServiceImpl implements OptimizePlanService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public OrderSource getOrderSource(Long orderId, Long planId, Long machineId) {
|
||||
public OrderSource getOrderSource(Long orderId, Long planId, String val) {
|
||||
if (!Objects.isNull(orderId) && !Objects.isNull(planId)) {
|
||||
throw new ServiceException(ORDER_PLAN_ID_IS_ONE);
|
||||
}
|
||||
@@ -292,6 +296,8 @@ public class OptimizePlanServiceImpl implements OptimizePlanService {
|
||||
return orderSource;
|
||||
}
|
||||
if (ObjectUtil.isNotNull(planId)) {
|
||||
// 获取排单锁
|
||||
planService.getPlanLock(new OrderPlanLockReqVO().setPlanId(planId).setVal(val));
|
||||
orderSource = getOrderSourceByPlanId(planId);
|
||||
return orderSource;
|
||||
}
|
||||
|
||||
+14
@@ -2,6 +2,7 @@ package com.cf.imes.module.executor.service.plan;
|
||||
|
||||
import com.cf.imes.framework.common.pojo.PageResult;
|
||||
import com.cf.imes.module.executor.controller.admin.order.vo.order.OrderRespVO;
|
||||
import com.cf.imes.module.executor.controller.admin.plan.vo.OrderPlanLockReqVO;
|
||||
import com.cf.imes.module.executor.controller.admin.plan.bo.OrderRoomBodyList;
|
||||
import com.cf.imes.module.executor.controller.admin.plan.vo.*;
|
||||
|
||||
@@ -93,4 +94,17 @@ public interface PlanService {
|
||||
|
||||
List<PlateResList> getPlanPlateList(Long planId);
|
||||
|
||||
/**
|
||||
* 获取排单锁
|
||||
*
|
||||
* @param orderPlanLockReqVO
|
||||
*/
|
||||
void getPlanLock(OrderPlanLockReqVO orderPlanLockReqVO);
|
||||
|
||||
/**
|
||||
* 释放排单锁
|
||||
*
|
||||
* @param orderPlanLockReqVO
|
||||
*/
|
||||
void releasePlanLock(OrderPlanLockReqVO orderPlanLockReqVO);
|
||||
}
|
||||
+57
-2
@@ -4,6 +4,7 @@ import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.collection.ListUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import co.elastic.clients.elasticsearch.ElasticsearchClient;
|
||||
import co.elastic.clients.elasticsearch._types.FieldValue;
|
||||
import co.elastic.clients.elasticsearch.core.UpdateByQueryRequest;
|
||||
@@ -27,6 +28,7 @@ import com.cf.imes.framework.security.core.util.SecurityFrameworkUtils;
|
||||
import com.cf.imes.module.executor.controller.admin.goods.vo.GoodsRespVO;
|
||||
import com.cf.imes.module.executor.controller.admin.order.vo.order.OrderPlanPlateNumAndAreaRespVO;
|
||||
import com.cf.imes.module.executor.controller.admin.order.vo.order.OrderRespVO;
|
||||
import com.cf.imes.module.executor.controller.admin.plan.vo.OrderPlanLockReqVO;
|
||||
import com.cf.imes.module.executor.controller.admin.plan.bo.OrderRoomBodyList;
|
||||
import com.cf.imes.module.executor.controller.admin.plan.saveOptimize.RemainBoardInfo;
|
||||
import com.cf.imes.module.executor.controller.admin.plan.vo.*;
|
||||
@@ -59,11 +61,11 @@ import com.cf.imes.module.executor.dal.mysql.remainplaten.RemainPlateMapper;
|
||||
import com.cf.imes.module.executor.enums.ErrorCodeConstants;
|
||||
import com.cf.imes.module.executor.enums.OrderPlanQueryTypeEnum;
|
||||
import com.cf.imes.module.executor.enums.OrderStatusEnum;
|
||||
import com.cf.imes.module.executor.service.order.OrderService;
|
||||
import com.cf.imes.module.executor.util.elasticsearch.EsUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.aop.framework.AopContext;
|
||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
@@ -71,13 +73,16 @@ import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.Duration;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.cf.imes.framework.common.exception.enums.GlobalErrorCodeConstants.DATA_DATA_ERROR;
|
||||
import static com.cf.imes.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static com.cf.imes.framework.common.util.json.JsonUtils.parseArray;
|
||||
import static com.cf.imes.framework.redis.constants.RedisKeyConstants.ORDER_PLAN_OPTIMIZE_KEY;
|
||||
import static com.cf.imes.framework.security.core.util.SecurityFrameworkUtils.getUserOrganId;
|
||||
import static com.cf.imes.module.executor.enums.ErrorCodeConstants.*;
|
||||
import static com.cf.imes.module.executor.enums.EsIndexEnum.*;
|
||||
@@ -135,7 +140,7 @@ public class PlanServiceImpl implements PlanService {
|
||||
private OrderComponentMapper orderComponentMapper;
|
||||
|
||||
@Resource
|
||||
private OrderService orderService;
|
||||
private StringRedisTemplate stringRedisTemplate;
|
||||
|
||||
// 重复使用的常量
|
||||
private static final String FIELD_ORDER_ID = "o.id";
|
||||
@@ -2087,4 +2092,54 @@ public class PlanServiceImpl implements PlanService {
|
||||
return resultList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getPlanLock(OrderPlanLockReqVO orderPlanLockReqVO) {
|
||||
Long planId = orderPlanLockReqVO.getPlanId();
|
||||
String lockValInput = orderPlanLockReqVO.getVal();
|
||||
|
||||
PlanDO planDO = planMapper.selectById(planId);
|
||||
|
||||
AssertUtils.notEmpty(planDO, PLAN_NOT_EXISTS);
|
||||
|
||||
String planLockKey = String.format(ORDER_PLAN_OPTIMIZE_KEY, planId);
|
||||
|
||||
// 获取优化锁
|
||||
String lockVal = stringRedisTemplate.opsForValue().get(planLockKey);
|
||||
|
||||
// 没有锁,尝试获取
|
||||
if (StrUtil.isBlank(lockVal)) {
|
||||
|
||||
Boolean success = stringRedisTemplate.opsForValue().setIfAbsent(
|
||||
planLockKey,
|
||||
lockValInput,
|
||||
Duration.ofMinutes(30)
|
||||
);
|
||||
|
||||
if (Boolean.TRUE.equals(success)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 极端并发场景
|
||||
lockVal = stringRedisTemplate.opsForValue().get(planLockKey);
|
||||
}
|
||||
|
||||
// 用不同的lockKey去请求优化提示已锁单
|
||||
if (!StrUtil.equals(lockVal, lockValInput)) {
|
||||
throw exception(ORDER_PLAN_LOCKED);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void releasePlanLock(OrderPlanLockReqVO orderPlanLockReqVO) {
|
||||
Long planId = orderPlanLockReqVO.getPlanId();
|
||||
String lockValInput = orderPlanLockReqVO.getVal();
|
||||
|
||||
String lockKey = String.format(ORDER_PLAN_OPTIMIZE_KEY, planId);
|
||||
|
||||
String lockVal = stringRedisTemplate.opsForValue().get(lockKey);
|
||||
|
||||
if (Objects.equals(lockVal, lockValInput)) {
|
||||
stringRedisTemplate.delete(lockKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user