短信通知

This commit is contained in:
磷叶 2025-04-16 15:00:52 +08:00
parent 4f4e3a3c56
commit cc628ffc94
16 changed files with 195 additions and 49 deletions

View File

@ -10,6 +10,7 @@ import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.exceptions.ClientException; import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.profile.DefaultProfile; import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile; import com.aliyuncs.profile.IClientProfile;
import com.ruoyi.common.exception.ServiceException;
@Service @Service
public class SmsAliService { public class SmsAliService {
@ -34,28 +35,30 @@ public class SmsAliService {
/** /**
* 发送短信验证码 * 发送短信验证码
*/ */
public SendSmsResponse send(SmsSendDTO dto) public SendSmsResponse send(SmsSendDTO dto) {
throws ClientException { try {
// 可自助调整超时时间 // 可自助调整超时时间
System.setProperty("sun.net.client.defaultConnectTimeout", "10000"); System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
System.setProperty("sun.net.client.defaultReadTimeout", "10000"); System.setProperty("sun.net.client.defaultReadTimeout", "10000");
// 初始化acsClient,暂不支持region化 // 初始化acsClient,暂不支持region化
IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessKeySecret); IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessKeySecret);
DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", product, domain); DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", product, domain);
IAcsClient acsClient = new DefaultAcsClient(profile); IAcsClient acsClient = new DefaultAcsClient(profile);
// 组装请求对象-具体描述见控制台-文档部分内容 // 组装请求对象-具体描述见控制台-文档部分内容
SendSmsRequest request = new SendSmsRequest(); SendSmsRequest request = new SendSmsRequest();
// 必填:待发送手机号 // 必填:待发送手机号
request.setPhoneNumbers(dto.getMobile()); request.setPhoneNumbers(dto.getMobile());
// 必填:短信签名-可在短信控制台中找到 // 必填:短信签名-可在短信控制台中找到
request.setSignName(signName); request.setSignName(signName);
// 必填:短信模板-可在短信控制台中找到 // 必填:短信模板-可在短信控制台中找到
request.setTemplateCode(dto.getTemplateCode()); request.setTemplateCode(dto.getTemplateCode());
// 可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}",此处的值为 // 可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}",此处的值为
request.setTemplateParam(dto.getParam().toJSONString()); request.setTemplateParam(dto.getParam().toJSONString());
// hint 此处可能会抛出异常注意catch // hint 此处可能会抛出异常注意catch
return acsClient.getAcsResponse(request); return acsClient.getAcsResponse(request);
} catch (ClientException e) {
throw new ServiceException("短信发送失败,错误信息:" + e.getMessage());
}
} }
} }

View File

