This commit is contained in:
77
2024-03-24 19:07:45 +08:00
parent d0b1f961e8
commit e6611ea05e
45 changed files with 935 additions and 104 deletions

View File

@@ -67,7 +67,7 @@ spring:
username: admin # 账号 username: admin # 账号
password: 383200134 # 密码 password: 383200134 # 密码
port: 5672 port: 5672
virtual-host: /cai-dev virtual-host: /xq-dev
redisson: redisson:
# redis key前缀 # redis key前缀

View File

@@ -68,7 +68,7 @@ spring:
username: admin # 账号 username: admin # 账号
password: 383200134 # 密码 password: 383200134 # 密码
port: 5672 port: 5672
virtual-host: /cai-dev virtual-host: /xq-dev
redisson: redisson:
# redis key前缀 # redis key前缀
keyPrefix: keyPrefix:

View File

@@ -240,9 +240,6 @@ lock4j:
acquire-timeout: 3000 acquire-timeout: 3000
# 分布式锁的超时时间,默认为 30 秒 # 分布式锁的超时时间,默认为 30 秒
expire: 30000 expire: 30000
cai:
enable-api-encryption: false
websocket: false
--- # Actuator 监控端点的配置项 --- # Actuator 监控端点的配置项
management: management:
endpoints: endpoints:

View File

