订单分成,还差月费处理

This commit is contained in:
墨大叔 2024-09-28 14:42:13 +08:00
parent f301da2af8
commit 0983df3a96
12 changed files with 243 additions and 133 deletions

View File

@ -34,10 +34,9 @@ public interface BonusConverter {
* @param agent
* @param platform
* @param device
* @param channel
* @return
*/
List<Bonus> genBonusList(SmUserVo mch, SmUserVo agent, SysDept platform, DeviceVO device, ChannelVO channel);
List<Bonus> genBonusList(SmUserVo mch, SmUserVo agent, SysDept platform, DeviceVO device);
/**
* 旧订单转为分成明细

View File

@ -2,16 +2,15 @@ package com.ruoyi.ss.bonus.service.impl;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.enums.ServiceType;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.ServiceUtil;
import com.ruoyi.ss.bonus.domain.Bonus;
import com.ruoyi.ss.bonus.domain.enums.BonusArrivalType;
import com.ruoyi.ss.bonus.domain.enums.BonusStatus;
import com.ruoyi.ss.bonus.service.BonusConverter;
import com.ruoyi.ss.channel.domain.ChannelVO;
import com.ruoyi.ss.device.domain.enums.DeviceServiceMode;
import com.ruoyi.ss.device.domain.vo.DeviceVO;
import com.ruoyi.ss.device.service.DeviceAssembler;
import com.ruoyi.ss.store.service.StoreService;
import com.ruoyi.ss.transactionBill.domain.TransactionBill;
import com.ruoyi.ss.transactionBill.domain.bo.RechargeBO;
@ -21,7 +20,6 @@ import com.ruoyi.ss.transactionBill.domain.vo.UserRechargeServiceVO;
import com.ruoyi.ss.transactionBill.service.TransactionBillService;
import com.ruoyi.ss.user.domain.SmUserVo;
import com.ruoyi.ss.user.service.ISmUserService;
import com.ruoyi.system.domain.enums.config.ConfigKey;
import com.ruoyi.system.service.ISysConfigService;
import com.ruoyi.system.service.ISysDeptService;
import org.springframework.beans.factory.annotation.Autowired;
@ -59,6 +57,9 @@ public class BonusConverterImpl implements BonusConverter {
@Autowired
private ISysConfigService sysConfigService;
@Autowired
private DeviceAssembler deviceAssembler;
/**
* 订单转为分成明细
*
@ -75,7 +76,7 @@ public class BonusConverterImpl implements BonusConverter {
return Collections.emptyList();
}
List<Bonus> result = genBonusList(bo.getMch(), null, bo.getPlatform(), bo.getDevice(), bo.getChannel());
List<Bonus> result = genBonusList(bo.getMch(), null, bo.getPlatform(), bo.getDevice());
for (Bonus bonus : result) {
bonus.setBillId(bill.getBillId());
@ -96,11 +97,11 @@ public class BonusConverterImpl implements BonusConverter {
return Collections.emptyList();
}
return genBonusList(bo.getMch(), bo.getAgent(), bo.getPlatform(), bo.getDevice(), null);
return genBonusList(bo.getMch(), bo.getAgent(), bo.getPlatform(), bo.getDevice());
}
@Override
public List<Bonus> genBonusList(SmUserVo mch, SmUserVo agent, SysDept platform, DeviceVO device, ChannelVO channel) {
public List<Bonus> genBonusList(SmUserVo mch, SmUserVo agent, SysDept platform, DeviceVO device) {
List<Bonus> result = new ArrayList<>();
if (mch == null || platform == null || device == null) {
return result;
@ -110,11 +111,11 @@ public class BonusConverterImpl implements BonusConverter {
// 直营模式
if (DeviceServiceMode.DIRECT.getMode().equals(device.getServiceMode())) {
// 平台收取服务费
UserRechargeServiceVO userRechargeService = transactionBillService.getMchRechargeService(channel, mch, device);
// 拼接设备服务费费率
deviceAssembler.assembleRealServiceRate(device);
// 按照百分比收取服务费
BigDecimal serviceRate = userRechargeService.getServiceRate(); // 服务费比例
BigDecimal serviceRate = device.getRealServiceRate(); // 服务费比例
result.add(this.toPo(platform, serviceRate));
point = point.subtract(serviceRate);

View File

@ -198,7 +198,7 @@ public class BonusServiceImpl implements BonusService
@Override
public int partBonus(List<BonusVO> bonusList, BigDecimal money) {
if (CollectionUtils.isEmptyElement(bonusList)) {
if (CollectionUtils.isEmptyElement(bonusList) || money == null) {
return 0;
}
@ -216,18 +216,61 @@ public class BonusServiceImpl implements BonusService
LocalDateTime now = LocalDateTime.now();
// TODO 最低分成假设为 0.05 若判断金额小于 0.05 则全部收取若分成小于 0.05 则收取0.05元
// 获取平台的分成
BonusVO platform = bonusList.stream().filter(bonus -> bonus.getArrivalType().equals(BonusArrivalType.PLATFORM.getType())).findFirst().orElse(null);
ServiceUtil.assertion(platform == null, "平台不存在");
BigDecimal platformAmount = money.multiply(platform.getPoint()).divide(decimal100, 2, RoundingMode.HALF_UP); // 平台预计分成金额
// 循环遍历构造分成金额
// 处理最低分成
BigDecimal minService = sysConfigService.getBigDecimal(ConfigKey.RECHARGE_MIN_SERVICE);
// 若总金额 < 最低分成则平台全收
if (money.compareTo(minService) < 0) {
this.setAmount(platform, money);
dividedAmount = platform.getAmount();
}
// 若平台分成 < 最低金额则收取最低金额其他金额给其他分成方分成
else if (platformAmount.compareTo(minService) < 0) {
// 平台设置分成为最低金额
this.setAmount(platform, minService);
dividedAmount = platform.getAmount();
// 计算其他分成方分成金额
BigDecimal remain = money.subtract(platform.getAmount()); // 剩余可分成金额
BigDecimal remainPoint = decimal100.subtract(platform.getPoint()); // 剩余总百分比
for (BonusVO bonus : bonusList) {
if (bonus.getArrivalType().equals(BonusArrivalType.PLATFORM.getType())) {
continue;
}
// 计算分成比例占剩余可分成金额的比例
BigDecimal bonusPoint = bonus.getPoint().multiply(decimal100).divide(remainPoint, 2, RoundingMode.HALF_UP);
BigDecimal amount = remain.multiply(bonusPoint).divide(decimal100, 2, RoundingMode.HALF_UP);
this.setAmount(bonus, amount);
// 增加已分成金额
dividedAmount = dividedAmount.add(amount);
}
}
// 其余情况正常收取费用
else {
// 循环遍历构造分成金额
for (BonusVO bonus : bonusList) {
BigDecimal amount = money.multiply(bonus.getPoint()).divide(decimal100, 2, RoundingMode.HALF_UP);
this.setAmount(bonus, amount);
// 增加已分成金额
dividedAmount = dividedAmount.add(amount);
}
}
// 若存在误差则平台吃掉误差
if (dividedAmount.compareTo(money) != 0) {
BigDecimal subtract = money.subtract(dividedAmount); // 误差值
this.setAmount(platform, platform.getAmount().add(subtract));
}
// 设置预计分成时间等数据
for (BonusVO bonus : bonusList) {
BigDecimal amount = money.multiply(bonus.getPoint()).divide(decimal100, 2, RoundingMode.HALF_UP);
bonus.setAmount(amount);
bonus.setWaitAmount(amount);
bonus.setStatus(BonusStatus.WAIT_DIVIDE.getStatus());
// 预计分成时间
bonus.setWaitAmount(bonus.getAmount());
// 设置预计分成时间
if (BonusArrivalType.userList().contains(bonus.getArrivalType())) {
SmUserVo user = userList.stream().filter(item -> item.getUserId().equals(bonus.getArrivalId())).findFirst().orElse(null);
if (user == null) {
@ -237,12 +280,6 @@ public class BonusServiceImpl implements BonusService
} else {
bonus.setPrePayTime(now);
}
dividedAmount = dividedAmount.add(amount);
}
// 若存在误差则平台吃掉误差
if (dividedAmount.compareTo(money) != 0) {
BigDecimal subtract = money.subtract(dividedAmount); // 误差值
platform.setAmount(platform.getAmount().add(subtract));
}
Integer result = transactionTemplate.execute(status -> {
@ -256,6 +293,11 @@ public class BonusServiceImpl implements BonusService
return result == null ? 0 : result;
}
private void setAmount(BonusVO bonus, BigDecimal amount) {
ServiceUtil.assertion(amount.compareTo(BigDecimal.ZERO) < 0, "分成金额不允许小于0");
bonus.setAmount(amount);
}
@Override
public List<CommonCountVO<Long>> selectCountByArrival(BonusQuery query) {
return bonusMapper.selectCountByArrival(query);

View File

@ -75,6 +75,12 @@ public class DeviceVO extends Device implements IotDevice {
@ApiModelProperty("型号产品ID")
private String modelProductId;
@ApiModelProperty("商户服务费率")
private BigDecimal userServiceRate;
@ApiModelProperty("最终生效的服务费率")
private BigDecimal realServiceRate;
@Override
public String iotMac1() {
return getMac();

View File

@ -153,7 +153,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
ss.contact_name as store_contact_name,
ss.contact_mobile as store_contact_mobile,
su.phonenumber as user_mobile,
su.user_name as user_name
su.user_name as user_name,
su.service_rate as user_service_rate
from sm_device sd
left join sm_model sm on sm.model_id = sd.model_id
left join sm_store ss on ss.store_id = sd.store_id

View File

@ -27,4 +27,13 @@ public interface DeviceAssembler {
*/
void assembleOrderCountInfo(List<DeviceVO> list);
/**
* 拼接真实的服务费率
*/
void assembleRealServiceRate(DeviceVO device);
/**
* 拼接真实的服务费率
*/
void assembleRealServiceRate(List<DeviceVO> list);
}

