临时提交,做到了恢复订单数据

This commit is contained in:
墨大叔 2024-09-27 15:38:11 +08:00
parent 013ce24296
commit 43a9bb67b4
14 changed files with 280 additions and 38 deletions

View File

@ -5,6 +5,7 @@ import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
/**
@ -34,4 +35,21 @@ public class BonusQuery extends BonusVO {
@DateTimeFormat(pattern = "yyyy-MM-dd")
private LocalDate payDateEnd;
@ApiModelProperty("实际支付时间(起始)")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime payTimeStart;
@ApiModelProperty("实际支付时间(结束)")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime payTimeEnd;
@ApiModelProperty("预计支付时间(起始)")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime prePayTimeStart;
@ApiModelProperty("预计支付时间(结束)")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime prePayTimeEnd;
}

View File

@ -2,6 +2,7 @@ package com.ruoyi.ss.bonus.mapper;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
import com.ruoyi.common.domain.vo.CommonCountVO;
@ -115,4 +116,19 @@ public interface BonusMapper
* 按日查询
*/
List<BonusDailyAmountVO> selectDailyAmount(@Param("query") BonusQuery query);
/**
* 支付分成
* @param id 分成ID
* @param amount 支付金额
* @param payTime 支付时间
*/
int pay(@Param("id") Long id, @Param("amount") BigDecimal amount, @Param("payTime") LocalDateTime payTime);
/**
* 查询数量
* @param query
* @return
*/
int selectCount(@Param("query") BonusQuery query);
}

View File

@ -45,6 +45,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="query.payTimeYear != null "> and year(sb.pay_time) = #{query.payTimeYear}</if>
<if test="query.payDateStart != null "> and date(sb.pay_time) >= #{query.payDateStart}</if>
<if test="query.payDateEnd != null "> and date(sb.pay_time) &lt;= #{query.payDateEnd}</if>
<if test="query.payTimeStart != null "> and sb.pay_time >= #{query.payTimeStart}</if>
<if test="query.payTimeEnd != null "> and sb.pay_time &lt;= #{query.payTimeEnd}</if>
<if test="query.prePayTimeStart != null "> and sb.pre_pay_time >= #{query.prePayTimeStart}</if>
<if test="query.prePayTimeEnd != null "> and sb.pre_pay_time &lt;= #{query.prePayTimeEnd}</if>
<if test="query.billIds != null and query.billIds.size() > 0 ">
and sb.bill_id in
<foreach collection="query.billIds" item="item" open="(" close=")" separator=",">
@ -163,6 +167,15 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
group by `key`
</select>
<select id="selectCount" resultType="java.lang.Integer">
select
count(sb.id)
from ss_bonus sb
<where>
<include refid="searchCondition"/>
</where>
</select>
<insert id="insertBonus" parameterType="Bonus" useGeneratedKeys="true" keyProperty="id">
insert into ss_bonus
<trim prefix="(" suffix=")" suffixOverrides=",">
@ -255,18 +268,35 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</foreach>
</insert>
<!--金额规则,无论金额如何变化,都需要遵循这个规则-->
<sql id="amountRule">
amount >= refund_amount + wait_amount + payed_amount
</sql>
<update id="refundWhenWaitDivide">
update ss_bonus
set refund_amount = refund_amount + #{amount},
wait_amount = wait_amount - #{amount}
where id = #{id} and wait_amount >= #{amount} and status = '2' and amount >= refund_amount + #{amount}
where id = #{id} and wait_amount >= #{amount} and status = '2'
and <include refid="amountRule"/>
</update>
<update id="refundWhenDividend">
update ss_bonus
set refund_amount = refund_amount + #{amount},
payed_amount = payed_amount - #{amount}
where id = #{id} and payed_amount >= #{amount} and status = '3' and amount >= refund_amount + #{amount}
where id = #{id} and payed_amount >= #{amount} and status = '3'
and <include refid="amountRule"/>
</update>
<update id="pay">
update ss_bonus
set payed_amount = payed_amount + #{amount},
wait_amount = wait_amount - #{amount},
status = '3',
pay_time = #{payTime}
where id = #{id} and wait_amount >= #{amount} and status = '2'
and <include refid="amountRule"/>
</update>
<update id="updateBonus" parameterType="Bonus">
@ -290,6 +320,16 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</otherwise>
</choose>
</foreach>
<foreach open="wait_amount = CASE id" collection="list" item="item" close="END,">
<choose>
<when test="item.waitAmount != null">
WHEN #{item.id} THEN #{item.waitAmount}
</when>
<otherwise>
WHEN #{item.id} THEN wait_amount
</otherwise>
</choose>
</foreach>
<foreach open="status = CASE id" collection="list" item="item" close="END,">
<choose>
<when test="item.status != null">

