Compare commits

...

2 Commits

Author SHA1 Message Date
磷叶
d4141faac0 Merge remote-tracking branch 'origin/master' 2025-04-10 16:47:20 +08:00
磷叶
ae65d4a90f 订单支付 2025-04-10 16:46:29 +08:00
18 changed files with 216 additions and 181 deletions

View File

@ -5,14 +5,14 @@ import java.util.List;
import com.ruoyi.bst.areaJoin.domain.AreaJoinVO;
import com.ruoyi.bst.bonus.domain.Bonus;
import com.ruoyi.bst.device.domain.DeviceVO;
import com.ruoyi.bst.order.domain.bo.OrderPayBO;
import com.ruoyi.bst.order.domain.bo.OrderCreateBO;
public interface BonusConverter {
/**
* 将订单支付BO转换为分成列表
*/
List<Bonus> toBonusList(OrderPayBO bo);
List<Bonus> toBonusList(OrderCreateBO bo);
/**
* 将设备合伙人加盟商转换为分成列表

View File

@ -22,7 +22,7 @@ import com.ruoyi.bst.channel.domain.ChannelVO;
import com.ruoyi.bst.channel.domain.enums.ChannelType;
import com.ruoyi.bst.device.domain.DeviceVO;
import com.ruoyi.bst.order.domain.Order;
import com.ruoyi.bst.order.domain.bo.OrderPayBO;
import com.ruoyi.bst.order.domain.bo.OrderCreateBO;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.collection.CollectionUtils;
import com.ruoyi.iot.util.BatUtil;
@ -34,7 +34,7 @@ public class BonusConverterImpl implements BonusConverter {
private AreaJoinService areaJoinService;
@Override
public List<Bonus> toBonusList(OrderPayBO bo) {
public List<Bonus> toBonusList(OrderCreateBO bo) {
if (bo == null) {
return Collections.emptyList();
}
@ -61,7 +61,7 @@ public class BonusConverterImpl implements BonusConverter {
}
// 处理官方收款分成
private List<Bonus> toBonusListPlatform(OrderPayBO bo) {
private List<Bonus> toBonusListPlatform(OrderCreateBO bo) {
// 获取基础分成列表
List<Bonus> result = toBaseBonusListPlatform(bo.getDevice(), bo.getPartners(), bo.getAreaJoin());

View File

@ -35,4 +35,7 @@ public class DeviceQuery extends DeviceVO {
@ApiModelProperty("剩余电量百分比范围")
private List<BigDecimal> powerRange;
@ApiModelProperty("订单为空或状态列表")
private List<String> nonOrOrderStatusList;
}

View File

@ -71,6 +71,9 @@ public class DeviceVO extends Device {
@ApiModelProperty("当前订单设备状态")
private String orderDeviceStatus;
@ApiModelProperty("当前订单用户ID")
private Long orderUserId;
// 剩余续航公里
public BigDecimal getRemainEndurance() {
BigDecimal remainEndurance = MathUtils.mulDecimal(getRemainingPower(), getModelFullEndurance());

View File

@ -61,7 +61,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
basua.nick_name as area_agent_name,
bo.status as order_status,
bo.no as order_no,
bod.status as order_device_status
bo.user_id as order_user_id,
bod.status as order_device_status,
bod.order_id as order_id
from <include refid="searchTables"/>
</sql>
@ -126,6 +128,15 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
and bd.remaining_power &gt;= #{query.powerRange[0]}
and bd.remaining_power &lt;= #{query.powerRange[1]}
</if>
<if test="query.nonOrOrderStatusList != null and query.nonOrOrderStatusList.size() > 0">
and (
bd.order_device_id is null
or bo.status in
<foreach item="item" collection="query.nonOrOrderStatusList" open="(" separator="," close=")">
#{item}
</foreach>
)
</if>
${@com.ruoyi.framework.util.DataScopeUtil@dataScope(
null,
"bd.mch_id,ba.user_id,basu.agent_id",
@ -227,37 +238,37 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</update>
<sql id="updateColumns">
<if test="data.modelId != null">model_id = #{data.modelId},</if>
<if test="data.picture != null">picture = #{data.picture},</if>
<if test="data.mac != null and data.mac != ''">mac = #{data.mac},</if>
<if test="data.sn != null and data.sn != ''">sn = #{data.sn},</if>
<if test="data.vehicleNum != null">vehicle_num = #{data.vehicleNum},</if>
<if test="data.areaId != null">area_id = #{data.areaId},</if>
<if test="data.activationTime != null">activation_time = #{data.activationTime},</if>
<if test="data.onlineStatus != null">online_status = #{data.onlineStatus},</if>
<if test="data.createTime != null">create_time = #{data.createTime},</if>
<if test="data.updateTime != null">update_time = #{data.updateTime},</if>
<if test="data.remark != null">remark = #{data.remark},</if>
<if test="data.status != null">status = #{data.status},</if>
<if test="data.lockStatus != null">lock_status = #{data.lockStatus},</if>
<if test="data.location != null">location = #{data.location},</if>
<if test="data.remainingPower != null">remaining_power = #{data.remainingPower},</if>
<if test="data.voltage != null">voltage = #{data.voltage},</if>
<if test="data.longitude != null">longitude = #{data.longitude},</if>
<if test="data.latitude != null">latitude = #{data.latitude},</if>
<if test="data.lastTime != null">last_time = #{data.lastTime},</if>
<if test="data.version != null">version = #{data.version},</if>
<if test="data.signalStrength != null">signal_strength = #{data.signalStrength},</if>
<if test="data.quality != null">quality = #{data.quality},</if>
<if test="data.satellites != null">satellites = #{data.satellites},</if>
<if test="data.gps != null">gps = #{data.gps},</if>
<if test="data.lastLocationTime != null">last_location_time = #{data.lastLocationTime},</if>
<if test="data.hardwareVersionId != null">hardware_version_id = #{data.hardwareVersionId},</if>
<if test="data.mchId != null">mch_id = #{data.mchId},</if>
<if test="data.iotStatus != null">iot_status = #{data.iotStatus},</if>
<if test="data.isSound != null">is_sound = #{data.isSound},</if>
<if test="data.lastOnlineTime != null">last_online_time = #{data.lastOnlineTime},</if>
<if test="data.orderDeviceId != null">order_device_id = #{data.orderDeviceId},</if>
<if test="data.modelId != null">bd.model_id = #{data.modelId},</if>
<if test="data.picture != null">bd.picture = #{data.picture},</if>
<if test="data.mac != null and data.mac != ''">bd.mac = #{data.mac},</if>
<if test="data.sn != null and data.sn != ''">bd.sn = #{data.sn},</if>
<if test="data.vehicleNum != null">bd.vehicle_num = #{data.vehicleNum},</if>
<if test="data.areaId != null">bd.area_id = #{data.areaId},</if>
<if test="data.activationTime != null">bd.activation_time = #{data.activationTime},</if>
<if test="data.onlineStatus != null">bd.online_status = #{data.onlineStatus},</if>
<if test="data.createTime != null">bd.create_time = #{data.createTime},</if>
<if test="data.updateTime != null">bd.update_time = #{data.updateTime},</if>
<if test="data.remark != null">bd.remark = #{data.remark},</if>
<if test="data.status != null">bd.status = #{data.status},</if>
<if test="data.lockStatus != null">bd.lock_status = #{data.lockStatus},</if>
<if test="data.location != null">bd.location = #{data.location},</if>
<if test="data.remainingPower != null">bd.remaining_power = #{data.remainingPower},</if>
<if test="data.voltage != null">bd.voltage = #{data.voltage},</if>
<if test="data.longitude != null">bd.longitude = #{data.longitude},</if>
<if test="data.latitude != null">bd.latitude = #{data.latitude},</if>
<if test="data.lastTime != null">bd.last_time = #{data.lastTime},</if>
<if test="data.version != null">bd.version = #{data.version},</if>
<if test="data.signalStrength != null">bd.signal_strength = #{data.signalStrength},</if>
<if test="data.quality != null">bd.quality = #{data.quality},</if>
<if test="data.satellites != null">bd.satellites = #{data.satellites},</if>
<if test="data.gps != null">bd.gps = #{data.gps},</if>
<if test="data.lastLocationTime != null">bd.last_location_time = #{data.lastLocationTime},</if>
<if test="data.hardwareVersionId != null">bd.hardware_version_id = #{data.hardwareVersionId},</if>
<if test="data.mchId != null">bd.mch_id = #{data.mchId},</if>
<if test="data.iotStatus != null">bd.iot_status = #{data.iotStatus},</if>
<if test="data.isSound != null">bd.is_sound = #{data.isSound},</if>
<if test="data.lastOnlineTime != null">bd.last_online_time = #{data.lastOnlineTime},</if>
<if test="data.orderDeviceId != null">bd.order_device_id = #{data.orderDeviceId},</if>
</sql>
<delete id="deleteDeviceById" parameterType="Long">
@ -297,6 +308,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<update id="updateByQuery">
update bst_device bd
left join bst_order_device bod on bod.id = bd.order_device_id
left join bst_order bo on bo.id = bod.order_id
<trim prefix="SET" suffixOverrides=",">
<include refid="updateColumns"/>
</trim>

View File

@ -1,5 +1,6 @@
package com.ruoyi.bst.device.service.impl;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@ -17,6 +18,7 @@ import com.ruoyi.bst.device.service.DeviceIotService;
import com.ruoyi.bst.device.service.DeviceService;
import com.ruoyi.bst.device.utils.DeviceUtil;
import com.ruoyi.bst.model.service.ModelValidator;
import com.ruoyi.bst.order.domain.enums.OrderStatus;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.ServiceUtil;
import com.ruoyi.common.utils.StringUtils;
@ -387,10 +389,21 @@ public class DeviceServiceImpl implements DeviceService
if (id == null || deviceOrderId == null) {
return 0;
}
// 允许下单的设备订单状态
List<String> orderStatusList = Arrays.asList(
OrderStatus.FINISHED.getCode(),
OrderStatus.CANCELED.getCode(),
OrderStatus.WAIT_VERIFY.getCode(),
OrderStatus.REJECTED.getCode(),
OrderStatus.REFUNDED.getCode()
);
Device data = new Device();
data.setOrderDeviceId(deviceOrderId);
data.setId(id);
return deviceMapper.updateDevice(data);
DeviceQuery query = new DeviceQuery();
query.setId(id);
query.setNonOrOrderStatusList(orderStatusList);
return deviceMapper.updateByQuery(data, query);
}
@Override

View File

@ -1,13 +1,20 @@
package com.ruoyi.bst.order.domain.bo;
import java.util.List;
import com.ruoyi.bst.app.domain.AppVO;
import com.ruoyi.bst.area.domain.AreaVO;
import com.ruoyi.bst.areaJoin.domain.AreaJoinVO;
import com.ruoyi.bst.channel.domain.ChannelVO;
import com.ruoyi.bst.device.domain.DeviceVO;
import com.ruoyi.bst.order.domain.Order;
import com.ruoyi.bst.order.domain.dto.OrderCreateDTO;
import com.ruoyi.bst.order.domain.vo.OrderPrePriceVO;
import com.ruoyi.bst.orderDevice.domain.OrderDevice;
import com.ruoyi.bst.orderDevice.domain.OrderDeviceVO;
import com.ruoyi.bst.pay.domain.vo.DoPayVO;
import com.ruoyi.bst.suit.domain.SuitVO;
import com.ruoyi.bst.userApp.domain.UserAppVO;
import com.ruoyi.common.core.domain.vo.UserVO;
import lombok.Data;
@ -35,10 +42,28 @@ public class OrderCreateBO {
// 计算的价格信息
private OrderPrePriceVO prePrice;
// 渠道
private ChannelVO channel;
// APP信息
private AppVO app;
// 设备的加盟商
private AreaJoinVO areaJoin;
// 运营区的合伙人
private List<AreaJoinVO> partners;
// 用户APP绑定信息
private UserAppVO userApp;
// 生成的订单
private Order order;
// 生成的订单设备
private OrderDevice orderDevice;
// 调起支付的返回值
private DoPayVO doPayVO;
}

View File

@ -21,7 +21,15 @@ public class OrderCreateDTO {
@NotNull(message = "套餐ID不能为空")
private Long suitId;
@ApiModelProperty("APP ID")
@NotNull(message = "APP ID不能为空")
private Long appId;
@ApiModelProperty("支付渠道ID")
@NotNull(message = "支付渠道ID不能为空")
private Long channelId;
@ApiModelProperty("价格信息")
private OrderPrePriceVO price;
}

View File

@ -29,7 +29,7 @@ public interface OrderService
* @return 订单
*/
public OrderVO selectOrderById(Long id, boolean scope);
default OrderVO selectOrderById(Long id) {
return this.selectOrderById(id, false);
}
@ -86,7 +86,7 @@ public interface OrderService
* @param dto 创建订单DTO
* @return 订单
*/
public OrderVO createOrder(OrderCreateDTO dto);
public DoPayVO createOrder(OrderCreateDTO dto);
/**
* 查询订单
@ -118,14 +118,6 @@ public interface OrderService
*/
public void cancelWhenExpired(Order order);
/**
* 支付订单
* @param order 订单
* @param dto 支付订单DTO
* @return 结果
*/
public DoPayVO pay(OrderVO order, OrderPayDTO dto);
/**
* 结束订单
* @param dto 参数

View File

@ -9,19 +9,13 @@ import com.ruoyi.bst.order.domain.bo.OrderPayBO;
import com.ruoyi.bst.order.domain.vo.OrderInParkingVO;
public interface OrderValidator {
/**
* 校验订单BO
* @param bo 订单BO
*/
void validate(OrderCreateBO bo);
/**
* 校验订单支付BO
* @param bo 订单支付BO
*/
void validate(OrderPayBO bo);
/**
* 校验用户是否可以支付指定订单
* @param order 订单
@ -44,7 +38,7 @@ public interface OrderValidator {
*/
void validate(OrderEndBO bo, boolean ignoreInParking);
/**
* 校验用户是否可以操作设备开启
* @param order 订单

View File

@ -129,14 +129,23 @@ public class OrderConverterImpl implements OrderConverter{
DeviceVO device = deviceService.selectDeviceById(dto.getDeviceId());
bo.setDevice(device);
// 运营区
if (device != null) {
// 运营区
AreaVO area = areaService.selectAreaById(device.getAreaId());
bo.setArea(area);
// 查询设备所属人的加盟信息
AreaJoinVO areaJoin = areaJoinService.selectByUserArea(device.getMchId(), device.getAreaId());
bo.setAreaJoin(areaJoin);
// 查询运营区的合伙人列表
List<AreaJoinVO> partners = areaJoinService.selectListByAreaId(device.getAreaId(), AreaJoinType.PARTNER.getCode());
bo.setPartners(partners);
}
// 用户
bo.setUser(userService.selectUserById(dto.getUserId()));
UserVO user = userService.selectUserById(dto.getUserId());
bo.setUser(user);
// 用户进行中的订单设备
OrderDeviceVO userOrderDevice = orderDeviceService.selectUsingByUserId(dto.getUserId());
@ -146,6 +155,20 @@ public class OrderConverterImpl implements OrderConverter{
OrderPrePriceVO prePrice = OrderUtil.calcPrePrice(suit);
bo.setPrePrice(prePrice);
// 查询渠道
ChannelVO channel = channelService.selectChannelByChannelId(dto.getChannelId());
bo.setChannel(channel);
// 查询应用
AppVO app = appService.selectAppById(dto.getAppId());
bo.setApp(app);
// 查询用户应用信息
if (user != null && app != null) {
UserAppVO userApp = userAppService.selectByUserApp(user.getUserId(), app.getId());
bo.setUserApp(userApp);
}
// 生成订单
Order order = this.generateOrder(bo);
bo.setOrder(order);
@ -153,6 +176,7 @@ public class OrderConverterImpl implements OrderConverter{
// 生成订单设备
OrderDevice orderDevice = this.generateOrderDevice(bo);
bo.setOrderDevice(orderDevice);
return bo;
}
@ -179,7 +203,7 @@ public class OrderConverterImpl implements OrderConverter{
}
Order order = new Order();
// 基础信息
order.setPayExpireTime(LocalDateTime.now().plusMinutes(10));
order.setPayExpireTime(LocalDateTime.now().plusMinutes(3));
// 用户信息
UserVO user = bo.getUser();

View File

@ -4,10 +4,10 @@ import java.math.BigDecimal;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import com.ruoyi.bst.device.domain.enums.DeviceUnLockType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.support.TransactionTemplate;
@ -22,6 +22,7 @@ import com.ruoyi.bst.bonus.domain.enums.BonusBstType;
import com.ruoyi.bst.bonus.service.BonusConverter;
import com.ruoyi.bst.bonus.service.BonusService;
import com.ruoyi.bst.device.domain.DeviceVO;
import com.ruoyi.bst.device.domain.enums.DeviceUnLockType;
import com.ruoyi.bst.device.service.DeviceIotService;
import com.ruoyi.bst.device.service.DeviceService;
import com.ruoyi.bst.fault.domain.Fault;
@ -34,11 +35,9 @@ import com.ruoyi.bst.order.domain.OrderVO;
import com.ruoyi.bst.order.domain.bo.OrderChangeBO;
import com.ruoyi.bst.order.domain.bo.OrderCreateBO;
import com.ruoyi.bst.order.domain.bo.OrderEndBO;
import com.ruoyi.bst.order.domain.bo.OrderPayBO;
import com.ruoyi.bst.order.domain.dto.OrderChangeDeviceDTO;
import com.ruoyi.bst.order.domain.dto.OrderCreateDTO;
import com.ruoyi.bst.order.domain.dto.OrderEndDTO;
import com.ruoyi.bst.order.domain.dto.OrderPayDTO;
import com.ruoyi.bst.order.domain.dto.OrderRefundDTO;
import com.ruoyi.bst.order.domain.dto.OrderVerifyDTO;
import com.ruoyi.bst.order.domain.enums.OrderReturnMode;
@ -63,6 +62,7 @@ import com.ruoyi.bst.pay.domain.enums.PayBstType;
import com.ruoyi.bst.pay.domain.vo.DoPayVO;
import com.ruoyi.bst.pay.service.PayConverter;
import com.ruoyi.bst.pay.service.PayService;
import com.ruoyi.common.core.domain.vo.UserVO;
import com.ruoyi.common.core.redis.RedisLock;
import com.ruoyi.common.core.redis.enums.RedisLockKey;
import com.ruoyi.common.utils.DateUtils;
@ -227,21 +227,30 @@ public class OrderServiceImpl implements OrderService
}
@Override
public OrderVO createOrder(OrderCreateDTO dto) {
public DoPayVO createOrder(OrderCreateDTO dto) {
ServiceUtil.assertion(dto == null || dto.getDeviceId() == null, "参数错误");
// 加锁防止设备重复下单
// TODO可以考虑加锁60秒存储车辆用户ID60秒内只允许同一个用户下单
Long lockKey = dto.getDeviceId();
boolean lock = redisLock.lock(RedisLockKey.ORDER_CREATE, lockKey);
ServiceUtil.assertion(!lock, "当前设备使用的人太多了,请稍后再试");
ServiceUtil.assertion(!lock, "当前车辆使用的人太多了,请稍后再试");
try {
// 转为BO对象
OrderCreateBO bo = orderConverter.toCreateBO(dto);
// 校验参数
orderValidator.validate(bo);
// 若设备当前订单未支付且是当前用户的订单则将其取消
DeviceVO device = bo.getDevice();
UserVO user = bo.getUser();
if (device.getOrderId() != null && OrderStatus.WAIT_PAY.getCode().equals(device.getOrderStatus()) && Objects.equals(device.getOrderUserId(), user.getUserId())) {
int cancel = this.cancelOrder(device.getOrderId(), "取消用户重复订单");
ServiceUtil.assertion(cancel != 1, "取消用户重复订单失败");
}
return transactionTemplate.execute(status -> {
// 创建订单
Order order = bo.getOrder();
int rows = this.insertOrder(order);
@ -249,7 +258,7 @@ public class OrderServiceImpl implements OrderService
// 查询订单
OrderVO vo = this.selectOrderByNo(order.getNo());
ServiceUtil.assertion(vo == null, "创建订单失败");
ServiceUtil.assertion(vo == null, "查询创建订单失败");
// 创建订单设备
OrderDevice orderDevice = bo.getOrderDevice();
@ -257,18 +266,19 @@ public class OrderServiceImpl implements OrderService
int orderDeviceRows = orderDeviceService.insertOrderDevice(orderDevice);
ServiceUtil.assertion(orderDeviceRows != 1, "创建订单设备失败");
// 更新订单当前设备
int updateOrderDeviceId = this.updateOrderDeviceId(orderDevice.getOrderId(), orderDevice.getId());
ServiceUtil.assertion(updateOrderDeviceId != 1, "更新订单当前设备失败");
// 设置用户运营区ID
int updateAreaId = userService.updateAreaId(vo.getUserId(), vo.getAreaId());
ServiceUtil.assertion(updateAreaId != 1, "更新用户运营区ID失败");
// 支付
DoPayVO doPayVO = this.pay(bo);
ServiceUtil.assertion(doPayVO == null, "支付失败");
bo.setDoPayVO(doPayVO);
// 加入延时队列超时取消
this.cancelWhenExpired(order);
return vo;
return doPayVO;
});
} finally {
redisLock.unlock(RedisLockKey.ORDER_CREATE, lockKey);
@ -327,6 +337,10 @@ public class OrderServiceImpl implements OrderService
ServiceUtil.assertion(order == null, "ID为%s的订单不存在", id);
ServiceUtil.assertion(!OrderStatus.canCancelPay().contains(order.getStatus()), "ID为%s的订单当前状态不允许取消", id);
Long deviceId = order.getDeviceId(); // 设备ID
Long orderDeviceId = order.getOrderDeviceId(); // 订单设备ID
// 取消订单
Integer result = transactionTemplate.execute(status -> {
// 更新订单状态
@ -339,6 +353,10 @@ public class OrderServiceImpl implements OrderService
int rows = orderMapper.updateByQuery(data, query);
ServiceUtil.assertion(rows != 1, "ID为%s的订单取消失败状态已发生变化", id);
// 清除设备上的订单ID
int clear = deviceService.clearCurrentOrderDevice(deviceId, orderDeviceId);
ServiceUtil.assertion(clear != 1, "清除设备订单失败");
// 取消支付单
boolean cancelPay = payService.closeByBstId(PayBstType.ORDER.getType(), id);
ServiceUtil.assertion(!cancelPay, "ID为%s的订单取消支付单失败", id);
@ -349,14 +367,7 @@ public class OrderServiceImpl implements OrderService
return result == null ? 0 : result;
}
@Override
public DoPayVO pay(OrderVO order, OrderPayDTO dto) {
ServiceUtil.assertion(order == null || dto == null, "参数错误");
// 转为BO对象
OrderPayBO bo = orderConverter.toPayBO(order, dto);
orderValidator.validate(bo);
private DoPayVO pay(OrderCreateBO bo) {
// 转为分成列表
List<Bonus> bonusList = bonusConverter.toBonusList(bo);

View File

@ -3,7 +3,6 @@ package com.ruoyi.bst.order.service.impl;
import java.util.List;
import java.util.Objects;
import com.ruoyi.common.exception.ServiceException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@ -17,10 +16,8 @@ import com.ruoyi.bst.device.service.DeviceService;
import com.ruoyi.bst.order.domain.OrderVO;
import com.ruoyi.bst.order.domain.bo.OrderCreateBO;
import com.ruoyi.bst.order.domain.bo.OrderEndBO;
import com.ruoyi.bst.order.domain.bo.OrderPayBO;
import com.ruoyi.bst.order.domain.dto.OrderCreateDTO;
import com.ruoyi.bst.order.domain.dto.OrderEndDTO;
import com.ruoyi.bst.order.domain.dto.OrderPayDTO;
import com.ruoyi.bst.order.domain.enums.OrderStatus;
import com.ruoyi.bst.order.domain.vo.OrderInParkingVO;
import com.ruoyi.bst.order.domain.vo.OrderPrePriceVO;
@ -30,6 +27,7 @@ import com.ruoyi.bst.orderDevice.domain.OrderDeviceVO;
import com.ruoyi.bst.suit.domain.SuitVO;
import com.ruoyi.common.constants.ServiceCode;
import com.ruoyi.common.core.domain.vo.UserVO;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.MathUtils;
import com.ruoyi.common.utils.ServiceUtil;
import com.ruoyi.common.utils.StringUtils;
@ -78,6 +76,16 @@ public class OrderValidatorImpl implements OrderValidator{
boolean priceEquals = OrderUtil.isEquals(prePrice, dto.getPrice());
ServiceUtil.assertion(!priceEquals, "当前价格已发生变化,请刷新后重新下单");
// 应用
AppVO app = bo.getApp();
ServiceUtil.assertion(app == null, "ID为%s的应用不存在", dto.getAppId());
// 渠道
ChannelVO channel = bo.getChannel();
ServiceUtil.assertion(channel == null, "ID为%s的渠道不存在", dto.getChannelId());
ServiceUtil.assertion(channel.getEnabled() == null || !channel.getEnabled(), "ID为%s的渠道暂不可用", channel.getChannelId());
ServiceUtil.assertion(channel.getAppIds() == null || !channel.getAppIds().contains(app.getId()), "ID为%s的渠道不支持ID为%s的应用", channel.getChannelId(), app.getId());
}
@Override
@ -95,34 +103,6 @@ public class OrderValidatorImpl implements OrderValidator{
return order != null && userId != null && Objects.equals(order.getUserId(), userId);
}
@Override
public void validate(OrderPayBO bo) {
ServiceUtil.assertion(bo == null, "参数错误");
OrderPayDTO dto = bo.getDto();
ServiceUtil.assertion(dto == null, "参数错误");
// 订单
OrderVO order = bo.getOrder();
ServiceUtil.assertion(order == null, "编号为%s的订单不存在", dto.getNo());
ServiceUtil.assertion(!OrderStatus.canPay().contains(order.getStatus()), "编号为%s的订单当前状态不可支付", dto.getNo());
// 应用
AppVO app = bo.getApp();
ServiceUtil.assertion(app == null, "ID为%s的应用不存在", dto.getAppId());
// 渠道
ChannelVO channel = bo.getChannel();
ServiceUtil.assertion(channel == null, "ID为%s的渠道不存在", dto.getChannelId());
ServiceUtil.assertion(channel.getEnabled() == null || !channel.getEnabled(), "ID为%s的渠道暂不可用", channel.getChannelId());
ServiceUtil.assertion(channel.getAppIds() == null || !channel.getAppIds().contains(app.getId()), "ID为%s的渠道不支持ID为%s的应用", channel.getChannelId(), app.getId());
// 设备
DeviceVO device = bo.getDevice();
ServiceUtil.assertion(device == null, "ID为%s的设备不存在", order.getOrderDeviceId());
}
@Override
public void validate(OrderEndBO bo, boolean ignoreInParking) {
OrderVO order = bo.getOrder();
@ -182,8 +162,9 @@ public class OrderValidatorImpl implements OrderValidator{
ServiceUtil.assertion(device == null || device.getId() == null, "车辆不存在");
ServiceUtil.assertion(!DeviceStatus.canUse().contains(device.getStatus()), "ID为%s的车辆当前状态不可使用", device.getId());
ServiceUtil.assertion(MathUtils.smallerThan(device.getRemainingPower(), device.getAreaUndercharge()), "ID为%s的车辆电量不足%s%%,暂时无法使用", device.getId(), device.getAreaUndercharge());
ServiceUtil.assertion(OrderStatus.PROCESSING.getCode().equals(device.getOrderStatus()), "ID为%s的车辆当前有正在进行的订单无法使用", device.getId());
// 设备能否在该订单上使用
// 设备能否在该订单上使用换车
if (order != null) {
DeviceQuery query = OrderUtil.toChangeDeviceQuery(order);
List<DeviceVO> list = deviceService.selectDeviceList(query);

View File

@ -78,7 +78,24 @@ public class OrderDeviceServiceImpl implements OrderDeviceService
@Override
public int insertOrderDevice(OrderDevice orderDevice)
{
return orderDeviceMapper.insertOrderDevice(orderDevice);
Integer result = transactionTemplate.execute(status -> {
int rows = orderDeviceMapper.insertOrderDevice(orderDevice);
if (rows > 0) {
// 修改订单信息
int updateOrder = orderService.updateOrderDeviceId(orderDevice.getOrderId(), orderDevice.getId());
ServiceUtil.assertion(updateOrder != 1, "更新订单信息失败");
// 修改设备信息
int updateDevice = deviceService.updateCurrentDeviceOrderId(orderDevice.getDeviceId(), orderDevice.getId());
ServiceUtil.assertion(updateDevice != 1, "占用设备失败,当前设备有他人使用,请尝试其他设备。");
}
return rows;
});
return result == null ? 0 : result;
}
/**
@ -145,28 +162,14 @@ public class OrderDeviceServiceImpl implements OrderDeviceService
ServiceUtil.assertion(orderDevice == null, "订单设备不能为空");
ServiceUtil.assertion(!OrderDeviceStatus.canStart().contains(orderDevice.getStatus()), "订单设备状态不允许开始");
Integer result = transactionTemplate.execute(status -> {
// 修改订单设备状态
OrderDevice data = new OrderDevice();
data.setStatus(OrderDeviceStatus.USING.getCode());
data.setStartTime(LocalDateTime.now());
OrderDeviceQuery query = new OrderDeviceQuery();
query.setId(orderDevice.getId());
query.setStatusList(OrderDeviceStatus.canStart());
int rows = orderDeviceMapper.updateByQuery(data, query);
// 修改订单信息
int updateOrder = orderService.updateOrderDeviceId(orderDevice.getOrderId(), orderDevice.getId());
ServiceUtil.assertion(updateOrder != 1, "更新订单信息失败");
// 修改设备信息
int updateDevice = deviceService.updateCurrentDeviceOrderId(orderDevice.getDeviceId(), orderDevice.getId());
ServiceUtil.assertion(updateDevice != 1, "更新设备信息失败");
return rows;
});
return result == null ? 0 : result;
// 修改订单设备状态
OrderDevice data = new OrderDevice();
data.setStatus(OrderDeviceStatus.USING.getCode());
data.setStartTime(LocalDateTime.now());
OrderDeviceQuery query = new OrderDeviceQuery();
query.setId(orderDevice.getId());
query.setStatusList(OrderDeviceStatus.canStart());
return orderDeviceMapper.updateByQuery(data, query);
}
@Override

View File

@ -1,6 +1,6 @@
package com.ruoyi.bst.pay.service;
import com.ruoyi.bst.order.domain.bo.OrderPayBO;
import com.ruoyi.bst.order.domain.bo.OrderCreateBO;
import com.ruoyi.bst.pay.domain.Pay;
public interface PayConverter {
@ -8,6 +8,6 @@ public interface PayConverter {
/**
* 将订单支付BO转换为支付PO
*/
Pay toPayPO(OrderPayBO bo);
Pay toPayPO(OrderCreateBO bo);
}

