调度工单:调度逻辑-用户骑车后调度订单消耗

This commit is contained in:
attiya 2025-11-27 10:01:53 +08:00
parent 67f68b03a7
commit c9089418dd
6 changed files with 117 additions and 9 deletions

View File

@ -0,0 +1,24 @@
package com.cdzy.operations.enums;
/**
* @author attiya
* @since 2025-10-15
*/
public interface OrderDispatchState {
/**
* 0-工单已处理但暂不生效
*/
int PROCESSED = 0;
/**
* 1-生效
*/
int EFFECTIVE = 1;
/**
* 2-不生效
*/
int INEFFECTIVE = 2;
}

View File

@ -0,0 +1,28 @@
package com.cdzy.operations.enums;
/**
* @author attiya
* @since 2025-10-15
*/
public interface OrderHandleState {
/**
* 0-未处理
*/
int UNPROCESSED = 0;
/**
* 1-已接单
*/
int ACCEPTED = 1;
/**
* 2-已处理
*/
int PROCESSED = 2;
/**
* 3-作废
*/
int VOIDED = 3;
}

View File

@ -38,6 +38,7 @@ import java.util.Objects;
import static com.cdzy.operations.model.entity.table.EbikeBatteryInfoTableDef.EBIKE_BATTERY_INFO; import static com.cdzy.operations.model.entity.table.EbikeBatteryInfoTableDef.EBIKE_BATTERY_INFO;
import static com.cdzy.operations.model.entity.table.EbikeBikeInfoTableDef.EBIKE_BIKE_INFO; import static com.cdzy.operations.model.entity.table.EbikeBikeInfoTableDef.EBIKE_BIKE_INFO;
import static com.cdzy.operations.model.entity.table.EbikeBikeOrderTableDef.EBIKE_BIKE_ORDER;
import static com.cdzy.operations.model.entity.table.EbikeBikeQrTableDef.EBIKE_BIKE_QR; import static com.cdzy.operations.model.entity.table.EbikeBikeQrTableDef.EBIKE_BIKE_QR;
import static com.cdzy.operations.model.entity.table.EbikeDefaultBillingConfigurationTableDef.EBIKE_DEFAULT_BILLING_CONFIGURATION; import static com.cdzy.operations.model.entity.table.EbikeDefaultBillingConfigurationTableDef.EBIKE_DEFAULT_BILLING_CONFIGURATION;
import static com.cdzy.operations.model.entity.table.EbikeEcuInfoTableDef.EBIKE_ECU_INFO; import static com.cdzy.operations.model.entity.table.EbikeEcuInfoTableDef.EBIKE_ECU_INFO;
@ -92,6 +93,9 @@ public class EbikeBikeInfoServiceImpl extends ServiceImpl<EbikeBikeInfoMapper, E
@Resource @Resource
private RedisUtil redisUtil; private RedisUtil redisUtil;
@Resource
private EbikeBikeOrderMapper orderMapper;
@Override @Override
@Transactional @Transactional
public void bind(EbikeBikeBindVo bindVo) { public void bind(EbikeBikeBindVo bindVo) {
@ -325,7 +329,32 @@ public class EbikeBikeInfoServiceImpl extends ServiceImpl<EbikeBikeInfoMapper, E
this.mapper.update(info); this.mapper.update(info);
//TODO清空redis中的为消耗调度工单工单调度状态修改为生效 //若存在已处理但暂未生效的调度工单清空redis中的为消耗调度工单已处理的工单调度状态修改为生效
query.clear();
query.where(EBIKE_BIKE_ORDER.BIKE_CODE.eq(info.getBikeCode()))
.where(EBIKE_BIKE_ORDER.ORDER_TYPE.eq(BikeOrderType.DISPATCH))
.where(EBIKE_BIKE_ORDER.HANDLE_STATE.eq(OrderHandleState.PROCESSED))
.where(EBIKE_BIKE_ORDER.DISPATCH_STATE.eq(OrderDispatchState.PROCESSED));
EbikeBikeOrder bikeOrder = orderMapper.selectOneByQuery(query);
if (bikeOrder != null) {
redisUtil.deleteDispatchOrder(bikeOrder.getOrderId());
bikeOrder.setDispatchState(OrderDispatchState.EFFECTIVE);
orderMapper.update(bikeOrder);
}
//若存在未处理/已接单的调度工单作废未处理的调度工单
List<Integer> list = new ArrayList<>();
list.add(OrderHandleState.UNPROCESSED);
list.add(OrderHandleState.ACCEPTED);
query.clear();
query.where(EBIKE_BIKE_ORDER.BIKE_CODE.in(info.getBikeCode()))
.where(EBIKE_BIKE_ORDER.ORDER_TYPE.eq(BikeOrderType.DISPATCH))
.where(EBIKE_BIKE_ORDER.HANDLE_STATE.in(list));
bikeOrder = orderMapper.selectOneByQuery(query);
if (bikeOrder != null) {
bikeOrder.setHandleState(OrderHandleState.VOIDED);
orderMapper.update(bikeOrder);
}
} }
@Override @Override

View File