View File

@ -6,6 +6,7 @@ import com.ruoyi.ss.channel.domain.ChannelVO;
import com.ruoyi.ss.device.domain.vo.DeviceVO;
import com.ruoyi.ss.transactionBill.domain.bo.RechargeBO;
import com.ruoyi.ss.transactionBill.domain.dto.RechargePayBO;
import com.ruoyi.ss.transactionBill.domain.vo.TransactionBillVO;
import com.ruoyi.ss.user.domain.SmUserVo;
import java.util.List;
@ -38,4 +39,9 @@ public interface BonusConverter {
*/
List<Bonus> genBonusList(SmUserVo mch, SmUserVo agent, SysDept platform, DeviceVO device, ChannelVO channel);
/**
* 旧订单转为分成明细
*/
List<Bonus> toPo(TransactionBillVO bill);
}

View File

@ -12,6 +12,7 @@ import com.ruoyi.ss.bonus.domain.BonusQuery;
import com.ruoyi.ss.bonus.domain.vo.BonusDailyAmountVO;
import com.ruoyi.ss.bonus.domain.vo.BonusMonthAmountVO;
import com.ruoyi.ss.bonus.domain.vo.ProvideBonusVO;
import com.ruoyi.ss.transactionBill.domain.vo.TransactionBillVO;
/**
* 分成明细Service接口
@ -82,6 +83,12 @@ public interface BonusService
*/
int payBonus(List<BonusVO> bonusList);
/**
* 支付分成
* @param bonus
*/
int payBonus(BonusVO bonus);
/**
* 处理分成按照比例分出金额
* @param bonusList 分成列表
@ -129,4 +136,10 @@ public interface BonusService
*/
List<BonusDailyAmountVO> selectDailyAmount(BonusQuery query);
/**
* 查询数量
* @param query
* @return
*/
int selectCount(BonusQuery query);
}

View File

