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 # 账号
password: 383200134 # 密码
port: 5672
virtual-host: /cai-dev
virtual-host: /xq-dev
redisson:
# redis key前缀

View File

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

View File

@@ -240,9 +240,6 @@ lock4j:
acquire-timeout: 3000
# 分布式锁的超时时间,默认为 30 秒
expire: 30000
cai:
enable-api-encryption: false
websocket: false
--- # Actuator 监控端点的配置项
management:
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.enums.BusinessType;
import com.ruoyi.xq.domain.AccountChangeLog;
import com.ruoyi.xq.dto.admin.log.AccountChangeLogAdminVo;
import com.ruoyi.xq.service.AccountChangeLogService;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
@@ -42,8 +43,8 @@ public class AccountChangeLogController extends BaseController {
*/
@SaCheckPermission("xq:accountChangeLog:list")
@GetMapping("/list")
public TableDataInfo<AccountChangeLog> list(AccountChangeLog bo, PageQuery pageQuery) {
Page<AccountChangeLog> page = accountChangeLogService.page(pageQuery.build(), Wrappers.lambdaQuery(bo));
public TableDataInfo<AccountChangeLogAdminVo> list(AccountChangeLogAdminVo bo, PageQuery pageQuery) {
Page<AccountChangeLogAdminVo> page = accountChangeLogService.pageAdmin(pageQuery, bo);
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;
/**
* 账户类型 1-余额 2-收益
*/
private Integer accountType;
/**
* 目标用户ID
* 来源用户
*/
private Long tarUserId;
/**
* 来源用户编码
*/
private String tarUsercode;
/**
* 目标用户基本信息备份
*/
@@ -56,21 +56,16 @@ public class AccountChangeLog implements Serializable {
* 变化编号
*/
private Integer changeType;
/**
* 变化编号
*/
private BigDecimal changeValue;
/**
* 变化值,为正 或者为负
*/
private Long traceId;
/**
* 是否为后台用户手动调整
*/
private BigDecimal changeValue;
private String traceId;
private Integer isAdmin;
private Long adminId;
private String adminName;
private String remark;
private LocalDateTime createTime;
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-已计算分销
*/
private String calculateStatus;
private Boolean calculateStatus;
/**
* 状态 -1-无须分销 0-待分销 1-已分销
*/
@@ -125,4 +125,10 @@ public class ConsumeLog implements Serializable {
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;
/**
* vip邀请返现比例
*/
private BigDecimal vipInviteRate;
/**
* 收益的余额
*/

View File

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

View File

@@ -33,6 +33,7 @@ public class VipOrder implements Serializable {
* 用户号
*/
private String usercode;
private String traceId;
/**
* 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;
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.Setter;
@@ -13,51 +15,11 @@ import lombok.Setter;
public enum SystemConfigEnum {
// TODO 限制为两位小数
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)),
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),
VIP_INVITE_RATE("0.30","默认会员分销价格",SystemConfigGroupEnum.BUSINESS, new RateSystemConfigCheck()),
SENSITIVE_ENABLE("1", "是否开启手机号脱敏",SystemConfigGroupEnum.SYSTEM,new BooleanSystemConfigCheck()),
YUNXIN_ONLINE_ENABLE("1", "是否开启云信监控在线状态",SystemConfigGroupEnum.SYSTEM,new BooleanSystemConfigCheck()),
SMS_CODE_ADMIN("", "万能验证码",SystemConfigGroupEnum.SYSTEM),
PASSWORD_ADMIN("", "公用密码",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 javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Collections;
@@ -225,6 +226,8 @@ public class LoginManager {
UserExtend userExtend = new UserExtend();
userExtend.setUsercode(usercode);
userExtend.setUserId(add.getId());
BigDecimal vipInviteRate = systemConfigManager.getSystemConfigOfBigDecimal(SystemConfigEnum.VIP_INVITE_RATE);
userExtend.setVipInviteRate(vipInviteRate);
userExtendService.save(userExtend);
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);
}
public String getWebSocketUrl(){
if(DEV_ACTIVE.equals(active)){
return SystemConfigEnum.WS_SOCKET_URL.getDefaultValue();
}
return getSystemConfig(SystemConfigEnum.WS_SOCKET_URL);
}
/**
* 获取配置信息返回boolean
* @param systemConfig

View File

@@ -1,7 +1,10 @@
package com.ruoyi.xq.mapper;
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.dto.admin.log.AccountChangeLogAdminVo;
import org.apache.ibatis.annotations.Param;
/**
* 账户明细Mapper接口
@@ -11,4 +14,5 @@ import com.ruoyi.xq.domain.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 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;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
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.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接口
@@ -11,4 +20,11 @@ import com.ruoyi.xq.domain.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.ruoyi.xq.domain.ConsumeLog;
import org.springframework.transaction.annotation.Transactional;
/**
* 分销记录Service接口
@@ -11,4 +12,8 @@ import com.ruoyi.xq.domain.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.service.IService;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.xq.domain.ConsumeLog;
import com.ruoyi.xq.domain.UserExtend;
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.UpdateWxTransNumReq;
import org.springframework.transaction.annotation.Transactional;
import com.ruoyi.xq.enums.user.AccountChangeCodeEnum;
import java.math.BigDecimal;
@@ -19,14 +20,23 @@ import java.math.BigDecimal;
*/
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);
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);
void updateIncomeCoin(UpdateIncomeCoinReq bo);
boolean distribution(ConsumeLog consumer, Long userId, BigDecimal amount, AccountChangeCodeEnum changeCodeEnum);
void updateWxTransNum(UpdateWxTransNumReq bo);
UserExtend getByUserId(Long id);
}

View File

@@ -19,4 +19,7 @@ public interface UserInviteService extends IService<UserInvite> {
void unBindInviteUser(Long userId);
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.xq.domain.VipOrder;
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接口
@@ -16,4 +20,8 @@ public interface VipOrderService extends IService<VipOrder> {
VipOrder createVipOrder(Long userId, Long vipPriceSettingId);
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;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
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.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.service.AccountChangeLogService;
import com.ruoyi.xq.service.UserService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
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业务层处理
*
@@ -17,4 +34,95 @@ import org.springframework.stereotype.Service;
@Service
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;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
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.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.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.transaction.annotation.Transactional;
import java.time.LocalDateTime;
/**
* 分销记录Service业务层处理
@@ -13,6 +34,98 @@ import org.springframework.stereotype.Service;
* @date 2024-03-20
*/
@Service
@Slf4j
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;
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.service.impl.ServiceImpl;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.helper.LoginHelper;
import com.ruoyi.xq.domain.ConsumeLog;
import com.ruoyi.xq.domain.User;
import com.ruoyi.xq.domain.UserExtend;
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.enums.common.OrderTypeEnum;
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.PlatformTypeEnum;
import com.ruoyi.xq.enums.user.AccountChangeCodeEnum;
import com.ruoyi.xq.enums.wxtrans.WxTransSourceEnum;
import com.ruoyi.xq.manager.OrderNoUtil;
import com.ruoyi.xq.manager.SystemConfigManager;
import com.ruoyi.xq.mapper.UserExtendMapper;
import com.ruoyi.xq.service.AccountChangeLogService;
import com.ruoyi.xq.service.UserExtendService;
import com.ruoyi.xq.service.UserService;
import com.ruoyi.xq.service.WxTransOrderService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -38,6 +44,7 @@ import java.math.BigDecimal;
*/
@RequiredArgsConstructor
@Service
@Slf4j
public class UserExtendServiceImpl extends ServiceImpl<UserExtendMapper,UserExtend> implements UserExtendService {
@Autowired
private UserService userService;
@@ -45,12 +52,14 @@ public class UserExtendServiceImpl extends ServiceImpl<UserExtendMapper,UserExte
private WxTransOrderService wxTransOrderService;
@Autowired
private SystemConfigManager systemConfigManager;
@Autowired
private AccountChangeLogService accountChangeLogService;
@Override
public boolean withdraw(Long userId, BigDecimal withdrawPrice){
public boolean withdraw(Long userId, BigDecimal withdrawPrice,String traceId){
boolean success = baseMapper.decrIncome(userId, withdrawPrice);
if(success){
// TODO 记录金额流水
accountChangeLogService.saveLogNoAdmin(userId, AccountChangeCodeEnum.WITHDRAW, withdrawPrice, traceId);
}
return success;
}
@@ -59,7 +68,7 @@ public class UserExtendServiceImpl extends ServiceImpl<UserExtendMapper,UserExte
public void resetWithdraw(Long userId, BigDecimal withdrawMoney, String traceId) {
boolean success = baseMapper.incrIncome(userId, withdrawMoney);
if(success){
// TODO 记录金额流水
accountChangeLogService.saveLogNoAdmin(userId, AccountChangeCodeEnum.WITHDRAW_FAIL, withdrawMoney, traceId);
}
}
@@ -69,10 +78,15 @@ public class UserExtendServiceImpl extends ServiceImpl<UserExtendMapper,UserExte
* @param withdrawMonty
*/
@Override
public boolean incsWithdrawCount(Long userId, BigDecimal withdrawMonty){
public boolean incsWithdrawTotal(Long userId, BigDecimal withdrawMonty){
return baseMapper.incsWithdrawCount(userId,withdrawMonty);
}
@Override
public boolean incsConsumeTotal(Long userId, BigDecimal consumeMonty) {
return baseMapper.incsConsumeTotal(userId,consumeMonty);
}
@Override
public Page<UserExtendAdminVo> pageAdmin(PageQuery pageQuery, UserExtendAdminVo bo) {
@@ -90,6 +104,31 @@ public class UserExtendServiceImpl extends ServiceImpl<UserExtendMapper,UserExte
if(!income){
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
@@ -119,4 +158,9 @@ public class UserExtendServiceImpl extends ServiceImpl<UserExtendMapper,UserExte
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) {
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.OrderTypeEnum;
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.TraceIdManager;
import com.ruoyi.xq.mapper.UserWithdrawMapper;
@@ -55,11 +54,11 @@ public class UserWithdrawServiceImpl extends ServiceImpl<UserWithdrawMapper,User
if(withdrawSetting == null){
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){
throw new ServiceException("提现失败,余额不足");
}
String traceId = TraceIdManager.gen(TraceIdEnum.WITHDRAW);
String orderNo = OrderNoUtil.gen(OrderTypeEnum.WITHDRAW);
UserWithdraw userWithdraw = new UserWithdraw();
userWithdraw.setUserId(user.getId());
@@ -97,7 +96,8 @@ public class UserWithdrawServiceImpl extends ServiceImpl<UserWithdrawMapper,User
.set(UserWithdraw::getAuditTime, LocalDateTime.now())
.set(UserWithdraw::getAuditRemark, "审核成功"));
if(flag){
UserWithdraw userWithdraw = this.getById(id);
userExtendService.incsWithdrawTotal(userWithdraw.getUserId(), userWithdraw.getWithdrawMoney());
if(autoTrans){
// TODO 自动打款
}

View File

@@ -1,23 +1,34 @@
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.service.impl.ServiceImpl;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.xq.domain.ConsumeLog;
import com.ruoyi.xq.domain.User;
import com.ruoyi.xq.domain.VipOrder;
import com.ruoyi.xq.domain.VipPrice;
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.TraceIdEnum;
import com.ruoyi.xq.enums.consumer.ConsumerTypeEnum;
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.TraceIdManager;
import com.ruoyi.xq.mapper.VipOrderMapper;
import com.ruoyi.xq.service.UserService;
import com.ruoyi.xq.service.VipOrderService;
import com.ruoyi.xq.service.VipPriceService;
import com.ruoyi.xq.service.*;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Map;
/**
* VIP订单Service业务层处理
@@ -33,6 +44,11 @@ public class VipOrderServiceImpl extends ServiceImpl<VipOrderMapper,VipOrder> im
private VipPriceService vipPriceService;
@Autowired
private UserService userService;
@Autowired
private UserVipService userVipService;
@Autowired
private ConsumeLogService consumeLogService;
@Override
public VipOrder createVipOrder(Long userId, Long vipPriceSettingId) {
VipPrice vipPrice = vipPriceService.getById(vipPriceSettingId);
@@ -48,6 +64,8 @@ public class VipOrderServiceImpl extends ServiceImpl<VipOrderMapper,VipOrder> im
vipOrder.setVipType(vipPrice.getVipType());
vipOrder.setVipTime(vipPrice.getVipTime());
vipOrder.setVipPrice(vipPrice.getVipPrice());
VipTimeEnum vipTimeEnum = VipTimeEnum.getByCode(vipPrice.getVipTime());
vipOrder.setVipMonth(vipTimeEnum.getMonth());
vipOrder.setOrderNo(orderNo);
vipOrder.setOrderName(vipPrice.getVipName());
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) {
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">
<mapper namespace="com.ruoyi.xq.mapper.AccountChangeLogMapper">
<resultMap type="com.ruoyi.xq.domain.AccountChangeLog" id="AccountChangeLogResult">
<result property="id" column="id"/>
<result property="userId" column="user_id"/>
<result property="usercode" column="usercode"/>
<result property="accountType" column="account_type"/>
<result property="tarUserId" column="tar_user_id"/>
<result property="tarJson" column="tar_json"/>
<result property="cateId" column="cate_id"/>
<result property="changeType" column="change_type"/>
<result property="changeValue" column="change_value"/>
<result property="traceId" column="trace_id"/>
<result property="isAdmin" column="is_admin"/>
<result property="createTime" column="create_time"/>
<result property="updateTime" column="update_time"/>
</resultMap>
<select id="pageAdmin" resultType="com.ruoyi.xq.dto.admin.log.AccountChangeLogAdminVo">
select t1.*, t2.nickname, t2.mobile,t2.avatar
from xq_account_change_log t1
left join xq_user t2 on t1.user_id = t2.id
<where>
<if test="bo.usercode != null and bo.usercode != ''">
and t1.usercode = #{bo.usercode}
</if>
<if test="bo.nickname != null and bo.nickname != ''">
and t2.nickname like concat('%',#{bo.nickname},'%')
</if>
<if test="bo.mobile != null and bo.mobile != ''">
and t2.mobile = #{bo.mobile}
</if>
</where>
order by create_time desc
</select>
</mapper>

View File

@@ -24,6 +24,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
set wx_trans_num = wx_trans_num + #{wxTransNum}
where user_id = #{userId}
</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 t1.*, t2.nickname,t2.mobile,t2.avatar
from xq_user_extend t1