View File

@ -7,7 +7,7 @@ import org.springframework.stereotype.Service;
import com.ruoyi.bst.app.domain.AppVO;
import com.ruoyi.bst.channel.domain.ChannelVO;
import com.ruoyi.bst.order.domain.Order;
import com.ruoyi.bst.order.domain.bo.OrderPayBO;
import com.ruoyi.bst.order.domain.bo.OrderCreateBO;
import com.ruoyi.bst.pay.domain.Pay;
import com.ruoyi.bst.pay.domain.enums.PayBstType;
import com.ruoyi.bst.pay.domain.enums.PayStatus;
@ -22,7 +22,7 @@ public class PayConverterImpl implements PayConverter {
@Override
public Pay toPayPO(OrderPayBO bo) {
public Pay toPayPO(OrderCreateBO bo) {
if (bo == null) {
return null;
}

View File

@ -81,7 +81,7 @@ public class AppOrderController extends BaseController {
return success(vo);
}
@ApiOperation("下单")
@ApiOperation("下单并支付")
@PostMapping
public AjaxResult createOrder(@RequestBody @Validated OrderCreateDTO dto) {
dto.setUserId(getUserId());
@ -91,12 +91,13 @@ public class AppOrderController extends BaseController {
@ApiOperation("支付")
@PostMapping("/pay")
public AjaxResult pay(@RequestBody @Validated OrderPayDTO dto) {
// 查询订单
OrderVO order = orderService.selectOrderByNo(dto.getNo());
ServiceUtil.assertion(!orderValidator.canPay(order, getUserId()), "您无权支付ID为%s的订单", order.getId());
return error("当前接口已弃用,请使用下单并支付接口");
// // 查询订单
// OrderVO order = orderService.selectOrderByNo(dto.getNo());
// ServiceUtil.assertion(!orderValidator.canPay(order, getUserId()), "您无权支付ID为%s的订单", order.getId());
// 支付
return success(orderService.pay(order, dto));
// // 支付
// return success(orderService.pay(order, dto));
}
@ApiOperation("结束本人订单(还车)")

View File

@ -6,16 +6,12 @@ import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.bst.orderDevice.domain.OrderDevice;
import com.ruoyi.bst.orderDevice.domain.OrderDeviceQuery;
import com.ruoyi.bst.orderDevice.domain.OrderDeviceVO;
import com.ruoyi.bst.orderDevice.service.OrderDeviceService;
@ -75,36 +71,4 @@ public class OrderDeviceController extends BaseController
return success(orderDeviceService.selectOrderDeviceById(id));
}
/**
* 新增订单设备
*/
@PreAuthorize("@ss.hasPermi('bst:orderDevice:add')")
@Log(title = "订单设备", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody OrderDevice orderDevice)
{
return toAjax(orderDeviceService.insertOrderDevice(orderDevice));
}
/**
* 修改订单设备
*/
@PreAuthorize("@ss.hasPermi('bst:orderDevice:edit')")
@Log(title = "订单设备", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody OrderDevice orderDevice)
{
return toAjax(orderDeviceService.updateOrderDevice(orderDevice));
}
/**
* 删除订单设备
*/
@PreAuthorize("@ss.hasPermi('bst:orderDevice:remove')")
@Log(title = "订单设备", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public AjaxResult remove(@PathVariable Long[] ids)
{
return toAjax(orderDeviceService.deleteOrderDeviceByIds(ids));
}
}