@ -15,6 +15,7 @@ import com.ruoyi.ss.store.service.StoreService;
import com.ruoyi.ss.transactionBill.domain.TransactionBill;
import com.ruoyi.ss.transactionBill.domain.bo.RechargeBO;
import com.ruoyi.ss.transactionBill.domain.dto.RechargePayBO;
import com.ruoyi.ss.transactionBill.domain.vo.TransactionBillVO;
import com.ruoyi.ss.transactionBill.domain.vo.UserRechargeServiceVO;
import com.ruoyi.ss.transactionBill.service.TransactionBillService;
import com.ruoyi.ss.user.domain.SmUserVo;
@ -88,14 +89,7 @@ public class BonusConverterImpl implements BonusConverter {
return Collections.emptyList();
}
List<Bonus> result = genBonusList(bo.getMch(), bo.getAgent(), bo.getPlatform(), bo.getDevice(), null);
for (Bonus bonus : result) {
bonus.setBillId(bill.getBillId());
bonus.setBillNo(bill.getBillNo());
}
return result;
return genBonusList(bo.getMch(), bo.getAgent(), bo.getPlatform(), bo.getDevice(), null);
}
@Override
@ -146,6 +140,20 @@ public class BonusConverterImpl implements BonusConverter {
return result;
}
@Override
public List<Bonus> toPo(TransactionBillVO bill) {
if (bill == null) {
return Collections.emptyList();
}
List<Bonus> result = new ArrayList<>();
// TODO 平台
// TODO 商户
return result;
}
private Bonus toPo(SysDept dept, BigDecimal point) {
if (dept == null) {
return null;

View File

@ -164,27 +164,37 @@ public class BonusServiceImpl implements BonusService
// 循环遍历添加金额到账户上
for (BonusVO bonus : bonusList) {
Integer result = transactionTemplate.execute(status -> {
int add = 0;
// 根据类型添加金额
if (BonusArrivalType.userList().contains(bonus.getArrivalType())) {
add = userService.addBalance(bonus.getArrivalId(), bonus.getAmount(), String.format("订单分成:%s", bonus.getBillNo()), RecordBalanceBstType.RECHARGE, bonus.getBillId());
} else if (BonusArrivalType.deptList().contains(bonus.getArrivalType())) {
// add = deptService.addBalance(bonus.getArrivalId(), bonus.getAmount(), String.format("订单分成:%s", bonus.getBillNo()), RecordBalanceBstType.RECHARGE, bonus.getBillId());
}
ServiceUtil.assertion(add != 1, "增加账户金额失败");
// TODO 更新分成状态为已分成
return add;
});
total += (result == null ? 0 : 1);
int pay = this.payBonus(bonus);
total += pay;
}
return total;
}
@Override
public int payBonus(BonusVO bonus) {
if (bonus == null) {
return 0;
}
Integer result = transactionTemplate.execute(status -> {
// 更新分成状态为已分成
int pay = bonusMapper.pay(bonus.getId(), bonus.getWaitAmount(), LocalDateTime.now());
ServiceUtil.assertion(pay != 1, "分成打款失败,待分金额不足或状态已改变");
// 根据类型添加金额
if (BonusArrivalType.userList().contains(bonus.getArrivalType())) {
int add = userService.addBalance(bonus.getArrivalId(), bonus.getWaitAmount(), String.format("订单分成:%s", bonus.getBillNo()), RecordBalanceBstType.RECHARGE, bonus.getBillId());
ServiceUtil.assertion(add != 1, "增加账户金额失败");
} else if (BonusArrivalType.deptList().contains(bonus.getArrivalType())) {
// add = deptService.addBalance(bonus.getArrivalId(), bonus.getAmount(), String.format("订单分成:%s", bonus.getBillNo()), RecordBalanceBstType.RECHARGE, bonus.getBillId());
}
return pay;
});
return result == null ? 0 : result;
}
@Override
public int partBonus(List<BonusVO> bonusList, BigDecimal money) {
if (CollectionUtils.isEmptyElement(bonusList)) {
@ -312,6 +322,11 @@ public class BonusServiceImpl implements BonusService
return bonusMapper.selectDailyAmount(query);
}
@Override
public int selectCount(BonusQuery query) {
return bonusMapper.selectCount(query);
}
private int batchUpdateAmount(List<BonusVO> list) {
if (CollectionUtils.isEmptyElement(list)) {
return 0;

View File

@ -270,6 +270,10 @@ public class TransactionBill extends BaseEntity implements Payable
@ApiModelProperty("订单低功率自动关闭值")
private BigDecimal suitLowPower;
@Excel(name = "版本号")
@ApiModelProperty("版本号")
private Integer version;
/**
* 获取价格
*/

View File

@ -67,6 +67,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
stb.device_product_id,
stb.device_product_id,
stb.device_service_mode,
stb.version,
</sql>
<sql id="selectSmTransactionBillVo">
@ -183,6 +184,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="query.createTimeEnd != null "> and stb.create_time &lt;= #{query.createTimeEnd}</if>
<if test="query.deviceProductId != null and query.deviceProductId != ''"> and stb.device_product_id = #{query.deviceProductId}</if>
<if test="query.deviceServiceMode != null and query.deviceServiceMode != ''"> and stb.device_service_mode = #{query.deviceServiceMode}</if>
<if test="query.version != null "> and version = #{query.version}</if>
<if test="query.isUsing != null">
<if test="query.isUsing">
and <include refid="isUsing"/>
@ -396,6 +398,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</select>
<insert id="insertSmTransactionBill" parameterType="TransactionBill" useGeneratedKeys="true" keyProperty="billId">
<selectKey resultType="Long" order="AFTER" keyProperty="billId">
SELECT LAST_INSERT_ID();
</selectKey>
insert into sm_transaction_bill
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="billNo != null">bill_no,</if>
@ -451,6 +456,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="suitEnableLowPowerClose != null">suit_enable_low_power_close,</if>
<if test="suitLowPower != null">suit_low_power,</if>
<if test="deviceProductId != null">device_product_id,</if>
<if test="version != null">version,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="billNo != null">#{billNo},</if>
@ -506,6 +512,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="suitEnableLowPowerClose != null">#{suitEnableLowPowerClose},</if>
<if test="suitLowPower != null">#{suitLowPower},</if>
<if test="deviceProductId != null">#{deviceProductId},</if>
<if test="version != null">#{version},</if>
</trim>
</insert>
@ -574,11 +581,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="data.offlineImage != null">stb.offline_image = #{data.offlineImage},</if>
<if test="data.depositPayId != null">stb.deposit_pay_id = #{data.depositPayId},</if>
<if test="data.payId != null">stb.pay_id = #{data.payId},</if>
<if test="data.suitEnableLowPowerClose != null">suit_enable_low_power_close = #{data.suitEnableLowPowerClose},</if>
<if test="data.suitLowPower != null">suit_low_power = #{data.suitLowPower},</if>
<if test="data.deviceProductId != null">device_product_id = #{data.deviceProductId},</if>
<if test="data.deviceRechargeStatus != null">device_recharge_status = #{data.deviceRechargeStatus},</if>
<if test="data.deviceServiceMode != null">device_service_mode = #{data.deviceServiceMode},</if>
<if test="data.suitEnableLowPowerClose != null">stb.suit_enable_low_power_close = #{data.suitEnableLowPowerClose},</if>
<if test="data.suitLowPower != null">stb.suit_low_power = #{data.suitLowPower},</if>
<if test="data.deviceProductId != null">stb.device_product_id = #{data.deviceProductId},</if>
<if test="data.deviceRechargeStatus != null">stb.device_recharge_status = #{data.deviceRechargeStatus},</if>
<if test="data.deviceServiceMode != null">stb.device_service_mode = #{data.deviceServiceMode},</if>
<if test="data.version != null">stb.version = #{data.version},</if>
</sql>
<update id="updateByQuery">

View File

@ -313,4 +313,9 @@ public interface TransactionBillService
* 获取商户的充值手续费
*/
UserRechargeServiceVO getMchRechargeService(ChannelVO channel, SmUserVo mch, DeviceVO device);
/**
* 修复订单数据
*/
int fix(Long billId);
}

View File

@ -12,6 +12,7 @@ import com.ruoyi.iot.domain.response.CommandResponse;
import com.ruoyi.iot.service.IotService;
import com.ruoyi.ss.account.domain.AccountVO;
import com.ruoyi.ss.bonus.domain.Bonus;
import com.ruoyi.ss.bonus.domain.BonusQuery;
import com.ruoyi.ss.bonus.domain.BonusVO;
import com.ruoyi.ss.bonus.domain.enums.BonusArrivalType;
import com.ruoyi.ss.bonus.domain.enums.BonusStatus;
@ -264,12 +265,16 @@ public class TransactionBillServiceImpl implements TransactionBillService, After
}
transactionTemplate.execute(status -> {
// 插入数据库
// 新增订单
int insert = this.insertSmTransactionBill(order);
ServiceUtil.assertion(insert != 1, "下单失败");
// 代理商模式插入分成列表
if (DeviceServiceMode.AGENT.getMode().equals(order.getDeviceServiceMode())) {
for (Bonus bonus : bo.getBonusList()) {
bonus.setBillId(order.getBillId());
bonus.setBillNo(order.getBillNo());
}
int bonusInsert = bonusService.batchInsert(bo.getBonusList());
ServiceUtil.assertion(bonusInsert != bo.getBonusList().size(), "创建分成失败");
}
@ -361,6 +366,30 @@ public class TransactionBillServiceImpl implements TransactionBillService, After
}
}
@Override
public int fix(Long billId) {
TransactionBillVO bill = selectSmTransactionBillByBillId(billId);
return fix(bill);
}
private int fix(TransactionBillVO bill) {
if (bill == null || bill.getBillId() == null) {
log.warn("修复订单数据失败订单不存在或订单ID为空");
return 0;
}
ServiceUtil.assertion(!TransactionBillStatus.payedOrder().contains(bill.getStatus()), "订单未支付,无法修复");
// 获取订单分成数据判断是否已有分成数据
BonusQuery query = new BonusQuery();
query.setBillId(bill.getBillId());
int bonusCount = bonusService.selectCount(query);
ServiceUtil.assertion(bonusCount > 0, "订单已存在分成数据,无法重复修复");
// TODO 根据订单生成新的分成数据
bonusConverter.toPo(bill);
}
// 转换为订单所需的数据
private TransactionBill parseToOrder(RechargeBO bo) {
// 校验
@ -1534,6 +1563,8 @@ public class TransactionBillServiceImpl implements TransactionBillService, After
// 拼接分成列表
transactionAssembler.assembleBonusList(bill);
List<BonusVO> bonusList = bill.getBonusList();
ServiceUtil.assertion(CollectionUtils.isEmptyElement(bonusList), "当前订单没有收益信息,无法退款");
Integer result = transactionTemplate.execute(status -> {
// 修改订单状态
@ -1548,13 +1579,12 @@ public class TransactionBillServiceImpl implements TransactionBillService, After
// 分成方余额按照比例扣减
// 按比例计算退款金额
BigDecimal refundAmount = dto.getRefundAmount(); // 总退款金额
if (CollectionUtils.isNotEmptyElement(bill.getBonusList())) {
int updateRefundBonus = this.updateRefundBonus(bill.getBonusList(), refundAmount);
ServiceUtil.assertion(updateRefundBonus != bill.getBonusList().size(), "商户余额更新失败");
}
int updateRefundBonus = this.updateRefundBonus(bonusList, refundAmount);
ServiceUtil.assertion(updateRefundBonus != bonusList.size(), "商户余额更新失败");
// 修改原订单的退款金额和退款手续费
int updateRefundAmount = this.addRefundAmount(bill.getBillId(), refundAmount, refundAmount, BigDecimal.ZERO);
Bonus platform = bonusList.stream().filter(bonus -> bonus.getArrivalType().equals(BonusArrivalType.PLATFORM.getType())).findFirst().orElse(null);
int updateRefundAmount = this.addRefundAmount(bill.getBillId(), refundAmount, BigDecimal.ZERO, BigDecimal.ZERO);
ServiceUtil.assertion(updateRefundAmount != 1, "修改原订单的退款金额和退款手续费失败");
// 发起退款

View File

@ -38,6 +38,7 @@ import com.ruoyi.ss.user.domain.dto.UserRealNameDTO;
import com.ruoyi.ss.user.domain.vo.UserRealNameVO;
import com.ruoyi.ss.user.mapper.SmUserMapper;
import com.ruoyi.ss.user.service.ISmUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@ -60,6 +61,7 @@ import java.util.stream.Collectors;
* @date 2024-01-24
*/
@Service
@Slf4j
public class SmUserServiceImpl implements ISmUserService
{
@Autowired
@ -161,7 +163,15 @@ public class SmUserServiceImpl implements ISmUserService
@Override
@Transactional
public int addBalance(Long userId, BigDecimal amount, String reason, RecordBalanceBstType bstType, Long bstId) {
ServiceUtil.assertion(BigDecimal.ZERO.compareTo(amount) > 0, "增加的金额需要大于0");
if (userId == null || amount == null) {
log.info("增加余额错误userId 或 amount 为空");
return 0;
}
ServiceUtil.assertion(BigDecimal.ZERO.compareTo(amount) > 0, "增加的金额不允许小于0");
// 余额+0则啥也不动
if (BigDecimal.ZERO.compareTo(amount) == 0) {
return 1;
}
// 查询用户
SmUserVo user = selectSmUserByUserId(userId);
@ -180,7 +190,15 @@ public class SmUserServiceImpl implements ISmUserService
@Override
@Transactional
public int subtractBalance(Long userId, BigDecimal amount, boolean check, String reason, RecordBalanceBstType bstType, Long bstId) {
if (userId == null || amount == null) {
log.info("减少余额错误userId 或 amount 为空");
return 0;
}
ServiceUtil.assertion(BigDecimal.ZERO.compareTo(amount) > 0, "减少的金额需要大于0");
// 余额-0则啥也不动
if (BigDecimal.ZERO.compareTo(amount) == 0) {
return 1;
}
// 查询用户
SmUserVo user = selectSmUserByUserId(userId);

View File

@ -0,0 +1,51 @@
package com.ruoyi.task.bonus;
import com.ruoyi.common.utils.collection.CollectionUtils;
import com.ruoyi.ss.bonus.domain.BonusQuery;
import com.ruoyi.ss.bonus.domain.BonusVO;
import com.ruoyi.ss.bonus.domain.enums.BonusStatus;
import com.ruoyi.ss.bonus.service.BonusService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.util.List;
/**
* @author wjh
* 2024/9/27
*/
@Component
@Slf4j
public class BonusTask {
@Autowired
private BonusService bonusService;
/**
* 分成打款
*/
public void payBonus() {
// 查询预计分成时间当前时间之前且为待分成的分成单
BonusQuery query = new BonusQuery();
query.setStatus(BonusStatus.WAIT_DIVIDE.getStatus());
query.setPrePayTimeEnd(LocalDateTime.now());
List<BonusVO> list = bonusService.selectBonusList(query);
if (CollectionUtils.isEmptyElement(list)) {
log.info("暂无待分成的分成单");
return;
}
for (BonusVO bonus : list) {
try {
bonusService.payBonus(bonus);
} catch (Exception e) {
log.warn("分成打款失败id={}, e={}", bonus.getId(), e.getMessage());
}
}
}
}

View File

@ -191,4 +191,14 @@ public class SmTransactionBillController extends BaseController
public AjaxResult close(@RequestBody @Validated EndUseDTO dto) {
return success(transactionBillService.endUse(transactionBillConverter.toEndUseBO(dto), true));
}
// 修复订单数据
@PutMapping("/{billId}/fix")
@Log(title = "修复订单数据", businessType = BusinessType.UPDATE)
@PreAuthorize("@ss.hasPermi('system:bill:fix')")
public AjaxResult fix(@PathVariable Long billId) {
return toAjax(transactionBillService.fix(billId));
}
}