This commit is contained in:
777
2025-12-10 14:04:51 +08:00
parent 7462e05864
commit bed746242d
12 changed files with 449 additions and 13 deletions

View File

@@ -1,2 +1,34 @@
ALTER TABLE cai_point_record_log
ADD COLUMN one_join tinyint default 1 not null comment '是否参与分销';
ALTER TABLE cai_point_record_log
ADD COLUMN trace_id varchar(100) default null comment '链路ID';
CREATE TABLE `cai_point_change_log`
(
`id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT '子账户ID',
`user_id` bigint(20) NOT NULL COMMENT '用户ID',
`usercode` varchar(100) NOT NULL COMMENT '用户',
`message` varchar(100) NOT NULL COMMENT '账户明细说明',
`tar_user_id` bigint DEFAULT NULL COMMENT '目标ID用户、抽奖ID',
`tar_usercode` varchar(20) DEFAULT NULL COMMENT '目标用户Code有用户才有用',
`tar_name` varchar(255) DEFAULT NULL COMMENT '目标名称,用户名称,抽奖名称',
`tar_price` bigint DEFAULT NULL COMMENT '礼物价值',
`tar_img` varchar(255) DEFAULT NULL COMMENT '目标提前缓存的',
`tar_json` JSON DEFAULT NULL COMMENT '目标额外字段',
`change_value` bigint NOT NULL DEFAULT '0.00' COMMENT '变化值,为正 或者为负',
`operate_ip` varchar(15) DEFAULT '' COMMENT '操作IP',
`is_admin` tinyint unsigned NOT NULL DEFAULT '0' COMMENT '是否为后台用户手动调整',
`trace_link_type` varchar(36) DEFAULT NULL COMMENT '跟踪类型 1-充值 2-分销 3-抽奖',
`trace_id` varchar(50) DEFAULT NULL COMMENT '跟踪ID 订单号-礼物ID',
`give_flag` tinyint NOT NULL DEFAULT '0' COMMENT '是否兑换',
`give_time` datetime comment '兑换时间',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`) USING BTREE,
UNIQUE KEY `user_id` (`user_id`) USING BTREE
) ENGINE = InnoDB
AUTO_INCREMENT = 1
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_general_ci
ROW_FORMAT = DYNAMIC COMMENT ='积分记录';

View File

@@ -0,0 +1,95 @@
package com.ruoyi.cai.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.cai.domain.PointChangeLog;
import com.ruoyi.cai.service.PointChangeLogService;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.annotation.RepeatSubmit;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.validate.AddGroup;
import com.ruoyi.common.core.validate.EditGroup;
import com.ruoyi.common.enums.BusinessType;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.Arrays;
/**
* 积分记录
*
* @author ruoyi
* @date 2025-12-10
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/cai/pointChangeLog")
public class PointChangeLogController extends BaseController {
private final PointChangeLogService pointChangeLogService;
/**
* 查询积分记录列表
*/
@SaCheckPermission("cai:pointChangeLog:list")
@GetMapping("/list")
public TableDataInfo<PointChangeLog> list(PointChangeLog bo, PageQuery pageQuery) {
Page<PointChangeLog> page = pointChangeLogService.page(pageQuery.build(), Wrappers.lambdaQuery(bo));
return TableDataInfo.build(page);
}
/**
* 获取积分记录详细信息
*
* @param id 主键
*/
@SaCheckPermission("cai:pointChangeLog:query")
@GetMapping("/{id}")
public R<PointChangeLog> getInfo(@NotNull(message = "主键不能为空")
@PathVariable String id) {
return R.ok(pointChangeLogService.getById(id));
}
/**
* 新增积分记录
*/
@SaCheckPermission("cai:pointChangeLog:add")
@Log(title = "积分记录", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody PointChangeLog bo) {
return toAjax(pointChangeLogService.save(bo));
}
/**
* 修改积分记录
*/
@SaCheckPermission("cai:pointChangeLog:edit")
@Log(title = "积分记录", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody PointChangeLog bo) {
return toAjax(pointChangeLogService.updateById(bo));
}
/**
* 删除积分记录
*
* @param ids 主键串
*/
@SaCheckPermission("cai:pointChangeLog:remove")
@Log(title = "积分记录", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable String[] ids) {
return toAjax(pointChangeLogService.removeBatchByIds(Arrays.asList(ids), true));
}
}