View File

@ -111,6 +111,11 @@ public interface DeviceService
*/
void pullDeviceInfo(List<Long> deviceIds);
/**
* 拉取设备信息并保存到数据库
*/
void pullDeviceInfoList(List<DeviceVO> list);
/**
* 通过SN绑定设备
*

View File

@ -1,5 +1,6 @@
package com.ruoyi.ss.device.service.impl;
import com.ruoyi.common.utils.ServiceUtil;
import com.ruoyi.common.utils.collection.CollectionUtils;
import com.ruoyi.ss.dashboard.vo.BillCountVo;
import com.ruoyi.ss.device.domain.vo.DeviceVO;
@ -15,6 +16,8 @@ import com.ruoyi.ss.transactionBill.domain.enums.TransactionBillGroupBy;
import com.ruoyi.ss.transactionBill.domain.enums.TransactionBillStatus;
import com.ruoyi.ss.transactionBill.domain.enums.TransactionBillType;
import com.ruoyi.ss.transactionBill.service.TransactionBillService;
import com.ruoyi.system.domain.enums.config.ConfigKey;
import com.ruoyi.system.service.ISysConfigService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@ -38,6 +41,9 @@ public class DeviceAssemblerImpl implements DeviceAssembler {
@Autowired
private DeviceSuitService deviceSuitService;
@Autowired
private ISysConfigService sysConfigService;
/**
* 拼接套餐列表
*
@ -113,4 +119,42 @@ public class DeviceAssemblerImpl implements DeviceAssembler {
}
}
@Override
public void assembleRealServiceRate(DeviceVO device) {
if (device == null) {
return;
}
this.assembleRealServiceRate(Collections.singletonList(device));
}
/**
* 拼接真实的服务费率
*
* @param list
*/
@Override
public void assembleRealServiceRate(List<DeviceVO> list) {
if (CollectionUtils.isEmptyElement(list)) {
return;
}
// 系统默认配置
BigDecimal sysServiceRate = sysConfigService.getBigDecimal(ConfigKey.SERVICE_FEE_RATE);
for (DeviceVO device : list) {
if (device == null) {
continue;
}
if (device.getServiceRate() != null) {
device.setRealServiceRate(device.getServiceRate());
} else if (device.getUserServiceRate() != null) {
device.setRealServiceRate(device.getUserServiceRate());
} else {
ServiceUtil.assertion(sysServiceRate != null, "系统服务费率未配置,请联系管理员");
device.setRealServiceRate(sysServiceRate);
}
}
}
}

