临时提交
This commit is contained in:
parent
7f9727c246
commit
ed1df8462c
|
@ -220,4 +220,8 @@ public class Constants
|
|||
* 设备已绑定
|
||||
*/
|
||||
public static final int DEVICE_BINDED = 2;
|
||||
/**
|
||||
* 根部门
|
||||
*/
|
||||
public static final long ROOT_DEPT = 100L;
|
||||
}
|
||||
|
|
|
@ -166,4 +166,7 @@ public class SmUser extends BaseEntity
|
|||
@ApiModelProperty("是否已经实名认证")
|
||||
@JsonView(JsonViewProfile.App.class)
|
||||
private Boolean isReal;
|
||||
|
||||
@ApiModelProperty("用户类型")
|
||||
private String type;
|
||||
}
|
||||
|
|
|
@ -22,7 +22,8 @@ public enum RedisLockKey {
|
|||
ADD_TIME_BILL("add_time_bill", "创建时长订单"),
|
||||
PAY_BILL("pay_bill", "支付订单"),
|
||||
PREPAY_DEPOSIT("prepay_deposit", "支付押金"),
|
||||
ADD_RECHARGE_ORDER("add_recharge_order", "创建充值订单");
|
||||
ADD_RECHARGE_ORDER("add_recharge_order", "创建充值订单"),
|
||||
RECOVER_DEVICE_BALANCE("recover_device_balance", "恢复设备余额");
|
||||
|
||||
|
||||
private final String key;
|
||||
|
|
|
@ -15,8 +15,9 @@ import java.util.Objects;
|
|||
@AllArgsConstructor
|
||||
public enum UserType {
|
||||
|
||||
TENANT("00", "租户"),
|
||||
LANDLORD("01", "商户");
|
||||
USER("1", "普通用户"),
|
||||
MCH("2", "商户"),
|
||||
AGENT("3", "代理商");
|
||||
|
||||
private final String type;
|
||||
private final String name;
|
||||
|
|
|
@ -43,4 +43,9 @@ public class ServiceUtil {
|
|||
throw new ServiceException(result.getMsg(), result.getCode());
|
||||
}
|
||||
}
|
||||
public static void assertion(boolean flag, String format, Object ...args) {
|
||||
if (flag) {
|
||||
throw new ServiceException(String.format(format, args), 500);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
package com.ruoyi.common.domain.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author wjh
|
||||
* 2024/8/23
|
||||
*/
|
||||
@Data
|
||||
public class CommonCountVO<T> {
|
||||
|
||||
// 键
|
||||
private T key;
|
||||
|
||||
// 数量
|
||||
private Integer count;
|
||||
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package com.ruoyi.common.domain.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* @author wjh
|
||||
* 2024/8/23
|
||||
*/
|
||||
@Data
|
||||
public class CommonSumVO<T> {
|
||||
|
||||
private T key;
|
||||
|
||||
private BigDecimal sum;
|
||||
|
||||
}
|
|
@ -1,10 +1,14 @@
|
|||
package com.ruoyi.iot.service;
|
||||
import com.ruoyi.common.core.redis.RedisLock;
|
||||
import com.ruoyi.common.core.redis.enums.RedisLockKey;
|
||||
import com.ruoyi.common.utils.NumberUtils;
|
||||
import com.ruoyi.common.utils.ServiceUtil;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.common.utils.collection.CollectionUtils;
|
||||
import com.ruoyi.iot.constants.ReceiveConstants;
|
||||
import com.ruoyi.iot.domain.IotDeviceDetail;
|
||||
import com.ruoyi.iot.domain.ReceiveMsg;
|
||||
import com.ruoyi.iot.domain.response.CommandResponse;
|
||||
import com.ruoyi.iot.enums.ReceiveStatus;
|
||||
import com.ruoyi.iot.enums.ReceiveType;
|
||||
import com.ruoyi.ss.device.domain.Device;
|
||||
|
@ -21,9 +25,11 @@ import com.ruoyi.ss.transactionBill.service.TransactionBillService;
|
|||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.support.TransactionTemplate;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
|
@ -46,6 +52,12 @@ public class IotReceiveServiceImpl implements IotReceiveService{
|
|||
@Autowired
|
||||
private IotService iotService;
|
||||
|
||||
@Autowired
|
||||
private RedisLock redisLock;
|
||||
|
||||
@Autowired
|
||||
private TransactionTemplate transactionTemplate;
|
||||
|
||||
@Override
|
||||
public void handleReceive(ReceiveMsg msg) {
|
||||
if (msg == null) {
|
||||
|
@ -65,43 +77,51 @@ public class IotReceiveServiceImpl implements IotReceiveService{
|
|||
|
||||
// 恢复设备的余额
|
||||
private void recoverBalance(ReceiveMsg msg) {
|
||||
// 查询设备
|
||||
DeviceVO device = deviceService.selectByMac(msg.getDevName());
|
||||
if (device == null) {
|
||||
String lockKey = msg.getDevName();
|
||||
if (!redisLock.lock(RedisLockKey.RECOVER_DEVICE_BALANCE, lockKey)){
|
||||
return;
|
||||
}
|
||||
try {
|
||||
// 查询设备
|
||||
DeviceVO device = deviceService.selectByMac(msg.getDevName());
|
||||
if (device == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 查询未结束的订单
|
||||
TransactionBillQuery query = new TransactionBillQuery();
|
||||
query.setDeviceId(device.getDeviceId());
|
||||
query.setIsFinished(false);
|
||||
query.setStatus(TransactionBillStatus.SUCCESS.getStatus());
|
||||
query.setSuitFeeTypes(SuitFeeType.singleList());
|
||||
List<TransactionBillVO> billList = transactionBillService.selectSmTransactionBillList(query);
|
||||
// 判断上次恢复余额的时间和本次恢复余额的时间是否相同,若相同则视为重复推送,则忽略
|
||||
if (device.getLastRecoverTime() != null && msg.getAt().equals(device.getLastRecoverTime())) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (CollectionUtils.isNotEmptyElement(billList)) {
|
||||
// 拼接剩余时长(秒)/电量(度)
|
||||
transactionAssembler.assembleSuitSurplus(billList);
|
||||
// 待恢复的时长(秒)
|
||||
LocalDateTime expireTime = device.getExpireTime();
|
||||
|
||||
long seconds = 0; // 待恢复的时长(秒)
|
||||
BigDecimal ele = BigDecimal.ZERO; // 待恢复的电量(度)
|
||||
// 待恢复的电量(度)
|
||||
BigDecimal ele = BigDecimal.ZERO;
|
||||
|
||||
for (TransactionBillVO bill : billList) {
|
||||
if (bill.getSuitSurplus().compareTo(BigDecimal.ZERO) > 0) {
|
||||
if (SuitFeeType.rechargeTimeList().contains(bill.getSuitFeeType())) {
|
||||
seconds += bill.getSuitSurplus().longValue();
|
||||
} else if (SuitFeeType.rechargeCountList().contains(bill.getSuitFeeType())) {
|
||||
ele = ele.add(bill.getSuitSurplus());
|
||||
// 若有需要恢复余额的设备,则进行操作
|
||||
if (expireTime != null || ele.compareTo(BigDecimal.ZERO) > 0) {
|
||||
BigDecimal finalEle = ele;
|
||||
transactionTemplate.execute(status -> {
|
||||
// 记录上次恢复余额的时间
|
||||
int update = deviceService.updateLastRecoverTime(device.getDeviceId(), msg.getAt());
|
||||
ServiceUtil.assertion(update != 1, "更新设备信息失败");
|
||||
|
||||
log.info("设备:{} 恢复余额,过期时间:{},剩余电量:{}", device.getMac(), expireTime, finalEle);
|
||||
if (expireTime != null ) {
|
||||
int setTime = deviceService.setTime(device, expireTime, true, 3);
|
||||
ServiceUtil.assertion(setTime != 1, "恢复设备时长失败");
|
||||
}
|
||||
if (finalEle.compareTo(BigDecimal.ZERO) > 0) {
|
||||
CommandResponse res = iotService.trySetEle(device.getMac(), finalEle, device.getModelProductId(), 3);
|
||||
ServiceUtil.assertion(!res.isSuccess(), "设备电量恢复失败:%s", res.getMsg());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (seconds > 0) {
|
||||
iotService.setTime(device.getMac(), seconds, device.getModelProductId());
|
||||
}
|
||||
if (ele.compareTo(BigDecimal.ZERO) > 0) {
|
||||
iotService.setEle(device.getMac(), ele, device.getModelProductId());
|
||||
return update;
|
||||
});
|
||||
}
|
||||
} finally {
|
||||
redisLock.unlock(RedisLockKey.RECOVER_DEVICE_BALANCE, lockKey);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -146,4 +146,22 @@ public interface IotService {
|
|||
* 直接设置设备电量(度)
|
||||
*/
|
||||
CommandResponse setEle(String deviceName, BigDecimal ele, String productId);
|
||||
|
||||
/**
|
||||
* 尝试设置设备剩余时长
|
||||
* @param mac MAC
|
||||
* @param seconds 时长
|
||||
* @param productId 产品ID
|
||||
* @param tryCount 尝试次数
|
||||
*/
|
||||
CommandResponse trySetTime(String mac, long seconds, String productId, int tryCount);
|
||||
/**
|
||||
* 尝试设置设备剩余时长
|
||||
* @param mac MAC
|
||||
* @param ele 电量(度)
|
||||
* @param productId 产品ID
|
||||
* @param tryCount 尝试次数
|
||||
*/
|
||||
CommandResponse trySetEle(String mac, BigDecimal ele, String productId, int tryCount);
|
||||
|
||||
}
|
||||
|
|
|
@ -283,4 +283,37 @@ public class IotServiceImpl implements IotService {
|
|||
return JSON.parseObject(result, CommandResponse.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResponse trySetTime(String mac, long seconds, String productId, int tryCount) {
|
||||
CommandResponse res = this.setTime(mac, seconds, productId);
|
||||
if (!res.isSuccess()) {
|
||||
if (tryCount > 0) {
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
return trySetTime(mac, seconds, productId, --tryCount);
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResponse trySetEle(String mac, BigDecimal ele, String productId, int tryCount) {
|
||||
CommandResponse res = this.setEle(mac, ele, productId);
|
||||
if (!res.isSuccess()) {
|
||||
if (tryCount > 0) {
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
return trySetEle(mac, ele, productId, --tryCount);
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,94 @@
|
|||
package com.ruoyi.ss.bonus.domain;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Date;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.fasterxml.jackson.annotation.JsonView;
|
||||
import com.ruoyi.common.core.domain.JsonViewProfile;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
import com.ruoyi.common.annotation.Excel;
|
||||
import com.ruoyi.common.core.domain.BaseEntity;
|
||||
|
||||
/**
|
||||
* 分成明细对象 ss_bonus
|
||||
*
|
||||
* @author ruoyi
|
||||
* @date 2024-08-20
|
||||
*/
|
||||
@Data
|
||||
public class Bonus extends BaseEntity
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private Long id;
|
||||
|
||||
@Excel(name = "订单ID")
|
||||
@ApiModelProperty("订单ID")
|
||||
@JsonView(JsonViewProfile.AppMch.class)
|
||||
private Long billId;
|
||||
|
||||
@Excel(name = "订单编号")
|
||||
@ApiModelProperty("订单编号")
|
||||
@JsonView(JsonViewProfile.AppMch.class)
|
||||
private String billNo;
|
||||
|
||||
@Excel(name = "状态")
|
||||
@ApiModelProperty("状态")
|
||||
@JsonView(JsonViewProfile.AppMch.class)
|
||||
private String status;
|
||||
|
||||
@Excel(name = "收款方ID")
|
||||
@ApiModelProperty("收款方ID")
|
||||
@JsonView(JsonViewProfile.AppMch.class)
|
||||
private Long arrivalId;
|
||||
|
||||
@Excel(name = "收款方名称")
|
||||
@ApiModelProperty("收款方名称")
|
||||
@JsonView(JsonViewProfile.AppMch.class)
|
||||
private String arrivalName;
|
||||
|
||||
@Excel(name = "收款方类型")
|
||||
@ApiModelProperty("收款方类型")
|
||||
@JsonView(JsonViewProfile.AppMch.class)
|
||||
private String arrivalType;
|
||||
|
||||
@Excel(name = "分成比例")
|
||||
@ApiModelProperty("分成比例")
|
||||
@JsonView(JsonViewProfile.AppMch.class)
|
||||
private BigDecimal point;
|
||||
|
||||
@Excel(name = "分成金额")
|
||||
@ApiModelProperty("分成金额")
|
||||
@JsonView(JsonViewProfile.AppMch.class)
|
||||
private BigDecimal amount;
|
||||
|
||||
@Excel(name = "退款金额")
|
||||
@ApiModelProperty("退款金额")
|
||||
@JsonView(JsonViewProfile.AppMch.class)
|
||||
private BigDecimal refundAmount;
|
||||
|
||||
@Excel(name = "收款方祖级列表")
|
||||
@ApiModelProperty("收款方祖级列表")
|
||||
private String ancestors;
|
||||
|
||||
@Excel(name = "收款方部门")
|
||||
@ApiModelProperty("收款方部门")
|
||||
private Long deptId;
|
||||
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@Excel(name = "实际分成时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
|
||||
@ApiModelProperty("实际分成时间")
|
||||
@JsonView(JsonViewProfile.AppMch.class)
|
||||
private LocalDateTime payTime;
|
||||
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@Excel(name = "预计分成时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
|
||||
@ApiModelProperty("预计分成时间")
|
||||
@JsonView(JsonViewProfile.AppMch.class)
|
||||
private LocalDateTime prePayTime;
|
||||
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
package com.ruoyi.ss.bonus.domain;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import nonapi.io.github.classgraph.utils.LogNode;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author wjh
|
||||
* 2024/8/23
|
||||
*/
|
||||
@Data
|
||||
public class BonusProvideQuery {
|
||||
|
||||
@ApiModelProperty("到账方ID")
|
||||
private Long arrivalId;
|
||||
|
||||
@ApiModelProperty("到账方类型")
|
||||
private List<String> arrivalTypes;
|
||||
|
||||
@ApiModelProperty("提供者ID列表")
|
||||
private List<Long> providerIds;
|
||||
|
||||
@ApiModelProperty("提供者类型")
|
||||
private List<String> providerTypes;
|
||||
|
||||
@ApiModelProperty("分成状态")
|
||||
private String status;
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
package com.ruoyi.ss.bonus.domain;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author wjh
|
||||
* 2024/8/20
|
||||
*/
|
||||
@Data
|
||||
public class BonusQuery extends BonusVO {
|
||||
|
||||
@ApiModelProperty("订单ID列表")
|
||||
private List<Long> billIds;
|
||||
|
||||
@ApiModelProperty("分成方ID列表")
|
||||
private List<Long> arrivalIds;
|
||||
|
||||
@ApiModelProperty("分成方类型列表")
|
||||
private List<String> arrivalTypes;
|
||||
|
||||
@ApiModelProperty("支付时间:年")
|
||||
private Integer payTimeYear;
|
||||
|
||||
@ApiModelProperty("支付日期(起始)")
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd")
|
||||
private LocalDate payDateStart;
|
||||
|
||||
@ApiModelProperty("支付日期(结束)")
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd")
|
||||
private LocalDate payDateEnd;
|
||||
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package com.ruoyi.ss.bonus.domain;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author wjh
|
||||
* 2024/8/20
|
||||
*/
|
||||
@Data
|
||||
public class BonusVO extends Bonus {
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
package com.ruoyi.ss.bonus.domain.enums;
|
||||
|
||||
import com.ruoyi.common.constant.Constants;
|
||||
import com.ruoyi.common.core.domain.entity.SysDept;
|
||||
import com.ruoyi.common.enums.UserType;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author wjh
|
||||
* 2024/8/21
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum BonusArrivalType {
|
||||
|
||||
PLATFORM("1", "平台"),
|
||||
AGENT("2", "代理商"),
|
||||
MCH("3", "商户");
|
||||
|
||||
private final String type;
|
||||
private final String msg;
|
||||
|
||||
public static BonusArrivalType parseByUserType(String type) {
|
||||
if (UserType.MCH.equalsType(type)) {
|
||||
return MCH;
|
||||
}
|
||||
if (UserType.AGENT.equalsType(type)) {
|
||||
return AGENT;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static BonusArrivalType parseByDept(SysDept dept) {
|
||||
if (dept == null) {
|
||||
return null;
|
||||
}
|
||||
if (Constants.ROOT_DEPT == dept.getDeptId()) {
|
||||
return PLATFORM;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static List<String> asList(BonusArrivalType ...types) {
|
||||
return Arrays.stream(types).map(BonusArrivalType::getType).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户表
|
||||
*/
|
||||
public static List<String> userList() {
|
||||
return asList(AGENT, MCH);
|
||||
}
|
||||
|
||||
/**
|
||||
* 部门表
|
||||
*/
|
||||
public static List<String> deptList() {
|
||||
return asList(PLATFORM);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package com.ruoyi.ss.bonus.domain.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* @author wjh
|
||||
* 2024/8/21
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum BonusStatus {
|
||||
|
||||
UN_DIVIDEND("1", "未分成"),
|
||||
DIVIDEND("2", "已分成");
|
||||
|
||||
private final String status;
|
||||
private final String msg;
|
||||
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package com.ruoyi.ss.bonus.domain.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
|
||||
/**
|
||||
* @author wjh
|
||||
* 2024/8/30
|
||||
*/
|
||||
@Data
|
||||
public class BonusDailyAmountVO {
|
||||
|
||||
private LocalDate key;
|
||||
|
||||
private BigDecimal sum;
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package com.ruoyi.ss.bonus.domain.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* @author wjh
|
||||
* 2024/8/28
|
||||
*/
|
||||
@Data
|
||||
public class BonusMonthAmountVO {
|
||||
|
||||
@ApiModelProperty("月份")
|
||||
private Integer month;
|
||||
|
||||
@ApiModelProperty("金额")
|
||||
private BigDecimal amount;
|
||||
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package com.ruoyi.ss.bonus.domain.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* @author wjh
|
||||
* 2024/8/23
|
||||
*/
|
||||
@Data
|
||||
public class ProvideBonusVO {
|
||||
|
||||
// 提供者ID
|
||||
private Long providerId;
|
||||
|
||||
// 到账人ID
|
||||
private Long arrivalId;
|
||||
|
||||
// 到账金额
|
||||
private BigDecimal arrivalAmount;
|
||||
}
|
|
@ -0,0 +1,113 @@
|
|||
package com.ruoyi.ss.bonus.mapper;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
|
||||
import com.ruoyi.common.domain.vo.CommonCountVO;
|
||||
import com.ruoyi.common.domain.vo.CommonSumVO;
|
||||
import com.ruoyi.ss.bonus.domain.Bonus;
|
||||
import com.ruoyi.ss.bonus.domain.BonusProvideQuery;
|
||||
import com.ruoyi.ss.bonus.domain.BonusVO;
|
||||
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 org.apache.ibatis.annotations.Param;
|
||||
|
||||
/**
|
||||
* 分成明细Mapper接口
|
||||
*
|
||||
* @author ruoyi
|
||||
* @date 2024-08-20
|
||||
*/
|
||||
public interface BonusMapper
|
||||
{
|
||||
/**
|
||||
* 查询分成明细
|
||||
*
|
||||
* @param id 分成明细主键
|
||||
* @return 分成明细
|
||||
*/
|
||||
public BonusVO selectBonusById(Long id);
|
||||
|
||||
/**
|
||||
* 查询分成明细列表
|
||||
*
|
||||
* @param query 分成明细
|
||||
* @return 分成明细集合
|
||||
*/
|
||||
public List<BonusVO> selectBonusList(@Param("query")BonusQuery query);
|
||||
|
||||
/**
|
||||
* 新增分成明细
|
||||
*
|
||||
* @param bonus 分成明细
|
||||
* @return 结果
|
||||
*/
|
||||
public int insertBonus(Bonus bonus);
|
||||
|
||||
/**
|
||||
* 修改分成明细
|
||||
*
|
||||
* @param bonus 分成明细
|
||||
* @return 结果
|
||||
*/
|
||||
public int updateBonus(@Param("data") Bonus bonus);
|
||||
|
||||
/**
|
||||
* 删除分成明细
|
||||
*
|
||||
* @param id 分成明细主键
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteBonusById(Long id);
|
||||
|
||||
/**
|
||||
* 批量删除分成明细
|
||||
*
|
||||
* @param ids 需要删除的数据主键集合
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteBonusByIds(Long[] ids);
|
||||
|
||||
/**
|
||||
* 批量插入
|
||||
*/
|
||||
int batchInsert(@Param("list") List<Bonus> bonusList);
|
||||
|
||||
/**
|
||||
* 批量更新分成金额
|
||||
*/
|
||||
int batchUpdateAmount(@Param("list") List<BonusVO> list);
|
||||
|
||||
/**
|
||||
* 根据到账方统计
|
||||
*/
|
||||
List<CommonCountVO<Long>> selectCountByArrival(@Param("query") BonusQuery query);
|
||||
|
||||
/**
|
||||
* 根据到账方统计金额
|
||||
*/
|
||||
List<CommonSumVO<Long>> selectBillAmountByArrival(@Param("query") BonusQuery query);
|
||||
|
||||
/**
|
||||
* 查询提供分成
|
||||
*/
|
||||
List<ProvideBonusVO> selectProvideBonus(@Param("query") BonusProvideQuery query);
|
||||
|
||||
/**
|
||||
* 增加退款金额
|
||||
*/
|
||||
int addRefundAmount(@Param("id") Long id, @Param("amount") BigDecimal amount);
|
||||
|
||||
/**
|
||||
* 按月查询
|
||||
*/
|
||||
List<BonusMonthAmountVO> selectMonthAmount(@Param("query") BonusQuery query);
|
||||
|
||||
/**
|
||||
* 按日查询
|
||||
*/
|
||||
List<BonusDailyAmountVO> selectDailyAmount(@Param("query") BonusQuery query);
|
||||
}
|
|
@ -0,0 +1,336 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper
|
||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.ruoyi.ss.bonus.mapper.BonusMapper">
|
||||
|
||||
<resultMap type="BonusVO" id="BonusResult" autoMapping="true"/>
|
||||
|
||||
<sql id="selectBonusVo">
|
||||
select
|
||||
sb.id,
|
||||
sb.bill_id,
|
||||
sb.bill_no,
|
||||
sb.status,
|
||||
sb.arrival_id,
|
||||
sb.arrival_name,
|
||||
sb.arrival_type,
|
||||
sb.point,
|
||||
sb.amount,
|
||||
sb.refund_amount,
|
||||
sb.ancestors,
|
||||
sb.create_time,
|
||||
sb.pay_time,
|
||||
sb.dept_id,
|
||||
sb.pre_pay_time
|
||||
<include refid="searchTables"/>
|
||||
</sql>
|
||||
|
||||
<sql id="searchTables">
|
||||
from ss_bonus sb
|
||||
left join sys_dept sd on sd.dept_id = sb.dept_id
|
||||
</sql>
|
||||
|
||||
<sql id="searchCondition">
|
||||
<if test="query.id != null "> and sb.id = #{query.id}</if>
|
||||
<if test="query.billId != null "> and sb.bill_id = #{query.billId}</if>
|
||||
<if test="query.deptId != null "> and sb.dept_id = #{query.deptId}</if>
|
||||
<if test="query.billNo != null and query.billNo != ''"> and sb.bill_no like concat('%', #{query.billNo}, '%')</if>
|
||||
<if test="query.status != null and query.status != ''"> and sb.status = #{query.status}</if>
|
||||
<if test="query.arrivalId != null "> and sb.arrival_id = #{query.arrivalId}</if>
|
||||
<if test="query.arrivalType != null and query.arrivalType != ''"> and sb.arrival_type = #{query.arrivalType}</if>
|
||||
<if test="query.arrivalName != null and query.arrivalName != ''"> and sb.arrival_name like concat('%', #{query.arrivalName}, '%')</if>
|
||||
<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) <= #{query.payDateEnd}</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=",">
|
||||
#{item}
|
||||
</foreach>
|
||||
</if>
|
||||
<if test="query.arrivalTypes != null and query.arrivalTypes.size() > 0 ">
|
||||
and sb.arrival_type in
|
||||
<foreach collection="query.arrivalTypes" item="item" open="(" close=")" separator=",">
|
||||
#{item}
|
||||
</foreach>
|
||||
</if>
|
||||
<if test="query.arrivalIds != null and query.arrivalIds.size() > 0 ">
|
||||
and sb.arrival_id in
|
||||
<foreach collection="query.arrivalIds" item="item" open="(" close=")" separator=",">
|
||||
#{item}
|
||||
</foreach>
|
||||
</if>
|
||||
${query.params.dataScope}
|
||||
${@com.ruoyi.common.utils.DataScopeUtil@dataScopeDept("sd", query.needScope)}
|
||||
</sql>
|
||||
|
||||
<select id="selectBonusList" parameterType="BonusQuery" resultMap="BonusResult">
|
||||
<include refid="selectBonusVo"/>
|
||||
<where>
|
||||
<include refid="searchCondition"/>
|
||||
</where>
|
||||
</select>
|
||||
|
||||
<select id="selectBonusById" parameterType="Long" resultMap="BonusResult">
|
||||
<include refid="selectBonusVo"/>
|
||||
where sb.id = #{id}
|
||||
</select>
|
||||
|
||||
<select id="selectCountByArrival" resultType="com.ruoyi.common.domain.vo.CommonCountVO">
|
||||
select
|
||||
sb.arrival_id as `key`,
|
||||
count(sb.id) as `count`
|
||||
<include refid="searchTables"/>
|
||||
<where>
|
||||
<include refid="searchCondition"/>
|
||||
</where>
|
||||
group by `key`
|
||||
</select>
|
||||
|
||||
<select id="selectBillAmountByArrival" resultType="com.ruoyi.common.domain.vo.CommonSumVO">
|
||||
select
|
||||
sb.arrival_id as `key`,
|
||||
sum(stb.money) as `sum`
|
||||
from ss_bonus sb
|
||||
left join sm_transaction_bill stb on stb.bill_id = sb.bill_id
|
||||
<where>
|
||||
<include refid="searchCondition"/>
|
||||
</where>
|
||||
group by `key`
|
||||
</select>
|
||||
|
||||
<resultMap id="ProvideBonusVO" type="ProvideBonusVO" autoMapping="true">
|
||||
<result property="arrivalAmount" column="arrival_amount" typeHandler="com.ruoyi.system.mapper.typehandler.NonNullDecimalTypeHandler"/>
|
||||
</resultMap>
|
||||
|
||||
<select id="selectProvideBonus" resultMap="ProvideBonusVO">
|
||||
select
|
||||
p.arrival_id as provider_id,
|
||||
a.arrival_id as arrival_id,
|
||||
sum(a.amount - a.refund_amount) as arrival_amount
|
||||
from ss_bonus p
|
||||
left join ss_bonus a on a.bill_id = p.bill_id
|
||||
<where>
|
||||
<if test="query.providerIds != null and query.providerIds.size() > 0">
|
||||
and p.arrival_id in
|
||||
<foreach collection="query.providerIds" item="item" open="(" close=")" separator=",">
|
||||
#{item}
|
||||
</foreach>
|
||||
</if>
|
||||
<if test="query.providerTypes != null and query.providerTypes.size() > 0">
|
||||
and p.arrival_type in
|
||||
<foreach collection="query.providerTypes" item="item" open="(" close=")" separator=",">
|
||||
#{item}
|
||||
</foreach>
|
||||
</if>
|
||||
<if test="query.arrivalId != null">
|
||||
and a.arrival_id = #{query.arrivalId}
|
||||
</if>
|
||||
<if test="query.arrivalTypes != null and query.arrivalTypes.size() > 0">
|
||||
and a.arrival_type in
|
||||
<foreach collection="query.arrivalTypes" item="item" open="(" close=")" separator=",">
|
||||
#{item}
|
||||
</foreach>
|
||||
</if>
|
||||
</where>
|
||||
group by p.arrival_id, a.arrival_id
|
||||
</select>
|
||||
|
||||
<resultMap id="BonusMonthAmountVO" type="BonusMonthAmountVO">
|
||||
<result property="amount" column="amount" typeHandler="com.ruoyi.system.mapper.typehandler.NonNullDecimalTypeHandler"/>
|
||||
</resultMap>
|
||||
|
||||
<select id="selectMonthAmount" resultMap="BonusMonthAmountVO">
|
||||
select
|
||||
month(sb.pay_time) as month,
|
||||
sum(amount) as amount
|
||||
<include refid="searchTables"/>
|
||||
<where>
|
||||
<include refid="searchCondition"/>
|
||||
</where>
|
||||
group by `month`
|
||||
</select>
|
||||
|
||||
<select id="selectDailyAmount" resultType="BonusDailyAmountVO">
|
||||
select
|
||||
date(sb.pay_time) as `key`,
|
||||
sum(amount) as `sum`
|
||||
<include refid="searchTables"/>
|
||||
<where>
|
||||
<include refid="searchCondition"/>
|
||||
</where>
|
||||
group by `key`
|
||||
</select>
|
||||
|
||||
<insert id="insertBonus" parameterType="Bonus" useGeneratedKeys="true" keyProperty="id">
|
||||
insert into ss_bonus
|
||||
<trim prefix="(" suffix=")" suffixOverrides=",">
|
||||
<if test="billId != null">bill_id,</if>
|
||||
<if test="billNo != null">bill_no,</if>
|
||||
<if test="status != null and status != ''">`status`,</if>
|
||||
<if test="arrivalId != null">arrival_id,</if>
|
||||
<if test="arrivalName != null and arrivalName != ''">arrival_name,</if>
|
||||
<if test="arrivalType != null and arrivalType != ''">arrival_type,</if>
|
||||
<if test="point != null">`point`,</if>
|
||||
<if test="amount != null">amount,</if>
|
||||
<if test="refundAmount != null">refund_amount,</if>
|
||||
<if test="ancestors != null and ancestors != ''">ancestors,</if>
|
||||
<if test="createTime != null">create_time,</if>
|
||||
<if test="payTime != null">pay_time,</if>
|
||||
<if test="deptId != null">dept_id,</if>
|
||||
<if test="prePayTime != null">pre_pay_time,</if>
|
||||
</trim>
|
||||
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||
<if test="billId != null">#{billId},</if>
|
||||
<if test="billNo != null">#{billNo},</if>
|
||||
<if test="status != null and status != ''">#{status},</if>
|
||||
<if test="arrivalId != null">#{arrivalId},</if>
|
||||
<if test="arrivalName != null and arrivalName != ''">#{arrivalName},</if>
|
||||
<if test="arrivalType != null and arrivalType != ''">#{arrivalType},</if>
|
||||
<if test="point != null">#{point},</if>
|
||||
<if test="amount != null">#{amount},</if>
|
||||
<if test="refundAmount != null">#{refundAmount},</if>
|
||||
<if test="ancestors != null and ancestors != ''">#{ancestors},</if>
|
||||
<if test="createTime != null">#{createTime},</if>
|
||||
<if test="payTime != null">#{payTime},</if>
|
||||
<if test="deptId != null">#{deptId},</if>
|
||||
<if test="prePayTime != null">#{prePayTime},</if>
|
||||
</trim>
|
||||
</insert>
|
||||
|
||||
<insert id="batchInsert">
|
||||
insert into ss_bonus(
|
||||
bill_id,
|
||||
bill_no,
|
||||
status,
|
||||
arrival_id,
|
||||
arrival_name,
|
||||
arrival_type,
|
||||
point,
|
||||
amount,
|
||||
refund_amount,
|
||||
ancestors,
|
||||
create_time,
|
||||
pay_time,
|
||||
dept_id,
|
||||
pre_pay_time
|
||||
)
|
||||
values
|
||||
<foreach collection="list" item="i" separator=",">
|
||||
<trim prefix="(" suffix=")" suffixOverrides=",">
|
||||
<if test="i.billId != null">#{i.billId},</if>
|
||||
<if test="i.billId == null">default,</if>
|
||||
<if test="i.billNo != null">#{i.billNo},</if>
|
||||
<if test="i.billNo == null">default,</if>
|
||||
<if test="i.status != null and i.status != ''">#{i.status},</if>
|
||||
<if test="i.status == null">default,</if>
|
||||
<if test="i.arrivalId != null">#{i.arrivalId},</if>
|
||||
<if test="i.arrivalId == null">default,</if>
|
||||
<if test="i.arrivalName != null and i.arrivalName != ''">#{i.arrivalName},</if>
|
||||
<if test="i.arrivalName == null or i.arrivalName == ''">default,</if>
|
||||
<if test="i.arrivalType != null and i.arrivalType != ''">#{i.arrivalType},</if>
|
||||
<if test="i.arrivalType == null or i.arrivalType == ''">default,</if>
|
||||
<if test="i.point != null">#{i.point},</if>
|
||||
<if test="i.point == null">default,</if>
|
||||
<if test="i.amount != null">#{i.amount},</if>
|
||||
<if test="i.amount == null">default,</if>
|
||||
<if test="i.refundAmount != null">#{i.refundAmount},</if>
|
||||
<if test="i.refundAmount == null">default,</if>
|
||||
<if test="i.ancestors != null and i.ancestors != ''">#{i.ancestors},</if>
|
||||
<if test="i.ancestors == null or i.ancestors == ''">default,</if>
|
||||
<if test="i.createTime != null">#{i.createTime},</if>
|
||||
<if test="i.createTime == null">default,</if>
|
||||
<if test="i.payTime != null">#{i.payTime},</if>
|
||||
<if test="i.payTime == null">default,</if>
|
||||
<if test="i.deptId != null">#{i.deptId},</if>
|
||||
<if test="i.deptId == null">default,</if>
|
||||
<if test="i.prePayTime != null">#{i.prePayTime},</if>
|
||||
<if test="i.prePayTime == null">default,</if>
|
||||
</trim>
|
||||
</foreach>
|
||||
</insert>
|
||||
|
||||
<insert id="addRefundAmount">
|
||||
update ss_bonus
|
||||
set refund_amount = refund_amount + #{amount}
|
||||
where id = #{id} and amount >= refund_amount + #{amount}
|
||||
</insert>
|
||||
|
||||
<update id="updateBonus" parameterType="Bonus">
|
||||
update ss_bonus
|
||||
<trim prefix="SET" suffixOverrides=",">
|
||||
<include refid="updateColumns"/>
|
||||
</trim>
|
||||
where id = #{data.id}
|
||||
</update>
|
||||
|
||||
<update id="batchUpdateAmount">
|
||||
update ss_bonus
|
||||
<trim prefix="SET" suffixOverrides=",">
|
||||
<foreach open="amount = CASE id" collection="list" item="item" close="END,">
|
||||
<choose>
|
||||
<when test="item.amount != null">
|
||||
WHEN #{item.id} THEN #{item.amount}
|
||||
</when>
|
||||
<otherwise>
|
||||
WHEN #{item.id} THEN amount
|
||||
</otherwise>
|
||||
</choose>
|
||||
</foreach>
|
||||
<foreach open="status = CASE id" collection="list" item="item" close="END,">
|
||||
<choose>
|
||||
<when test="item.status != null">
|
||||
WHEN #{item.id} THEN #{item.status}
|
||||
</when>
|
||||
<otherwise>
|
||||
WHEN #{item.id} THEN `status`
|
||||
</otherwise>
|
||||
</choose>
|
||||
</foreach>
|
||||
<foreach open="pay_time = CASE id" collection="list" item="item" close="END,">
|
||||
<choose>
|
||||
<when test="item.payTime != null">
|
||||
WHEN #{item.id} THEN #{item.payTime}
|
||||
</when>
|
||||
<otherwise>
|
||||
WHEN #{item.id} THEN `pay_time`
|
||||
</otherwise>
|
||||
</choose>
|
||||
</foreach>
|
||||
</trim>
|
||||
where id in
|
||||
<foreach collection="list" item="item" open="(" separator="," close=")">
|
||||
#{item.id}
|
||||
</foreach>
|
||||
and `status` = '1'
|
||||
</update>
|
||||
|
||||
<sql id="updateColumns">
|
||||
<if test="data.billId != null">bill_id = #{data.billId},</if>
|
||||
<if test="data.billNo != null">bill_no = #{data.billNo},</if>
|
||||
<if test="data.status != null and data.status != ''">`status` = #{data.status},</if>
|
||||
<if test="data.arrivalId != null">arrival_id = #{data.arrivalId},</if>
|
||||
<if test="data.arrivalName != null and data.arrivalName != ''">arrival_name = #{data.arrivalName},</if>
|
||||
<if test="data.arrivalType != null and data.arrivalType != ''">arrival_type = #{data.arrivalType},</if>
|
||||
<if test="data.point != null">`point` = #{data.point},</if>
|
||||
<if test="data.amount != null">amount = #{data.amount},</if>
|
||||
<if test="data.refundAmount != null">refund_amount = #{data.refundAmount},</if>
|
||||
<if test="data.ancestors != null and data.ancestors != ''">ancestors = #{data.ancestors},</if>
|
||||
<if test="data.createTime != null">create_time = #{data.createTime},</if>
|
||||
<if test="data.payTime != null">pay_time = #{data.payTime},</if>
|
||||
<if test="data.deptId != null">dept_id = #{data.deptId},</if>
|
||||
<if test="data.prePayTime != null">pre_pay_time = #{data.prePayTime},</if>
|
||||
</sql>
|
||||
|
||||
<delete id="deleteBonusById" parameterType="Long">
|
||||
delete from ss_bonus where id = #{id}
|
||||
</delete>
|
||||
|
||||
<delete id="deleteBonusByIds" parameterType="String">
|
||||
delete from ss_bonus where id in
|
||||
<foreach item="id" collection="array" open="(" separator="," close=")">
|
||||
#{id}
|
||||
</foreach>
|
||||
</delete>
|
||||
</mapper>
|
|
@ -0,0 +1,32 @@
|
|||
package com.ruoyi.ss.bonus.service;
|
||||
|
||||
import com.ruoyi.common.core.domain.entity.SysDept;
|
||||
import com.ruoyi.ss.bonus.domain.Bonus;
|
||||
import com.ruoyi.ss.device.domain.vo.DeviceVO;
|
||||
import com.ruoyi.ss.transactionBill.domain.bo.RechargeBO;
|
||||
import com.ruoyi.ss.user.domain.SmUserVo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author wjh
|
||||
* 2024/8/20
|
||||
*/
|
||||
public interface BonusConverter {
|
||||
|
||||
/**
|
||||
* 订单转为分成明细
|
||||
*/
|
||||
List<Bonus> toPo(RechargeBO bo);
|
||||
|
||||
/**
|
||||
* 生成分成列表
|
||||
*
|
||||
* @param mch
|
||||
* @param agent
|
||||
* @param platform
|
||||
* @param device
|
||||
* @return
|
||||
*/
|
||||
List<Bonus> genBonusList(SmUserVo mch, SmUserVo agent, SysDept platform, DeviceVO device);
|
||||
}
|
|
@ -0,0 +1,120 @@
|
|||
package com.ruoyi.ss.bonus.service;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
|
||||
import com.ruoyi.common.domain.vo.CommonCountVO;
|
||||
import com.ruoyi.common.domain.vo.CommonSumVO;
|
||||
import com.ruoyi.ss.bonus.domain.Bonus;
|
||||
import com.ruoyi.ss.bonus.domain.BonusProvideQuery;
|
||||
import com.ruoyi.ss.bonus.domain.BonusVO;
|
||||
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;
|
||||
|
||||
/**
|
||||
* 分成明细Service接口
|
||||
*
|
||||
* @author ruoyi
|
||||
* @date 2024-08-20
|
||||
*/
|
||||
public interface BonusService
|
||||
{
|
||||
/**
|
||||
* 查询分成明细
|
||||
*
|
||||
* @param id 分成明细主键
|
||||
* @return 分成明细
|
||||
*/
|
||||
public BonusVO selectBonusById(Long id);
|
||||
|
||||
/**
|
||||
* 查询分成明细列表
|
||||
*
|
||||
* @param bonus 分成明细
|
||||
* @return 分成明细集合
|
||||
*/
|
||||
public List<BonusVO> selectBonusList(BonusQuery bonus);
|
||||
|
||||
/**
|
||||
* 新增分成明细
|
||||
*
|
||||
* @param bonus 分成明细
|
||||
* @return 结果
|
||||
*/
|
||||
public int insertBonus(Bonus bonus);
|
||||
|
||||
/**
|
||||
* 修改分成明细
|
||||
*
|
||||
* @param bonus 分成明细
|
||||
* @return 结果
|
||||
*/
|
||||
public int updateBonus(Bonus bonus);
|
||||
|
||||
/**
|
||||
* 批量删除分成明细
|
||||
*
|
||||
* @param ids 需要删除的分成明细主键集合
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteBonusByIds(Long[] ids);
|
||||
|
||||
/**
|
||||
* 删除分成明细信息
|
||||
*
|
||||
* @param id 分成明细主键
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteBonusById(Long id);
|
||||
|
||||
/**
|
||||
* 批量新增
|
||||
*/
|
||||
int batchInsert(List<Bonus> bonusList);
|
||||
|
||||
/**
|
||||
* 处理分成支付
|
||||
* @param bonusList 分成列表
|
||||
* @param money 总金额
|
||||
* @return 处理数量
|
||||
*/
|
||||
int payBonus(List<BonusVO> bonusList, BigDecimal money);
|
||||
|
||||
/**
|
||||
* 根据到账方统计
|
||||
*/
|
||||
List<CommonCountVO<Long>> selectCountByArrival(BonusQuery query);
|
||||
|
||||
/**
|
||||
* 根据到账方统计订单金额
|
||||
*/
|
||||
List<CommonSumVO<Long>> selectBillAmountByArrival(BonusQuery query);
|
||||
|
||||
/**
|
||||
* 查询提供分成
|
||||
*/
|
||||
List<ProvideBonusVO> selectProvideBonus(BonusProvideQuery query);
|
||||
|
||||
/**
|
||||
* 增加已退款金额
|
||||
*/
|
||||
int addRefundAmount(Long id, BigDecimal amount);
|
||||
|
||||
/**
|
||||
* 数据隔离过滤
|
||||
*/
|
||||
<T extends Bonus> List<T> filterBonusScope(List<T> bonusList);
|
||||
|
||||
/**
|
||||
* 按月查询分成金额
|
||||
*/
|
||||
List<BonusMonthAmountVO> selectMonthAmount(BonusQuery query);
|
||||
|
||||
/**
|
||||
* 按日查询分成
|
||||
*/
|
||||
List<BonusDailyAmountVO> selectDailyAmount(BonusQuery query);
|
||||
}
|
|
@ -0,0 +1,168 @@
|
|||
package com.ruoyi.ss.bonus.service.impl;
|
||||
|
||||
import com.ruoyi.common.constant.Constants;
|
||||
import com.ruoyi.common.core.domain.entity.SysDept;
|
||||
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.device.domain.vo.DeviceVO;
|
||||
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.service.TransactionBillService;
|
||||
import com.ruoyi.ss.user.domain.SmUserVo;
|
||||
import com.ruoyi.ss.user.service.ISmUserService;
|
||||
import com.ruoyi.system.service.ISysDeptService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author wjh
|
||||
* 2024/8/20
|
||||
*/
|
||||
@Service
|
||||
public class BonusConverterImpl implements BonusConverter {
|
||||
|
||||
@Autowired
|
||||
private ISmUserService userService;
|
||||
|
||||
@Autowired
|
||||
private StoreService storeService;
|
||||
|
||||
@Autowired
|
||||
private ISysDeptService deptService;
|
||||
|
||||
@Autowired
|
||||
private TransactionBillService transactionBillService;
|
||||
|
||||
/**
|
||||
* 订单转为分成明细
|
||||
*
|
||||
* @param bo
|
||||
*/
|
||||
@Override
|
||||
public List<Bonus> toPo(RechargeBO bo) {
|
||||
if (bo == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
TransactionBill bill = bo.getOrder();
|
||||
if (bill == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
List<Bonus> result = bo.getBonusList();
|
||||
for (Bonus bonus : result) {
|
||||
bonus.setBillId(bill.getBillId());
|
||||
bonus.setBillNo(bill.getBillNo());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Bonus> genBonusList(SmUserVo mch, SmUserVo agent, SysDept platform, DeviceVO device) {
|
||||
List<Bonus> result = new ArrayList<>();
|
||||
|
||||
BigDecimal point = BigDecimal.valueOf(100);
|
||||
|
||||
// TODO 平台收取服务费
|
||||
|
||||
// TODO 代理商收取服务费
|
||||
|
||||
// TODO 剩余的给商户
|
||||
|
||||
//
|
||||
// // 根据设备的投资人、经营场所获取各自的分成比例
|
||||
// result.add(this.toPo(store, storeInvestor, mch));
|
||||
// result.add(this.toPo(mch, mch.getPoint()));
|
||||
// BigDecimal lastPoint = mch.getPoint().add(storeInvestor.getPoint()); // 上一次的分成比例
|
||||
//
|
||||
// // 投资人上级
|
||||
// if (StringUtils.hasText(mch.getAncestors()) && CollectionUtils.isNotEmpty(agent)) {
|
||||
// List<Long> collect = Arrays.stream(mch.getAncestors().split(",")).map(Long::valueOf).collect(Collectors.toList());
|
||||
// for (int i = collect.size() - 1; i >= 0; i --) {
|
||||
// Long id = collect.get(i);
|
||||
// SmUserVo investorAncestor = agent.stream().filter(item -> item.getUserId().equals(id)).findFirst().orElse(null);
|
||||
// if (investorAncestor != null) {
|
||||
// result.add(this.toPo(investorAncestor, investorAncestor.getPoint().subtract(lastPoint)));
|
||||
// lastPoint = investorAncestor.getPoint();
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // 直属部门
|
||||
// result.add(this.toPo(platform, platform.getPoint().subtract(lastPoint)));
|
||||
// lastPoint = platform.getPoint();
|
||||
//
|
||||
// // 直属部门的祖级列表
|
||||
// if (StringUtils.hasText(platform.getAncestors()) && CollectionUtils.isNotEmpty(investorDeptList)) {
|
||||
// List<Long> collect = Arrays.stream(platform.getAncestors().split(",")).map(Long::valueOf).collect(Collectors.toList());
|
||||
// for (int i = collect.size() - 1; i >= 0; i --) {
|
||||
// Long id = collect.get(i);
|
||||
// SysDept d = investorDeptList.stream().filter(item -> item.getDeptId().equals(id)).findFirst().orElse(null);
|
||||
// if (d != null) {
|
||||
// result.add(this.toPo(d, d.getPoint().subtract(lastPoint)));
|
||||
// lastPoint = d.getPoint();
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// 校验分成比例
|
||||
// ServiceUtil.assertion(lastPoint.compareTo(BigDecimal.valueOf(100)) != 0, "分成计算失败:最终分成比例不等于100");
|
||||
// BigDecimal total = BigDecimal.ZERO;
|
||||
// BigDecimal decimal100 = BigDecimal.valueOf(100);
|
||||
// for (Bonus bonus : result) {
|
||||
// ServiceUtil.assertion(bonus.getPoint().compareTo(BigDecimal.ZERO) < 0, "分成计算失败:分成比例小于0");
|
||||
// ServiceUtil.assertion(bonus.getPoint().compareTo(decimal100) > 0, "分成计算失败:分成比例大于100");
|
||||
// total = total.add(bonus.getPoint());
|
||||
// }
|
||||
// ServiceUtil.assertion(total.compareTo(decimal100) > 0, "分成计算失败:分成比例总和大于100");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private Bonus toPo(SysDept dept, BigDecimal point) {
|
||||
if (dept == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Bonus po = new Bonus();
|
||||
po.setStatus(BonusStatus.UN_DIVIDEND.getStatus());
|
||||
po.setArrivalId(dept.getDeptId());
|
||||
po.setArrivalName(dept.getDeptName());
|
||||
BonusArrivalType arrivalType = BonusArrivalType.parseByDept(dept);
|
||||
if (arrivalType != null) {
|
||||
po.setArrivalType(arrivalType.getType());
|
||||
}
|
||||
po.setPoint(point);
|
||||
po.setAncestors(dept.getAncestors());
|
||||
po.setDeptId(dept.getDeptId());
|
||||
|
||||
return po;
|
||||
}
|
||||
|
||||
private Bonus toPo(SmUserVo user, BigDecimal point, DeviceVO device) {
|
||||
if (user == null || point == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Bonus po = new Bonus();
|
||||
po.setStatus(BonusStatus.UN_DIVIDEND.getStatus());
|
||||
po.setArrivalId(user.getUserId());
|
||||
po.setArrivalName(user.getRealOrUserName());
|
||||
BonusArrivalType arrivalType = BonusArrivalType.parseByUserType(user.getType());
|
||||
if (arrivalType != null) {
|
||||
po.setArrivalType(arrivalType.getType());
|
||||
}
|
||||
po.setPoint(point);
|
||||
// po.setAncestors(Arrays.asList(device.getAgentId(), device.getUserId()));
|
||||
po.setDeptId(Constants.ROOT_DEPT);
|
||||
|
||||
return po;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,269 @@
|
|||
package com.ruoyi.ss.bonus.service.impl;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.ruoyi.common.core.domain.model.LoginUser;
|
||||
import com.ruoyi.common.domain.vo.CommonCountVO;
|
||||
import com.ruoyi.common.domain.vo.CommonSumVO;
|
||||
import com.ruoyi.common.enums.LoginType;
|
||||
import com.ruoyi.common.utils.DateUtils;
|
||||
import com.ruoyi.common.utils.SecurityUtils;
|
||||
import com.ruoyi.common.utils.ServiceUtil;
|
||||
import com.ruoyi.common.utils.collection.CollectionUtils;
|
||||
import com.ruoyi.ss.bonus.domain.BonusProvideQuery;
|
||||
import com.ruoyi.ss.bonus.domain.enums.BonusArrivalType;
|
||||
import com.ruoyi.ss.bonus.domain.enums.BonusStatus;
|
||||
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.recordBalance.domain.enums.RecordBalanceBstType;
|
||||
import com.ruoyi.ss.store.service.StoreService;
|
||||
import com.ruoyi.ss.user.service.ISmUserService;
|
||||
import com.ruoyi.system.service.ISysDeptService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import com.ruoyi.ss.bonus.mapper.BonusMapper;
|
||||
import com.ruoyi.ss.bonus.domain.Bonus;
|
||||
import com.ruoyi.ss.bonus.domain.BonusVO;
|
||||
import com.ruoyi.ss.bonus.domain.BonusQuery;
|
||||
import com.ruoyi.ss.bonus.service.BonusService;
|
||||
import org.springframework.transaction.support.TransactionTemplate;
|
||||
|
||||
/**
|
||||
* 分成明细Service业务层处理
|
||||
*
|
||||
* @author ruoyi
|
||||
* @date 2024-08-20
|
||||
*/
|
||||
@Service
|
||||
public class BonusServiceImpl implements BonusService
|
||||
{
|
||||
@Autowired
|
||||
private BonusMapper bonusMapper;
|
||||
|
||||
@Autowired
|
||||
private TransactionTemplate transactionTemplate;
|
||||
|
||||
@Autowired
|
||||
private ISmUserService userService;
|
||||
|
||||
@Autowired
|
||||
private ISysDeptService deptService;
|
||||
|
||||
@Autowired
|
||||
private StoreService storeService;
|
||||
|
||||
/**
|
||||
* 查询分成明细
|
||||
*
|
||||
* @param id 分成明细主键
|
||||
* @return 分成明细
|
||||
*/
|
||||
@Override
|
||||
public BonusVO selectBonusById(Long id)
|
||||
{
|
||||
return bonusMapper.selectBonusById(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询分成明细列表
|
||||
*
|
||||
* @param bonus 分成明细
|
||||
* @return 分成明细
|
||||
*/
|
||||
@Override
|
||||
public List<BonusVO> selectBonusList(BonusQuery bonus)
|
||||
{
|
||||
return bonusMapper.selectBonusList(bonus);
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增分成明细
|
||||
*
|
||||
* @param bonus 分成明细
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int insertBonus(Bonus bonus)
|
||||
{
|
||||
this.buildBeforeCreate(bonus);
|
||||
return bonusMapper.insertBonus(bonus);
|
||||
}
|
||||
|
||||
// 补全新增前的数据
|
||||
private void buildBeforeCreate(Bonus bonus) {
|
||||
bonus.setCreateTime(DateUtils.getNowDate());
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改分成明细
|
||||
*
|
||||
* @param bonus 分成明细
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int updateBonus(Bonus bonus)
|
||||
{
|
||||
return bonusMapper.updateBonus(bonus);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除分成明细
|
||||
*
|
||||
* @param ids 需要删除的分成明细主键
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int deleteBonusByIds(Long[] ids)
|
||||
{
|
||||
return bonusMapper.deleteBonusByIds(ids);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除分成明细信息
|
||||
*
|
||||
* @param id 分成明细主键
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int deleteBonusById(Long id)
|
||||
{
|
||||
return bonusMapper.deleteBonusById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int batchInsert(List<Bonus> bonusList) {
|
||||
if (CollectionUtils.isEmptyElement(bonusList)) {
|
||||
return 0;
|
||||
}
|
||||
for (Bonus bonus : bonusList) {
|
||||
this.buildBeforeCreate(bonus);
|
||||
}
|
||||
return bonusMapper.batchInsert(bonusList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int payBonus(List<BonusVO> bonusList, BigDecimal money) {
|
||||
if (CollectionUtils.isEmptyElement(bonusList)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
BigDecimal decimal100 = new BigDecimal(100);
|
||||
BigDecimal dividedAmount = BigDecimal.ZERO; // 已分配金额
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
|
||||
// 循环遍历,构造分成金额
|
||||
for (BonusVO bonus : bonusList) {
|
||||
BigDecimal amount = money.multiply(bonus.getPoint()).divide(decimal100, 2, RoundingMode.HALF_UP);
|
||||
bonus.setAmount(amount);
|
||||
bonus.setStatus(BonusStatus.DIVIDEND.getStatus());
|
||||
bonus.setPayTime(now);
|
||||
dividedAmount = dividedAmount.add(amount);
|
||||
}
|
||||
// 平台吃掉误差
|
||||
BonusVO platform = bonusList.stream().filter(bonus -> bonus.getArrivalType().equals(BonusArrivalType.PLATFORM.getType())).findFirst().orElse(null);
|
||||
ServiceUtil.assertion(platform == null, "平台不存在");
|
||||
if (dividedAmount.compareTo(money) != 0) {
|
||||
BigDecimal subtract = money.subtract(dividedAmount); // 误差值
|
||||
platform.setAmount(platform.getAmount().add(subtract));
|
||||
}
|
||||
|
||||
Integer result = transactionTemplate.execute(status -> {
|
||||
|
||||
// 循环遍历,添加金额到账户上
|
||||
for (BonusVO bonus : bonusList) {
|
||||
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, "增加账户金额失败");
|
||||
}
|
||||
|
||||
// 批量更新分成金额
|
||||
int updateAmount = this.batchUpdateAmount(bonusList);
|
||||
ServiceUtil.assertion(updateAmount != bonusList.size(), "更新分成金额失败");
|
||||
|
||||
return updateAmount;
|
||||
});
|
||||
|
||||
return result == null ? 0 : result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CommonCountVO<Long>> selectCountByArrival(BonusQuery query) {
|
||||
return bonusMapper.selectCountByArrival(query);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CommonSumVO<Long>> selectBillAmountByArrival(BonusQuery query) {
|
||||
return bonusMapper.selectBillAmountByArrival(query);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ProvideBonusVO> selectProvideBonus(BonusProvideQuery query) {
|
||||
return bonusMapper.selectProvideBonus(query);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int addRefundAmount(Long id, BigDecimal amount) {
|
||||
if (id == null) {
|
||||
return 0;
|
||||
}
|
||||
ServiceUtil.assertion(amount.compareTo(BigDecimal.ZERO) < 0, "退款金额必须大于0");
|
||||
return bonusMapper.addRefundAmount(id, amount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Bonus> List<T> filterBonusScope(List<T> bonusList) {
|
||||
LoginUser loginUser = SecurityUtils.getLoginUser();
|
||||
Long userId = loginUser.getUserId();
|
||||
Long deptId = loginUser.getDeptId();
|
||||
return bonusList.stream().filter(bonus -> {
|
||||
// 前台用户过滤
|
||||
if (LoginType.FRONT.equals(loginUser.getLoginType())) {
|
||||
return BonusArrivalType.userList().contains(bonus.getArrivalType()) && (
|
||||
Arrays.asList(bonus.getAncestors().split(",")).contains(userId.toString())
|
||||
|| bonus.getArrivalId().equals(userId)
|
||||
);
|
||||
}
|
||||
// 后台用户过滤
|
||||
else if (LoginType.ADMIN.equals(loginUser.getLoginType())) {
|
||||
if (BonusArrivalType.userList().contains(bonus.getArrivalType())) {
|
||||
return true;
|
||||
}
|
||||
if (BonusArrivalType.deptList().contains(bonus.getArrivalType())) {
|
||||
return Arrays.asList(bonus.getAncestors().split(",")).contains(deptId.toString())
|
||||
|| bonus.getArrivalId().equals(deptId);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BonusMonthAmountVO> selectMonthAmount(BonusQuery query) {
|
||||
return bonusMapper.selectMonthAmount(query);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BonusDailyAmountVO> selectDailyAmount(BonusQuery query) {
|
||||
return bonusMapper.selectDailyAmount(query);
|
||||
}
|
||||
|
||||
private int batchUpdateAmount(List<BonusVO> list) {
|
||||
if (CollectionUtils.isEmptyElement(list)) {
|
||||
return 0;
|
||||
}
|
||||
return bonusMapper.batchUpdateAmount(list);
|
||||
}
|
||||
}
|
|
@ -199,4 +199,7 @@ public class Device extends BaseEntity
|
|||
@ApiModelProperty("剩余电量(度)")
|
||||
@JsonView(JsonViewProfile.App.class)
|
||||
private BigDecimal surplusEle;
|
||||
|
||||
@ApiModelProperty("上次恢复余额的时间戳")
|
||||
private Long lastRecoverTime;
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import com.ruoyi.ss.device.domain.enums.DevicePowerStatus;
|
|||
import com.ruoyi.ss.device.domain.vo.DeviceVO;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
@ -307,4 +308,15 @@ public interface DeviceService
|
|||
*/
|
||||
int resetEleWithBill(Long deviceId);
|
||||
|
||||
int updateLastRecoverTime(Long deviceId, Long lastRecoverTime);
|
||||
|
||||
/**
|
||||
* 设置时间
|
||||
* @param device 设备
|
||||
* @param expireTime 过期时间
|
||||
* @param withIot 是否操作设备
|
||||
* @param tryCount 尝试次数
|
||||
*/
|
||||
int setTime(DeviceVO device, LocalDateTime expireTime, boolean withIot, int tryCount);
|
||||
|
||||
}
|
||||
|
|
|
@ -540,6 +540,20 @@ public class DeviceServiceImpl implements DeviceService
|
|||
return result == null ? 0 : result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int updateLastRecoverTime(Long deviceId, Long lastRecoverTime) {
|
||||
Device data = new Device();
|
||||
data.setDeviceId(deviceId);
|
||||
data.setLastRecoverTime(lastRecoverTime);
|
||||
return deviceMapper.updateSmDevice(data);
|
||||
}
|
||||
|
||||
// TODO
|
||||
@Override
|
||||
public int setTime(DeviceVO device, LocalDateTime expireTime, boolean withIot, int tryCount) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean addTime(Long deviceId, long seconds, boolean withIot) {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package com.ruoyi.ss.transactionBill.domain.bo;
|
||||
|
||||
import com.ruoyi.ss.bonus.domain.Bonus;
|
||||
import com.ruoyi.ss.channel.domain.ChannelVO;
|
||||
import com.ruoyi.ss.device.domain.vo.DeviceVO;
|
||||
import com.ruoyi.ss.store.domain.StoreVo;
|
||||
|
@ -9,6 +10,8 @@ import com.ruoyi.ss.transactionBill.domain.dto.RechargeDTO;
|
|||
import com.ruoyi.ss.user.domain.SmUserVo;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 设备充值BO
|
||||
* @author wjh
|
||||
|
@ -38,4 +41,7 @@ public class RechargeBO {
|
|||
// 店铺
|
||||
private StoreVo store;
|
||||
|
||||
// 分成详情
|
||||
private List<Bonus> bonusList;
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
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;
|
||||
|
@ -12,7 +13,9 @@ import com.ruoyi.ss.transactionBill.domain.vo.TransactionBillVO;
|
|||
import com.ruoyi.ss.transactionBill.domain.dto.BillRefundDTO;
|
||||
import com.ruoyi.ss.transactionBill.domain.dto.WithdrawApprovalDTO;
|
||||
import com.ruoyi.ss.transactionBill.domain.enums.TransactionBillStatus;
|
||||
import com.ruoyi.ss.transactionBill.domain.vo.UserRechargeServiceVO;
|
||||
import com.ruoyi.ss.transactionBill.domain.vo.UserWithdrawServiceVO;
|
||||
import com.ruoyi.ss.user.domain.SmUserVo;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
|
@ -293,4 +296,9 @@ public interface TransactionBillService
|
|||
* 开启/关闭订单设备
|
||||
*/
|
||||
int switchDevice(TransactionBillVO bill, boolean open);
|
||||
|
||||
/**
|
||||
* 获取商户的充值手续费
|
||||
*/
|
||||
UserRechargeServiceVO getMchRechargeService(ChannelVO channel, SmUserVo mch, DeviceVO device);
|
||||
}
|
||||
|
|
|
@ -62,7 +62,7 @@ public class RechargeDepositAfterPay implements AfterPay {
|
|||
query.setBillId(bill.getBillId());
|
||||
query.setStatus(TransactionBillStatus.UNPAID_DEPOSIT.getStatus());
|
||||
int update = transactionBillService.updateByQuery(data, query);
|
||||
ServiceUtil.assertion(update != 1, "修改订单信息失败,状态已经发生改变");
|
||||
ServiceUtil.assertion(update != 1, "修改订单信息失败,状态已经发生改变:%s", bill.getBillNo());
|
||||
|
||||
try {
|
||||
iotService.open(device.getMac(), device.getModelProductId());
|
||||
|
|
|
@ -272,7 +272,7 @@ public class TransactionBillServiceImpl implements TransactionBillService, After
|
|||
private void handleRechargeService(RechargePayBO bo) {
|
||||
TransactionBillVO order = bo.getOrder();
|
||||
// 获取商户的服务费配置
|
||||
UserRechargeServiceVO userRechargeService = this.getUserRechargeService(bo.getChannel(), bo.getMch(), bo.getDevice());
|
||||
UserRechargeServiceVO userRechargeService = this.getMchRechargeService(bo.getChannel(), bo.getMch(), bo.getDevice());
|
||||
String serviceType = userRechargeService.getServiceType(); // 服务费类型
|
||||
BigDecimal serviceRate = userRechargeService.getServiceRate(); // 服务费
|
||||
|
||||
|
@ -313,7 +313,8 @@ public class TransactionBillServiceImpl implements TransactionBillService, After
|
|||
|
||||
}
|
||||
|
||||
private UserRechargeServiceVO getUserRechargeService(ChannelVO channel, SmUserVo mch, DeviceVO device) {
|
||||
@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());
|
||||
|
@ -973,14 +974,14 @@ public class TransactionBillServiceImpl implements TransactionBillService, After
|
|||
data.setSuitEndEle(totalEle);
|
||||
TransactionBillQuery query = new TransactionBillQuery();
|
||||
query.setBillId(order.getBillId());
|
||||
|
||||
query.setStatus(TransactionBillStatus.SUCCESS.getStatus());
|
||||
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, "修改订单信息失败");
|
||||
ServiceUtil.assertion(update != 1, "修改订单信息失败,请重试:%s", order.getBillNo());
|
||||
|
||||
// 若金额 > 0.01 则申请退款
|
||||
if (BigDecimal.valueOf(0.01).compareTo(refundAmount) < 0) {
|
||||
|
@ -1069,13 +1070,14 @@ public class TransactionBillServiceImpl implements TransactionBillService, After
|
|||
data.setSuitEndEle(totalEle);
|
||||
TransactionBillQuery query = new TransactionBillQuery();
|
||||
query.setBillId(order.getBillId());
|
||||
query.setStatus(TransactionBillStatus.SUCCESS.getStatus());
|
||||
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, "修改订单信息失败");
|
||||
ServiceUtil.assertion(update != 1, "修改订单信息失败,请重试:%s", order.getBillNo());
|
||||
|
||||
return update;
|
||||
});
|
||||
|
@ -1439,7 +1441,7 @@ public class TransactionBillServiceImpl implements TransactionBillService, After
|
|||
billQuery.setBillId(dto.getBillId());
|
||||
billQuery.setStatus(TransactionBillStatus.SUCCESS.getStatus());
|
||||
int updateBill = this.updateByQuery(data, billQuery);
|
||||
ServiceUtil.assertion(updateBill != 1, "修改订单状态失败");
|
||||
ServiceUtil.assertion(updateBill != 1, "退款时修改订单状态失败,订单状态已发生改变,请刷新后重试");
|
||||
|
||||
// 商户余额按照比例扣减
|
||||
// 按比例计算退款金额
|
||||
|
@ -1600,10 +1602,25 @@ public class TransactionBillServiceImpl implements TransactionBillService, After
|
|||
ServiceUtil.assertion(StringUtils.isBlank(device.getMac()), "设备MAC为空,请联系管理员处理");
|
||||
|
||||
if (open) {
|
||||
return iotService.open(device.getMac(), device.getModelProductId()) ? 1 : 0;
|
||||
if (SuitFeeType.timingList().contains(bill.getSuitFeeType())) {
|
||||
return iotService.open(device.getMac(), device.getModelProductId()) ? 1 : 0;
|
||||
} else {
|
||||
// 计算设备剩余时长
|
||||
LocalDateTime expireTime = device.getExpireTime();
|
||||
if (expireTime == null) {
|
||||
return 0;
|
||||
}
|
||||
Duration between = Duration.between(LocalDateTime.now(), expireTime);
|
||||
if (between.getSeconds() > 0) {
|
||||
CommandResponse res = iotService.setTime(device.getMac(), between.getSeconds(), device.getModelProductId());
|
||||
return res.isSuccess() ? 1 : 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return iotService.close(device.getMac(), device.getModelProductId()) ? 1 : 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -39,4 +39,8 @@ public class SmUserVo extends SmUser {
|
|||
@ApiModelProperty("商户店铺数量")
|
||||
@JsonView(JsonViewProfile.App.class)
|
||||
private Integer storeCount;
|
||||
|
||||
@ApiModelProperty("实名或用户名")
|
||||
private String realOrUserName;
|
||||
|
||||
}
|
||||
|
|
|
@ -45,6 +45,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
su.real_id_card,
|
||||
su.real_phone,
|
||||
su.is_real,
|
||||
if(su.is_real, su.real_name, su.user_name) as real_or_user_name,
|
||||
(select sum(stb.money) from sm_transaction_bill stb where stb.user_id = su.user_id and stb.type = '1' and stb.status = '2') as recharge_amount,
|
||||
(select sum(stb.arrival_amount) from sm_transaction_bill stb where stb.user_id = su.user_id and stb.type = '2' and stb.status = '14') as with_drawl_amount,
|
||||
(select sum(stb.arrival_amount) from sm_transaction_bill stb where stb.mch_id = su.user_id and stb.type = '1' and stb.status = '2') as total_income
|
||||
|
|
|
@ -109,7 +109,7 @@ public interface ISmUserService
|
|||
* @param bstType
|
||||
* @param bstId
|
||||
*/
|
||||
void addBalance(Long userId, BigDecimal amount, String reason, RecordBalanceBstType bstType, Long bstId);
|
||||
int addBalance(Long userId, BigDecimal amount, String reason, RecordBalanceBstType bstType, Long bstId);
|
||||
|
||||
/**
|
||||
* 减少余额
|
||||
|
|
|
@ -128,7 +128,7 @@ public class SmUserServiceImpl implements ISmUserService
|
|||
|
||||
@Override
|
||||
@Transactional
|
||||
public void addBalance(Long userId, BigDecimal amount, String reason, RecordBalanceBstType bstType, Long bstId) {
|
||||
public int addBalance(Long userId, BigDecimal amount, String reason, RecordBalanceBstType bstType, Long bstId) {
|
||||
ServiceUtil.assertion(BigDecimal.ZERO.compareTo(amount) > 0, "增加的金额需要大于0");
|
||||
|
||||
// 查询用户
|
||||
|
@ -141,6 +141,8 @@ public class SmUserServiceImpl implements ISmUserService
|
|||
// 余额变动记录
|
||||
int record = recordBalanceService.record(userId, user.getBalance(), amount, reason, bstType, bstId);
|
||||
ServiceUtil.assertion(record != 1, "用户余额变动记录失败");
|
||||
|
||||
return updateCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
Loading…
Reference in New Issue
Block a user