diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/device/domain/Device.java b/smart-switch-service/src/main/java/com/ruoyi/ss/device/domain/Device.java index 1fbd6164..98daed9a 100644 --- a/smart-switch-service/src/main/java/com/ruoyi/ss/device/domain/Device.java +++ b/smart-switch-service/src/main/java/com/ruoyi/ss/device/domain/Device.java @@ -184,4 +184,8 @@ public class Device extends BaseEntity @Excel(name = "超出起步时长价格", readConverterExp = "元=") @ApiModelProperty("超出起步时长价格") private BigDecimal overPrice; + + @ApiModelProperty("设备租期到期时间") + @JsonView(JsonViewProfile.AppMch.class) + private LocalDateTime rentTime; } diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/device/mapper/DeviceMapper.java b/smart-switch-service/src/main/java/com/ruoyi/ss/device/mapper/DeviceMapper.java index 3eb0f68a..f3cd7c2a 100644 --- a/smart-switch-service/src/main/java/com/ruoyi/ss/device/mapper/DeviceMapper.java +++ b/smart-switch-service/src/main/java/com/ruoyi/ss/device/mapper/DeviceMapper.java @@ -180,4 +180,9 @@ public interface DeviceMapper * 更新服务费 */ int updateServiceRate(DeviceVO data); + + /** + * 续费时长 + */ + int renewalRentTime(@Param("deviceId") Long deviceId, @Param("seconds") long seconds); } diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/device/mapper/DeviceMapper.xml b/smart-switch-service/src/main/java/com/ruoyi/ss/device/mapper/DeviceMapper.xml index d1b1b3a6..eb21db6d 100644 --- a/smart-switch-service/src/main/java/com/ruoyi/ss/device/mapper/DeviceMapper.xml +++ b/smart-switch-service/src/main/java/com/ruoyi/ss/device/mapper/DeviceMapper.xml @@ -99,6 +99,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" sd.over_time, sd.over_unit, sd.over_price, + sd.rent_time, sm.model_name as model, sm.picture as picture, sm.tags as model_tags, @@ -259,6 +260,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" over_time, over_unit, over_price, + rent_time, #{storeId}, @@ -296,6 +298,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" #{overTime}, #{overUnit}, #{overPrice}, + #{rentTime}, @@ -354,6 +357,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" over_time = #{overTime}, over_unit = #{overUnit}, over_price = #{overPrice}, + rent_time = #{rentTime}, where device_id = #{deviceId} @@ -457,6 +461,16 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" where device_id = #{deviceId} + + update sm_device + set rent_time = if( + now() > rent_time, + date_add(now(), interval #{seconds} second), + date_add(rent_time, interval #{seconds} second) + ) + where device_id = #{deviceId} + + delete from sm_device where device_id = #{deviceId} diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/device/service/DeviceService.java b/smart-switch-service/src/main/java/com/ruoyi/ss/device/service/DeviceService.java index e1e3eda4..4798638e 100644 --- a/smart-switch-service/src/main/java/com/ruoyi/ss/device/service/DeviceService.java +++ b/smart-switch-service/src/main/java/com/ruoyi/ss/device/service/DeviceService.java @@ -12,6 +12,7 @@ import com.ruoyi.ss.device.domain.vo.DeviceVO; import java.math.BigDecimal; import java.util.List; import java.util.Map; +import java.util.concurrent.TimeUnit; import java.util.function.Function; /** @@ -267,4 +268,12 @@ public interface DeviceService * 更新服务费 */ int updateServiceRate(DeviceVO data); + + /** + * 续费时长 + * @param deviceId 设备ID + * @param time 时长 + * @param timeUnit 时长单位 + */ + int renewalRentTime(Long deviceId, int time, TimeUnit timeUnit); } diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/device/service/impl/DeviceServiceImpl.java b/smart-switch-service/src/main/java/com/ruoyi/ss/device/service/impl/DeviceServiceImpl.java index 488b1c2d..a321facb 100644 --- a/smart-switch-service/src/main/java/com/ruoyi/ss/device/service/impl/DeviceServiceImpl.java +++ b/smart-switch-service/src/main/java/com/ruoyi/ss/device/service/impl/DeviceServiceImpl.java @@ -393,6 +393,12 @@ public class DeviceServiceImpl implements DeviceService return deviceMapper.updateServiceRate(data); } + @Override + public int renewalRentTime(Long deviceId, int time, TimeUnit timeUnit) { + long seconds = timeUnit.toSeconds(time); + return deviceMapper.renewalRentTime(deviceId, seconds); + } + @Override public boolean addTime(Long deviceId, long seconds, boolean withIot) { diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/receiveBill/service/ReceiveBillService.java b/smart-switch-service/src/main/java/com/ruoyi/ss/receiveBill/service/ReceiveBillService.java index ec05768f..c5a6cced 100644 --- a/smart-switch-service/src/main/java/com/ruoyi/ss/receiveBill/service/ReceiveBillService.java +++ b/smart-switch-service/src/main/java/com/ruoyi/ss/receiveBill/service/ReceiveBillService.java @@ -1,14 +1,12 @@ package com.ruoyi.ss.receiveBill.service; import java.math.BigDecimal; -import java.time.LocalDateTime; import java.util.List; -import com.ruoyi.ss.device.domain.vo.DeviceVO; import com.ruoyi.ss.receiveBill.domain.ReceiveBill; import com.ruoyi.ss.receiveBill.domain.ReceiveBillVO; import com.ruoyi.ss.receiveBill.domain.ReceiveBillQuery; -import com.ruoyi.ss.user.domain.SmUserVo; +import com.ruoyi.ss.transactionBill.domain.bo.RechargeBO; /** * 应收账单Service接口 @@ -69,12 +67,10 @@ public interface ReceiveBillService /** * 月费商户出账 * - * @param user 用户ID - * @param device - * @param billTime 出账日期 - * @param amount + * @param bo 充值BO + * @param amount 收取的金额 */ - int genBillByMonthAndPay(SmUserVo user, DeviceVO device, LocalDateTime billTime, BigDecimal amount); + int genBillByMonthAndPay(RechargeBO bo, BigDecimal amount); /** * 查询数量 diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/receiveBill/service/impl/ReceiveBillServiceImpl.java b/smart-switch-service/src/main/java/com/ruoyi/ss/receiveBill/service/impl/ReceiveBillServiceImpl.java index 3aa85b2e..69613030 100644 --- a/smart-switch-service/src/main/java/com/ruoyi/ss/receiveBill/service/impl/ReceiveBillServiceImpl.java +++ b/smart-switch-service/src/main/java/com/ruoyi/ss/receiveBill/service/impl/ReceiveBillServiceImpl.java @@ -3,13 +3,16 @@ package com.ruoyi.ss.receiveBill.service.impl; import java.math.BigDecimal; import java.time.LocalDateTime; import java.util.List; +import java.util.concurrent.TimeUnit; import com.ruoyi.common.utils.DateUtils; import com.ruoyi.common.utils.ServiceUtil; import com.ruoyi.ss.device.domain.vo.DeviceVO; +import com.ruoyi.ss.device.service.DeviceService; import com.ruoyi.ss.receiveBill.domain.enums.ReceiveBillStatus; import com.ruoyi.ss.receiveBill.domain.enums.ReceiveBillType; -import com.ruoyi.ss.transactionBill.service.impl.TransactionBillServiceImpl; +import com.ruoyi.ss.transactionBill.domain.TransactionBill; +import com.ruoyi.ss.transactionBill.domain.bo.RechargeBO; import com.ruoyi.ss.user.domain.SmUserVo; import com.ruoyi.ss.user.service.ISmUserService; import org.springframework.beans.factory.annotation.Autowired; @@ -35,8 +38,10 @@ public class ReceiveBillServiceImpl implements ReceiveBillService @Autowired private ISmUserService userService; + @Autowired - private TransactionBillServiceImpl transactionBillService; + private DeviceService deviceService; + @Autowired private TransactionTemplate transactionTemplate; @@ -114,26 +119,37 @@ public class ReceiveBillServiceImpl implements ReceiveBillService } @Override - public int genBillByMonthAndPay(SmUserVo user, DeviceVO device, LocalDateTime billTime, BigDecimal amount) { - ServiceUtil.assertion(user == null || user.getUserId() == null, "用户不存在"); + public int genBillByMonthAndPay(RechargeBO bo, BigDecimal amount) { + SmUserVo mch = bo.getMch(); + DeviceVO device = bo.getDevice(); + TransactionBill order = bo.getOrder(); + LocalDateTime billTime = LocalDateTime.now(); + ServiceUtil.assertion(mch == null || mch.getUserId() == null, "用户不存在"); ServiceUtil.assertion(device == null || device.getDeviceId() == null, "设备不存在"); - ServiceUtil.assertion(billTime == null, "请指定一个月份"); - // 查询指定月份是否已出账 - ReceiveBillQuery query = new ReceiveBillQuery(); - query.setBillYear(billTime.getYear()); - query.setBillMonth(billTime.getMonthValue()); - query.setType(ReceiveBillType.MONTH.getType()); - query.setUserId(user.getUserId()); - query.setDeviceId(device.getDeviceId()); - int count = this.selectCount(query); - if ( count > 0) { - return count; + // 设备未过期,则不生成账单 + if (device.getRentTime() != null && device.getRentTime().isAfter(LocalDateTime.now())) { + return 1; } - // 若未出账则生成账单 + // 查询指定月份是否已出账,已出账则不生成账单 +// ReceiveBillQuery query = new ReceiveBillQuery(); +// query.setBillYear(billTime.getYear()); +// query.setBillMonth(billTime.getMonthValue()); +// query.setType(ReceiveBillType.MONTH.getType()); +// query.setUserId(mch.getUserId()); +// query.setDeviceId(device.getDeviceId()); +// int count = this.selectCount(query); +// if ( count > 0) { +// return count; +// } + + // 判断商户余额 + 订单金额是否足够账单金额 + ServiceUtil.assertion(mch.getBalance().add(order.getArrivalAmount()).compareTo(amount) < 0, "设备到期,商家余额不足,请联系商家处理"); + + // 生成账单 ReceiveBill bill = new ReceiveBill(); - bill.setUserId(user.getUserId()); + bill.setUserId(mch.getUserId()); bill.setDeviceId(device.getDeviceId()); bill.setType(ReceiveBillType.MONTH.getType()); bill.setStatus(ReceiveBillStatus.PAID.getStatus()); @@ -143,11 +159,18 @@ public class ReceiveBillServiceImpl implements ReceiveBillService bill.setReceivedAmount(amount); Integer result = transactionTemplate.execute(status -> { // 用户余额扣减 - int subtract = userService.subtractBalance(user.getUserId(), amount, false, bill.getDescription()); + int subtract = userService.subtractBalance(mch.getUserId(), amount, true, bill.getDescription()); ServiceUtil.assertion(subtract != 1, "扣减商户余额失败"); // 插入账单 - return this.insertReceiveBill(bill); + int insert = this.insertReceiveBill(bill); + ServiceUtil.assertion(insert != 1, "新增账单失败"); + + // 设备续费30天 + int renewal = deviceService.renewalRentTime(device.getDeviceId(), 30, TimeUnit.DAYS); + ServiceUtil.assertion(renewal != 1, "设备续费失败"); + + return insert; }); return result == null ? 0 : result; diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/domain/vo/UserRechargeServiceVO.java b/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/domain/vo/UserRechargeServiceVO.java new file mode 100644 index 00000000..10413dd9 --- /dev/null +++ b/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/domain/vo/UserRechargeServiceVO.java @@ -0,0 +1,28 @@ +package com.ruoyi.ss.transactionBill.domain.vo; + +import lombok.Data; + +import java.math.BigDecimal; + +/** + * 用户充值手续费 + * @author wjh + * 2024/8/5 + */ +@Data +public class UserRechargeServiceVO { + + // 类型 + private String serviceType; + + // 手续费 + private BigDecimal serviceRate; + + public UserRechargeServiceVO() { + } + + public UserRechargeServiceVO(String serviceType, BigDecimal serviceRate) { + this.serviceType = serviceType; + this.serviceRate = serviceRate; + } +} diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/service/impl/TransactionBillServiceImpl.java b/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/service/impl/TransactionBillServiceImpl.java index 11a47c0d..e56a601d 100644 --- a/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/service/impl/TransactionBillServiceImpl.java +++ b/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/service/impl/TransactionBillServiceImpl.java @@ -27,6 +27,7 @@ import com.ruoyi.ss.transactionBill.domain.TransactionBill; import com.ruoyi.ss.transactionBill.domain.TransactionBillQuery; import com.ruoyi.ss.transactionBill.domain.vo.TransactionBillVO; import com.ruoyi.ss.transactionBill.domain.bo.RechargeBO; +import com.ruoyi.ss.transactionBill.domain.vo.UserRechargeServiceVO; import com.ruoyi.ss.transactionBill.domain.vo.UserWithdrawServiceVO; import com.ruoyi.ss.transactionBill.domain.bo.WithdrawBO; import com.ruoyi.ss.transactionBill.domain.dto.BillRefundDTO; @@ -45,7 +46,6 @@ import com.ruoyi.system.service.ISysConfigService; import com.ruoyi.task.bill.BillDelayedManager; import com.wechat.pay.java.service.payments.jsapi.model.PrepayWithRequestPaymentResponse; import com.wechat.pay.java.service.payments.model.Transaction; -import com.wechat.pay.java.service.transferbatch.model.InitiateBatchTransferResponse; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; @@ -242,35 +242,23 @@ public class TransactionBillServiceImpl implements TransactionBillService { } // 处理充值服务费 - private void handleRechargeService(TransactionBill order, ChannelVO channel, SmUserVo mch, DeviceVO device) { + private void handleRechargeService(RechargeBO bo) { + TransactionBill order = bo.getOrder(); + ChannelVO channel = bo.getChannel(); + SmUserVo mch = bo.getMch(); + DeviceVO device = bo.getDevice(); ServiceUtil.assertion(mch == null, "商户不存在,不允许下单"); ServiceUtil.assertion(device == null, "设备不存在,不允许下单"); - String serviceType = null; // 服务费类型 - BigDecimal serviceRate = null; // 服务费 - - // 优先级: 设备 > 商户 > 渠道 - if (device.getServiceRate() != null && StringUtils.hasText(device.getServiceType())) { - serviceType = device.getServiceType(); - serviceRate = device.getServiceRate(); - } - // 商户 - else if (mch.getServiceRate() != null && StringUtils.hasText(mch.getServiceType())) { - serviceType = mch.getServiceType(); - serviceRate = mch.getServiceRate(); - } - // 渠道 - else { - ServiceUtil.assertion(channel == null, "支付渠道不存在"); - ServiceUtil.assertion(channel.getServiceRate() == null, "支付渠道服务费未配置,请联系管理员"); - ServiceUtil.assertion(StringUtils.isBlank(channel.getServiceType()), "支付渠道服务费收取方式未配置,请联系管理员"); - serviceType = channel.getServiceType(); - serviceRate = channel.getServiceRate(); - } + // 获取商户的服务费配置 + UserRechargeServiceVO userRechargeService = this.getUserRechargeService(channel, mch, device); + String serviceType = userRechargeService.getServiceType(); // 服务费类型 + BigDecimal serviceRate = userRechargeService.getServiceRate(); // 服务费 + // 根据服务费类型进行对应操作 // 月费 if (ServiceType.MONTH.getType().equals(serviceType)) { - int count = receiveBillService.genBillByMonthAndPay(mch, device, LocalDateTime.now(), serviceRate); + int count = receiveBillService.genBillByMonthAndPay(bo, serviceRate); ServiceUtil.assertion(count == 0, "商户出账失败,请刷新后重试"); // 服务费 = 0 order.setServiceCharge(BigDecimal.ZERO); @@ -290,6 +278,24 @@ public class TransactionBillServiceImpl implements TransactionBillService { } + private UserRechargeServiceVO getUserRechargeService(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()); + } + } + // 转换为订单所需的数据 private TransactionBill parseToOrder(RechargeBO bo) { // 校验 @@ -332,7 +338,7 @@ public class TransactionBillServiceImpl implements TransactionBillService { // 渠道费用计算 order.setChannelCost(channel.getCostRate().multiply(order.getMoney()).divide(new BigDecimal(100), 2, RoundingMode.HALF_UP)); // 充值服务费处理 - this.handleRechargeService(order, channel, mch, device); + this.handleRechargeService(bo); // 支付过期时间 long expireTime = TimeUnit.MILLISECONDS.convert(Constants.BILL_UNPAID_TIMEOUT, Constants.BILL_UNPAID_TIMEUNIT) + System.currentTimeMillis(); order.setExpireTime(new Date(expireTime));