@ -3,9 +3,7 @@ package com.cdzy.operations.service.impl;
import cn.dev33.satoken.stp.StpUtil; import cn.dev33.satoken.stp.StpUtil;
import com.cdzy.common.ex.EbikeException; import com.cdzy.common.ex.EbikeException;
import com.cdzy.common.model.dto.ResGPSDto; import com.cdzy.common.model.dto.ResGPSDto;
import com.cdzy.operations.enums.BikeOrderType; import com.cdzy.operations.enums.*;
import com.cdzy.operations.enums.BikeStatus;
import com.cdzy.operations.enums.BikeUsageStatus;
import com.cdzy.operations.mapper.*; import com.cdzy.operations.mapper.*;
import com.cdzy.operations.model.dto.EbikeBikeOrderInfoDto; import com.cdzy.operations.model.dto.EbikeBikeOrderInfoDto;
import com.cdzy.operations.model.entity.EbikeBikeInfo; import com.cdzy.operations.model.entity.EbikeBikeInfo;
@ -24,6 +22,7 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
@ -109,11 +108,11 @@ public class EbikeBikeOrderServiceImpl extends ServiceImpl<EbikeBikeOrderMapper,
Long orderId = ebikeBikeOrder.getOrderId(); Long orderId = ebikeBikeOrder.getOrderId();
List<Integer> parts = inspectionSwapOrderVo.getParts(); List<Integer> parts = inspectionSwapOrderVo.getParts();
List<String> fileUrls = inspectionSwapOrderVo.getFileUrls(); List<String> fileUrls = inspectionSwapOrderVo.getFileUrls();
if (parts!=null && !parts.isEmpty()){ if (parts != null && !parts.isEmpty()) {
List<EbikeOrderPart> list = parts.stream().map(e -> EbikeOrderPart.builder().orderId(orderId).orderPart(e).build()).toList(); List<EbikeOrderPart> list = parts.stream().map(e -> EbikeOrderPart.builder().orderId(orderId).orderPart(e).build()).toList();
orderPartMapper.insertBatch(list); orderPartMapper.insertBatch(list);
} }
if (fileUrls!=null && !fileUrls.isEmpty()){ if (fileUrls != null && !fileUrls.isEmpty()) {
List<EbikeOrderFile> list = fileUrls.stream().map(e -> EbikeOrderFile.builder().orderId(orderId).fileUrl(e).build()).toList(); List<EbikeOrderFile> list = fileUrls.stream().map(e -> EbikeOrderFile.builder().orderId(orderId).fileUrl(e).build()).toList();
orderFileMapper.insertBatch(list); orderFileMapper.insertBatch(list);
} }
@ -123,7 +122,12 @@ public class EbikeBikeOrderServiceImpl extends ServiceImpl<EbikeBikeOrderMapper,
@Override @Override
public void createDispatchSwapOrder(String bikeCode) { public void createDispatchSwapOrder(String bikeCode) {
EbikeBikeInfo bikeInfo = checkBikeCode(bikeCode); EbikeBikeInfo bikeInfo = checkBikeCode(bikeCode);
QueryWrapper queryWrapper = QueryWrapper.create().where(EBIKE_BIKE_ORDER.BIKE_CODE.eq(bikeInfo.getBikeCode())) List<Integer> list = new ArrayList<>();
list.add(OrderHandleState.UNPROCESSED);
list.add(OrderHandleState.ACCEPTED);
QueryWrapper queryWrapper = QueryWrapper.create()
.where(EBIKE_BIKE_ORDER.HANDLE_STATE.in(list))
.where(EBIKE_BIKE_ORDER.BIKE_CODE.eq(bikeInfo.getBikeCode()))
.where(EBIKE_BIKE_ORDER.ORDER_TYPE.eq(BikeOrderType.DISPATCH)); .where(EBIKE_BIKE_ORDER.ORDER_TYPE.eq(BikeOrderType.DISPATCH));
EbikeBikeOrder bikeOrder = this.mapper.selectOneByQuery(queryWrapper); EbikeBikeOrder bikeOrder = this.mapper.selectOneByQuery(queryWrapper);
if (bikeOrder != null) { if (bikeOrder != null) {
@ -131,6 +135,17 @@ public class EbikeBikeOrderServiceImpl extends ServiceImpl<EbikeBikeOrderMapper,
throw new EbikeException("车辆已存在调度工单"); throw new EbikeException("车辆已存在调度工单");
} }
queryWrapper.clear();
queryWrapper.where(EBIKE_BIKE_ORDER.HANDLE_STATE.eq(OrderHandleState.PROCESSED))
.where(EBIKE_BIKE_ORDER.BIKE_CODE.eq(bikeInfo.getBikeCode()))
.where(EBIKE_BIKE_ORDER.ORDER_TYPE.eq(BikeOrderType.DISPATCH))
.where(EBIKE_BIKE_ORDER.DISPATCH_STATE.eq(OrderDispatchState.PROCESSED));
EbikeBikeOrder order = this.mapper.selectOneByQuery(queryWrapper);
if (order != null) {
log.error("车辆存在已完成但暂未生效的调度工单,bikeCode={} ", bikeInfo.getBikeCode());
throw new EbikeException("车辆短时间内不能多次调度");
}
EbikeBikeOrder ebikeBikeOrder = EbikeBikeOrder.builder() EbikeBikeOrder ebikeBikeOrder = EbikeBikeOrder.builder()
.bikeCode(bikeInfo.getBikeCode()) .bikeCode(bikeInfo.getBikeCode())
.orderCode(snowFlakeIDKeyGenerator.nextId()) .orderCode(snowFlakeIDKeyGenerator.nextId())
@ -145,12 +160,12 @@ public class EbikeBikeOrderServiceImpl extends ServiceImpl<EbikeBikeOrderMapper,
@Override @Override
public EbikeBikeOrderInfoDto getInfo(Long orderId) { public EbikeBikeOrderInfoDto getInfo(Long orderId) {
QueryWrapper queryWrapper = QueryWrapper.create() QueryWrapper queryWrapper = QueryWrapper.create()
.select(EBIKE_BIKE_INFO.LOCATION,EBIKE_BIKE_ORDER.ORDER_ID,EBIKE_BIKE_ORDER.ORDER_TYPE,EBIKE_BIKE_ORDER.BIKE_CODE,EBIKE_BIKE_ORDER.REMARKS,EBIKE_BIKE_ORDER.CREATED_AT,EBIKE_BIKE_ORDER.REMARKS,EBIKE_ECU_INFO.ECU_SN) .select(EBIKE_BIKE_INFO.LOCATION, EBIKE_BIKE_ORDER.ORDER_ID, EBIKE_BIKE_ORDER.ORDER_TYPE, EBIKE_BIKE_ORDER.BIKE_CODE, EBIKE_BIKE_ORDER.REMARKS, EBIKE_BIKE_ORDER.CREATED_AT, EBIKE_BIKE_ORDER.REMARKS, EBIKE_ECU_INFO.ECU_SN)
.where(EBIKE_BIKE_ORDER.ORDER_ID.eq(orderId)) .where(EBIKE_BIKE_ORDER.ORDER_ID.eq(orderId))
.leftJoin(EBIKE_BIKE_INFO).on(EBIKE_BIKE_INFO.BIKE_CODE.eq(EBIKE_BIKE_ORDER.BIKE_CODE)) .leftJoin(EBIKE_BIKE_INFO).on(EBIKE_BIKE_INFO.BIKE_CODE.eq(EBIKE_BIKE_ORDER.BIKE_CODE))
.leftJoin(EBIKE_ECU_INFO).on(EBIKE_ECU_INFO.ECU_ID.eq(EBIKE_BIKE_INFO.ECU_ID)); .leftJoin(EBIKE_ECU_INFO).on(EBIKE_ECU_INFO.ECU_ID.eq(EBIKE_BIKE_INFO.ECU_ID));
EbikeBikeOrderInfoDto infoDto = this.mapper.selectOneWithRelationsByQueryAs(queryWrapper, EbikeBikeOrderInfoDto.class); EbikeBikeOrderInfoDto infoDto = this.mapper.selectOneWithRelationsByQueryAs(queryWrapper, EbikeBikeOrderInfoDto.class);
ResGPSDto resGPSDto = (ResGPSDto)redisUtil.get(RedisUtil.Database.DB2, infoDto.getEcuSn()); ResGPSDto resGPSDto = (ResGPSDto) redisUtil.get(RedisUtil.Database.DB2, infoDto.getEcuSn());
if (Objects.nonNull(resGPSDto)) { if (Objects.nonNull(resGPSDto)) {
infoDto.setSoc(resGPSDto.getSoc()); infoDto.setSoc(resGPSDto.getSoc());
} }

View File

@ -453,6 +453,13 @@ public class RedisUtil {
set(Database.DB2, BIKE_DISPATCH_ORDER_PREFIX + orderId, orderData, timeout, unit); set(Database.DB2, BIKE_DISPATCH_ORDER_PREFIX + orderId, orderData, timeout, unit);
} }
/**
* 数据库2专用存储调度工单并设置过期时间
*/
public void deleteDispatchOrder(Long orderId) {
delete(Database.DB2, BIKE_DISPATCH_ORDER_PREFIX + orderId);
}
/** /**
* 数据库2专用分布式锁针对调度任务 * 数据库2专用分布式锁针对调度任务
*/ */

View File

@ -21,7 +21,12 @@ class EbikeOperationsApplicationTests {
SnowFlakeIDKeyGenerator generator = new SnowFlakeIDKeyGenerator(); SnowFlakeIDKeyGenerator generator = new SnowFlakeIDKeyGenerator();
long nextId = generator.nextId(); long nextId = generator.nextId();
redisUtil.saveDispatchOrder(nextId, "2", 16L, TimeUnit.HOURS); redisUtil.saveDispatchOrder(nextId, "2", 16L, TimeUnit.HOURS);
System.out.println(nextId);
}
@Test
void deleteDispatchOrder() throws IOException {
redisUtil.deleteDispatchOrder(351467314753310720L);
} }