卡券功能

This commit is contained in:
磷叶 2025-05-27 14:08:25 +08:00
parent ecfbd97e88
commit d9b769ce52
20 changed files with 224 additions and 89 deletions

View File

@ -177,7 +177,7 @@ public class BonusConverterImpl implements BonusConverter {
String reason = "卡券订单收入:" + order.getNo();
for (Bonus bonus : result) {
bonus.setReason(reason);
bonus.setBstType(BonusBstType.ORDER.getType());
bonus.setBstType(BonusBstType.VIP_ORDER.getType());
bonus.setBstId(order.getId());
bonus.setStatus(BonusStatus.INVALID.getStatus());
bonus.setToBalance(true);

View File

@ -39,8 +39,8 @@ public class DeviceUtil {
}
// 转换经纬度坐标系并赋值
// 只有定位是正常的才认为是有获取到定位
if (DeviceUtil.validLocation(sys.getLon(), sys.getLat())) {
// 只有定位是正常的 && 卫星信号大于2颗 才认为是有获取到定位
if (DeviceUtil.validLocation(sys.getLon(), sys.getLat()) && sys.getS() != null && sys.getS() > 2) {
List<BigDecimal> coordinates = null;
// 转换坐标

View File

@ -281,4 +281,8 @@ public class Order extends BaseEntity {
@Excel(name = "卡券优惠值")
@ApiModelProperty("卡券优惠值")
private BigDecimal vipDiscountValue;
@Excel(name = "卡券名称")
@ApiModelProperty("卡券名称")
private String vipName;
}

View File

@ -65,5 +65,8 @@ public class OrderQuery extends OrderVO {
@ApiModelProperty("骑行费支付日期范围")
@DateTimeFormat(pattern = "yyyy-MM-dd")
private List<LocalDate> ridePayDateRange;
@ApiModelProperty("VIP ID 为空")
private Boolean isNullVipUserId;
}

View File

@ -134,4 +134,9 @@ public class OrderVO extends Order implements IotDevice {
public BigDecimal getActualReceivedAmount() {
return MathUtils.subtractDecimal(this.getActualAmount(), this.getAdminRefundAmount());
}
// 总优惠金额
public BigDecimal getTotalDiscountAmount() {
return this.getRidingDiscount();
}
}

View File

@ -1,24 +1,27 @@
package com.ruoyi.bst.order.domain.bo;
package com.ruoyi.bst.order.domain.dto;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import com.ruoyi.bst.order.domain.OrderVO;
import com.ruoyi.bst.order.domain.enums.OrderPayType;
import lombok.Data;
@Data
public class OrderRidePaySuccessBO {
public class OrderRidePaySuccessDTO {
// 订单数据
private OrderVO order;
private Long orderId;
// 支付方式
private OrderPayType payType;
// 是否忽略审核
private Boolean ignoreVerify;
// 支付金额
private BigDecimal payAmount;
// 支付ID
private Long payId;

View File

@ -91,4 +91,9 @@ public enum OrderStatus {
public static List<String> canUpdatePrice() {
return CollectionUtils.map(OrderStatus::getCode, RIDE_WAIT_PAY);
}
// 允许恢复VIP优惠次数的订单状态
public static List<String> canRecoverVipCount() {
return CollectionUtils.map(OrderStatus::getCode, RIDE_WAIT_PAY);
}
}

View File

@ -206,7 +206,7 @@ public interface OrderMapper {
* 押金抵扣
* @param data
*/
int deductDeposit(@Param("data") Order data);
int deductDeposit(@Param("id") Long id, @Param("depositDeductionAmount") BigDecimal depositDeductionAmount);
/**
* 更新退款信息
@ -216,4 +216,12 @@ public interface OrderMapper {
*/
int updateRefund(@Param("data") Order data, @Param("query") OrderQuery query);
/**
* 清空订单的VIP信息
* @param orderId
* @param vipUserId
* @return
*/
int clearVipInfo(@Param("orderId") Long orderId, @Param("vipUserId") Long vipUserId);
}

View File

@ -75,6 +75,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
bo.riding_discount,
bo.vip_type,
bo.vip_discount_value,
bo.vip_name,
<include refid="depositCanDeductRemain"/> as deposit_deduct_remain,
ba.name as area_name,
su.nick_name as user_name,
@ -167,6 +168,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="query.adminRefundCount != null "> and bo.admin_refund_count = #{query.adminRefundCount}</if>
<if test="query.adminRefundAmount != null "> and bo.admin_refund_amount = #{query.adminRefundAmount}</if>
<if test="query.priceChanged != null "> and bo.price_changed = #{query.priceChanged}</if>
<if test="query.isNullVipUserId != null"> and bo.vip_user_id is <if test="!query.isNullVipUserId">not</if> null</if>
<if test="query.vipName != null and query.vipName != ''"> and bo.vip_name like concat('%', #{query.vipName}, '%')</if>
<if test="query.bonusUserId != null ">
and bo.id in (
select distinct bb.bst_id from bst_bonus bb
@ -299,6 +302,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="ridingDiscount != null">riding_discount,</if>
<if test="vipType != null">vip_type,</if>
<if test="vipDiscountValue != null">vip_discount_value,</if>
<if test="vipName != null">vip_name,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="no != null and no != ''">#{no},</if>
@ -364,6 +368,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="ridingDiscount != null">#{ridingDiscount},</if>
<if test="vipType != null">#{vipType},</if>
<if test="vipDiscountValue != null">#{vipDiscountValue},</if>
<if test="vipName != null">#{vipName},</if>
</trim>
</insert>
@ -439,6 +444,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="data.ridingDiscount != null">riding_discount = #{data.ridingDiscount},</if>
<if test="data.vipType != null">vip_type = #{data.vipType},</if>
<if test="data.vipDiscountValue != null">vip_discount_value = #{data.vipDiscountValue},</if>
<if test="data.vipName != null">vip_name = #{data.vipName},</if>
</sql>
<delete id="deleteOrderById" parameterType="Long">
@ -635,14 +641,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<update id="deductDeposit">
update bst_order bo
left join bst_pay bp on bp.id = bo.pay_id
set bo.deposit_deduction_amount = bo.deposit_deduction_amount + #{data.depositDeductionAmount},
bo.actual_amount = #{data.actualAmount},
bo.actual_riding_fee = #{data.actualRidingFee},
bo.actual_dispatch_fee = #{data.actualDispatchFee},
bo.actual_manage_fee = #{data.actualManageFee},
bo.actual_deduction_fee = #{data.actualDeductionFee}
where bo.id = #{data.id}
and <include refid="depositCanDeductRemain"/> &gt;= #{data.depositDeductionAmount}
set bo.deposit_deduction_amount = bo.deposit_deduction_amount + #{depositDeductionAmount}
where bo.id = #{id}
and <include refid="depositCanDeductRemain"/> &gt;= #{depositDeductionAmount}
</update>
<!-- 剩余可抵扣押金 = 已支付押金 - 退款中 - 已退款 - 已抵扣 -->
@ -701,5 +702,17 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</update>
<!-- clearVipInfo -->
<update id="clearVipInfo">
update bst_order bo
set bo.vip_user_id = null,
bo.vip_type = null,
bo.vip_discount_value = null,
bo.vip_name = null,
bo.riding_discount = 0
where bo.id = #{orderId}
and bo.vip_user_id = #{vipUserId}
and bo.status = 'RIDE_WAIT_PAY'
</update>
</mapper>

View File

@ -7,7 +7,7 @@ import com.ruoyi.bst.device.domain.vo.DeviceIotVO;
import com.ruoyi.bst.order.domain.Order;
import com.ruoyi.bst.order.domain.OrderQuery;
import com.ruoyi.bst.order.domain.OrderVO;
import com.ruoyi.bst.order.domain.bo.OrderRidePaySuccessBO;
import com.ruoyi.bst.order.domain.dto.OrderRidePaySuccessDTO;
import com.ruoyi.bst.order.domain.dto.OrderCalcFeeDTO;
import com.ruoyi.bst.order.domain.dto.OrderCalcRideFeeDTO;
import com.ruoyi.bst.order.domain.dto.OrderChangeDeviceDTO;
@ -246,10 +246,9 @@ public interface OrderService {
/**
* 处理骑行费支付成功
* @param bo
* @return
* @param dto @return
*/
public int handleRidePaySuccess(OrderRidePaySuccessBO bo);
public int handleRidePaySuccess(OrderRidePaySuccessDTO dto);
/**
* 改价

View File

@ -3,35 +3,30 @@ package com.ruoyi.bst.order.service.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.bst.order.domain.OrderVO;
import com.ruoyi.bst.order.domain.bo.OrderRidePaySuccessBO;
import com.ruoyi.bst.order.domain.dto.OrderRidePaySuccessDTO;
import com.ruoyi.bst.order.domain.enums.OrderPayType;
import com.ruoyi.bst.order.service.OrderService;
import com.ruoyi.bst.pay.domain.PayVO;
import com.ruoyi.bst.pay.interfaces.PayHandler;
import com.ruoyi.common.utils.ServiceUtil;
@Service
public class OrderRidePayHandlerImpl implements PayHandler {
@Autowired
private OrderService orderService;
@Override
public boolean onPaySuccess(PayVO pay) {
// 查询订单
OrderVO order = orderService.selectOrderById(pay.getBstId());
ServiceUtil.assertion(order == null, "订单不存在");
// 处理骑行费支付成功
OrderRidePaySuccessBO bo = new OrderRidePaySuccessBO();
bo.setOrder(order);
bo.setPayType(OrderPayType.USER_PAY);
bo.setPayAmount(pay.getAmount());
bo.setIgnoreVerify(false);
bo.setPayId(pay.getId());
bo.setPayTime(pay.getPayTime());
int rows = orderService.handleRidePaySuccess(bo);
OrderRidePaySuccessDTO dto = new OrderRidePaySuccessDTO();
dto.setOrderId(pay.getBstId());
dto.setPayType(OrderPayType.USER_PAY);
dto.setPayAmount(pay.getAmount());
dto.setIgnoreVerify(false);
dto.setPayId(pay.getId());
dto.setPayTime(pay.getPayTime());
int rows = orderService.handleRidePaySuccess(dto);
return rows == 1;
}

View File

@ -47,7 +47,7 @@ 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.OrderPayRideFeeBO;
import com.ruoyi.bst.order.domain.bo.OrderRidePaySuccessBO;
import com.ruoyi.bst.order.domain.dto.OrderRidePaySuccessDTO;
import com.ruoyi.bst.order.domain.dto.OrderCalcFeeDTO;
import com.ruoyi.bst.order.domain.dto.OrderCalcRideFeeDTO;
import com.ruoyi.bst.order.domain.dto.OrderChangeDeviceDTO;
@ -592,7 +592,8 @@ public class OrderServiceImpl implements OrderService {
BigDecimal remain = payAmount;
data.setActualAmount(payAmount);
// 骑行费实收
data.setActualRidingFee(MathUtils.min(remain, old.getRidingFee()));
BigDecimal ridingFee = MathUtils.subtractDecimal(old.getRidingFee(), old.getRidingDiscount());
data.setActualRidingFee(MathUtils.min(remain, ridingFee));
remain = MathUtils.subtractDecimal(remain, data.getActualRidingFee());
// 调度费实收
data.setActualDispatchFee(MathUtils.min(remain, old.getDispatchFee()));
@ -1048,22 +1049,22 @@ public class OrderServiceImpl implements OrderService {
// 更新订单数据
Integer result = transactionTemplate.execute(status -> {
// 恢复旧优惠券次数清空订单优惠券信息
this.recoverVipCount(order);
// 押金抵扣计算实收金额
Order data = new Order();
data.setId(order.getId());
data.setDepositDeductionAmount(deductAmount);
this.setActualAmount(data, order, deductAmount);
int deduct = orderMapper.deductDeposit(data);
int deduct = orderMapper.deductDeposit(order.getId(), deductAmount);
ServiceUtil.assertion(deduct != 1, "ID为%s的订单押金抵扣失败剩余可抵扣押金不足%s元", order.getId(), deductAmount);
// 处理抵扣成功
OrderRidePaySuccessBO bo = new OrderRidePaySuccessBO();
bo.setOrder(order);
bo.setPayType(OrderPayType.DEPOSIT_DEDUCTION);
bo.setIgnoreVerify(ignoreVerify);
bo.setPayId(null);
bo.setPayTime(LocalDateTime.now());
return this.handleRidePaySuccess(bo);
OrderRidePaySuccessDTO dto = new OrderRidePaySuccessDTO();
dto.setOrderId(order.getId());
dto.setPayType(OrderPayType.DEPOSIT_DEDUCTION);
dto.setIgnoreVerify(ignoreVerify);
dto.setPayAmount(deductAmount);
dto.setPayId(null);
dto.setPayTime(LocalDateTime.now());
return this.handleRidePaySuccess(dto);
});
return result == null ? 0 : result;
@ -1076,18 +1077,21 @@ public class OrderServiceImpl implements OrderService {
* 处理骑行费支付成功
*/
@Override
public int handleRidePaySuccess(OrderRidePaySuccessBO bo) {
OrderVO order = bo.getOrder();
OrderPayType payType = bo.getPayType();
public int handleRidePaySuccess(OrderRidePaySuccessDTO dto) {
OrderVO order = selectOrderById(dto.getOrderId());
ServiceUtil.assertion(order == null, "ID为%s的订单不存在", dto.getOrderId());
OrderPayType payType = dto.getPayType();
// 更新订单数据
Order data = new Order();
// 支付信息
data.setPayType(payType.getCode());
data.setRidePayId(bo.getPayId());
data.setRidePayTime(bo.getPayTime());
data.setRidePayId(dto.getPayId());
data.setRidePayTime(dto.getPayTime());
this.setActualAmount(data, order, dto.getPayAmount());
// 设置订单状态
boolean ignoreVerify = bo.getIgnoreVerify() != null && bo.getIgnoreVerify();
boolean ignoreVerify = dto.getIgnoreVerify() != null && dto.getIgnoreVerify();
if (order.getAreaReturnVerify() != null && order.getAreaReturnVerify() && !ignoreVerify) {
data.setStatus(OrderStatus.WAIT_VERIFY.getCode());
} else {
@ -1137,32 +1141,35 @@ public class OrderServiceImpl implements OrderService {
OrderVO order = bo.getOrder();
VipUserVO vipUser = bo.getVipUser();
OrderCalcRideFeeVO fee = bo.getFee();
return transactionTemplate.execute(status -> {
// TODO 恢复旧优惠券次数清空订单优惠券信息
if (order.getVipUserId() != null) {
}
return transactionTemplate.execute(status -> {
// 恢复旧优惠券次数清空订单优惠券信息
this.recoverVipCount(order);
// 更新订单信息
Order data = new Order();
if (vipUser != null) {
data.setVipUserId(vipUser.getId());
data.setVipDiscountValue(vipUser.getDiscount());
data.setVipType(vipUser.getType());
// TODO 卡名称
data.setVipName(vipUser.getName());
}
data.setRidingDiscount(fee.getRideFeeDiscount());
OrderQuery query = new OrderQuery();
query.setId(order.getId());
query.setVipUserIdIsNull(true);
orderMapper.updateByQuery(data, query);
query.setIsNullVipUserId(true);
int rows = orderMapper.updateByQuery(data, query);
ServiceUtil.assertion(rows != 1, "ID为%s的订单更新失败", order.getId());
// 若有使用优惠券则扣减优惠券次数
if (vipUser != null) {
int deduct = vipUserService.deductVipCount(vipUser.getId(), 1);
ServiceUtil.assertion(deduct != 1, "优惠券可用次数不足");
}
// TODO 若有使用优惠券则扣减优惠券次数
// 转为支付单
Pay pay = payConverter.toPayPO(bo);
// 创建并调起支付
return payService.createPayBill(pay);
@ -1173,6 +1180,32 @@ public class OrderServiceImpl implements OrderService {
}
/**
* 恢复VIP优惠次数
*/
private int recoverVipCount(OrderVO order) {
ServiceUtil.assertion(order == null, "订单不存在");
if (order.getVipUserId() == null) {
return 1;
}
ServiceUtil.assertion(!OrderStatus.canRecoverVipCount().contains(order.getStatus()), "ID为%s的订单当前状态不允许恢复VIP优惠次数", order.getId());
Integer result = transactionTemplate.execute(status -> {
// 清空订单的VIP信息
int clear = orderMapper.clearVipInfo(order.getId(), order.getVipUserId());
ServiceUtil.assertion(clear != 1, "ID为%s的订单清空VIP信息失败", order.getId());
// 尝试恢复VIP优惠次数
try {
vipUserService.recoverVipCount(order.getVipUserId(), 1);
} catch (Exception e) {
log.error("ID为{}的订单恢复VIP优惠次数失败", order.getId(), e);
}
return clear;
});
return result == null ? 0 : result;
}
@Override
public int updatePrice(OrderUpdatePriceDTO dto) {
// 查询订单
@ -1235,7 +1268,7 @@ public class OrderServiceImpl implements OrderService {
public OrderCalcRideFeeVO calcRideFee(OrderVO order, VipUserVO vipUser) {
ServiceUtil.assertion(order == null, "订单不存在");
// 计算应付费用
// 计算应付费用
OrderCalcRideFeeVO vo = new OrderCalcRideFeeVO();
vo.setOriginalAmount(order.getRidingFee());
vo.setRideFeeDiscount(VipUserUtil.calcDiscountAmount(vo.getOriginalAmount(), vipUser)); // 骑行费优惠
@ -1243,7 +1276,7 @@ public class OrderServiceImpl implements OrderService {
vo.setDispatchFee(order.getDispatchFee()); // 调度费
vo.setManageFee(order.getManageFee()); // 管理费
vo.setDeductionFee(order.getDeductionFee()); // 车损费
return vo;
}
}

View File

@ -82,7 +82,6 @@ public class OrderValidatorImpl implements OrderValidator{
ModelVO model = bo.getModel();
ServiceUtil.assertion(model == null, "ID为%s的车型不存在", device.getModelId());
ServiceUtil.assertion(CollectionUtils.isEmptyElement(model.getSuitIds()) || !model.getSuitIds().contains(suit.getId()), "ID为%s的套餐不可在ID为%s的车辆使用", dto.getSuitId(), dto.getDeviceId());
ServiceUtil.assertion(suit.getSeconds() == null || suit.getSeconds() <= 0, "ID为%s的套餐时长不能为0或小于0", dto.getSuitId());
// 用户
UserVO user = bo.getUser();
@ -262,7 +261,12 @@ public class OrderValidatorImpl implements OrderValidator{
OrderCalcRideFeeVO fee = bo.getFee();
ServiceUtil.assertion(fee == null, "ID为%s的订单当前费用不存在", dto.getOrderId());
ServiceUtil.assertion(!OrderUtil.isEquals(fee, dto.getFee()), "ID为%s的订单当前费用已发生变化请刷新后重新支付", dto.getOrderId());
// 用户
UserVO user = bo.getUser();
ServiceUtil.assertion(user == null, "ID为%s的用户不存在", dto.getUserId());
ServiceUtil.assertion(!Objects.equals(order.getUserId(), user.getUserId()), "ID为%s的用户无权限支付ID为%s的订单", dto.getUserId(), dto.getOrderId());
// 优惠券
VipUserVO vipUser = bo.getVipUser();
if (vipUser != null) {
@ -274,15 +278,12 @@ public class OrderValidatorImpl implements OrderValidator{
int limitCount = MathUtils.dv(vipUser.getLimitCount());
ServiceUtil.assertion(roundCount >= limitCount, "ID为%s的卡券已达到本周期使用次数上限", vipUser.getId());
}
ServiceUtil.assertion(!Objects.equals(order.getAreaId(), vipUser.getAreaId()), "ID为%s的卡券不可在ID为%s的运营区使用", vipUser.getId(), order.getAreaId());
ServiceUtil.assertion(!Objects.equals(vipUser.getUserId(), user.getUserId()), "ID为%s的用户无权使用ID为%s的卡券", user.getUserId(), vipUser.getId());
}
// 用户
UserVO user = bo.getUser();
ServiceUtil.assertion(user == null, "ID为%s的用户不存在", dto.getUserId());
ServiceUtil.assertion(!Objects.equals(order.getUserId(), user.getUserId()), "ID为%s的用户无权限支付ID为%s的订单", dto.getUserId(), dto.getOrderId());
// 支付校验
payValidator.checkPay(bo.getApp(), bo.getChannel(), bo.getUserApp());
}
}

View File

@ -9,6 +9,7 @@ import com.ruoyi.bst.channel.domain.ChannelVO;
import com.ruoyi.bst.order.domain.Order;
import com.ruoyi.bst.order.domain.bo.OrderCreateBO;
import com.ruoyi.bst.order.domain.bo.OrderPayRideFeeBO;
import com.ruoyi.bst.order.domain.vo.OrderCalcRideFeeVO;
import com.ruoyi.bst.pay.domain.Pay;
import com.ruoyi.bst.pay.domain.enums.PayBstType;
import com.ruoyi.bst.pay.domain.enums.PayStatus;
@ -90,7 +91,8 @@ public class PayConverterImpl implements PayConverter {
ChannelVO channel = bo.getChannel();
UserAppVO userApp = bo.getUserApp();
AppVO app = bo.getApp();
if (order == null || user == null || channel == null || userApp == null || app == null) {
OrderCalcRideFeeVO fee = bo.getFee();
if (order == null || user == null || channel == null || userApp == null || app == null || fee == null) {
return null;
}
@ -99,7 +101,7 @@ public class PayConverterImpl implements PayConverter {
// 订单信息
pay.setBstType(PayBstType.ORDER_RIDE.getType());
pay.setBstId(order.getId());
pay.setAmount(order.getTotalFee());
pay.setAmount(fee.getPayAmount());
pay.setAreaId(order.getAreaId());
pay.setDescription("骑行费:" + order.getNo());

View File

@ -96,4 +96,20 @@ public interface VipUserMapper
* @return
*/
int logicDel(@Param("ids") List<Long> ids);
/**
* 恢复VIP优惠次数
* @param vipUserId
* @param count
* @return
*/
int recoverVipCount(@Param("vipUserId") Long vipUserId, @Param("count") int count);
/**
* 扣减VIP优惠次数
* @param id
* @param count
* @return
*/
int deductVipCount(@Param("id") Long id, @Param("count") int count);
}

View File

@ -193,4 +193,23 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
and bvu.deleted = false
</update>
<!-- recoverVipCount -->
<update id="recoverVipCount">
update bst_vip_user bvu
set bvu.round_count = if (bvu.round_count &gt; 0, bvu.round_count - #{count}, 0),
bvu.surplus_total = bvu.surplus_total + #{count}
where bvu.id = #{vipUserId}
</update>
<!-- deductVipCount -->
<update id="deductVipCount">
update bst_vip_user bvu
set bvu.round_count = bvu.round_count + #{count},
bvu.surplus_total = bvu.surplus_total - #{count}
where bvu.id = #{id}
and bvu.surplus_total &gt;= #{count}
and bvu.round_count + #{count} &lt;= bvu.limit_count
</update>
</mapper>

View File

@ -74,4 +74,19 @@ public interface VipUserService
*/
public int logicDel(List<Long> ids);
/**
* 恢复VIP优惠次数
* @param vipUserId
* @return
*/
public int recoverVipCount(Long vipUserId, int count);
/**
* 扣减VIP优惠次数
* @param id
* @param count
* @return
*/
public int deductVipCount(Long id, int count);
}

View File

@ -121,4 +121,19 @@ public class VipUserServiceImpl implements VipUserService
return vipUserMapper.logicDel(ids);
}
@Override
public int recoverVipCount(Long vipUserId, int count) {
if (vipUserId == null || count <= 0) {
return 0;
}
return vipUserMapper.recoverVipCount(vipUserId, count);
}
@Override
public int deductVipCount(Long id, int count) {
if (id == null || count <= 0) {
return 0;
}
return vipUserMapper.deductVipCount(id, count);
}
}

View File

@ -11,7 +11,7 @@ import com.ruoyi.bst.vipUser.domain.VipUserVO;
import com.ruoyi.common.utils.MathUtils;
public class VipUserUtil {
public static LocalDateTime getNextResetTime(VipUser vip) {
if (vip == null) {
return null;
@ -32,9 +32,11 @@ public class VipUserUtil {
if (vipUser == null || originalAmount == null) {
return BigDecimal.ZERO;
}
if (VipType.DISCOUNT.getCode().equals(vipUser.getType())) {
return MathUtils.mulDecimal(originalAmount, vipUser.getDiscount()).divide(BigDecimal.valueOf(10), 2, RoundingMode.HALF_UP);
BigDecimal decimal10 = BigDecimal.valueOf(10);
return MathUtils.mulDecimal(originalAmount, MathUtils.subtractDecimal(decimal10, vipUser.getDiscount()))
.divide(decimal10, 2, RoundingMode.DOWN);
} else if (VipType.DEDUCT.getCode().equals(vipUser.getType())) {
return MathUtils.min(originalAmount, vipUser.getDiscount());
} else if (VipType.BALANCE.getCode().equals(vipUser.getType())) {

View File

@ -149,7 +149,7 @@ public class AppOrderController extends BaseController {
}
return error("关闭订单失败");
}
@ApiOperation("计算订单费用")
@PostMapping("/calcFee")
@Log(title = "计算订单费用", businessType = BusinessType.OTHER, bizIdName = "arg0", bizType = LogBizType.ORDER)
@ -174,7 +174,6 @@ public class AppOrderController extends BaseController {
OrderVO order = orderService.selectOrderById(dto.getOrderId());
ServiceUtil.assertion(order == null, "订单不存在");
ServiceUtil.assertion(!orderValidator.canOpenDevice(order, getUserId()), "您无权操作ID为%s的订单设备开启", order.getId());
ServiceUtil.assertion(orderValidator.isTimeout(order), "预存款已完用,请还车后再扫码骑行,或联系客服人员处理!");
if (dto.getRequiredIot() == null) {
dto.setRequiredIot(true);
}
@ -194,7 +193,6 @@ public class AppOrderController extends BaseController {
OrderVO order = orderService.selectOrderById(dto.getOrderId());
ServiceUtil.assertion(order == null, "订单不存在");
ServiceUtil.assertion(!orderValidator.canCloseDevice(order, getUserId()), "您无权操作ID为%s的订单设备关闭", order.getId());
ServiceUtil.assertion(orderValidator.isTimeout(order), "预存款已完用,请还车后再扫码骑行,或联系客服人员处理!");
if (dto.getRequiredIot() == null) {
dto.setRequiredIot(true);
}
@ -213,7 +211,6 @@ public class AppOrderController extends BaseController {
OrderVO order = orderService.selectOrderById(dto.getOrderId());
ServiceUtil.assertion(!orderValidator.canChangeDevice(order, getUserId()), "您无权操作ID为%s的订单换车", order.getId());
ServiceUtil.assertion(orderValidator.isTimeout(order), "预存款已完用,请还车后再扫码骑行,或联系客服人员处理!");
dto.setUserId(getUserId());
dto.setUserName(getNickName());
return toAjax(orderService.changeDevice(dto));
@ -226,7 +223,7 @@ public class AppOrderController extends BaseController {
// 设置日志参数
LogParamHolder.set(LogParamHolder.PARAM_LON, dto.getLon());
LogParamHolder.set(LogParamHolder.PARAM_LAT, dto.getLat());
OrderVO order = orderService.selectOrderById(dto.getOrderId());
ServiceUtil.assertion(!orderValidator.isUser(order, getUserId()), "您无权操作ID为%s的订单打开坐垫锁", order.getId());
if (dto.getRequiredIot() == null) {