View File

@@ -0,0 +1,96 @@
package com.ruoyi.cai.domain;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* 积分记录对象 cai_point_change_log
*
* @author ruoyi
* @date 2025-12-10
*/
@Data
@TableName("cai_point_change_log")
public class PointChangeLog implements Serializable {
private static final long serialVersionUID=1L;
/**
* 子账户ID
*/
@TableId(value = "id")
private String id;
// 1-充值 2-系统调整 3-分销 4-抽奖
private String actionType;
/**
* 用户ID
*/
private Long userId;
/**
* 用户
*/
private String usercode;
/**
* 账户明细说明
*/
private String message;
/**
* 目标ID用户、抽奖ID
*/
private Long tarUserId;
/**
* 目标用户Code有用户才有用
*/
private String tarUsercode;
/**
* 目标名称,用户名称,抽奖名称
*/
private String tarName;
/**
* 礼物价值
*/
private Long tarPrice;
/**
* 目标提前缓存的
*/
private String tarImg;
/**
* 目标额外字段
*/
private String tarJson;
/**
* 变化值,为正 或者为负
*/
private Long changeValue;
/**
* 操作IP
*/
private String operateIp;
/**
* 是否为后台用户手动调整
*/
private Boolean isAdmin;
/**
* 跟踪类型 1-充值 2-分销 3-抽奖
*/
private String traceLinkType;
/**
* 跟踪ID 订单号-礼物ID
*/
private String traceId;
/**
* 是否兑换
*/
private Integer giveFlag;
/**
* 兑换时间
*/
private LocalDateTime giveTime;
private LocalDateTime createTime;
}

View File

@@ -79,6 +79,7 @@ public class PointRecordLog implements Serializable{
* 备注
*/
private String remark;
private String traceId;
private LocalDateTime createTime;
}

View File

@@ -0,0 +1,19 @@
package com.ruoyi.cai.enums.point;
import lombok.Getter;
@Getter
public enum PointChangeLogActionTypeEnum {
PAY("1","充值"),
SYSTEM("2","系统调整"),
INVITE("3","分销"),
USE("4","抽奖"),
;
private final String code;
private final String name;
PointChangeLogActionTypeEnum(String code, String name) {
this.code = code;
this.name = name;
}
}

View File

@@ -0,0 +1,19 @@
package com.ruoyi.cai.enums.point;
import lombok.Getter;
@Getter
public enum PointChangeTraceTypeEnum {
PAY("1","充值"),
SYSTEM("2","系统调整"),
INVITE("3","分销"),
USE("4","抽奖"),
;
private final String code;
private final String name;
PointChangeTraceTypeEnum(String code, String name) {
this.code = code;
this.name = name;
}
}

View File

@@ -0,0 +1,14 @@
package com.ruoyi.cai.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.cai.domain.PointChangeLog;
/**
* 积分记录Mapper接口
*
* @author ruoyi
* @date 2025-12-10
*/
public interface PointChangeLogMapper extends BaseMapper<PointChangeLog> {
}

View File

@@ -0,0 +1,21 @@
package com.ruoyi.cai.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.cai.domain.PointChangeLog;
/**
* 积分记录Service接口
*
* @author ruoyi
* @date 2025-12-10
*/
public interface PointChangeLogService extends IService<PointChangeLog> {
void rechargeOrderChange(String orderNo, Long userId, Long givePoint);
void rechargeOrderInviteChange(Long userId, Long givePoint, Long inviteUserId, String traceId);
void adminChange(Long userId, Long givePoint);
void adminInvite(Long userId, Long givePoint, Long inviteUserId, String traceId);
}