View File

@ -768,7 +768,8 @@ public class DeviceServiceImpl implements DeviceService
this.pullDeviceInfoList(list);
}
private void pullDeviceInfoList(List<DeviceVO> list) {
@Override
public void pullDeviceInfoList(List<DeviceVO> list) {
if (CollectionUtils.isEmptyElement(list)) {
return;
}
@ -783,27 +784,26 @@ public class DeviceServiceImpl implements DeviceService
IotDeviceInfo deviceInfo = iotService.getDeviceInfo(device);
// 更新设备信息
Device data = new Device();
data.setDeviceId(device.getDeviceId());
device.setDeviceId(device.getDeviceId());
if (deviceInfo != null) {
data.setLastPullTime(deviceInfo.getAt());
data.setTotalElectriQuantity(deviceInfo.getW());
data.setPowerStatus(deviceInfo.getS());
data.setRemainTime(deviceInfo.getTime());
data.setRealTimePower(deviceInfo.getP());
data.setVoltage(deviceInfo.getV());
data.setElectricity(deviceInfo.getA());
device.setLastPullTime(deviceInfo.getAt());
device.setTotalElectriQuantity(deviceInfo.getW());
device.setPowerStatus(deviceInfo.getS());
device.setRemainTime(deviceInfo.getTime());
device.setRealTimePower(deviceInfo.getP());
device.setVoltage(deviceInfo.getV());
device.setElectricity(deviceInfo.getA());
// 是否有WIFI
if (ModelTag.hasTag(device.getModelTags(), ModelTag.WIFI)) {
data.setWifi(deviceInfo.getWifi());
device.setWifi(deviceInfo.getWifi());
}
// 是否有电量
if (ModelTag.hasTag(device.getModelTags(), ModelTag.ELE)) {
data.setSurplusEle(deviceInfo.getM());
device.setSurplusEle(deviceInfo.getM());
} else {
data.setSurplusEle(BigDecimal.ZERO);
device.setSurplusEle(BigDecimal.ZERO);
}
}
@ -811,29 +811,50 @@ public class DeviceServiceImpl implements DeviceService
// 设备过期时间 > 当前时间则正在使用
boolean hasTime = device.getExpireTime() != null && device.getExpireTime().isAfter(now);
// 若当前设备有电量则正在使用
boolean hasEle = data.getSurplusEle() != null && data.getSurplusEle().compareTo(BigDecimal.ZERO) > 0;
boolean hasEle = device.getSurplusEle() != null && device.getSurplusEle().compareTo(BigDecimal.ZERO) > 0;
// 若开关开启则正在使用
boolean hasOpen = DevicePowerStatus.ON.getStatus().equals(data.getPowerStatus());
boolean hasOpen = DevicePowerStatus.ON.getStatus().equals(device.getPowerStatus());
if (hasTime || hasEle || hasOpen) {
data.setStatus(DeviceStatus.USING.getStatus());
device.setStatus(DeviceStatus.USING.getStatus());
} else {
data.setStatus(DeviceStatus.NORMAL.getStatus());
device.setStatus(DeviceStatus.NORMAL.getStatus());
}
// 是否在线
String onlineStatus = iotService.getOnlineStatus(device).getStatus();
data.setOnlineStatus(onlineStatus);
device.setOnlineStatus(onlineStatus);
if (DeviceOnlineStatus.ONLINE.getStatus().equals(onlineStatus)) {
data.setLastOnlineTime(now);
device.setLastOnlineTime(now);
}
deviceMapper.updateSmDevice(data);
this.updateIotInfo(device);
} catch (Exception e) {
log.error("更新设备信息失败deviceId:{}", device.getDeviceId(), e);
}
}
}
/**
* 更新物联网信息
*/
private int updateIotInfo(Device device) {
Device data = new Device();
data.setDeviceId(device.getDeviceId());
data.setLastPullTime(device.getLastPullTime());
data.setTotalElectriQuantity(device.getTotalElectriQuantity());
data.setPowerStatus(device.getPowerStatus());
data.setRemainTime(device.getRemainTime());
data.setRealTimePower(device.getRealTimePower());
data.setVoltage(device.getVoltage());
data.setElectricity(device.getElectricity());
data.setWifi(device.getWifi());
data.setSurplusEle(device.getSurplusEle());
data.setStatus(device.getStatus());
data.setOnlineStatus(device.getOnlineStatus());
data.setLastOnlineTime(device.getLastOnlineTime());
return deviceMapper.updateSmDevice(device);
}
/**
* 异步延迟执行拉取设备信息
* @param deviceIds 设备id列表

View File

@ -1,6 +1,5 @@
package com.ruoyi.ss.transactionBill.service;
import com.ruoyi.ss.channel.domain.ChannelVO;
import com.ruoyi.ss.dashboard.vo.BillCountVo;
import com.ruoyi.ss.device.domain.vo.DeviceVO;
import com.ruoyi.ss.payBill.domain.vo.DoPayVO;
@ -309,11 +308,6 @@ public interface TransactionBillService
*/
TransactionBillVO selectLastOne(TransactionBillQuery query);
/**
* 获取商户的充值手续费
*/
UserRechargeServiceVO getMchRechargeService(ChannelVO channel, SmUserVo mch, DeviceVO device);
/**
* 修复订单数据
*/