@ -8,8 +8,11 @@ import lombok.EqualsAndHashCode;
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
public class AreaVO extends Area { public class AreaVO extends Area {
// 所属用户
@ApiModelProperty("用户名称") @ApiModelProperty("用户名称")
private String userName; private String userName;
@ApiModelProperty("用户手机号")
private String userPhone;
@ApiModelProperty("创建人名称") @ApiModelProperty("创建人名称")
private String createName; private String createName;

View File

@ -48,6 +48,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
ba.outage_distance, ba.outage_distance,
su.nick_name as user_name, su.nick_name as user_name,
su.agent_id as agent_id, su.agent_id as agent_id,
su.user_name as user_phone,
suc.nick_name as create_name suc.nick_name as create_name
from <include refid="searchTables"/> from <include refid="searchTables"/>
</sql> </sql>
@ -80,6 +81,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="query.deleted == null "> and ba.deleted = false</if> <if test="query.deleted == null "> and ba.deleted = false</if>
<if test="query.userName != null and query.userName != ''"> and su.nick_name like concat('%', #{query.userName}, '%')</if> <if test="query.userName != null and query.userName != ''"> and su.nick_name like concat('%', #{query.userName}, '%')</if>
<if test="query.createName != null and query.createName != ''"> and suc.nick_name like concat('%', #{query.createName}, '%')</if> <if test="query.createName != null and query.createName != ''"> and suc.nick_name like concat('%', #{query.createName}, '%')</if>
<if test="query.userPhone != null and query.userPhone != ''"> and su.user_name like concat('%', #{query.userPhone}, '%')</if>
<if test="query.ids != null and query.ids.size() > 0"> <if test="query.ids != null and query.ids.size() > 0">
and ba.id in and ba.id in
<foreach collection="query.ids" item="item" open="(" separator="," close=")"> <foreach collection="query.ids" item="item" open="(" separator="," close=")">

View File

@ -10,7 +10,8 @@ import lombok.Getter;
public enum BalanceLogBstType { public enum BalanceLogBstType {
ORDER("ORDER", "订单"), ORDER("ORDER", "订单"),
WITHDRAW("WITHDRAW", "提现"); WITHDRAW("WITHDRAW", "提现"),
SMS("SMS", "短信");
private final String code; private final String code;
private final String name; private final String name;

View File

@ -39,10 +39,6 @@ public class OrderVO extends Order {
// 运营区 // 运营区
@ApiModelProperty("运营区名称") @ApiModelProperty("运营区名称")
private String areaName; private String areaName;
@ApiModelProperty("运营区联系人")
private String areaContact;
@ApiModelProperty("运营区联系电话")
private String areaPhone;
// 用户 // 用户
@ApiModelProperty("用户名称") @ApiModelProperty("用户名称")

View File

@ -14,9 +14,6 @@ public class OrderEndDTO {
@NotNull(message = "订单ID不能为空") @NotNull(message = "订单ID不能为空")
private Long orderId; private Long orderId;
@ApiModelProperty("是否辅助还车(管理员还车)")
private Boolean isAdmin;
@ApiModelProperty("手机定位(经度)") @ApiModelProperty("手机定位(经度)")
private BigDecimal lon; private BigDecimal lon;
@ -28,4 +25,7 @@ public class OrderEndDTO {
@ApiModelProperty("车辆图片") @ApiModelProperty("车辆图片")
private String picture; private String picture;
@ApiModelProperty("还车类型")
private String returnType;
} }

View File

@ -1,5 +1,8 @@
package com.ruoyi.bst.order.domain.enums; package com.ruoyi.bst.order.domain.enums;
import java.util.Arrays;
import java.util.List;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;
@ -8,10 +11,20 @@ import lombok.Getter;
public enum OrderReturnType { public enum OrderReturnType {
NORMAL("1", "正常还车"), NORMAL("1", "正常还车"),
AUXILIARY("2", "辅助还车"); AUXILIARY("2", "辅助还车"),
SYSTEM("3", "系统还车");
private String code; private String code;
private String name; private String name;
// 是否是管理员还车
public static boolean isAdmin(String returnType) {
return AUXILIARY.getCode().equals(returnType) || SYSTEM.getCode().equals(returnType);
}
// 需要审核的还车类型
public static List<String> needVerify() {
return Arrays.asList(NORMAL.getCode(), SYSTEM.getCode());
}
} }

View File

@ -52,8 +52,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
bo.area_user_id, bo.area_user_id,
bo.area_agent_id, bo.area_agent_id,
ba.name as area_name, ba.name as area_name,
ba.contact as area_contact,
ba.phone as area_phone,
su.nick_name as user_name, su.nick_name as user_name,
su.user_name as user_phone, su.user_name as user_phone,
bp.no as pay_no, bp.no as pay_no,

View File

@ -133,7 +133,7 @@ public interface OrderService
* @param dto 参数 * @param dto 参数
* @return 结果 * @return 结果
*/ */
public OrderFeeVO preEndCheck(OrderEndDTO dto); public OrderFeeVO calcFee(OrderEndDTO dto);
/** /**
* 退款 * 退款

View File

@ -65,6 +65,7 @@ import com.ruoyi.bst.pay.domain.enums.PayBstType;
import com.ruoyi.bst.pay.domain.vo.DoPayVO; import com.ruoyi.bst.pay.domain.vo.DoPayVO;
import com.ruoyi.bst.pay.service.PayConverter; import com.ruoyi.bst.pay.service.PayConverter;
import com.ruoyi.bst.pay.service.PayService; import com.ruoyi.bst.pay.service.PayService;
import com.ruoyi.bst.sms.service.SmsService;
import com.ruoyi.common.core.domain.vo.UserVO; import com.ruoyi.common.core.domain.vo.UserVO;
import com.ruoyi.common.core.redis.RedisLock; import com.ruoyi.common.core.redis.RedisLock;
import com.ruoyi.common.core.redis.enums.RedisLockKey; import com.ruoyi.common.core.redis.enums.RedisLockKey;
@ -142,6 +143,9 @@ public class OrderServiceImpl implements OrderService
@Autowired @Autowired
private UserService userService; private UserService userService;
@Autowired
private SmsService smsService;
/** /**
* 查询订单 * 查询订单
* *
@ -235,7 +239,7 @@ public class OrderServiceImpl implements OrderService
ServiceUtil.assertion(dto == null || dto.getDeviceId() == null, "参数错误"); ServiceUtil.assertion(dto == null || dto.getDeviceId() == null, "参数错误");
// 加锁防止设备重复下单 // 加锁防止设备重复下单
// TODO可以考虑加锁60秒存储车辆用户ID60秒内只允许同一个用户下单 // TODO 可以考虑加锁60秒存储车辆用户ID60秒内只允许同一个用户下单
Long lockKey = dto.getDeviceId(); Long lockKey = dto.getDeviceId();
boolean lock = redisLock.lock(RedisLockKey.ORDER_CREATE, lockKey); boolean lock = redisLock.lock(RedisLockKey.ORDER_CREATE, lockKey);
ServiceUtil.assertion(!lock, "当前车辆使用的人太多了,请稍后再试"); ServiceUtil.assertion(!lock, "当前车辆使用的人太多了,请稍后再试");
@ -398,10 +402,13 @@ public class OrderServiceImpl implements OrderService
// 转为BO对象 // 转为BO对象
OrderEndBO bo = orderConverter.toEndBO(dto); OrderEndBO bo = orderConverter.toEndBO(dto);
// 校验参数 // 校验参数
boolean isAdmin = dto.getIsAdmin() != null && dto.getIsAdmin(); String returnType = dto.getReturnType();
boolean isAdmin = OrderReturnType.isAdmin(returnType);
orderValidator.validate(bo, isAdmin); orderValidator.validate(bo, isAdmin);
// 提取数据
OrderVO order = bo.getOrder(); OrderVO order = bo.getOrder();
OrderInParkingVO inParkingVO = bo.getInParkingVO(); OrderInParkingVO inParkingVO = bo.getInParkingVO();
AreaVO area = bo.getArea(); AreaVO area = bo.getArea();
@ -413,13 +420,13 @@ public class OrderServiceImpl implements OrderService
order.setDistance(LocationLogUtil.calcDistance(bo.getPositionList())); order.setDistance(LocationLogUtil.calcDistance(bo.getPositionList()));
order.setEndReason(dto.getEndReason()); order.setEndReason(dto.getEndReason());
// 还车类型 // 还车类型
order.setReturnType(isAdmin ? OrderReturnType.AUXILIARY.getCode() : OrderReturnType.NORMAL.getCode()); order.setReturnType(returnType);
// 订单状态 // 订单状态
this.setOrderStatus(order, isAdmin); this.setOrderStatus(order, returnType);
// 订单费用 // 订单费用
this.setOrderFee(order, area, inParkingVO); this.setOrderFee(order, area, inParkingVO);
Integer result = transactionTemplate.execute(status -> { transactionTemplate.execute(status -> {
// 更新订单数据 // 更新订单数据
Order data = orderConverter.toPOByEnd(order); Order data = orderConverter.toPOByEnd(order);
OrderQuery query = new OrderQuery(); OrderQuery query = new OrderQuery();
@ -437,6 +444,9 @@ public class OrderServiceImpl implements OrderService
// 预分成 // 预分成
boolean bonus = bonusService.prepayByBst(BonusBstType.ORDER, order.getId()); boolean bonus = bonusService.prepayByBst(BonusBstType.ORDER, order.getId());
ServiceUtil.assertion(!bonus, "ID为%s的订单预分成失败", order.getId()); ServiceUtil.assertion(!bonus, "ID为%s的订单预分成失败", order.getId());
} else if (OrderStatus.WAIT_VERIFY.getCode().equals(order.getStatus())) {
// 发送还车审核通知
smsService.sendOrderWaitVerifyMsg(order);
} }
// 结束订单设备 // 结束订单设备
@ -444,7 +454,7 @@ public class OrderServiceImpl implements OrderService
ServiceUtil.assertion(finish != 1, "结束ID为%s的订单设备失败", orderDevice.getId()); ServiceUtil.assertion(finish != 1, "结束ID为%s的订单设备失败", orderDevice.getId());
// 设备上锁必须放最后因为会操作设备 // 设备上锁必须放最后因为会操作设备
DeviceIotVO lock = deviceIotService.lock(orderDevice.getDeviceId(), dto.getIsAdmin(), "订单结束上锁:" + orderDevice.getOrderNo(), false); DeviceIotVO lock = deviceIotService.lock(orderDevice.getDeviceId(), isAdmin, "订单结束上锁:" + orderDevice.getOrderNo(), false);
ServiceUtil.assertion(lock.getDb() != 1, "ID为%s的设备上锁失败", orderDevice.getDeviceId()); ServiceUtil.assertion(lock.getDb() != 1, "ID为%s的设备上锁失败", orderDevice.getDeviceId());
vo.setIot(lock.getIot()); vo.setIot(lock.getIot());
@ -455,9 +465,9 @@ public class OrderServiceImpl implements OrderService
} }
// 设置订单状态 // 设置订单状态
private void setOrderStatus(OrderVO order, boolean isAdmin) { private void setOrderStatus(OrderVO order, String returnType) {
// 根据是否需要审核设置订单状态 // 根据是否需要审核设置订单状态
if (order.getAreaReturnVerify() != null && order.getAreaReturnVerify() && !isAdmin) { if (order.getAreaReturnVerify() != null && order.getAreaReturnVerify() && OrderReturnType.needVerify().contains(returnType)) {
// 更新订单状态为待审核 // 更新订单状态为待审核
order.setStatus(OrderStatus.WAIT_VERIFY.getCode()); order.setStatus(OrderStatus.WAIT_VERIFY.getCode());
} else { } else {
@ -530,7 +540,7 @@ public class OrderServiceImpl implements OrderService
} }
@Override @Override
public OrderFeeVO preEndCheck(OrderEndDTO dto) { public OrderFeeVO calcFee(OrderEndDTO dto) {
// 查询订单 // 查询订单
OrderVO order = this.selectOrderById(dto.getOrderId()); OrderVO order = this.selectOrderById(dto.getOrderId());
if (order == null) { if (order == null) {

View File

@ -0,0 +1,16 @@
package com.ruoyi.bst.sms.constants;
public class SmsTemplateCode {
// 还车待审核模板您名下有一笔租车订单已归还订单金额${name}
public static final String ORDER_WAIT_VERIFY = "SMS_470225045";
// 订单支付成功通知模板您有一笔订单${orderNo}用户已付款可在小程序管理端查看
public static final String ORDER_PAY_SUCCESS = "SMS_470585077";
// 押金提现申请通知模板用户${name}发起押金提现申请请尽快审核
public static final String DEPOSIT_WITHDRAW_APPLY = "SMS_470400077";
// 验证码模板您的验证码为${code}请勿泄露于他人
public static final String VERIFICATION_CODE = "SMS_470385109";
}

View File

@ -0,0 +1,12 @@
package com.ruoyi.bst.sms.service;
import com.ruoyi.bst.order.domain.OrderVO;
public interface SmsService {
/**
* 还车待审核通知
*/
void sendOrderWaitVerifyMsg(OrderVO order);
}

View File

@ -0,0 +1,87 @@
package com.ruoyi.bst.sms.service.impl;
import java.math.BigDecimal;
import java.util.concurrent.ScheduledExecutorService;
import com.ruoyi.common.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.support.TransactionTemplate;
import com.alibaba.fastjson2.JSONObject;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.ruoyi.bst.area.domain.AreaVO;
import com.ruoyi.bst.area.service.AreaService;
import com.ruoyi.bst.balanceLog.domain.enums.BalanceLogBstType;
import com.ruoyi.bst.order.domain.OrderVO;
import com.ruoyi.bst.sms.constants.SmsTemplateCode;
import com.ruoyi.bst.sms.service.SmsService;
import com.ruoyi.common.sms.SmsAliService;
import com.ruoyi.common.sms.SmsSendDTO;
import com.ruoyi.common.utils.ServiceUtil;
import com.ruoyi.system.user.service.UserService;
import lombok.extern.slf4j.Slf4j;
@Service
@Slf4j
public class SmsServiceImpl implements SmsService {
@Autowired
private SmsAliService smsAliService;
@Autowired
private AreaService areaService;
@Autowired
private ScheduledExecutorService scheduledExecutorService;
@Autowired
private TransactionTemplate transactionTemplate;
@Autowired
private UserService userService;
@Override
public void sendOrderWaitVerifyMsg(OrderVO order) {
AreaVO area = areaService.selectAreaById(order.getAreaId());
if (area == null || area.getMsgSwitch() == null || !area.getMsgSwitch()) {
return;
}
String mobile = area.getUserPhone();
if (StringUtils.isBlank(mobile)) {
return;
}
String reason = "订单" + order.getNo() + "还车待审核短信通知,接收手机:" + mobile;
SmsSendDTO dto = new SmsSendDTO();
dto.setMobile(mobile);
dto.setTemplateCode(SmsTemplateCode.ORDER_WAIT_VERIFY);
JSONObject param = new JSONObject();
param.put("name", order.getTotalFee());
dto.setParam(param);
this.sendAsync(area.getUserId(), reason, dto);
}
// 异步发送短信
private void sendAsync(Long userId, String reason, SmsSendDTO dto) {
scheduledExecutorService.execute(() -> {
transactionTemplate.execute(status -> {
// 扣费
int rows = userService.subtractBalance(userId, BigDecimal.valueOf(0.1), BalanceLogBstType.SMS, userId, reason, true);
ServiceUtil.assertion(rows != 1, "短信扣费失败,用户%s余额不足", userId);
// 发送短信
SendSmsResponse res = smsAliService.send(dto);
ServiceUtil.assertion(res == null, "给用户%s发送短信失败未知原因", userId);
ServiceUtil.assertion(!"OK".equals(res.getCode()), "给用户%s短信发送失败%s", userId, res.getMessage());
return rows;
});
});
}
}

View File

@ -11,6 +11,7 @@ import org.springframework.stereotype.Component;
import com.ruoyi.bst.order.domain.OrderQuery; import com.ruoyi.bst.order.domain.OrderQuery;
import com.ruoyi.bst.order.domain.OrderVO; import com.ruoyi.bst.order.domain.OrderVO;
import com.ruoyi.bst.order.domain.dto.OrderEndDTO; import com.ruoyi.bst.order.domain.dto.OrderEndDTO;
import com.ruoyi.bst.order.domain.enums.OrderReturnType;
import com.ruoyi.bst.order.domain.enums.OrderStatus; import com.ruoyi.bst.order.domain.enums.OrderStatus;
import com.ruoyi.bst.order.mapper.OrderMapper; import com.ruoyi.bst.order.mapper.OrderMapper;
import com.ruoyi.bst.order.service.OrderService; import com.ruoyi.bst.order.service.OrderService;
@ -63,7 +64,7 @@ public class OrderTask implements ApplicationRunner {
for (OrderVO order : orderList) { for (OrderVO order : orderList) {
try { try {
OrderEndDTO dto = new OrderEndDTO(); OrderEndDTO dto = new OrderEndDTO();
dto.setIsAdmin(true); dto.setReturnType(OrderReturnType.SYSTEM.getCode());
dto.setOrderId(order.getId()); dto.setOrderId(order.getId());
dto.setEndReason("超时系统自动结束"); dto.setEndReason("超时系统自动结束");
orderService.endOrder(dto); orderService.endOrder(dto);

View File

@ -2,6 +2,7 @@ package com.ruoyi.web.app;
import java.util.List; import java.util.List;
import com.ruoyi.common.annotation.Anonymous;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
@ -19,6 +20,7 @@ import com.ruoyi.bst.order.domain.dto.OrderCloseDeviceDTO;
import com.ruoyi.bst.order.domain.dto.OrderCreateDTO; import com.ruoyi.bst.order.domain.dto.OrderCreateDTO;
import com.ruoyi.bst.order.domain.dto.OrderEndDTO; import com.ruoyi.bst.order.domain.dto.OrderEndDTO;
import com.ruoyi.bst.order.domain.dto.OrderPayDTO; import com.ruoyi.bst.order.domain.dto.OrderPayDTO;
import com.ruoyi.bst.order.domain.enums.OrderReturnType;
import com.ruoyi.bst.order.domain.enums.OrderStatus; import com.ruoyi.bst.order.domain.enums.OrderStatus;
import com.ruoyi.bst.order.domain.vo.OrderEndVO; import com.ruoyi.bst.order.domain.vo.OrderEndVO;
import com.ruoyi.bst.order.domain.vo.OrderFeeVO; import com.ruoyi.bst.order.domain.vo.OrderFeeVO;
@ -75,6 +77,7 @@ public class AppOrderController extends BaseController {
@ApiOperation("支付前计算订单价格") @ApiOperation("支付前计算订单价格")
@PostMapping("/calculatePrice") @PostMapping("/calculatePrice")
@Anonymous
public AjaxResult calculatePrice(@RequestBody @Validated OrderCalcPrePriceDTO dto) { public AjaxResult calculatePrice(@RequestBody @Validated OrderCalcPrePriceDTO dto) {
OrderPrePriceVO vo = orderConverter.toOrderPrePriceVO(dto); OrderPrePriceVO vo = orderConverter.toOrderPrePriceVO(dto);
if (vo == null) { if (vo == null) {
@ -107,7 +110,7 @@ public class AppOrderController extends BaseController {
public AjaxResult endOrder(@RequestBody @Validated OrderEndDTO dto) { public AjaxResult endOrder(@RequestBody @Validated OrderEndDTO dto) {
OrderVO order = orderService.selectOrderById(dto.getOrderId()); OrderVO order = orderService.selectOrderById(dto.getOrderId());
ServiceUtil.assertion(!orderValidator.canEnd(order, getUserId()), "您无权结束ID为%s的订单", order.getId()); ServiceUtil.assertion(!orderValidator.canEnd(order, getUserId()), "您无权结束ID为%s的订单", order.getId());
dto.setIsAdmin(false); dto.setReturnType(OrderReturnType.NORMAL.getCode());
dto.setEndReason("用户【" + getNickName() + "】手动还车"); dto.setEndReason("用户【" + getNickName() + "】手动还车");
OrderEndVO vo = orderService.endOrder(dto); OrderEndVO vo = orderService.endOrder(dto);
if (vo.getDb() > 0) { if (vo.getDb() > 0) {
@ -119,8 +122,8 @@ public class AppOrderController extends BaseController {
@ApiOperation("计算订单费用") @ApiOperation("计算订单费用")
@PostMapping("/calcFee") @PostMapping("/calcFee")
public AjaxResult calcFee(@RequestBody @Validated OrderEndDTO dto) { public AjaxResult calcFee(@RequestBody @Validated OrderEndDTO dto) {
dto.setIsAdmin(false); dto.setReturnType(OrderReturnType.NORMAL.getCode());
OrderFeeVO fee = orderService.preEndCheck(dto); OrderFeeVO fee = orderService.calcFee(dto);
ServiceUtil.assertion(fee == null, "价格计算失败"); ServiceUtil.assertion(fee == null, "价格计算失败");
return success(fee); return success(fee);
} }

View File

@ -23,6 +23,7 @@ import com.ruoyi.bst.order.domain.OrderVO;
import com.ruoyi.bst.order.domain.dto.OrderEndDTO; import com.ruoyi.bst.order.domain.dto.OrderEndDTO;
import com.ruoyi.bst.order.domain.dto.OrderRefundDTO; import com.ruoyi.bst.order.domain.dto.OrderRefundDTO;
import com.ruoyi.bst.order.domain.dto.OrderVerifyDTO; import com.ruoyi.bst.order.domain.dto.OrderVerifyDTO;
import com.ruoyi.bst.order.domain.enums.OrderReturnType;
import com.ruoyi.bst.order.domain.vo.OrderEndVO; import com.ruoyi.bst.order.domain.vo.OrderEndVO;
import com.ruoyi.bst.order.service.OrderAssembler; import com.ruoyi.bst.order.service.OrderAssembler;
import com.ruoyi.bst.order.service.OrderService; import com.ruoyi.bst.order.service.OrderService;
@ -109,7 +110,7 @@ public class OrderController extends BaseController
if (!orderValidator.canOperate(dto.getOrderId())) { if (!orderValidator.canOperate(dto.getOrderId())) {
return error("您无权结束ID为" + dto.getOrderId() + "的订单"); return error("您无权结束ID为" + dto.getOrderId() + "的订单");
} }
dto.setIsAdmin(true); dto.setReturnType(OrderReturnType.AUXILIARY.getCode());
dto.setEndReason("管理员【" + getNickName() + "】手动还车"); dto.setEndReason("管理员【" + getNickName() + "】手动还车");
OrderEndVO vo = orderService.endOrder(dto); OrderEndVO vo = orderService.endOrder(dto);
if (vo.getDb() > 0) { if (vo.getDb() > 0) {