View File

@@ -9,9 +9,7 @@ import com.ruoyi.cai.domain.*;
import com.ruoyi.cai.dto.admin.vo.AccountAdminVo;
import com.ruoyi.cai.dto.video.VideoSettleResp;
import com.ruoyi.cai.dto.video.WithholdingFeeUserResp;
import com.ruoyi.cai.enums.ConsumeLogStatus;
import com.ruoyi.cai.enums.ConsumeLogType;
import com.ruoyi.cai.enums.PointLogType;
import com.ruoyi.cai.enums.SystemConfigEnum;
import com.ruoyi.cai.enums.account.AccountChangeCodeEnum;
import com.ruoyi.cai.enums.account.AccountTypeEnum;
@@ -35,7 +33,6 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
* 用户账户Service业务层处理
@@ -219,6 +216,8 @@ public class AccountServiceImpl extends ServiceImpl<AccountMapper, Account> impl
@Autowired
private PointRecordLogService pointRecordLogService;
@Autowired
private PointChangeLogService pointChangeLogService;
@Transactional(rollbackFor = Exception.class)
@Override
@@ -227,7 +226,7 @@ public class AccountServiceImpl extends ServiceImpl<AccountMapper, Account> impl
return null;
}
log.info("开始赠送积分 orderNo={}", rechargeOrder.getOrderNo());
baseMapper.incrPoint(rechargeOrder.getUserId(), rechargeOrder.getGivePoint());
pointChangeLogService.rechargeOrderChange(rechargeOrder.getOrderNo(), rechargeOrder.getUserId(),rechargeOrder.getGivePoint());
PointRecordLog pointRecordLog = pointRecordLogService.initOrder(rechargeOrder, user);
return pointRecordLog;
}

View File

