From dfa1eafe5faf981c0d81b386717a0b645173ee3a Mon Sep 17 00:00:00 2001
From: zhangli <123879394@qq.com>
Date: Sun, 24 Aug 2025 15:29:28 +0800
Subject: [PATCH] =?UTF-8?q?=E7=BB=91=E5=AE=9A=E8=BD=A6=E8=BE=86=E5=92=8C?=
=?UTF-8?q?=E8=BF=98=E8=BD=A6=E5=A2=9E=E5=8A=A0=E5=8F=98=E6=9B=B4=E8=BD=A6?=
=?UTF-8?q?=E8=BE=86=E7=8A=B6=E6=80=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../common/constant/RedisKeyConstants.java | 2 +
.../order/common/enums/CarStatusEnum.java | 21 +++
.../java/com/sczx/order/mapper/CarMapper.java | 16 ++
src/main/java/com/sczx/order/po/CarPO.java | 140 ++++++++++++++++
.../com/sczx/order/repository/CarRepo.java | 16 ++
.../order/repository/impl/CarRepoImpl.java | 20 +++
.../order/service/impl/OrderServiceImpl.java | 149 +++++++++++-------
src/main/resources/mapper/CarMapper.xml | 5 +
8 files changed, 311 insertions(+), 58 deletions(-)
create mode 100644 src/main/java/com/sczx/order/common/enums/CarStatusEnum.java
create mode 100644 src/main/java/com/sczx/order/mapper/CarMapper.java
create mode 100644 src/main/java/com/sczx/order/po/CarPO.java
create mode 100644 src/main/java/com/sczx/order/repository/CarRepo.java
create mode 100644 src/main/java/com/sczx/order/repository/impl/CarRepoImpl.java
create mode 100644 src/main/resources/mapper/CarMapper.xml
diff --git a/src/main/java/com/sczx/order/common/constant/RedisKeyConstants.java b/src/main/java/com/sczx/order/common/constant/RedisKeyConstants.java
index 0a2c4de..ef56aa7 100644
--- a/src/main/java/com/sczx/order/common/constant/RedisKeyConstants.java
+++ b/src/main/java/com/sczx/order/common/constant/RedisKeyConstants.java
@@ -5,4 +5,6 @@ public interface RedisKeyConstants {
String ORDER_SUB_KEY = SERVICE_PREFIX + "orderSub:";
+ String BIND_CAR_KEY = SERVICE_PREFIX + "bindCar:";
+
}
diff --git a/src/main/java/com/sczx/order/common/enums/CarStatusEnum.java b/src/main/java/com/sczx/order/common/enums/CarStatusEnum.java
new file mode 100644
index 0000000..d8b3ec4
--- /dev/null
+++ b/src/main/java/com/sczx/order/common/enums/CarStatusEnum.java
@@ -0,0 +1,21 @@
+package com.sczx.order.common.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * @Author: 张黎
+ * @Date: 2024/03/08/17:42
+ * @Description: 车状态
+ */
+@AllArgsConstructor
+@Getter
+public enum CarStatusEnum {
+ NORMAL("0", "正常"),
+ REMOVED("1", "下架"),
+ RENT_ING("9", "租赁中"),
+ ;
+ private final String code;
+
+ private final String msg;
+}
diff --git a/src/main/java/com/sczx/order/mapper/CarMapper.java b/src/main/java/com/sczx/order/mapper/CarMapper.java
new file mode 100644
index 0000000..0102d7c
--- /dev/null
+++ b/src/main/java/com/sczx/order/mapper/CarMapper.java
@@ -0,0 +1,16 @@
+package com.sczx.order.mapper;
+
+import com.sczx.order.po.CarPO;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ *
+ * 电动车信息表 Mapper 接口
+ *
+ *
+ * @author zhangli
+ * @since 2025-08-24 14:55:02
+ */
+public interface CarMapper extends BaseMapper {
+
+}
diff --git a/src/main/java/com/sczx/order/po/CarPO.java b/src/main/java/com/sczx/order/po/CarPO.java
new file mode 100644
index 0000000..1cd7c13
--- /dev/null
+++ b/src/main/java/com/sczx/order/po/CarPO.java
@@ -0,0 +1,140 @@
+package com.sczx.order.po;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ *
+ * 电动车信息表
+ *
+ *
+ * @author zhangli
+ * @since 2025-08-24 14:55:02
+ */
+@Getter
+@Setter
+@TableName("zc_car")
+@ApiModel(value = "CarPO对象", description = "电动车信息表")
+public class CarPO implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ @ApiModelProperty("主键ID")
+ @TableId(value = "id", type = IdType.AUTO)
+ private Long id;
+
+ @ApiModelProperty("车架号(VIN)")
+ private String vin;
+
+ @ApiModelProperty("车牌号码")
+ private String licensePlate;
+
+ @ApiModelProperty("车辆品牌ID")
+ private Long brandId;
+
+ @ApiModelProperty("车辆品牌名称")
+ private String brandName;
+
+ @ApiModelProperty("车辆型号ID")
+ private Long modelId;
+
+ @ApiModelProperty("车辆型号名称")
+ private String modelName;
+
+ @ApiModelProperty("支持电池类型(48V标准版/100km,48V超长版/200km等)")
+ private String batteryType;
+
+ @ApiModelProperty("整车重量(kg)")
+ private String weight;
+
+ @ApiModelProperty("最高时速(km/h)")
+ private String maxSpeed;
+
+ @ApiModelProperty("LOT识别号")
+ private String lotNumber;
+
+ @ApiModelProperty("采购日期")
+ private LocalDateTime purchaseDate;
+
+ @ApiModelProperty("采购价格(元)")
+ private BigDecimal purchasePrice;
+
+ @ApiModelProperty("车辆归属(0归属于合,1归属运营商)")
+ private String belongType;
+
+ @ApiModelProperty("车辆图片(多个图片用逗号分隔)")
+ private String images;
+
+ @ApiModelProperty("BRS车辆状态(空闲/使用中/维修中/丢失报损等)")
+ private String brsStatus;
+
+ @ApiModelProperty("IoT设备状态")
+ private String iotStatus;
+
+ @ApiModelProperty("IoT识别码")
+ private String iotCode;
+
+ @ApiModelProperty("所属运营商ID")
+ private Long operatorId;
+
+ @ApiModelProperty("所属运营商名称")
+ private String operatorName;
+
+ @ApiModelProperty("所属门店ID")
+ private Long storeId;
+
+ @ApiModelProperty("所属门店名称")
+ private String storeName;
+
+ @ApiModelProperty("应用套餐ID")
+ private Long packageId;
+
+ @ApiModelProperty("应用套餐名称")
+ private String packageName;
+
+ @ApiModelProperty("状态(0正常 1停用)")
+ private String status;
+
+ @ApiModelProperty("删除标志(0代表存在 2代表删除)")
+ private String delFlag;
+
+ @ApiModelProperty("创建者")
+ private String createBy;
+
+ @ApiModelProperty("创建时间")
+ private LocalDateTime createTime;
+
+ @ApiModelProperty("更新者")
+ private String updateBy;
+
+ @ApiModelProperty("更新时间")
+ private LocalDateTime updateTime;
+
+ @ApiModelProperty("备注信息")
+ private String remark;
+
+ @ApiModelProperty("扩展字段1")
+ private String extend1;
+
+ @ApiModelProperty("扩展字段2")
+ private String extend2;
+
+ @ApiModelProperty("扩展字段3")
+ private String extend3;
+
+ @ApiModelProperty("扩展字段4")
+ private String extend4;
+
+ @ApiModelProperty("扩展字段5")
+ private String extend5;
+
+
+}
diff --git a/src/main/java/com/sczx/order/repository/CarRepo.java b/src/main/java/com/sczx/order/repository/CarRepo.java
new file mode 100644
index 0000000..1153e2a
--- /dev/null
+++ b/src/main/java/com/sczx/order/repository/CarRepo.java
@@ -0,0 +1,16 @@
+package com.sczx.order.repository;
+
+import com.sczx.order.po.CarPO;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ *
+ * 电动车信息表 服务类
+ *
+ *
+ * @author zhangli
+ * @since 2025-08-24 14:55:02
+ */
+public interface CarRepo extends IService {
+
+}
diff --git a/src/main/java/com/sczx/order/repository/impl/CarRepoImpl.java b/src/main/java/com/sczx/order/repository/impl/CarRepoImpl.java
new file mode 100644
index 0000000..d4eab09
--- /dev/null
+++ b/src/main/java/com/sczx/order/repository/impl/CarRepoImpl.java
@@ -0,0 +1,20 @@
+package com.sczx.order.repository.impl;
+
+import com.sczx.order.po.CarPO;
+import com.sczx.order.mapper.CarMapper;
+import com.sczx.order.repository.CarRepo;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ *
+ * 电动车信息表 服务实现类
+ *
+ *
+ * @author zhangli
+ * @since 2025-08-24 14:55:02
+ */
+@Service
+public class CarRepoImpl extends ServiceImpl implements CarRepo {
+
+}
diff --git a/src/main/java/com/sczx/order/service/impl/OrderServiceImpl.java b/src/main/java/com/sczx/order/service/impl/OrderServiceImpl.java
index 7d29076..a0e1510 100644
--- a/src/main/java/com/sczx/order/service/impl/OrderServiceImpl.java
+++ b/src/main/java/com/sczx/order/service/impl/OrderServiceImpl.java
@@ -11,9 +11,11 @@ import com.sczx.order.convert.OrderSubConvert;
import com.sczx.order.dto.*;
import com.sczx.order.exception.BizException;
import com.sczx.order.exception.InnerException;
+import com.sczx.order.po.CarPO;
import com.sczx.order.po.OrderCarImgPO;
import com.sczx.order.po.OrderMainPO;
import com.sczx.order.po.OrderSubPO;
+import com.sczx.order.repository.CarRepo;
import com.sczx.order.repository.OrderCarImgRepo;
import com.sczx.order.repository.OrderMainRepo;
import com.sczx.order.repository.OrderSubRepo;
@@ -51,6 +53,9 @@ public class OrderServiceImpl implements OrderService {
@Autowired
private CarInteg carInteg;
+ @Autowired
+ private CarRepo carRepo;
+
@Autowired
private OrderMainRepo orderMainRepo;
@@ -712,68 +717,87 @@ public class OrderServiceImpl implements OrderService {
@Transactional(rollbackFor = Exception.class)
@Override
public OrderDTO bindCarToOrder(BindCarToOrderReq bindCarToOrderReq) {
- CarDTO carDTO = carInteg.getCarByCarCondition(CarQueryConditionReq.builder().vin(bindCarToOrderReq.getVin()).build());
- if(carDTO==null){
- throw new BizException("车辆不存在");
- }
- LambdaQueryWrapper queryOrderWrapper = new LambdaQueryWrapper<>();
- queryOrderWrapper.eq(OrderMainPO::getOrderNo, bindCarToOrderReq.getOrderNo());
- OrderMainPO orderMainPO = orderMainRepo.getOne(queryOrderWrapper);
- if(orderMainPO==null){
- throw new BizException("订单不存在");
- }
- if(!orderMainPO.getOrderStatus().equals(OrderStatusEnum.WAIT_PICK.getCode())){
- throw new BizException("订单状态异常,非待取车状态");
- }
+ String redisLockKey = RedisKeyConstants.BIND_CAR_KEY + bindCarToOrderReq.getVin();
+ if(redisUtil.getRedisLock(redisLockKey, "绑定车辆")) {
+ try {
+ CarDTO carDTO = carInteg.getCarByCarCondition(CarQueryConditionReq.builder().vin(bindCarToOrderReq.getVin()).build());
+ if(carDTO==null){
+ throw new BizException("车辆不存在");
+ }
+ if(!CarStatusEnum.NORMAL.getCode().equalsIgnoreCase(carDTO.getBrsStatus())){
+ throw new BizException("车辆已出租或已下架");
+ }
+ LambdaQueryWrapper queryOrderWrapper = new LambdaQueryWrapper<>();
+ queryOrderWrapper.eq(OrderMainPO::getOrderNo, bindCarToOrderReq.getOrderNo());
+ OrderMainPO orderMainPO = orderMainRepo.getOne(queryOrderWrapper);
+ if(orderMainPO==null){
+ throw new BizException("订单不存在");
+ }
+ if(!orderMainPO.getOrderStatus().equals(OrderStatusEnum.WAIT_PICK.getCode())){
+ throw new BizException("订单状态异常,非待取车状态");
+ }
- LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();
- queryWrapper.eq(OrderSubPO::getOrderId, orderMainPO.getOrderId())
- .eq(OrderSubPO::getSuborderType, SubOrderTypeEnum.RENTCAR.getCode())
- .isNull(OrderSubPO::getVinBatteryNo)
- .orderByDesc(OrderSubPO::getCreatedAt)
- .last(" limit 1");
- OrderSubPO renOrderSubPO = orderSubRepo.getOne(queryWrapper);
- if(renOrderSubPO==null){
- throw new BizException("租车子订单不存在");
- }
- //记录车架号
- LambdaUpdateWrapper updateSubWrapper = new LambdaUpdateWrapper<>();
- updateSubWrapper.set(OrderSubPO::getVinBatteryNo, carDTO.getVin());
- updateSubWrapper.eq(OrderSubPO::getSuborderId, renOrderSubPO.getSuborderId());
- orderSubRepo.update(updateSubWrapper);
- //变更订单状态,记录租车时间
- LocalDateTime currentTime = LocalDateTime.now();
+ LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();
+ queryWrapper.eq(OrderSubPO::getOrderId, orderMainPO.getOrderId())
+ .eq(OrderSubPO::getSuborderType, SubOrderTypeEnum.RENTCAR.getCode())
+ .isNull(OrderSubPO::getVinBatteryNo)
+ .orderByDesc(OrderSubPO::getCreatedAt)
+ .last(" limit 1");
+ OrderSubPO renOrderSubPO = orderSubRepo.getOne(queryWrapper);
+ if(renOrderSubPO==null){
+ throw new BizException("租车子订单不存在");
+ }
+ //记录车架号
+ LambdaUpdateWrapper updateSubWrapper = new LambdaUpdateWrapper<>();
+ updateSubWrapper.set(OrderSubPO::getVinBatteryNo, carDTO.getVin());
+ updateSubWrapper.eq(OrderSubPO::getSuborderId, renOrderSubPO.getSuborderId());
+ orderSubRepo.update(updateSubWrapper);
+ //变更订单状态,记录租车时间
+ LocalDateTime currentTime = LocalDateTime.now();
- //设置预计还车时间
- LocalDateTime endRentTime = OrderUtil.getEndRentTime(currentTime,orderMainPO.getRentalDays(), orderMainPO.getRentalType());
+ //设置预计还车时间
+ LocalDateTime endRentTime = OrderUtil.getEndRentTime(currentTime,orderMainPO.getRentalDays(), orderMainPO.getRentalType());
- LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper<>();
- updateWrapper.set(OrderMainPO::getOrderStatus, OrderStatusEnum.RENT_ING.getCode());
- updateWrapper.set(OrderMainPO::getStartRentTime, currentTime);
- updateWrapper.set(OrderMainPO::getPickCarTime, currentTime);
- updateWrapper.set(endRentTime!=null ,OrderMainPO::getEndRentTime, endRentTime);
- updateWrapper.set(OrderMainPO::getVehicleId, carDTO.getId());
- updateWrapper.eq(OrderMainPO::getOrderNo, bindCarToOrderReq.getOrderNo());
- orderMainRepo.update(updateWrapper);
+ LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper<>();
+ updateWrapper.set(OrderMainPO::getOrderStatus, OrderStatusEnum.RENT_ING.getCode());
+ updateWrapper.set(OrderMainPO::getStartRentTime, currentTime);
+ updateWrapper.set(OrderMainPO::getPickCarTime, currentTime);
+ updateWrapper.set(endRentTime!=null ,OrderMainPO::getEndRentTime, endRentTime);
+ updateWrapper.set(OrderMainPO::getVehicleId, carDTO.getId());
+ updateWrapper.eq(OrderMainPO::getOrderNo, bindCarToOrderReq.getOrderNo());
+ orderMainRepo.update(updateWrapper);
- if(!CollectionUtils.isEmpty(bindCarToOrderReq.getImageList())){
- //添加车辆图片
- List carImagePOList = new ArrayList<>();
- for(OrderCarImgDTO image:bindCarToOrderReq.getImageList()){
- OrderCarImgPO imgPO = new OrderCarImgPO();
- imgPO.setOrderId(orderMainPO.getOrderId());
- imgPO.setOrderNo(orderMainPO.getOrderNo());
- imgPO.setImgType(image.getImgType());
- imgPO.setImgUrl(image.getImgUrl());
- carImagePOList.add(imgPO);
+ if(!CollectionUtils.isEmpty(bindCarToOrderReq.getImageList())){
+ //添加车辆图片
+ List carImagePOList = new ArrayList<>();
+ for(OrderCarImgDTO image:bindCarToOrderReq.getImageList()){
+ OrderCarImgPO imgPO = new OrderCarImgPO();
+ imgPO.setOrderId(orderMainPO.getOrderId());
+ imgPO.setOrderNo(orderMainPO.getOrderNo());
+ imgPO.setImgType(image.getImgType());
+ imgPO.setImgUrl(image.getImgUrl());
+ carImagePOList.add(imgPO);
+ }
+ orderCarImgRepo.saveBatch(carImagePOList);
+ }
+
+ //变更车辆状态
+ LambdaUpdateWrapper carPOLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
+ carPOLambdaUpdateWrapper.eq(CarPO::getId, carDTO.getId())
+ .set(CarPO::getBrsStatus, CarStatusEnum.RENT_ING.getCode());
+ carRepo.update(carPOLambdaUpdateWrapper);
+
+ return getOrderInfoByOrderNo(bindCarToOrderReq.getOrderNo());
+ } catch (Exception e){
+ log.warn("绑定车辆失败");
+ throw new InnerException("绑定车辆失败");
+ } finally {
+ redisUtil.deleteRedisLock(redisLockKey);
}
- orderCarImgRepo.saveBatch(carImagePOList);
+ } else {
+ log.warn("绑定车辆失败,锁已被占用");
+ throw new InnerException("服务器正在处理,请稍后再试");
}
-
-
- //TODO 变更车辆状态
-
- return getOrderInfoByOrderNo(bindCarToOrderReq.getOrderNo());
}
@Override
@@ -800,6 +824,7 @@ public class OrderServiceImpl implements OrderService {
return orderDTO;
}
+ @Transactional(rollbackFor = Exception.class)
@Override
public OrderDTO confirmReturnCar(ReturnCarReq returnCarReq) {
//变更订单状态,记录还车时间
@@ -824,8 +849,16 @@ public class OrderServiceImpl implements OrderService {
}
orderCarImgRepo.saveBatch(carImagePOList);
}
- //TODO 变更车辆状态
-
+ //T变更车辆状态
+ CarPO carPO = carRepo.getById(orderDTO.getVehicleId());
+ if(carPO == null){
+ throw new BizException("车辆不存在");
+ }
+ //变更车辆状态
+ LambdaUpdateWrapper carPOLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
+ carPOLambdaUpdateWrapper.eq(CarPO::getId, orderDTO.getVehicleId())
+ .set(CarPO::getBrsStatus, CarStatusEnum.NORMAL.getCode());
+ carRepo.update(carPOLambdaUpdateWrapper);
//异步执行分润
ThreadPoolUtils.getThreadPool().execute(() -> {
orderDistribService.saveOrderDistrib(returnCarReq.getOrderNo());
diff --git a/src/main/resources/mapper/CarMapper.xml b/src/main/resources/mapper/CarMapper.xml
new file mode 100644
index 0000000..f8a452f
--- /dev/null
+++ b/src/main/resources/mapper/CarMapper.xml
@@ -0,0 +1,5 @@
+
+
+
+
+