View File

@ -18,7 +18,6 @@ import com.ruoyi.ss.bonus.domain.enums.BonusArrivalType;
import com.ruoyi.ss.bonus.domain.enums.BonusStatus;
import com.ruoyi.ss.bonus.service.BonusConverter;
import com.ruoyi.ss.bonus.service.BonusService;
import com.ruoyi.ss.channel.domain.ChannelVO;
import com.ruoyi.ss.channelWithdraw.domain.ChannelWithdrawVO;
import com.ruoyi.ss.channelWithdraw.service.ChannelWithdrawService;
import com.ruoyi.ss.dashboard.vo.BillCountVo;
@ -255,14 +254,12 @@ public class TransactionBillServiceImpl implements TransactionBillService, After
// 拉取设备信息
deviceService.pullDeviceInfo(Collections.singletonList(bo.getDevice().getDeviceId()));
//
// 生成订
TransactionBill order = parseToOrder(bo);
// 代理商模式生成分成列表
if (DeviceServiceMode.AGENT.getMode().equals(order.getDeviceServiceMode())) {
List<Bonus> bonusList = bonusConverter.toPo(bo);
bo.setBonusList(bonusList);
}
// 生成分成列表
List<Bonus> bonusList = bonusConverter.toPo(bo);
bo.setBonusList(bonusList);
// TODO 收取月费
@ -272,14 +269,12 @@ public class TransactionBillServiceImpl implements TransactionBillService, After
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(), "创建分成失败");
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(), "创建分成失败");
return insert;
});
@ -349,25 +344,6 @@ public class TransactionBillServiceImpl implements TransactionBillService, After
}
@Override
public UserRechargeServiceVO getMchRechargeService(ChannelVO channel, SmUserVo mch, DeviceVO device) {
// 优先级 设备 > 商户 > 渠道
if (device.getServiceRate() != null && StringUtils.hasText(device.getServiceType())) {
return new UserRechargeServiceVO(device.getServiceType(), device.getServiceRate());
}
// 商户
else if (mch.getServiceRate() != null && StringUtils.hasText(mch.getServiceType())) {
return new UserRechargeServiceVO(mch.getServiceType(), mch.getServiceRate());
}
// 渠道
else {
ServiceUtil.assertion(channel == null, "支付渠道不存在");
ServiceUtil.assertion(channel.getServiceRate() == null, "支付渠道服务费未配置,请联系管理员");
ServiceUtil.assertion(StringUtils.isBlank(channel.getServiceType()), "支付渠道服务费收取方式未配置,请联系管理员");
return new UserRechargeServiceVO(channel.getServiceType(), channel.getServiceRate());
}
}
@Override
public int fix(Long billId) {
TransactionBillVO bill = selectSmTransactionBillByBillId(billId);
@ -1085,10 +1061,13 @@ public class TransactionBillServiceImpl implements TransactionBillService, After
} else {
throw new ServiceException("计算金额出错,套餐收费类型不支持");
}
// 最低金额
if (totalAmount.compareTo(BigDecimal.valueOf(0.01)) < 0) {
totalAmount = BigDecimal.valueOf(0.01);
// 最低金额不允许低于最低服务费
BigDecimal minService = sysConfigService.getBigDecimal(ConfigKey.RECHARGE_MIN_SERVICE);
if (totalAmount.compareTo(minService) < 0) {
totalAmount = minService;
}
return totalAmount;
}
@ -1112,9 +1091,6 @@ public class TransactionBillServiceImpl implements TransactionBillService, After
// 若结束时间 > 订单结束时间 或者 结束电量 > 订单结束电量则表示已经结束使用
ServiceUtil.assertion(order.getIsFinished() != null && order.getIsFinished(), "当前订单已结束,无法操作");
// 计算需要退款的金额
BigDecimal refundAmount = this.calcRefundAmount(order, endTime, totalEle);
Integer result = transactionTemplate.execute(status -> {
// 修改结束使用的时间
TransactionBill data = new TransactionBill();
@ -1124,28 +1100,30 @@ public class TransactionBillServiceImpl implements TransactionBillService, After
query.setBillId(order.getBillId());
query.setStatus(TransactionBillStatus.SUCCESS.getStatus());
query.setIsFinished(false);
// if (SuitFeeType.TIME.getType().equals(order.getSuitFeeType())) {
// query.setStartSuitEndTime(endTime); // 计时的话需要结束时间在这之后的订单
// } else if (SuitFeeType.COUNT.getType().equals(order.getSuitFeeType())) {
// query.setStartSuitEndEle(totalEle); // 计量的话需要结束电量比这个大的订单
// }
int update = this.updateByQuery(data, query);
ServiceUtil.assertion(update != 1, "修改订单信息失败,请重试:" + order.getBillNo());
// 若金额 > 0.01 则申请退款
if (BigDecimal.valueOf(0.01).compareTo(refundAmount) < 0) {
// 申请退款
BillRefundDTO refundDto = new BillRefundDTO();
refundDto.setBillId(order.getBillId());
refundDto.setRefundAmount(refundAmount);
refundDto.setRefundReason(String.format("充值订单%s智能退款%s元", order.getBillNo(), refundAmount));
int refund = this.refund(refundDto);
ServiceUtil.assertion(refund != 1, "申请退款失败");
}
return update;
});
boolean success = result != null && result == 1; // 是否成功
if (success) {
// 计算需要退款的金额,若金额 > 0.01 则申请退款
BigDecimal refundAmount = this.calcRefundAmount(order, endTime, totalEle);
if (BigDecimal.valueOf(0.01).compareTo(refundAmount) < 0) {
scheduledExecutorService.schedule(() -> {
// 申请退款
BillRefundDTO refundDto = new BillRefundDTO();
refundDto.setBillId(order.getBillId());
refundDto.setRefundAmount(refundAmount);
refundDto.setRefundReason(String.format("充值订单%s智能退款%s元", order.getBillNo(), refundAmount));
int refund = this.refund(refundDto);
ServiceUtil.assertion(refund != 1, "申请退款失败");
}, 0, TimeUnit.SECONDS);
}
}
// 清零设备
if (resetDevice) {
try {
@ -1249,16 +1227,25 @@ public class TransactionBillServiceImpl implements TransactionBillService, After
}
private BigDecimal calcRefundAmount(TransactionBillVO order, LocalDateTime endTime, BigDecimal totalEle) {
BigDecimal refund = BigDecimal.ZERO;
// 智能收费时长计费
if (SuitFeeType.TIME.getType().equals(order.getSuitFeeType())) {
return this.calcTimeRefund(order, endTime);
refund = this.calcTimeRefund(order, endTime);
}
// 智能收费计量收费
else if (SuitFeeType.COUNT.getType().equals(order.getSuitFeeType())) {
return this.calcCountRefund(order, totalEle);
} else {
refund = this.calcCountRefund(order, totalEle);
}
else {
throw new ServiceException("不支持的智能收费方式");
}
// 退款金额不允许大于订单金额
if (refund.compareTo(order.getMoney()) > 0) {
refund = order.getMoney();
}
return refund;
}
@Override
@ -1614,13 +1601,12 @@ public class TransactionBillServiceImpl implements TransactionBillService, After
// 分成方余额按照比例扣减
// 按比例计算退款金额
BigDecimal refundAmount = dto.getRefundAmount(); // 总退款金额
int updateRefundBonus = this.updateRefundBonus(bonusList, refundAmount);
int updateRefundBonus = this.updateRefundBonus(bonusList, refundAmount, bill.getMoney());
ServiceUtil.assertion(updateRefundBonus != bonusList.size(), "商户余额更新失败");
// 修改原订单的退款金额和退款手续费
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, "修改原订单的退款金额和退款手续费失败");
ServiceUtil.assertion(updateRefundAmount != 1, "修改原订单的退款金额失败");
// 发起退款
PayBillRefundDTO refundDto = new PayBillRefundDTO();
@ -1638,14 +1624,15 @@ public class TransactionBillServiceImpl implements TransactionBillService, After
/**
* 更新分成的退款金额
* @param bonusList 分成列表
* @param refundAmount 本次退款金额
* @param billAmount 订单总金额
*/
private int updateRefundBonus(List<BonusVO> bonusList, BigDecimal refundAmount) {
private int updateRefundBonus(List<BonusVO> bonusList, BigDecimal refundAmount, BigDecimal billAmount) {
if (CollectionUtils.isEmptyElement(bonusList)) {
return 0;
}
BigDecimal decimal100 = BigDecimal.valueOf(100);
// 构建退款列表
List<Bonus> refundList = new ArrayList<>(); // 退款的列表
BigDecimal dividedAmount = BigDecimal.ZERO; // 已分配金额
@ -1653,14 +1640,21 @@ public class TransactionBillServiceImpl implements TransactionBillService, After
if (bonus == null) {
continue;
}
// 计算扣减金额
BigDecimal bonusRefundAmount = refundAmount.multiply(bonus.getPoint()).divide(decimal100, 2, RoundingMode.HALF_UP);
bonus.setRefundAmount(bonusRefundAmount);
refundList.add(bonus);
// 计算扣减金额 = 退款金额 * 分配金额 / 总金额
BigDecimal bonusRefundAmount = refundAmount.multiply(bonus.getAmount()).divide(billAmount, 2, RoundingMode.HALF_UP);
Bonus refundBonus = new Bonus();
refundBonus.setId(bonus.getId());
refundBonus.setStatus(bonus.getStatus());
refundBonus.setRefundAmount(bonusRefundAmount);
refundBonus.setArrivalId(bonus.getArrivalId());
refundBonus.setArrivalType(bonus.getArrivalType());
refundBonus.setBillNo(bonus.getBillNo());
refundBonus.setBillId(bonus.getBillId());
refundList.add(refundBonus);
dividedAmount = dividedAmount.add(bonusRefundAmount);
}
// 平台吃掉误差
Bonus platform = refundList.stream().filter(bonus -> bonus.getArrivalType().equals(BonusArrivalType.PLATFORM.getType())).findFirst().orElse(null);
ServiceUtil.assertion(platform == null, "平台不存在");
@ -1669,6 +1663,10 @@ public class TransactionBillServiceImpl implements TransactionBillService, After
platform.setRefundAmount(platform.getRefundAmount().add(subtract));
}
// 校验金额
for (Bonus bonus : refundList) {
ServiceUtil.assertion(bonus.getRefundAmount().compareTo(BigDecimal.ZERO) < 0, "退款金额不允许小于0");
}
BigDecimal sum = refundList.stream().map(Bonus::getRefundAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
ServiceUtil.assertion(sum.compareTo(refundAmount) != 0, "退款金额分配出错");
@ -1889,12 +1887,6 @@ public class TransactionBillServiceImpl implements TransactionBillService, After
ServiceUtil.assertion(!redisLock.lock(RedisLockKey.PREPAY, lockKey), "当前订单正在支付,请稍后重试");
try {
// 直营计算分成
if (DeviceServiceMode.DIRECT.getMode().equals(order.getDeviceServiceMode())) {
List<Bonus> bonusList = bonusConverter.toPo(bo);
bo.setBonusList(bonusList);
}
return transactionTemplate.execute(status -> {
// 修改订单信息
TransactionBill data = new TransactionBill();
@ -1906,12 +1898,6 @@ public class TransactionBillServiceImpl implements TransactionBillService, After
int paying = this.updateByQuery(data, query);
ServiceUtil.assertion(paying != 1, "订单状态已发生变化,更新失败");
// 直营,新增分成信息
if (DeviceServiceMode.DIRECT.getMode().equals(order.getDeviceServiceMode())) {
int bonusInsert = bonusService.batchInsert(bo.getBonusList());
ServiceUtil.assertion(bonusInsert != bo.getBonusList().size(), "新增分成失败");
}
// 创建支付订单并发起支付
return payBillService.createPayBill(payBillConverter.toPoByRechargeMoney(bo));
});

View File

@ -74,6 +74,7 @@ public class AppDeviceController extends BaseController {
startPage();
smDevice.setUserId(getUserId());
List<DeviceVO> list = smDeviceService.selectSmDeviceList(smDevice);
smDeviceService.pullDeviceInfoList(list);
return getDataTable(list);
}
@ -84,6 +85,7 @@ public class AppDeviceController extends BaseController {
startPage();
query.setStoreId(storeId);
List<DeviceVO> list = smDeviceService.selectSmDeviceList(query);
smDeviceService.pullDeviceInfoList(list);
deviceAssembler.assembleBusinessTime(list); // 店铺营业时间
return getDataTable(list);
}