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));