@@ -0,0 +1,108 @@
package com.ruoyi.cai.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.cai.domain.PointChangeLog;
import com.ruoyi.cai.domain.User;
import com.ruoyi.cai.enums.point.PointChangeLogActionTypeEnum;
import com.ruoyi.cai.enums.point.PointChangeTraceTypeEnum;
import com.ruoyi.cai.mapper.AccountMapper;
import com.ruoyi.cai.mapper.PointChangeLogMapper;
import com.ruoyi.cai.service.PointChangeLogService;
import com.ruoyi.cai.service.UserService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
/**
* 积分记录Service业务层处理
*
* @author ruoyi
* @date 2025-12-10
*/
@RequiredArgsConstructor
@Service
public class PointChangeLogServiceImpl extends ServiceImpl<PointChangeLogMapper,PointChangeLog> implements PointChangeLogService {
@Autowired
private UserService userService;
@Resource
private AccountMapper accountMapper;
@Override
public void rechargeOrderChange(String orderNo, Long userId, Long givePoint){
accountMapper.incrPoint(userId, givePoint);
User user = userService.getById(userId);
PointChangeLog pointChangeLog = new PointChangeLog();
pointChangeLog.setUserId(userId);
pointChangeLog.setUsercode(user.getUsercode());
pointChangeLog.setActionType(PointChangeLogActionTypeEnum.PAY.getCode());
pointChangeLog.setMessage("充值赠送"+givePoint+"积分");
pointChangeLog.setChangeValue(givePoint);
pointChangeLog.setIsAdmin(false);
pointChangeLog.setTraceLinkType(PointChangeTraceTypeEnum.PAY.getCode());
pointChangeLog.setTraceId(orderNo);
this.save(pointChangeLog);
}
@Override
public void rechargeOrderInviteChange(Long userId, Long givePoint, Long inviteUserId, String traceId){
accountMapper.incrPoint(userId, givePoint);
User user = userService.getById(userId);
User inviteUser = userService.getById(inviteUserId);
PointChangeLog pointChangeLog = new PointChangeLog();
pointChangeLog.setUserId(userId);
pointChangeLog.setUsercode(user.getUsercode());
pointChangeLog.setActionType(PointChangeLogActionTypeEnum.INVITE.getCode());
String message = String.format("从【%s】中充值分成新增%s积分", inviteUser.getNickname(), givePoint);
pointChangeLog.setMessage(message);
pointChangeLog.setTarUserId(inviteUser.getId());
pointChangeLog.setTarUsercode(inviteUser.getUsercode());
pointChangeLog.setTarName(inviteUser.getNickname());
pointChangeLog.setTarImg(inviteUser.getAvatar());
pointChangeLog.setChangeValue(givePoint);
pointChangeLog.setIsAdmin(false);
pointChangeLog.setTraceLinkType(PointChangeTraceTypeEnum.INVITE.getCode());
pointChangeLog.setTraceId(traceId);
this.save(pointChangeLog);
}
@Override
public void adminChange(Long userId, Long givePoint){
accountMapper.incrPoint(userId, givePoint);
User user = userService.getById(userId);
PointChangeLog pointChangeLog = new PointChangeLog();
pointChangeLog.setUserId(userId);
pointChangeLog.setUsercode(user.getUsercode());
pointChangeLog.setActionType(PointChangeLogActionTypeEnum.SYSTEM.getCode());
String message = String.format("系统调整:%s%s积分", givePoint > 0 ? "新增" : "减少", givePoint);
pointChangeLog.setMessage(message);
pointChangeLog.setChangeValue(givePoint);
pointChangeLog.setIsAdmin(true);
pointChangeLog.setTraceLinkType(PointChangeTraceTypeEnum.SYSTEM.getCode());
this.save(pointChangeLog);
}
@Override
public void adminInvite(Long userId, Long givePoint, Long inviteUserId, String traceId){
accountMapper.incrPoint(userId, givePoint);
User user = userService.getById(userId);
User inviteUser = userService.getById(inviteUserId);
PointChangeLog pointChangeLog = new PointChangeLog();
pointChangeLog.setUserId(userId);
pointChangeLog.setUsercode(user.getUsercode());
pointChangeLog.setActionType(PointChangeLogActionTypeEnum.SYSTEM.getCode());
String message = String.format("从【%s】中充值分成新增%s积分", inviteUser.getNickname(), givePoint);
pointChangeLog.setMessage(message);
pointChangeLog.setTarUserId(inviteUser.getId());
pointChangeLog.setTarUsercode(inviteUser.getUsercode());
pointChangeLog.setTarName(inviteUser.getNickname());
pointChangeLog.setTarImg(inviteUser.getAvatar());
pointChangeLog.setChangeValue(givePoint);
pointChangeLog.setIsAdmin(false);
pointChangeLog.setTraceLinkType(PointChangeTraceTypeEnum.INVITE.getCode());
pointChangeLog.setTraceId(traceId);
this.save(pointChangeLog);
}
}

View File