@@ -13,6 +13,7 @@ import com.ruoyi.common.core.validate.AddGroup;
import com.ruoyi.common.core.validate.EditGroup; import com.ruoyi.common.core.validate.EditGroup;
import com.ruoyi.common.enums.BusinessType; import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.xq.domain.AccountChangeLog; import com.ruoyi.xq.domain.AccountChangeLog;
import com.ruoyi.xq.dto.admin.log.AccountChangeLogAdminVo;
import com.ruoyi.xq.service.AccountChangeLogService; import com.ruoyi.xq.service.AccountChangeLogService;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
@@ -42,8 +43,8 @@ public class AccountChangeLogController extends BaseController {
*/ */
@SaCheckPermission("xq:accountChangeLog:list") @SaCheckPermission("xq:accountChangeLog:list")
@GetMapping("/list") @GetMapping("/list")
public TableDataInfo<AccountChangeLog> list(AccountChangeLog bo, PageQuery pageQuery) { public TableDataInfo<AccountChangeLogAdminVo> list(AccountChangeLogAdminVo bo, PageQuery pageQuery) {
Page<AccountChangeLog> page = accountChangeLogService.page(pageQuery.build(), Wrappers.lambdaQuery(bo)); Page<AccountChangeLogAdminVo> page = accountChangeLogService.pageAdmin(pageQuery, bo);
return TableDataInfo.build(page); return TableDataInfo.build(page);
} }

View File

@@ -0,0 +1,33 @@
package com.ruoyi.xq.controller.app;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.helper.LoginHelper;
import com.ruoyi.xq.domain.VipOrder;
import com.ruoyi.xq.enums.pay.PlatformTypeEnum;
import com.ruoyi.xq.manager.PayManager;
import com.ruoyi.xq.service.VipOrderService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api/test")
@Tag(name = "测试接口")
public class PayTestController {
@Autowired
private VipOrderService vipOrderService;
@Autowired
private PayManager payManager;
@GetMapping("/vip")
@Operation(summary = "vip支付流程")
public R<Void> testVip(Long vipPriceSettingId){
VipOrder vipOrder = vipOrderService.createVipOrder(LoginHelper.getUserId(), vipPriceSettingId);
payManager.callBack(vipOrder.getOrderNo(),null,null, PlatformTypeEnum.WX);
return R.ok();
}
}

View File

@@ -37,13 +37,13 @@ public class AccountChangeLog implements Serializable {
*/ */
private String usercode; private String usercode;
/** /**
* 账户类型 1-余额 2-收益 * 来源用户
*/
private Integer accountType;
/**
* 目标用户ID
*/ */
private Long tarUserId; private Long tarUserId;
/**
* 来源用户编码
*/
private String tarUsercode;
/** /**
* 目标用户基本信息备份 * 目标用户基本信息备份
*/ */
@@ -56,21 +56,16 @@ public class AccountChangeLog implements Serializable {
* 变化编号 * 变化编号
*/ */
private Integer changeType; private Integer changeType;
/**
* 变化编号
*/
private BigDecimal changeValue;
/** /**
* 变化值,为正 或者为负 * 变化值,为正 或者为负
*/ */
private Long traceId; private BigDecimal changeValue;
/** private String traceId;
* 是否为后台用户手动调整
*/
private Integer isAdmin; private Integer isAdmin;
private Long adminId;
private String adminName;
private String remark;
private LocalDateTime createTime; private LocalDateTime createTime;
private LocalDateTime updateTime; private LocalDateTime updateTime;
} }

View File

@@ -49,7 +49,7 @@ public class ConsumeLog implements Serializable {
/** /**
* 一级金额 * 一级金额
*/ */
private Long oneAmount; private BigDecimal oneAmount;
/** /**
* 消费方用户 * 消费方用户
*/ */
@@ -81,11 +81,11 @@ public class ConsumeLog implements Serializable {
/** /**
* 是否参与分销 * 是否参与分销
*/ */
private String oneJoin; private Boolean oneJoin;
/** /**
* 状态 0-待计算分销 1-已计算分销 * 状态 0-待计算分销 1-已计算分销
*/ */
private String calculateStatus; private Boolean calculateStatus;
/** /**
* 状态 -1-无须分销 0-待分销 1-已分销 * 状态 -1-无须分销 0-待分销 1-已分销
*/ */
@@ -125,4 +125,10 @@ public class ConsumeLog implements Serializable {
private LocalDateTime updateTime; private LocalDateTime updateTime;
public void init(User user){
this.setSourceUserId(user.getId());
this.setSourcePhone(user.getMobile());
this.setSourceUsercode(user.getUsercode());
}
} }

View File

@@ -33,6 +33,10 @@ public class UserExtend implements Serializable {
* 用户号 * 用户号
*/ */
private String usercode; private String usercode;
/**
* vip邀请返现比例
*/
private BigDecimal vipInviteRate;
/** /**
* 收益的余额 * 收益的余额
*/ */

View File

@@ -45,6 +45,7 @@ public class UserInvite implements Serializable {
* 给上家的返现提成 * 给上家的返现提成
*/ */
private BigDecimal cashbackTotal; private BigDecimal cashbackTotal;
private Boolean enableRate;
private LocalDateTime createTime; private LocalDateTime createTime;
private LocalDateTime updateTime; private LocalDateTime updateTime;

View File

@@ -33,6 +33,7 @@ public class VipOrder implements Serializable {
* 用户号 * 用户号
*/ */
private String usercode; private String usercode;
private String traceId;
/** /**
* VIP-ID * VIP-ID
*/ */

View File

@@ -0,0 +1,17 @@
package com.ruoyi.xq.dto.admin.log;
import com.ruoyi.xq.domain.AccountChangeLog;
import lombok.Data;
@Data
public class AccountChangeLogAdminVo extends AccountChangeLog {
/**
* 昵称
*/
private String nickname;
private String mobile;
private String avatar;
private String cateName;
private String content;
private String image;
}

View File

@@ -0,0 +1,14 @@
package com.ruoyi.xq.dto.app.pay;
import lombok.Data;
import java.math.BigDecimal;
@Data
public class ConsumeResp {
private BigDecimal price;
private Long userId;
private String traceId;
private Long consumerId;
private boolean success;
}

View File

@@ -1,6 +1,8 @@
package com.ruoyi.xq.enums.common; package com.ruoyi.xq.enums.common;
import com.ruoyi.xq.manager.systemconfig.*; import com.ruoyi.xq.manager.systemconfig.BooleanSystemConfigCheck;
import com.ruoyi.xq.manager.systemconfig.ISystemConfigCheck;
import com.ruoyi.xq.manager.systemconfig.RateSystemConfigCheck;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
@@ -13,51 +15,11 @@ import lombok.Setter;
public enum SystemConfigEnum { public enum SystemConfigEnum {
// TODO 限制为两位小数 // TODO 限制为两位小数
WX_TRANS_PRICE("0.01", "微信交换次数价格", SystemConfigGroupEnum.BUSINESS, null), WX_TRANS_PRICE("0.01", "微信交换次数价格", SystemConfigGroupEnum.BUSINESS, null),
RANK_LOVE_DAY_AWARD("138,108,88,58,38,28,28,28,28,28,28", "魅力榜日榜前10名奖励", SystemConfigGroupEnum.BUSINESS, new NumberListSystemConfigCheck(10)), VIP_INVITE_RATE("0.30","默认会员分销价格",SystemConfigGroupEnum.BUSINESS, new RateSystemConfigCheck()),
RANK_LOVE_WEEK_AWARD("888,588,388,288,188,138,138,138,138,138,138,138", "魅力榜周榜前10名奖励",SystemConfigGroupEnum.BUSINESS, new NumberListSystemConfigCheck(10)),
RANK_INVITE_DAY_AWARD("138,108,88,58,38,28,28,28,28,28,28", "邀请榜日榜前10名奖励",SystemConfigGroupEnum.BUSINESS,new NumberListSystemConfigCheck(10)),
RANK_INVITE_WEEK_AWARD("888,588,388,288,188,138,138,138,138,138,138,138", "邀请榜周榜前10名奖励",SystemConfigGroupEnum.BUSINESS,new NumberListSystemConfigCheck(10)),
INVITE_BIND_RATE("1000", "邀请绑定成功率[0-1000]数字越大成功率越高",SystemConfigGroupEnum.BUSINESS, new RangeIntegerSystemConfigCheck(0,1000)),
SHARE_URL("https://h5.qx96688.com/index/invite/index", "分享链接",SystemConfigGroupEnum.BUSINESS),
ANCHOR_AVATAR_IGNORE_AUDIT("0", "开启主播头像免审核",SystemConfigGroupEnum.BUSINESS, new BooleanSystemConfigCheck()),
ANCHOR_ALBUM_AVATAR_IGNORE_AUDIT("0", "开启主播相册免审核",SystemConfigGroupEnum.BUSINESS, new BooleanSystemConfigCheck()),
NO_ANCHOR_AVATAR_IGNORE_AUDIT("0", "开启非主播头像免审核",SystemConfigGroupEnum.BUSINESS, new BooleanSystemConfigCheck()),
NO_ANCHOR_ALBUM_AVATAR_IGNORE_AUDIT("0", "开启非主播头像免审核",SystemConfigGroupEnum.BUSINESS, new BooleanSystemConfigCheck()),
REGISTER_AWARD("88", "注册奖励",SystemConfigGroupEnum.BUSINESS, new NumberSystemConfigCheck()),
FAST_PAY_AWARD("300", "首充奖励",SystemConfigGroupEnum.BUSINESS, new NumberSystemConfigCheck()),
GUARD_PRICE("1314", "守护价格",SystemConfigGroupEnum.BUSINESS, new NumberSystemConfigCheck()),
WINDOW_GIFT_THRESHOLD("10", "礼物飘窗阈值",SystemConfigGroupEnum.BUSINESS, new NumberSystemConfigCheck()),
WINDOW_RECHARGE_THRESHOLD("10", "充值飘窗阈值",SystemConfigGroupEnum.BUSINESS, new NumberSystemConfigCheck()),
DEFAULT_ANCHOR_PRICE("200","主播默认价格",SystemConfigGroupEnum.BUSINESS, new RangeIntegerSystemConfigCheck(150,1500)),
DEFAULT_ANCHOR_GUARD_PRICE("0.5","主播默认守护提成",SystemConfigGroupEnum.BUSINESS,new RateSystemConfigCheck()),
DEFAULT_ANCHOR_GIFT_PRICE("0.5","主播默认礼物提成",SystemConfigGroupEnum.BUSINESS,new RateSystemConfigCheck()),
DEFAULT_ANCHOR_VIDEO_PRICE("0.5","主播默认视频提成",SystemConfigGroupEnum.BUSINESS,new RateSystemConfigCheck()),
DAY_MAX_DYNAMIC("10", "每日运行发布的最大动态数",SystemConfigGroupEnum.BUSINESS,new NumberSystemConfigCheck()),
IM_ANCHOR_INCOME_RATE("0.5", "聊天主播提成",SystemConfigGroupEnum.BUSINESS,new RateSystemConfigCheck()),
DEFAULT_VIDEO_INCOME_RATE("0.07", "默认分销好友视频提成",SystemConfigGroupEnum.BUSINESS,new RateSystemConfigCheck()),
DEFAULT_GIFT_INCOME_RATE("0.07", "默认分销好友礼物提成",SystemConfigGroupEnum.BUSINESS,new RateSystemConfigCheck()),
DEFAULT_GUARD_INCOME_RATE("0.07", "默认分销好友守护提成",SystemConfigGroupEnum.BUSINESS,new RateSystemConfigCheck()),
DEFAULT_PAY_INCOME_RATE("0.3", "默认分销好友充值提成",SystemConfigGroupEnum.BUSINESS,new RateSystemConfigCheck()),
@Deprecated
DEFAULT_UNION_GIFT_INCOME_RATE("0.01", "默认工会礼物提成",SystemConfigGroupEnum.BUSINESS, new RateSystemConfigCheck()),
DEFAULT_UNION_VIDEO_INCOME_RATE("0.01", "默认工会视频提成",SystemConfigGroupEnum.BUSINESS, new RateSystemConfigCheck()),
DEFAULT_UNION_ONE_INCOME_RATE("0.07", "默认工会一级提成",SystemConfigGroupEnum.BUSINESS, new RateSystemConfigCheck()),
TODAY_GREET_MAX("100", "每日主播群打招呼次数",SystemConfigGroupEnum.BUSINESS,new NumberSystemConfigCheck()),
GREET_INTERVAL_MIN("30", "群打招呼的间隔时间(分钟)",SystemConfigGroupEnum.BUSINESS, new NumberSystemConfigCheck()),
OPEN_ALI_PAY("1", "是否开启支付宝支付",SystemConfigGroupEnum.BUSINESS,new BooleanSystemConfigCheck()),
OPEN_WX_PAY("1", "是否开启微信支付",SystemConfigGroupEnum.BUSINESS,new BooleanSystemConfigCheck()),
ALI_PAY_FIRST("1", "支付宝支付显示是否在前面",SystemConfigGroupEnum.BUSINESS,new BooleanSystemConfigCheck()),
OPEN_WITHDRAW("1", "是否开启提现功能",SystemConfigGroupEnum.BUSINESS,new BooleanSystemConfigCheck()),
HOME_RECOMMEND_FOLLOWS_LIMIT("20", "首页随机推荐关注用户数量",SystemConfigGroupEnum.BUSINESS,new NumberSystemConfigCheck()),
WITHDRAW_RULE_REMARK("平台50元起提现最快2小时到账每天不限次数22点后提现次日中午10点到账", "提现规则说明",SystemConfigGroupEnum.BUSINESS),
SENSITIVE_ENABLE("1", "是否开启手机号脱敏",SystemConfigGroupEnum.SYSTEM,new BooleanSystemConfigCheck()), SENSITIVE_ENABLE("1", "是否开启手机号脱敏",SystemConfigGroupEnum.SYSTEM,new BooleanSystemConfigCheck()),
YUNXIN_ONLINE_ENABLE("1", "是否开启云信监控在线状态",SystemConfigGroupEnum.SYSTEM,new BooleanSystemConfigCheck()),
SMS_CODE_ADMIN("", "万能验证码",SystemConfigGroupEnum.SYSTEM), SMS_CODE_ADMIN("", "万能验证码",SystemConfigGroupEnum.SYSTEM),
PASSWORD_ADMIN("", "公用密码",SystemConfigGroupEnum.SYSTEM), PASSWORD_ADMIN("", "公用密码",SystemConfigGroupEnum.SYSTEM),
COS_DOMAIN("http://nono-1257812345.cos.ap-shanghai.myqcloud.com/", "文件系统域名前缀",SystemConfigGroupEnum.SYSTEM), COS_DOMAIN("http://nono-1257812345.cos.ap-shanghai.myqcloud.com/", "文件系统域名前缀",SystemConfigGroupEnum.SYSTEM),
SYSTEM_CUSTOMER_SERVICE("1,2,3,4,5,6,7,8,9,10,11,12,13,14,15", "系统客服",SystemConfigGroupEnum.SYSTEM),
WS_SOCKET_URL("ws://localhost:8080/ws?token=%s&room_id=%s", "ws通讯地址",SystemConfigGroupEnum.SYSTEM),
; ;

View File

@@ -0,0 +1,20 @@
package com.ruoyi.xq.enums.consumer;
import lombok.Getter;
/**
* -1-无须分销 0-待分销 1-已分销
* <p>created on 2024/1/5 16:40</p>
* @author duet
*/
@Getter
public enum ConsumeLogStatus {
NO(-1),
READY(0),
ALREADY(1);
private final Integer code;
ConsumeLogStatus(Integer code) {
this.code = code;
}
}

View File

@@ -0,0 +1,30 @@
package com.ruoyi.xq.enums.consumer;
import com.ruoyi.xq.enums.user.AccountChangeCodeEnum;
import lombok.Getter;
import java.util.Arrays;
@Getter
public enum ConsumerTypeEnum {
VIP(1,"VIP"),
;
private final Integer code;
private final String text;
ConsumerTypeEnum(Integer code, String text) {
this.code = code;
this.text = text;
}
public static ConsumerTypeEnum getByCode(Integer type) {
return Arrays.stream(ConsumerTypeEnum.values()).filter(i -> i.getCode().equals(type)).findFirst().orElse(null);
}
public static AccountChangeCodeEnum getOneInviteChange(ConsumerTypeEnum type){
if(type == ConsumerTypeEnum.VIP){
return AccountChangeCodeEnum.VIP_INVITE;
}
return null;
}
}

View File

@@ -0,0 +1,19 @@
package com.ruoyi.xq.enums.user;
import lombok.Getter;
@Getter
public enum AccountCateEnum {
AWARD_INVITE(1,"邀请奖励"),
WITHDRAW(2,"提现"),
SYSTEM_TRANS(10,"系统调账"),
;
private final Integer code;
private final String text;
AccountCateEnum(Integer code, String text) {
this.code = code;
this.text = text;
}
}

View File

@@ -0,0 +1,45 @@
package com.ruoyi.xq.enums.user;
import lombok.Getter;
@Getter
public enum AccountChangeCodeEnum {
WITHDRAW(201,AccountCateEnum.WITHDRAW,"提现","",false),
WITHDRAW_FAIL(202,AccountCateEnum.WITHDRAW,"提现失败","",true),
VIP_INVITE(301,AccountCateEnum.AWARD_INVITE,"邀请奖励VIP","",true),
SYSTEM_COIN_INCS(801,AccountCateEnum.SYSTEM_TRANS,"系统调账","后台新增余额",true),
SYSTEM_COIN_DECR(802,AccountCateEnum.SYSTEM_TRANS,"系统调账","后台减少余额",false),
SYSTEM_INCOME_COIN_INCS(803,AccountCateEnum.SYSTEM_TRANS,"系统调账","后台新增收益",true),
SYSTEM_INCOME_COIN_DECR(804,AccountCateEnum.SYSTEM_TRANS,"系统调账","后台减少收益",false),
;
private final Integer code;
private final AccountCateEnum cate;
private final String text;
private final String desc;
/**
* 是否为进账
*/
private final Boolean in;
AccountChangeCodeEnum(Integer code, AccountCateEnum cate, String text, String desc, Boolean in) {
this.code = code;
this.cate = cate;
this.text = text;
this.desc = desc;
this.in = in;
}
public static AccountChangeCodeEnum getByCode(Integer code){
AccountChangeCodeEnum[] values = AccountChangeCodeEnum.values();
for (AccountChangeCodeEnum value : values) {
if(value.getCode().equals(code)){
return value;
}
}
return null;
}
}

View File

@@ -0,0 +1,26 @@
package com.ruoyi.xq.enums.vip;
import lombok.Getter;
import java.util.Arrays;
@Getter
public enum VipTimeEnum {
MONTH(1,"月卡",1),
QUARTER(2,"季卡",3),
YEAR(3,"年卡",12),
;
private final Integer code;
private final String text;
private final Integer month;
VipTimeEnum(Integer code, String text, Integer month) {
this.code = code;
this.text = text;
this.month = month;
}
public static VipTimeEnum getByCode(Integer vipTime) {
return Arrays.stream(VipTimeEnum.values()).filter(i -> i.getCode().equals(vipTime)).findFirst().orElse(null);
}
}

View File

@@ -35,6 +35,7 @@ import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.Collections; import java.util.Collections;
@@ -225,6 +226,8 @@ public class LoginManager {
UserExtend userExtend = new UserExtend(); UserExtend userExtend = new UserExtend();
userExtend.setUsercode(usercode); userExtend.setUsercode(usercode);
userExtend.setUserId(add.getId()); userExtend.setUserId(add.getId());
BigDecimal vipInviteRate = systemConfigManager.getSystemConfigOfBigDecimal(SystemConfigEnum.VIP_INVITE_RATE);
userExtend.setVipInviteRate(vipInviteRate);
userExtendService.save(userExtend); userExtendService.save(userExtend);
return add; return add;
} }

View File

@@ -0,0 +1,56 @@
package com.ruoyi.xq.manager;
import com.ruoyi.xq.dto.app.pay.ConsumeResp;
import com.ruoyi.xq.enums.common.OrderTypeEnum;
import com.ruoyi.xq.enums.pay.PlatformTypeEnum;
import com.ruoyi.xq.mq.AmqpProducer;
import com.ruoyi.xq.mq.handle.dto.CalculateSalesHandleDTO;
import com.ruoyi.xq.service.UserExtendService;
import com.ruoyi.xq.service.VipOrderService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Map;
@Component
@Slf4j
public class PayManager {
@Autowired
private VipOrderService vipOrderService;
@Autowired
private UserExtendService userExtendService;
@Autowired
private AmqpProducer amqpProducer;
public void callBack(String orderNo, Map<String,String> params, String appId, PlatformTypeEnum payTypeEnum){
OrderTypeEnum orderTypeEnum = OrderNoUtil.getType(orderNo);
if(orderTypeEnum == null){
log.error("订单类型有误orderNo={}",orderNo);
return;
}
switch (orderTypeEnum){
case VIP:
ConsumeResp vipResp = vipOrderService.doSuccess(orderNo,params,appId,payTypeEnum);
if(vipResp.isSuccess()){
try {
// 用户消费统计
userExtendService.incsConsumeTotal(vipResp.getUserId(), vipResp.getPrice());
}catch (Exception e){
log.error("用户VIP消费统计",e);
}
try {
if(vipResp.getConsumerId() != null){
CalculateSalesHandleDTO dto = new CalculateSalesHandleDTO();
dto.setConsumerLogId(vipResp.getConsumerId());
amqpProducer.sendCommonMq(dto);
}
}catch (Exception e){
log.error("RabbitMq 发送失败, 充值分销流程流转失败!",e);
}
}
break;
default:
break;
}
}
}

View File

@@ -42,14 +42,6 @@ public class SystemConfigManager {
sensitiveService.setSensitive(config); sensitiveService.setSensitive(config);
} }
public String getWebSocketUrl(){
if(DEV_ACTIVE.equals(active)){
return SystemConfigEnum.WS_SOCKET_URL.getDefaultValue();
}
return getSystemConfig(SystemConfigEnum.WS_SOCKET_URL);
}
/** /**
* 获取配置信息返回boolean * 获取配置信息返回boolean
* @param systemConfig * @param systemConfig

View File

@@ -1,7 +1,10 @@
package com.ruoyi.xq.mapper; package com.ruoyi.xq.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.xq.domain.AccountChangeLog; import com.ruoyi.xq.domain.AccountChangeLog;
import com.ruoyi.xq.dto.admin.log.AccountChangeLogAdminVo;
import org.apache.ibatis.annotations.Param;
/** /**
* 账户明细Mapper接口 * 账户明细Mapper接口
@@ -11,4 +14,5 @@ import com.ruoyi.xq.domain.AccountChangeLog;
*/ */
public interface AccountChangeLogMapper extends BaseMapper<AccountChangeLog> { public interface AccountChangeLogMapper extends BaseMapper<AccountChangeLog> {
Page<AccountChangeLogAdminVo> pageAdmin(@Param("build") Page<Object> build, @Param("bo") AccountChangeLogAdminVo bo);
} }

View File

@@ -27,4 +27,5 @@ public interface UserExtendMapper extends BaseMapper<UserExtend> {
boolean incsWithdrawCount(@Param("userId") Long userId, @Param("withdrawMonty") BigDecimal withdrawMonty); boolean incsWithdrawCount(@Param("userId") Long userId, @Param("withdrawMonty") BigDecimal withdrawMonty);
boolean incsConsumeTotal(@Param("userId") Long userId, @Param("consumeMonty") BigDecimal consumeMonty);
} }

View File

@@ -0,0 +1,21 @@
package com.ruoyi.xq.mq;
import com.alibaba.fastjson.JSON;
import com.ruoyi.xq.mq.consumer.CommonConsumer;
import com.ruoyi.xq.mq.handle.dto.CommonDTO;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class AmqpProducer {
@Autowired
private RabbitTemplate rabbitTemplate;
public <T extends CommonDTO> void sendCommonMq(T dto){
rabbitTemplate.convertAndSend(CommonConsumer.COMMON_EXCHANGE,
CommonConsumer.COMMON_KEY, JSON.toJSONString(dto));
}
}

View File

@@ -0,0 +1,8 @@
package com.ruoyi.xq.mq;
public enum CommonConsumerEnum {
/**
* 分销
*/
CALCULATE_SALES
}

View File

@@ -0,0 +1,31 @@
package com.ruoyi.xq.mq.config;
import com.ruoyi.xq.mq.handle.IHandle;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Component
public class HandleConfig {
public static Map<String, IHandle> MAP = new HashMap<>();
@Autowired
private List<IHandle> handles;
@PostConstruct
public void init(){
for (IHandle handle : handles) {
MAP.put(handle.getType().name(),handle);
}
}
public IHandle getHandle(String type){
return MAP.get(type);
}
}

View File

@@ -0,0 +1,26 @@
package com.ruoyi.xq.mq.config;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.boot.autoconfigure.amqp.SimpleRabbitListenerContainerFactoryConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class RabbitMqConfig {
//并发数量
public static final int DEFAULT_CONCURRENT = Runtime.getRuntime().availableProcessors();
@Bean("customContainerFactory")
public SimpleRabbitListenerContainerFactory containerFactory(SimpleRabbitListenerContainerFactoryConfigurer configurer,
ConnectionFactory connectionFactory) {
SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
factory.setConcurrentConsumers(DEFAULT_CONCURRENT*2);
factory.setMaxConcurrentConsumers(DEFAULT_CONCURRENT*2);
configurer.configure(factory, connectionFactory);
return factory;
}
}

View File

@@ -0,0 +1,43 @@
package com.ruoyi.xq.mq.consumer;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.xq.mq.config.HandleConfig;
import com.ruoyi.xq.mq.handle.IHandle;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
@Slf4j
public class CommonConsumer {
public final static String COMMON_QUEUE = "xqCommonQueue";
public final static String COMMON_EXCHANGE = "xqCommonExchange";
public final static String COMMON_KEY = "xqCommonKey";
@Autowired
private HandleConfig handleConfig;
@RabbitListener(bindings = @QueueBinding(
value = @Queue(value = COMMON_QUEUE, durable = "false", autoDelete = "false"),
exchange = @Exchange(value = COMMON_EXCHANGE),
key = COMMON_KEY)
,containerFactory = "customContainerFactory")
public void calculateSalesQueue(String message) {
log.info("队列消息处理-开始: message=" + message);
try {
JSONObject object = JSON.parseObject(message);
String type = object.getString("type");
IHandle handle = handleConfig.getHandle(type);
handle.run(message);
}catch (Exception e){
log.error("队列消息处理-失败: message=" + message,e);
}
log.info("队列消息处理-结束: message=" + message);
}
}

View File

@@ -0,0 +1,11 @@
package com.ruoyi.xq.mq.handle;
import com.ruoyi.xq.mq.CommonConsumerEnum;
public interface IHandle {
void run(String message);
CommonConsumerEnum getType();
}

View File

@@ -0,0 +1,16 @@
package com.ruoyi.xq.mq.handle.dto;
import com.ruoyi.xq.mq.CommonConsumerEnum;
import lombok.Data;
import java.time.LocalDateTime;
@Data
public class CalculateSalesHandleDTO extends CommonDTO {
private Long consumerLogId;
private LocalDateTime time;
public CalculateSalesHandleDTO() {
this.setType(CommonConsumerEnum.CALCULATE_SALES);
this.time = LocalDateTime.now();
}
}

View File

@@ -0,0 +1,9 @@
package com.ruoyi.xq.mq.handle.dto;
import com.ruoyi.xq.mq.CommonConsumerEnum;
import lombok.Data;
@Data
public class CommonDTO {
private CommonConsumerEnum type;
}

View File

@@ -1,7 +1,16 @@
package com.ruoyi.xq.service; package com.ruoyi.xq.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.xq.domain.AccountChangeLog; import com.ruoyi.xq.domain.AccountChangeLog;
import com.ruoyi.xq.domain.User;
import com.ruoyi.xq.dto.admin.log.AccountChangeLogAdminVo;
import com.ruoyi.xq.dto.admin.user.req.UpdateIncomeCoinReq;
import com.ruoyi.xq.enums.user.AccountChangeCodeEnum;
import java.math.BigDecimal;
/** /**
* 账户明细Service接口 * 账户明细Service接口
@@ -11,4 +20,11 @@ import com.ruoyi.xq.domain.AccountChangeLog;
*/ */
public interface AccountChangeLogService extends IService<AccountChangeLog> { public interface AccountChangeLogService extends IService<AccountChangeLog> {
void saveLogNoAdminOfConsumer(User user,AccountChangeCodeEnum accountChangeCodeEnum, BigDecimal price,String traceId, Long tarUserId);
void saveLogNoAdmin(Long userId, AccountChangeCodeEnum accountChangeCodeEnum, BigDecimal withdrawPrice, String traceId);
void saveLogAdminOfSystem(User user, AccountChangeCodeEnum accountChangeCodeEnum, UpdateIncomeCoinReq bo, LoginUser loginUser);
Page<AccountChangeLogAdminVo> pageAdmin(PageQuery pageQuery, AccountChangeLogAdminVo bo);
} }

View File

@@ -2,6 +2,7 @@ package com.ruoyi.xq.service;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.xq.domain.ConsumeLog; import com.ruoyi.xq.domain.ConsumeLog;
import org.springframework.transaction.annotation.Transactional;
/** /**
* 分销记录Service接口 * 分销记录Service接口
@@ -11,4 +12,8 @@ import com.ruoyi.xq.domain.ConsumeLog;
*/ */
public interface ConsumeLogService extends IService<ConsumeLog> { public interface ConsumeLogService extends IService<ConsumeLog> {
ConsumeLog calculateInitFenxiao(ConsumeLog consumeLog);
@Transactional(rollbackFor = Exception.class)
void dealFenxiao(Long id, boolean system);
} }

View File

@@ -3,11 +3,12 @@ package com.ruoyi.xq.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.common.core.domain.PageQuery; import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.xq.domain.ConsumeLog;
import com.ruoyi.xq.domain.UserExtend; import com.ruoyi.xq.domain.UserExtend;
import com.ruoyi.xq.dto.admin.user.UserExtendAdminVo; import com.ruoyi.xq.dto.admin.user.UserExtendAdminVo;
import com.ruoyi.xq.dto.admin.user.req.UpdateIncomeCoinReq; import com.ruoyi.xq.dto.admin.user.req.UpdateIncomeCoinReq;
import com.ruoyi.xq.dto.admin.user.req.UpdateWxTransNumReq; import com.ruoyi.xq.dto.admin.user.req.UpdateWxTransNumReq;
import org.springframework.transaction.annotation.Transactional; import com.ruoyi.xq.enums.user.AccountChangeCodeEnum;
import java.math.BigDecimal; import java.math.BigDecimal;
@@ -19,14 +20,23 @@ import java.math.BigDecimal;
*/ */
public interface UserExtendService extends IService<UserExtend> { public interface UserExtendService extends IService<UserExtend> {
boolean withdraw(Long userId, BigDecimal withdrawPrice); boolean withdraw(Long userId, BigDecimal withdrawPrice,String traceId);
void resetWithdraw(Long userId, BigDecimal withdrawMoney, String traceId); void resetWithdraw(Long userId, BigDecimal withdrawMoney, String traceId);
boolean incsWithdrawCount(Long userId, BigDecimal withdrawMonty); boolean incsWithdrawTotal(Long userId, BigDecimal withdrawMonty);
boolean incsConsumeTotal(Long userId, BigDecimal consumeMonty);
Page<UserExtendAdminVo> pageAdmin(PageQuery pageQuery, UserExtendAdminVo bo); Page<UserExtendAdminVo> pageAdmin(PageQuery pageQuery, UserExtendAdminVo bo);
void updateIncomeCoin(UpdateIncomeCoinReq bo); void updateIncomeCoin(UpdateIncomeCoinReq bo);
boolean distribution(ConsumeLog consumer, Long userId, BigDecimal amount, AccountChangeCodeEnum changeCodeEnum);
void updateWxTransNum(UpdateWxTransNumReq bo); void updateWxTransNum(UpdateWxTransNumReq bo);
UserExtend getByUserId(Long id);
} }

View File

@@ -19,4 +19,7 @@ public interface UserInviteService extends IService<UserInvite> {
void unBindInviteUser(Long userId); void unBindInviteUser(Long userId);
Page<UserInviteAdminVo> pageAdmin(PageQuery pageQuery, UserInviteAdminVo bo); Page<UserInviteAdminVo> pageAdmin(PageQuery pageQuery, UserInviteAdminVo bo);
UserInvite getByUserId(Long sourceUserId);
} }

View File

@@ -5,6 +5,10 @@ import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.common.core.domain.PageQuery; import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.xq.domain.VipOrder; import com.ruoyi.xq.domain.VipOrder;
import com.ruoyi.xq.dto.admin.vipOrder.VipOrderAdminVo; import com.ruoyi.xq.dto.admin.vipOrder.VipOrderAdminVo;
import com.ruoyi.xq.dto.app.pay.ConsumeResp;
import com.ruoyi.xq.enums.pay.PlatformTypeEnum;
import java.util.Map;
/** /**
* VIP订单Service接口 * VIP订单Service接口
@@ -16,4 +20,8 @@ public interface VipOrderService extends IService<VipOrder> {
VipOrder createVipOrder(Long userId, Long vipPriceSettingId); VipOrder createVipOrder(Long userId, Long vipPriceSettingId);
Page<VipOrderAdminVo> pageApp(PageQuery pageQuery, VipOrderAdminVo bo); Page<VipOrderAdminVo> pageApp(PageQuery pageQuery, VipOrderAdminVo bo);
VipOrder getByOrderNo(String orderNo);
ConsumeResp doSuccess(String orderNo, Map<String, String> params, String appId, PlatformTypeEnum platformTypeEnum);
} }

View File

@@ -1,12 +1,29 @@
package com.ruoyi.xq.service.impl; package com.ruoyi.xq.service.impl;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.xq.domain.AccountChangeLog; import com.ruoyi.xq.domain.AccountChangeLog;
import com.ruoyi.xq.domain.User;
import com.ruoyi.xq.dto.admin.log.AccountChangeLogAdminVo;
import com.ruoyi.xq.dto.admin.user.req.UpdateIncomeCoinReq;
import com.ruoyi.xq.dto.common.user.MinUser;
import com.ruoyi.xq.enums.user.AccountCateEnum;
import com.ruoyi.xq.enums.user.AccountChangeCodeEnum;
import com.ruoyi.xq.mapper.AccountChangeLogMapper; import com.ruoyi.xq.mapper.AccountChangeLogMapper;
import com.ruoyi.xq.service.AccountChangeLogService; import com.ruoyi.xq.service.AccountChangeLogService;
import com.ruoyi.xq.service.UserService;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
/** /**
* 账户明细Service业务层处理 * 账户明细Service业务层处理
* *
@@ -17,4 +34,95 @@ import org.springframework.stereotype.Service;
@Service @Service
public class AccountChangeLogServiceImpl extends ServiceImpl<AccountChangeLogMapper,AccountChangeLog> implements AccountChangeLogService { public class AccountChangeLogServiceImpl extends ServiceImpl<AccountChangeLogMapper,AccountChangeLog> implements AccountChangeLogService {
@Autowired
private UserService userService;
@Override
public void saveLogNoAdminOfConsumer(User user, AccountChangeCodeEnum accountChangeCodeEnum, BigDecimal price, String traceId, Long tarUserId) {
AccountChangeLog accountChangeLog = new AccountChangeLog();
accountChangeLog.setUserId(user.getId());
accountChangeLog.setUsercode(user.getUsercode());
accountChangeLog.setTarUserId(tarUserId);
MinUser tarMinUser = userService.getMinUserById(tarUserId);
if(tarMinUser != null){
accountChangeLog.setTarUsercode(tarMinUser.getUsercode());
}
accountChangeLog.setCateId(accountChangeCodeEnum.getCate().getCode());
accountChangeLog.setChangeType(accountChangeCodeEnum.getCode());
accountChangeLog.setChangeValue(price);
accountChangeLog.setTraceId(traceId);
accountChangeLog.setIsAdmin(0);
this.save(accountChangeLog);
}
@Override
public void saveLogNoAdmin(Long userId, AccountChangeCodeEnum accountChangeCodeEnum, BigDecimal withdrawPrice, String traceId) {
MinUser minUser = userService.getMinUserById(userId);
AccountChangeLog accountChangeLog = new AccountChangeLog();
accountChangeLog.setUserId(minUser.getId());
accountChangeLog.setUsercode(minUser.getUsercode());
accountChangeLog.setCateId(accountChangeCodeEnum.getCate().getCode());
accountChangeLog.setChangeType(accountChangeCodeEnum.getCode());
accountChangeLog.setChangeValue(withdrawPrice);
accountChangeLog.setTraceId(traceId);
accountChangeLog.setIsAdmin(0);
this.save(accountChangeLog);
}
@Override
public void saveLogAdminOfSystem(User user, AccountChangeCodeEnum accountChangeCodeEnum, UpdateIncomeCoinReq bo, LoginUser loginUser) {
AccountChangeLog accountChangeLog = new AccountChangeLog();
accountChangeLog.setUserId(user.getId());
accountChangeLog.setUsercode(user.getUsercode());
accountChangeLog.setCateId(accountChangeCodeEnum.getCate().getCode());
accountChangeLog.setChangeType(accountChangeCodeEnum.getCode());
accountChangeLog.setChangeValue(bo.getRechargeCoin());
accountChangeLog.setRemark(bo.getRemark());
accountChangeLog.setIsAdmin(1);
if(loginUser != null){
accountChangeLog.setAdminId(loginUser.getUserId());
accountChangeLog.setAdminName(loginUser.getUsername());
}
this.save(accountChangeLog);
}
@Override
public Page<AccountChangeLogAdminVo> pageAdmin(PageQuery pageQuery, AccountChangeLogAdminVo bo) {
Page<AccountChangeLogAdminVo> result = baseMapper.pageAdmin(pageQuery.build(), bo);
List<AccountChangeLogAdminVo> records = result.getRecords();
List<Long> userIds = records.stream().map(AccountChangeLog::getUserId).collect(Collectors.toList());
List<User> usersList = userService.listByIds(userIds);
Map<Long, User> userMap = usersList.stream().collect(Collectors.toMap(User::getId, Function.identity()));
for (AccountChangeLogAdminVo record : records) {
User user = userMap.get(record.getUserId());
if(user != null){
record.setNickname(user.getNickname());
record.setAvatar(user.getAvatar());
record.setMobile(user.getMobile());
}
AccountChangeCodeEnum accountChangeCodeEnum = AccountChangeCodeEnum.getByCode(record.getChangeType());
if(accountChangeCodeEnum != null){
AccountCateEnum cate = accountChangeCodeEnum.getCate();
record.setCateName(cate.getText());
switch (cate){
case SYSTEM_TRANS:
double price = record.getChangeValue().doubleValue();
String content = String.format("系统调整手动%s收益: %s", price > 0 ? "新增" : "减少", price);
record.setContent(content);
break;
case WITHDRAW:
record.setContent(accountChangeCodeEnum.getText());
break;
case AWARD_INVITE:
record.setContent(accountChangeCodeEnum.getText());
break;
default:
break;
}
}
}
return result;
}
} }

View File

@@ -1,10 +1,31 @@
package com.ruoyi.xq.service.impl; package com.ruoyi.xq.service.impl;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.helper.LoginHelper;
import com.ruoyi.xq.domain.ConsumeLog; import com.ruoyi.xq.domain.ConsumeLog;
import com.ruoyi.xq.domain.User;
import com.ruoyi.xq.domain.UserExtend;
import com.ruoyi.xq.domain.UserInvite;
import com.ruoyi.xq.enums.consumer.ConsumeLogStatus;
import com.ruoyi.xq.enums.consumer.ConsumerTypeEnum;
import com.ruoyi.xq.enums.user.AccountChangeCodeEnum;
import com.ruoyi.xq.mapper.ConsumeLogMapper; import com.ruoyi.xq.mapper.ConsumeLogMapper;
import com.ruoyi.xq.service.ConsumeLogService; import com.ruoyi.xq.service.ConsumeLogService;
import com.ruoyi.xq.service.UserExtendService;
import com.ruoyi.xq.service.UserInviteService;
import com.ruoyi.xq.service.UserService;
import com.ruoyi.xq.util.CaiNumUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.BooleanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
/** /**
* 分销记录Service业务层处理 * 分销记录Service业务层处理
@@ -13,6 +34,98 @@ import org.springframework.stereotype.Service;
* @date 2024-03-20 * @date 2024-03-20
*/ */
@Service @Service
@Slf4j
public class ConsumeLogServiceImpl extends ServiceImpl<ConsumeLogMapper,ConsumeLog> implements ConsumeLogService { public class ConsumeLogServiceImpl extends ServiceImpl<ConsumeLogMapper,ConsumeLog> implements ConsumeLogService {
@Autowired
private UserInviteService userInviteService;
@Autowired
private UserService userService;
@Autowired
private UserExtendService userExtendService;
@Override
public ConsumeLog calculateInitFenxiao(ConsumeLog consumeLog){
Long sourceUserId = consumeLog.getSourceUserId();
UserInvite userInvite = userInviteService.getByUserId(sourceUserId);
if(userInvite != null){
User oneUser = userService.getById(userInvite.getInviteId());
if(oneUser != null){
UserExtend userExtend = userExtendService.getByUserId(oneUser.getId());
consumeLog.setOneRate(userExtend.getVipInviteRate());
consumeLog.setOneUserId(oneUser.getId());
consumeLog.setOneUsercode(oneUser.getUsercode());
consumeLog.setOnePhone(oneUser.getMobile());
consumeLog.setOneJoin(userInvite.getEnableRate());
consumeLog.setOneAmount(CaiNumUtil.coin(consumeLog.getAmount(),consumeLog.getOneRate()));
}
}
consumeLog.setCalculateStatus(true);
return consumeLog;
}
@Override
@Transactional(rollbackFor = Exception.class)
public void dealFenxiao(Long id,boolean system){
ConsumeLog consumer = this.getById(id);
if(consumer == null){
return;
}
if(!ConsumeLogStatus.READY.getCode().equals(consumer.getStatus())){
// 已经分销完成,无需继续分销
return;
}
if(!BooleanUtils.isTrue(consumer.getCalculateStatus())){
// 先计算
boolean update = this.update(Wrappers.lambdaUpdate(ConsumeLog.class)
.eq(ConsumeLog::getId, id)
.eq(ConsumeLog::getCalculateStatus, false)
.set(ConsumeLog::getOpCreate, LocalDateTime.now())
.set(ConsumeLog::getCalculateStatus, true));
if(update){
consumer = calculateInitFenxiao(consumer);
consumer.setCalculateStatus(true);
this.updateById(consumer);
}
}
String opName = "system";
Long opId = null;
if(!system){
LoginUser loginUser = LoginHelper.getLoginUser();
if(loginUser != null){
opName = loginUser.getUsername();
opId = loginUser.getUserId();
}
}
// 分销
boolean update = this.update(Wrappers.lambdaUpdate(ConsumeLog.class)
.eq(ConsumeLog::getId, id)
.eq(ConsumeLog::getStatus, ConsumeLogStatus.READY.getCode())
.set(ConsumeLog::getOpName, opName)
.set(ConsumeLog::getOpId, opId)
.set(ConsumeLog::getStatus, ConsumeLogStatus.ALREADY.getCode()));
if(!update){
log.error("无需分销 consumer={}", JSON.toJSONString(consumer));
return;
}
ConsumerTypeEnum code = ConsumerTypeEnum.getByCode(consumer.getType());
if(code == null){
log.error("分销失败 BusinessEnum状态错误! consumerLog={}",JSON.toJSONString(consumer));
throw new ServiceException("分销失败!请联系管理员排查问题!");
}
try {
boolean oneInviteSend = false;
// 计算一级
if(consumer.getOneUserId() != null && BooleanUtils.isTrue(consumer.getOneJoin())
&& consumer.getOneAmount() != null && consumer.getOneAmount().doubleValue() > 0){
AccountChangeCodeEnum changeCodeEnum = ConsumerTypeEnum.getOneInviteChange(code);
oneInviteSend = userExtendService.distribution(consumer, consumer.getOneUserId(), consumer.getOneAmount(), changeCodeEnum);
}
}catch (Exception e){
log.error("分销发生未知错误,请联系开发检查!",e);
}
}
} }

View File

@@ -1,11 +1,13 @@
package com.ruoyi.xq.service.impl; package com.ruoyi.xq.service.impl;
import cn.hutool.core.util.NumberUtil; import cn.hutool.core.util.NumberUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.core.domain.PageQuery; import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.helper.LoginHelper; import com.ruoyi.common.helper.LoginHelper;
import com.ruoyi.xq.domain.ConsumeLog;
import com.ruoyi.xq.domain.User; import com.ruoyi.xq.domain.User;
import com.ruoyi.xq.domain.UserExtend; import com.ruoyi.xq.domain.UserExtend;
import com.ruoyi.xq.domain.WxTransOrder; import com.ruoyi.xq.domain.WxTransOrder;
@@ -14,16 +16,20 @@ import com.ruoyi.xq.dto.admin.user.req.UpdateIncomeCoinReq;
import com.ruoyi.xq.dto.admin.user.req.UpdateWxTransNumReq; import com.ruoyi.xq.dto.admin.user.req.UpdateWxTransNumReq;
import com.ruoyi.xq.enums.common.OrderTypeEnum; import com.ruoyi.xq.enums.common.OrderTypeEnum;
import com.ruoyi.xq.enums.common.SystemConfigEnum; import com.ruoyi.xq.enums.common.SystemConfigEnum;
import com.ruoyi.xq.enums.consumer.ConsumerTypeEnum;
import com.ruoyi.xq.enums.pay.PayStatusEnum; import com.ruoyi.xq.enums.pay.PayStatusEnum;
import com.ruoyi.xq.enums.pay.PlatformTypeEnum; import com.ruoyi.xq.enums.pay.PlatformTypeEnum;
import com.ruoyi.xq.enums.user.AccountChangeCodeEnum;
import com.ruoyi.xq.enums.wxtrans.WxTransSourceEnum; import com.ruoyi.xq.enums.wxtrans.WxTransSourceEnum;
import com.ruoyi.xq.manager.OrderNoUtil; import com.ruoyi.xq.manager.OrderNoUtil;
import com.ruoyi.xq.manager.SystemConfigManager; import com.ruoyi.xq.manager.SystemConfigManager;
import com.ruoyi.xq.mapper.UserExtendMapper; import com.ruoyi.xq.mapper.UserExtendMapper;
import com.ruoyi.xq.service.AccountChangeLogService;
import com.ruoyi.xq.service.UserExtendService; import com.ruoyi.xq.service.UserExtendService;
import com.ruoyi.xq.service.UserService; import com.ruoyi.xq.service.UserService;
import com.ruoyi.xq.service.WxTransOrderService; import com.ruoyi.xq.service.WxTransOrderService;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@@ -38,6 +44,7 @@ import java.math.BigDecimal;
*/ */
@RequiredArgsConstructor @RequiredArgsConstructor
@Service @Service
@Slf4j
public class UserExtendServiceImpl extends ServiceImpl<UserExtendMapper,UserExtend> implements UserExtendService { public class UserExtendServiceImpl extends ServiceImpl<UserExtendMapper,UserExtend> implements UserExtendService {
@Autowired @Autowired
private UserService userService; private UserService userService;
@@ -45,12 +52,14 @@ public class UserExtendServiceImpl extends ServiceImpl<UserExtendMapper,UserExte
private WxTransOrderService wxTransOrderService; private WxTransOrderService wxTransOrderService;
@Autowired @Autowired
private SystemConfigManager systemConfigManager; private SystemConfigManager systemConfigManager;
@Autowired
private AccountChangeLogService accountChangeLogService;
@Override @Override
public boolean withdraw(Long userId, BigDecimal withdrawPrice){ public boolean withdraw(Long userId, BigDecimal withdrawPrice,String traceId){
boolean success = baseMapper.decrIncome(userId, withdrawPrice); boolean success = baseMapper.decrIncome(userId, withdrawPrice);
if(success){ if(success){
// TODO 记录金额流水 accountChangeLogService.saveLogNoAdmin(userId, AccountChangeCodeEnum.WITHDRAW, withdrawPrice, traceId);
} }
return success; return success;
} }
@@ -59,7 +68,7 @@ public class UserExtendServiceImpl extends ServiceImpl<UserExtendMapper,UserExte
public void resetWithdraw(Long userId, BigDecimal withdrawMoney, String traceId) { public void resetWithdraw(Long userId, BigDecimal withdrawMoney, String traceId) {
boolean success = baseMapper.incrIncome(userId, withdrawMoney); boolean success = baseMapper.incrIncome(userId, withdrawMoney);
if(success){ if(success){
// TODO 记录金额流水 accountChangeLogService.saveLogNoAdmin(userId, AccountChangeCodeEnum.WITHDRAW_FAIL, withdrawMoney, traceId);
} }
} }
@@ -69,10 +78,15 @@ public class UserExtendServiceImpl extends ServiceImpl<UserExtendMapper,UserExte
* @param withdrawMonty * @param withdrawMonty
*/ */
@Override @Override
public boolean incsWithdrawCount(Long userId, BigDecimal withdrawMonty){ public boolean incsWithdrawTotal(Long userId, BigDecimal withdrawMonty){
return baseMapper.incsWithdrawCount(userId,withdrawMonty); return baseMapper.incsWithdrawCount(userId,withdrawMonty);
} }
@Override
public boolean incsConsumeTotal(Long userId, BigDecimal consumeMonty) {
return baseMapper.incsConsumeTotal(userId,consumeMonty);
}
@Override @Override
public Page<UserExtendAdminVo> pageAdmin(PageQuery pageQuery, UserExtendAdminVo bo) { public Page<UserExtendAdminVo> pageAdmin(PageQuery pageQuery, UserExtendAdminVo bo) {
@@ -90,6 +104,31 @@ public class UserExtendServiceImpl extends ServiceImpl<UserExtendMapper,UserExte
if(!income){ if(!income){
throw new ServiceException("调整失败,请保证调整后金额不为负数"); throw new ServiceException("调整失败,请保证调整后金额不为负数");
} }
if(bo.getRechargeCoin().doubleValue() > 0){ // 正数
accountChangeLogService.saveLogAdminOfSystem(user, AccountChangeCodeEnum.SYSTEM_INCOME_COIN_INCS, bo,LoginHelper.getLoginUser());
}else if(bo.getRechargeCoin().doubleValue() < 0){ // 负数
accountChangeLogService.saveLogAdminOfSystem(user, AccountChangeCodeEnum.SYSTEM_INCOME_COIN_INCS, bo,LoginHelper.getLoginUser());
}
}
@Override
public boolean distribution(ConsumeLog consumer, Long userId, BigDecimal amount, AccountChangeCodeEnum changeCodeEnum) {
User user = userService.getById(userId);
UserExtend userExtend = this.getByUserId(userId);
if(userExtend == null || user == null){
log.error("分销失败,无效账号 userId={}",userId);
return false;
}
if(amount == null || changeCodeEnum == null){
log.error("分销失败,参数错误 amount={},accountChangeEnum={}",amount,changeCodeEnum);
return false;
}
baseMapper.incrIncome(userId, amount);
if(ConsumerTypeEnum.VIP.getCode().equals(consumer.getType())){
accountChangeLogService.saveLogNoAdminOfConsumer(user, changeCodeEnum,amount,consumer.getTraceId(), consumer.getSourceUserId());
return true;
}
return false;
} }
@Override @Override
@@ -119,4 +158,9 @@ public class UserExtendServiceImpl extends ServiceImpl<UserExtendMapper,UserExte
wxTransOrderService.save(wxTransOrder); wxTransOrderService.save(wxTransOrder);
} }
@Override
public UserExtend getByUserId(Long userId) {
return this.getOne(Wrappers.lambdaQuery(UserExtend.class).eq(UserExtend::getUserId, userId).last("limit 1"));
}
} }

View File

@@ -73,4 +73,9 @@ public class UserInviteServiceImpl extends ServiceImpl<UserInviteMapper, UserInv
public Page<UserInviteAdminVo> pageAdmin(PageQuery pageQuery, UserInviteAdminVo bo) { public Page<UserInviteAdminVo> pageAdmin(PageQuery pageQuery, UserInviteAdminVo bo) {
return baseMapper.pageAdmin(pageQuery.build(), bo); return baseMapper.pageAdmin(pageQuery.build(), bo);
} }
@Override
public UserInvite getByUserId(Long sourceUserId) {
return this.getOne(Wrappers.lambdaQuery(UserInvite.class).eq(UserInvite::getUserId, sourceUserId).last("limit 1"));
}
} }

