提交 621dd91c authored 作者: aiqingguo's avatar aiqingguo

接单加锁

上级 f6a8fae9
......@@ -43,23 +43,30 @@ public enum PerformanceResultEnum implements ResultEnum {
ORDER_CHILD_STATUS_CHANGED(1302, "运单状态已变更,请重新刷新页面"),
ORDER_CHILD_CANCELED(1303, "运单状态已取消"),
ORDER_CHILD_COMPLETE(1304, "运单状态已完成"),
ORDER_CHILD_LOAD_TIMEOUT(1305, "超过最晚到达货源地时间"),
ORDER_CHILD_CANCEL_FORBID(1306, "运单无法取消"),
ORDER_CHILD_CANCEL_FORBID_COUNT(1307, "今日取消运单次数超过上限,暂时无法取消"),
ORDER_CHILD_POUND_AUDIT(1308, "磅单审核中"),
ORDER_CHILD_POUND_REJECT(1309, "磅单审核驳回,请重新提交信息"),
ORDER_CHILD_DIRECT_ORDER_TRUCK_ERROR(1310, "请选择定向车辆"),
ORDER_CHILD_DIRECT_ORDER_TRUCK_ERROR1(1311, "请选择非定向车辆"),
ORDER_CHILD_DIRECT_REJECT_TRUCK_ERROR(1312, "非定向车辆无法取消"),
ORDER_CHILD_TRUCK_MODEL_ERROR(1313, "请选择合适的车型"),
ORDER_CHILD_LOAD_WEIGHT_ERROR(1314, "装货净重超过载重的1.5倍"),
ORDER_CHILD_UNLOAD_WEIGHT_ERROR(1315, "卸货净重超过载重的1.5倍"),
ORDER_CHILD_LOAD_TIME_ERROR(1316, "非装车时间段"),
ORDER_CHILD_UNLOAD_TIME_ERROR(1317, "非卸车时间段"),
ORDER_CHILD_ARRIVE_SEND_ADDRESS_DISTANCE_ERROR(1318, "没有到达货源地"),
ORDER_CHILD_ARRIVE_RECEIVE_ADDRESS_DISTANCE_ERROR(1319, "没有到达目的地"),
ORDER_CHILD_OPERATION_FORBID(1320, "没有权限操作"),
ORDER_CHILD_OPERATION_FORBID(1305, "没有权限操作"),
ORDER_CHILD_SAVE_FAIL(1321, "接单失败,请稍后再试"),
ORDER_CHILD_SAVE_FREQUENCY_ERROR(1322, "请误频繁点击"),
ORDER_CHILD_TRUCK_MODEL_ERROR(1323, "请选择合适的车型"),
ORDER_CHILD_DIRECT_ORDER_TRUCK_ERROR(1324, "请选择定向车辆"),
ORDER_CHILD_DIRECT_ORDER_TRUCK_ERROR1(1325, "请选择非定向车辆"),
ORDER_CHILD_LOAD_TIME_ERROR(1341, "非装车时间段"),
ORDER_CHILD_UNLOAD_TIME_ERROR(1342, "非卸车时间段"),
ORDER_CHILD_ARRIVE_SEND_ADDRESS_DISTANCE_ERROR(1343, "没有到达货源地"),
ORDER_CHILD_ARRIVE_RECEIVE_ADDRESS_DISTANCE_ERROR(1344, "没有到达目的地"),
ORDER_CHILD_LOAD_TIMEOUT(1345, "超过最晚到达货源地时间"),
ORDER_CHILD_LOAD_WEIGHT_ERROR(1346, "装货净重超过载重的1.5倍"),
ORDER_CHILD_UNLOAD_WEIGHT_ERROR(1347, "卸货净重超过载重的1.5倍"),
ORDER_CHILD_POUND_AUDIT(1361, "磅单审核中"),
ORDER_CHILD_POUND_REJECT(1362, "磅单审核驳回,请重新提交信息"),
ORDER_CHILD_DIRECT_REJECT_TRUCK_ERROR(1381, "非定向车辆无法取消"),
ORDER_CHILD_CANCEL_FORBID(1382, "运单无法取消"),
ORDER_CHILD_CANCEL_FORBID_COUNT(1383, "今日取消运单次数超过上限,暂时无法取消"),
;
private final int code;
......
package com.clx.performance.constant;
public class RedissonConstants {
// 接单锁
public static final String ORDER_CHILD_SAVE_USER_TRUCK_LOCK = "clx-performance:orderChild:save:userTruck:";
public static final String ORDER_CHILD_SAVE_ORDER_GOODS_NO_LOCK = "clx-performance:orderChild:save:orderGoodsNo:";
}
......@@ -21,6 +21,7 @@ import java.util.List;
public interface OrderChildService {
SaveOrderChildVO saveOrderChild(OrderChildSaveParam param);
SaveOrderChildVO doSaveOrderChild(OrderChildSaveParam param);
void updateReject(OrderChildRejectParam param);
......
......@@ -3,9 +3,9 @@ package com.clx.performance.service.impl;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.clx.order.enums.OrderEnum;
import com.clx.order.feign.OrderFeign;
import com.clx.order.param.feign.UpdateOrderInfoParam;
import com.clx.order.vo.feign.FeignAddressVO;
import com.clx.order.vo.feign.FeignOrderInfoVO;
import com.clx.performance.constant.RedissonConstants;
import com.clx.performance.dao.*;
import com.clx.performance.enums.*;
import com.clx.performance.extranal.user.AddressService;
......@@ -21,6 +21,7 @@ import com.clx.performance.service.OrderChildPoundLogService;
import com.clx.performance.service.OrderChildService;
import com.clx.performance.service.OrderGoodsService;
import com.clx.performance.struct.*;
import com.clx.performance.utils.spring.ApplicationContextUtils;
import com.clx.performance.vo.app.*;
import com.clx.performance.vo.pc.*;
import com.clx.user.enums.driver.DriverInfoEnum;
......@@ -36,9 +37,9 @@ import com.msl.user.utils.TokenUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
......@@ -48,6 +49,8 @@ import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;
import java.util.stream.Collectors;
/**
......@@ -78,7 +81,6 @@ public class OrderChildServiceImpl implements OrderChildService {
private final DriverService driverService;
private final OrderChildStruct orderChildStruct;
private final OrderChildPoundImageStruct orderChildPoundImageStruct;
private final OrderGoodsService orderGoodsService;
private final OrderChildPoundStruct orderChildPoundStruct;
private final OrderChildFreightStruct orderChildFreightStruct;
......@@ -87,14 +89,67 @@ public class OrderChildServiceImpl implements OrderChildService {
private final UniqueOrderNumService uniqueOrderNumService;
private final OrderFeign orderFeign;
private final RedissonClient redissonClient;
@Override
public SaveOrderChildVO saveOrderChild(OrderChildSaveParam param) {
// 司机车辆锁
saveOrderChildOrderUserTruckLock(param);
// 货单锁
return saveOrderChildOrderGoodsLock(param, ()-> ApplicationContextUtils.getBean(OrderChildService.class).doSaveOrderChild(param));
}
/**
* 用户车辆锁
*/
public void saveOrderChildOrderUserTruckLock(OrderChildSaveParam param) {
Long userNo = param.getDriverUserNo();
Integer truckId = param.getTruckId();
RLock lock = redissonClient.getLock(RedissonConstants.ORDER_CHILD_SAVE_USER_TRUCK_LOCK+ userNo+":"+truckId);
boolean flag;
try{
flag = lock.tryLock( 1, 3, TimeUnit.SECONDS);
}catch (Exception e){
throw new ServiceSystemException(PerformanceResultEnum.ORDER_CHILD_SAVE_FAIL);
}
if (!flag){
log.warn("接单异常,orderGoodsNo:{}, userNo:{}", param.getOrderGoodsNo(), userNo);
throw new ServiceSystemException(PerformanceResultEnum.ORDER_CHILD_SAVE_FREQUENCY_ERROR);
}
}
/**
* 货单锁
*/
public SaveOrderChildVO saveOrderChildOrderGoodsLock(OrderChildSaveParam param, Supplier<SaveOrderChildVO> function) {
String orderGoodsNo = param.getOrderGoodsNo();
RLock lock = redissonClient.getLock(RedissonConstants.ORDER_CHILD_SAVE_ORDER_GOODS_NO_LOCK+orderGoodsNo);
try{
boolean flag = lock.tryLock(15, 30, TimeUnit.SECONDS);
if (!flag){throw new ServiceSystemException(PerformanceResultEnum.ORDER_CHILD_SAVE_FAIL);}
return function.get();
}catch (ServiceSystemException e){
throw e;
}catch (Exception e){
throw new ServiceSystemException(PerformanceResultEnum.ORDER_CHILD_SAVE_FAIL);
}finally {
if (lock.isLocked() && lock.isHeldByCurrentThread()) {
lock.unlock();
}
}
@Autowired
private StringRedisTemplate stringRedisTemplate;
}
@Override
@Transactional(rollbackFor = Exception.class)
public SaveOrderChildVO saveOrderChild(OrderChildSaveParam param) {
public SaveOrderChildVO doSaveOrderChild(OrderChildSaveParam param) {
UserSessionData loginUserInfo = TokenUtil.getLoginUserInfo();
Long userNo = loginUserInfo.getUserNo();
......@@ -988,7 +1043,6 @@ public class OrderChildServiceImpl implements OrderChildService {
* 更新货单数据
*/
private void updateOrderGoodsAmount(OrderGoods orderGoods, BigDecimal weight){
int count = orderChildDao.countValidByOrderGoodsNo(orderGoods.getOrderGoodsNo());
Integer status = OrderGoodsStatusEnum.Status.GO_TO_SEND.getCode();
......@@ -1002,7 +1056,7 @@ public class OrderChildServiceImpl implements OrderChildService {
private void updateOrderGoodsAmountReturn(OrderChild orderChild, OrderGoods orderGoods){
int count = orderChildDao.countValidByOrderGoodsNo(orderGoods.getOrderGoodsNo())-1;
Integer status = orderGoods.getOrderGoodsStatus();
Integer status = null;
if (count == 0){
status = OrderGoodsStatusEnum.Status.PAYING.getCode();
}
......@@ -1019,8 +1073,6 @@ public class OrderChildServiceImpl implements OrderChildService {
private void updateOrderGoodsAmountLoad(OrderGoods orderGoods, BigDecimal dif){
if (dif.compareTo(BigDecimal.ZERO) == 0){return;}
int count = orderChildDao.countValidByOrderGoodsNo(orderGoods.getOrderGoodsNo());
Integer status = OrderGoodsStatusEnum.Status.GO_TO_SEND.getCode();
orderGoodsService.updateOrderGoodsReduceWeightAndStatus(orderGoods.getId(), dif, status);
......
package com.clx.performance.utils.spring;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
@Component
public class ApplicationContextUtils implements ApplicationContextAware {
private static ApplicationContext context;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
context = applicationContext;
}
/**
* 根据Bean名称获取Bean对象
*/
public static Object getBean(String name) {
return context.getBean(name);
}
/**
* 根据Bean的类型获取对应的Bean
*/
public static <T> T getBean(Class<T> requiredType) {
return context.getBean(requiredType);
}
/**
* 根据Bean名称获取指定类型的Bean对象
*/
public static <T> T getBean(String name, Class<T> requiredType) {
return context.getBean(name, requiredType);
}
/**
* 判断是否包含对应名称的Bean对象
*/
public static boolean containsBean(String name) {
return context.containsBean(name);
}
/**
* 获取对应Bean名称的类型
*/
public static Class<?> getType(String name) {
return context.getType(name);
}
/**
* 获取上下文对象,可进行各种Spring的上下文操作
*/
public static ApplicationContext getContext() {
return context;
}
}
\ No newline at end of file
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论