@@ -6,12 +6,10 @@ import com.ruoyi.cai.domain.*;
import com.ruoyi.cai.dto.AddPointAdminDto;
import com.ruoyi.cai.enums.ConsumeLogStatus;
import com.ruoyi.cai.enums.PointLogType;
import com.ruoyi.cai.manager.IdManager;
import com.ruoyi.cai.mapper.AccountMapper;
import com.ruoyi.cai.mapper.PointRecordLogMapper;
import com.ruoyi.cai.service.PointRecordLogService;
import com.ruoyi.cai.service.UserInfoService;
import com.ruoyi.cai.service.UserInviteService;
import com.ruoyi.cai.service.UserService;
import com.ruoyi.cai.service.*;
import com.ruoyi.cai.util.CaiNumUtil;
import com.ruoyi.common.exception.ServiceException;
import lombok.RequiredArgsConstructor;
@@ -39,6 +37,8 @@ public class PointRecordLogServiceImpl extends ServiceImpl<PointRecordLogMapper,
private UserInfoService userInfoService;
@Resource
private AccountMapper accountMapper;
@Autowired
private PointChangeLogService pointChangeLogService;
@Override
@Transactional(rollbackFor = Exception.class)
@@ -53,7 +53,7 @@ public class PointRecordLogServiceImpl extends ServiceImpl<PointRecordLogMapper,
throw new ServiceException("开启分销情况下,无法调整积分为负数");
}
}
accountMapper.incrPoint(user.getId(), dto.getChangePoints());
pointChangeLogService.adminChange(user.getId(),dto.getChangePoints());
PointRecordLog pointLog = new PointRecordLog();
pointLog.setPoints(dto.getChangePoints());
pointLog.setSourceUserId(user.getId());
@@ -75,7 +75,9 @@ public class PointRecordLogServiceImpl extends ServiceImpl<PointRecordLogMapper,
if(dto.isDistribution()){ // 需要分销,直接分销
pointLog.setStatus(ConsumeLogStatus.ALREADY.getCode());
if(pointLog.getOnePoints() >= 0 && pointLog.getOneUserId() != null && !pointLog.getOneJoin()){
accountMapper.incrPoint(pointLog.getOneUserId(), pointLog.getOnePoints());
String traceId = IdManager.nextIdStr();
pointChangeLogService.adminInvite(pointLog.getOneUserId(),pointLog.getOnePoints(),pointLog.getSourceUserId(),traceId);
pointLog.setTraceId(traceId);
}
}else{
pointLog.setStatus(ConsumeLogStatus.NO.getCode());
@@ -124,10 +126,12 @@ public class PointRecordLogServiceImpl extends ServiceImpl<PointRecordLogMapper,
if(!ConsumeLogStatus.READY.getCode().equals(pointRecordLog.getStatus())){
return;
}
String traceId = IdManager.nextIdStr();
boolean update = this.update(Wrappers.lambdaUpdate(PointRecordLog.class)
.eq(PointRecordLog::getId, pointLogId)
.eq(PointRecordLog::getStatus, ConsumeLogStatus.READY.getCode())
.set(PointRecordLog::getStatus, ConsumeLogStatus.ALREADY.getCode()));
.set(PointRecordLog::getStatus, ConsumeLogStatus.ALREADY.getCode())
.set(PointRecordLog::getTraceId, traceId));
if(!update){
return;
}
@@ -137,8 +141,7 @@ public class PointRecordLogServiceImpl extends ServiceImpl<PointRecordLogMapper,
if(!pointRecordLog.getOneJoin()){
return;
}
accountMapper.incrPoint(pointRecordLog.getOneUserId(), pointRecordLog.getOnePoints());
pointChangeLogService.adminInvite(pointRecordLog.getOneUserId(),pointRecordLog.getOnePoints(),pointRecordLog.getSourceUserId(),traceId);
}

View File

@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.cai.mapper.PointChangeLogMapper">
<resultMap type="com.ruoyi.cai.domain.PointChangeLog" id="PointChangeLogResult">
<result property="id" column="id"/>
<result property="userId" column="user_id"/>
<result property="usercode" column="usercode"/>
<result property="message" column="message"/>
<result property="tarUserId" column="tar_user_id"/>
<result property="tarUsercode" column="tar_usercode"/>
<result property="tarName" column="tar_name"/>
<result property="tarPrice" column="tar_price"/>
<result property="tarImg" column="tar_img"/>
<result property="tarJson" column="tar_json"/>
<result property="changeValue" column="change_value"/>
<result property="operateIp" column="operate_ip"/>
<result property="isAdmin" column="is_admin"/>
<result property="traceLinkType" column="trace_link_type"/>
<result property="traceId" column="trace_id"/>
<result property="getFlag" column="get_flag"/>
<result property="createTime" column="create_time"/>
<result property="getTime" column="get_time"/>
</resultMap>
</mapper>