View File

@@ -14,7 +14,6 @@ import com.ruoyi.xq.dto.app.withdraw.WithdrawListPageQuery;
import com.ruoyi.xq.enums.common.AuditEnum; import com.ruoyi.xq.enums.common.AuditEnum;
import com.ruoyi.xq.enums.common.OrderTypeEnum; import com.ruoyi.xq.enums.common.OrderTypeEnum;
import com.ruoyi.xq.enums.common.TraceIdEnum; import com.ruoyi.xq.enums.common.TraceIdEnum;
import com.ruoyi.xq.enums.user.UserAuthTypeEnum;
import com.ruoyi.xq.manager.OrderNoUtil; import com.ruoyi.xq.manager.OrderNoUtil;
import com.ruoyi.xq.manager.TraceIdManager; import com.ruoyi.xq.manager.TraceIdManager;
import com.ruoyi.xq.mapper.UserWithdrawMapper; import com.ruoyi.xq.mapper.UserWithdrawMapper;
@@ -55,11 +54,11 @@ public class UserWithdrawServiceImpl extends ServiceImpl<UserWithdrawMapper,User
if(withdrawSetting == null){ if(withdrawSetting == null){
throw new ServiceException("提现参数错误"); throw new ServiceException("提现参数错误");
} }
boolean withdraw = userExtendService.withdraw(userId, withdrawSetting.getMoney()); String traceId = TraceIdManager.gen(TraceIdEnum.WITHDRAW);
boolean withdraw = userExtendService.withdraw(userId, withdrawSetting.getMoney(),traceId);
if(!withdraw){ if(!withdraw){
throw new ServiceException("提现失败,余额不足"); throw new ServiceException("提现失败,余额不足");
} }
String traceId = TraceIdManager.gen(TraceIdEnum.WITHDRAW);
String orderNo = OrderNoUtil.gen(OrderTypeEnum.WITHDRAW); String orderNo = OrderNoUtil.gen(OrderTypeEnum.WITHDRAW);
UserWithdraw userWithdraw = new UserWithdraw(); UserWithdraw userWithdraw = new UserWithdraw();
userWithdraw.setUserId(user.getId()); userWithdraw.setUserId(user.getId());
@@ -97,7 +96,8 @@ public class UserWithdrawServiceImpl extends ServiceImpl<UserWithdrawMapper,User
.set(UserWithdraw::getAuditTime, LocalDateTime.now()) .set(UserWithdraw::getAuditTime, LocalDateTime.now())
.set(UserWithdraw::getAuditRemark, "审核成功")); .set(UserWithdraw::getAuditRemark, "审核成功"));
if(flag){ if(flag){
UserWithdraw userWithdraw = this.getById(id);
userExtendService.incsWithdrawTotal(userWithdraw.getUserId(), userWithdraw.getWithdrawMoney());
if(autoTrans){ if(autoTrans){
// TODO 自动打款 // TODO 自动打款
} }

View File

@@ -1,23 +1,34 @@
package com.ruoyi.xq.service.impl; package com.ruoyi.xq.service.impl;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.core.domain.PageQuery; import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.xq.domain.ConsumeLog;
import com.ruoyi.xq.domain.User; import com.ruoyi.xq.domain.User;
import com.ruoyi.xq.domain.VipOrder; import com.ruoyi.xq.domain.VipOrder;
import com.ruoyi.xq.domain.VipPrice; import com.ruoyi.xq.domain.VipPrice;
import com.ruoyi.xq.dto.admin.vipOrder.VipOrderAdminVo; import com.ruoyi.xq.dto.admin.vipOrder.VipOrderAdminVo;
import com.ruoyi.xq.dto.app.pay.ConsumeResp;
import com.ruoyi.xq.enums.common.OrderTypeEnum; import com.ruoyi.xq.enums.common.OrderTypeEnum;
import com.ruoyi.xq.enums.common.TraceIdEnum;
import com.ruoyi.xq.enums.consumer.ConsumerTypeEnum;
import com.ruoyi.xq.enums.pay.PayStatusEnum; import com.ruoyi.xq.enums.pay.PayStatusEnum;
import com.ruoyi.xq.enums.pay.PlatformTypeEnum;
import com.ruoyi.xq.enums.vip.VipTimeEnum;
import com.ruoyi.xq.enums.vip.VipTypeEnum;
import com.ruoyi.xq.manager.OrderNoUtil; import com.ruoyi.xq.manager.OrderNoUtil;
import com.ruoyi.xq.manager.TraceIdManager;
import com.ruoyi.xq.mapper.VipOrderMapper; import com.ruoyi.xq.mapper.VipOrderMapper;
import com.ruoyi.xq.service.UserService; import com.ruoyi.xq.service.*;
import com.ruoyi.xq.service.VipOrderService;
import com.ruoyi.xq.service.VipPriceService;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Map;
/** /**
* VIP订单Service业务层处理 * VIP订单Service业务层处理
@@ -33,6 +44,11 @@ public class VipOrderServiceImpl extends ServiceImpl<VipOrderMapper,VipOrder> im
private VipPriceService vipPriceService; private VipPriceService vipPriceService;
@Autowired @Autowired
private UserService userService; private UserService userService;
@Autowired
private UserVipService userVipService;
@Autowired
private ConsumeLogService consumeLogService;
@Override @Override
public VipOrder createVipOrder(Long userId, Long vipPriceSettingId) { public VipOrder createVipOrder(Long userId, Long vipPriceSettingId) {
VipPrice vipPrice = vipPriceService.getById(vipPriceSettingId); VipPrice vipPrice = vipPriceService.getById(vipPriceSettingId);
@@ -48,6 +64,8 @@ public class VipOrderServiceImpl extends ServiceImpl<VipOrderMapper,VipOrder> im
vipOrder.setVipType(vipPrice.getVipType()); vipOrder.setVipType(vipPrice.getVipType());
vipOrder.setVipTime(vipPrice.getVipTime()); vipOrder.setVipTime(vipPrice.getVipTime());
vipOrder.setVipPrice(vipPrice.getVipPrice()); vipOrder.setVipPrice(vipPrice.getVipPrice());
VipTimeEnum vipTimeEnum = VipTimeEnum.getByCode(vipPrice.getVipTime());
vipOrder.setVipMonth(vipTimeEnum.getMonth());
vipOrder.setOrderNo(orderNo); vipOrder.setOrderNo(orderNo);
vipOrder.setOrderName(vipPrice.getVipName()); vipOrder.setOrderName(vipPrice.getVipName());
vipOrder.setPayStatus(PayStatusEnum.READY_PAY.getCode()); vipOrder.setPayStatus(PayStatusEnum.READY_PAY.getCode());
@@ -59,4 +77,53 @@ public class VipOrderServiceImpl extends ServiceImpl<VipOrderMapper,VipOrder> im
public Page<VipOrderAdminVo> pageApp(PageQuery pageQuery, VipOrderAdminVo bo) { public Page<VipOrderAdminVo> pageApp(PageQuery pageQuery, VipOrderAdminVo bo) {
return baseMapper.pageApp(pageQuery.build(), bo); return baseMapper.pageApp(pageQuery.build(), bo);
} }
@Override
public VipOrder getByOrderNo(String orderNo){
return this.getOne(Wrappers.lambdaQuery(VipOrder.class).eq(VipOrder::getOrderNo, orderNo).last("limit 1"));
}
@Override
@Transactional(rollbackFor = Exception.class)
public ConsumeResp doSuccess(String orderNo, Map<String, String> params, String appId, PlatformTypeEnum payTypeEnum){
VipOrder vipOrder = this.getByOrderNo(orderNo);
if(vipOrder == null){
ConsumeResp resp = new ConsumeResp();
resp.setSuccess(false);
return resp;
}
String traceId = TraceIdManager.gen(TraceIdEnum.VIP);
boolean success = this.update(Wrappers.lambdaUpdate(VipOrder.class)
.eq(VipOrder::getId, vipOrder.getId())
.eq(VipOrder::getPayStatus, PayStatusEnum.READY_PAY.getCode())
.set(VipOrder::getPayStatus, PayStatusEnum.PAY.getCode())
.set(VipOrder::getTraceId, traceId)
.set(VipOrder::getReturnContent, JSON.toJSONString(params))
.set(VipOrder::getAppid,appId)
.set(VipOrder::getPlatformType, payTypeEnum.getCode()));
if(!success){
ConsumeResp resp = new ConsumeResp();
resp.setSuccess(false);
return resp;
}
User user = userService.getById(vipOrder.getUserId());
userVipService.incsVip(user, vipOrder.getVipType(), vipOrder.getVipMonth());
ConsumeLog consumeLog = new ConsumeLog();
consumeLog.init(user);
consumeLog.setTraceId(traceId);
consumeLog.setType(ConsumerTypeEnum.VIP.getCode());
consumeLog.setAmount(vipOrder.getVipPrice());
consumeLogService.calculateInitFenxiao(consumeLog);
if(consumeLog.getOneUserId() != null){
consumeLogService.save(consumeLog);
}
ConsumeResp resp = new ConsumeResp();
resp.setConsumerId(consumeLog.getId());
resp.setPrice(vipOrder.getVipPrice());
resp.setUserId(vipOrder.getUserId());
resp.setTraceId(traceId);
resp.setSuccess(true);
return resp;
}
} }

View File

@@ -0,0 +1,53 @@
package com.ruoyi.xq.util;
import cn.hutool.core.util.NumberUtil;
import java.math.BigDecimal;
import java.math.RoundingMode;
public class CaiNumUtil {
/**
* 向下取整计算金额
* @param value
* @param rate
* @return
*/
public static BigDecimal coin(BigDecimal value, BigDecimal rate){
if(value == null || rate == null){
return BigDecimal.ZERO;
}
BigDecimal decimal = NumberUtil.mul(value, rate);
return decimal.setScale(0, RoundingMode.DOWN);
}
public static String rateToStr(BigDecimal rate){
BigDecimal mul = NumberUtil.mul(rate, 100);
return mul.intValue()+"%";
}
public static BigDecimal memberDay(BigDecimal price, Integer days){
BigDecimal div = NumberUtil.div(price, days, 2);
if(div.compareTo(BigDecimal.ZERO) == 0){
return new BigDecimal("0.01");
}
return div;
}
public static BigDecimal diffRate(Long onlineTodayNum, Long onlineLastNum) {
Long diff = onlineTodayNum - onlineLastNum;
if(onlineLastNum == 0){
return BigDecimal.ZERO;
}
return NumberUtil.div(diff,onlineLastNum,3);
}
public static BigDecimal diffRate(BigDecimal onlineTodayNum, BigDecimal onlineLastNum) {
BigDecimal diff = NumberUtil.sub(onlineTodayNum, onlineLastNum);
if(onlineLastNum.compareTo(BigDecimal.ZERO) == 0){
return BigDecimal.ZERO;
}
return NumberUtil.div(diff,onlineLastNum,3);
}
}

View File

@@ -4,21 +4,23 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd"> "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.xq.mapper.AccountChangeLogMapper"> <mapper namespace="com.ruoyi.xq.mapper.AccountChangeLogMapper">
<resultMap type="com.ruoyi.xq.domain.AccountChangeLog" id="AccountChangeLogResult"> <select id="pageAdmin" resultType="com.ruoyi.xq.dto.admin.log.AccountChangeLogAdminVo">
<result property="id" column="id"/> select t1.*, t2.nickname, t2.mobile,t2.avatar
<result property="userId" column="user_id"/> from xq_account_change_log t1
<result property="usercode" column="usercode"/> left join xq_user t2 on t1.user_id = t2.id
<result property="accountType" column="account_type"/> <where>
<result property="tarUserId" column="tar_user_id"/> <if test="bo.usercode != null and bo.usercode != ''">
<result property="tarJson" column="tar_json"/> and t1.usercode = #{bo.usercode}
<result property="cateId" column="cate_id"/> </if>
<result property="changeType" column="change_type"/> <if test="bo.nickname != null and bo.nickname != ''">
<result property="changeValue" column="change_value"/> and t2.nickname like concat('%',#{bo.nickname},'%')
<result property="traceId" column="trace_id"/> </if>
<result property="isAdmin" column="is_admin"/> <if test="bo.mobile != null and bo.mobile != ''">
<result property="createTime" column="create_time"/> and t2.mobile = #{bo.mobile}
<result property="updateTime" column="update_time"/> </if>
</resultMap> </where>
order by create_time desc
</select>
</mapper> </mapper>

View File

@@ -24,6 +24,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
set wx_trans_num = wx_trans_num + #{wxTransNum} set wx_trans_num = wx_trans_num + #{wxTransNum}
where user_id = #{userId} where user_id = #{userId}
</update> </update>
<update id="incsConsumeTotal">
update xq_user_extend
set consume_total = consume_total + #{consumeMonty}
where user_id = #{userId}
</update>
<select id="pageAdmin" resultType="com.ruoyi.xq.dto.admin.user.UserExtendAdminVo"> <select id="pageAdmin" resultType="com.ruoyi.xq.dto.admin.user.UserExtendAdminVo">
select t1.*, t2.nickname,t2.mobile,t2.avatar select t1.*, t2.nickname,t2.mobile,t2.avatar
from xq_user_extend t1 from xq_user_extend t1