src/main/java/com/webmanage/controller/PointsController.java
@@ -2,12 +2,10 @@ import com.webmanage.common.PageResult; import com.webmanage.common.Result; import com.webmanage.dto.AddPointsFlowDTO; import com.webmanage.dto.PointsFlowQueryDTO; import com.webmanage.dto.PointsMainQueryDTO; import com.webmanage.dto.PointsRuleDTO; import com.webmanage.dto.*; import com.webmanage.entity.Points; import com.webmanage.entity.PointsRule; import com.webmanage.entity.UserPoints; import com.webmanage.service.PointsFlowService; import com.webmanage.service.PointsRuleService; import com.webmanage.service.PointsService; @@ -91,7 +89,7 @@ @PostMapping("/rule/update") @ApiOperation("修改积分规则") public Result<Object> updatePointsRule(@Valid @RequestBody PointsRuleDTO pointsRuleDTO) { public Result<Object> updatePointsRule(@Valid @RequestBody List<PointsRuleDTO> pointsRuleDTO) { try { boolean result = pointsRuleService.updatePointsRule(pointsRuleDTO); if (result) { @@ -252,10 +250,10 @@ @GetMapping("/total/user/{userId}") @ApiOperation("获取用户积分统计") public Result<Object> getUserPointsTotal(@ApiParam("用户ID") @PathVariable Long userId) { public Result<UserPoints> getUserPointsTotal(@ApiParam("用户ID") @PathVariable Long userId) { try { Integer total = pointsFlowService.getUserPointsTotal(userId); return Result.success(total); UserPoints userPoints = pointsFlowService.getUserPointsTotal(userId); return Result.success(userPoints); } catch (Exception e) { log.error("获取用户积分统计失败", e); return Result.error("获取用户积分统计失败:" + e.getMessage()); @@ -264,13 +262,27 @@ @GetMapping("/total/unit/{unitId}") @ApiOperation("获取单位积分统计") public Result<Object> getUnitPointsTotal(@ApiParam("单位ID") @PathVariable Long unitId) { public Result<UserPoints> getUnitPointsTotal(@ApiParam("单位ID") @PathVariable Long unitId) { try { Integer total = pointsFlowService.getUnitPointsTotal(unitId); UserPoints total = pointsFlowService.getUnitPointsTotal(unitId); return Result.success(total); } catch (Exception e) { log.error("获取单位积分统计失败", e); return Result.error("获取单位积分统计失败:" + e.getMessage()); } } // ==================== 积分流水数据类目 ==================== @GetMapping("/flow/categories") @ApiOperation("获取积分流水数据类目列表") public Result<Object> getPointsFlowCategories() { try { List<String> categories = pointsFlowService.getPointsFlowCategories(); return Result.success(categories); } catch (Exception e) { log.error("获取积分流水数据类目失败", e); return Result.error("获取积分流水数据类目失败:" + e.getMessage()); } } } src/main/java/com/webmanage/dto/AddPointsFlowDTO.java
@@ -22,20 +22,28 @@ @NotNull(message = "单位ID不能为空") private Long unitId; @ApiModelProperty("规则类型(获得/消费)") @NotBlank(message = "规则类型不能为空") private String ruleType; @ApiModelProperty("规则类型(0获得/1消费)") @NotNull(message = "规则类型不能为空") private Integer ruleType; @ApiModelProperty("规则名称") @NotBlank(message = "规则名称不能为空") private String ruleName; @ApiModelProperty("积分规则类别(资源贡献、资源传播、资源交易、交流社区互动)") @NotBlank(message = "规则类别不能为空") private String category; @ApiModelProperty("积分规则类别(资源贡献、资源传播、资源交易、交流社区互动)") @NotBlank(message = "积分规则编码") private String ruleNameCode; @ApiModelProperty("数据类目)") @NotBlank(message = "数据类目不能为空") private String dataCategoty; @ApiModelProperty("关联订单ID") private String orderId; @ApiModelProperty("积分流水描述") private String description; @ApiModelProperty("触发次数(默认为1)") private Integer count = 1; @ApiModelProperty("流水描述(可选,不填则使用规则描述)") private String description; } src/main/java/com/webmanage/dto/PointsFlowQueryDTO.java
@@ -25,20 +25,23 @@ @ApiModelProperty("单位ID") private Long unitId; @ApiModelProperty("流水类型(获得/消费)") private String flowType; @ApiModelProperty("流水类型(0获得1/消费)") private Integer dataType; @ApiModelProperty("积分来源") private String pointsSource; @ApiModelProperty("数据类目") private String dataCategory; @ApiModelProperty("关联订单ID") private String orderId; @ApiModelProperty("开始时间") private LocalDateTime startTime; private LocalDateTime flowStartTime; @ApiModelProperty("结束时间") private LocalDateTime endTime; private LocalDateTime flowEndTime; @ApiModelProperty("排序字段") private String orderBy = "created_at"; src/main/java/com/webmanage/dto/PointsRuleDTO.java
@@ -1,5 +1,6 @@ package com.webmanage.dto; import com.baomidou.mybatisplus.annotation.TableField; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; @@ -16,39 +17,44 @@ public class PointsRuleDTO { @ApiModelProperty("主键ID") private Long id; private Long pointsId; @ApiModelProperty("规则名称") @NotBlank(message = "规则名称不能为空") private String ruleName; @ApiModelProperty("规则编码") @NotBlank(message = "规则编码不能为空") private String ruleNameCode; @ApiModelProperty("规则类型(获得/消费)") @NotBlank(message = "规则类型不能为空") private String ruleType; @NotNull(message = "规则类型不能为空") private Integer ruleType; @ApiModelProperty("规则类别") private String category; @ApiModelProperty("积分值") @NotNull(message = "积分值不能为空") private Integer pointsValue; @ApiModelProperty("触发条件") @NotBlank(message = "触发条件不能为空") private String triggerCondition; @ApiModelProperty("触发金额") private BigDecimal triggerAmount; @ApiModelProperty("规则描述") private String description; private String ruleDescription; @ApiModelProperty("是否启用") private Boolean isEnabled = true; @ApiModelProperty("优先级") private Integer priority = 1; @ApiModelProperty("每日上限") private Integer dailyLimit; @ApiModelProperty("有效期开始时间") private String validStartTime; @ApiModelProperty("积分拥有者(0贡献值1用户)") private Integer pointsWinner; @ApiModelProperty("有效期结束时间") private String validEndTime; @ApiModelProperty("积分是否有上限(0有1没有)") private Integer isLimit; @ApiModelProperty("排序") private Integer ruleOrder; } src/main/java/com/webmanage/dto/PointsRuleDetailDTO.java
File was deleted src/main/java/com/webmanage/emun/RuleTypeEnum.java
@@ -9,16 +9,16 @@ */ public enum RuleTypeEnum { GET(0L,"获取"),CONSUME(1L,"消费"); private Long code; GET(0,"获取"),CONSUME(1,"消费"); private Integer code; private String name; RuleTypeEnum(Long code, String name) { RuleTypeEnum(Integer code, String name) { this.code = code; this.name = name; } public Long getCode() { public Integer getCode() { return code; } src/main/java/com/webmanage/entity/PointsFlow.java
@@ -48,7 +48,7 @@ * 数据类型 */ @TableField("data_type") private String dataType; private Integer dataType; /** * 名称/描述 @@ -86,4 +86,10 @@ @TableLogic @TableField("deleted") private Integer deleted; /** * 规则ID */ @TableField("rule_id") private Long rlueId; } src/main/java/com/webmanage/entity/PointsRule.java
@@ -28,9 +28,13 @@ @TableId(value = "id", type = IdType.AUTO) private Long id; @ApiModelProperty("points_id") @TableField("points_id") private Long pointsId; @ApiModelProperty("规则类型(0获得/1消费)") @TableField("rule_type") private Long ruleType; private Integer ruleType; @ApiModelProperty("规则类别") @TableField("category") @@ -40,13 +44,17 @@ @TableField("rule_name") private String ruleName; @ApiModelProperty("规则编码") @TableField("rule_name_code") private String ruleNameCode; @ApiModelProperty("规则描述") @TableField("rule_description") private String ruleDescription; @ApiModelProperty("是否启用") @TableField("is_enabled") private Boolean isEnabled; private Integer isEnabled; @ApiModelProperty("创建时间") @TableField(value = "created_at", fill = FieldFill.INSERT) @@ -69,4 +77,17 @@ @ApiModelProperty("积分是否有上限(0有1没有)") @TableField("is_limit") private Integer isLimit; @ApiModelProperty("排序") @TableField("rule_order") private Integer ruleOrder; @ApiModelProperty("积分值") @TableField("points_value") private Integer pointsValue; @ApiModelProperty("每日上限") @TableField("daily_limit") private Integer dailyLimit; } src/main/java/com/webmanage/entity/PointsRuleDetail.java
File was deleted src/main/java/com/webmanage/entity/PointsRuleEntity.java
File was deleted src/main/java/com/webmanage/mapper/PointsFlowMapper.java
@@ -16,17 +16,4 @@ @Mapper public interface PointsFlowMapper extends BaseMapper<PointsFlow> { /** * 分页查询积分流水 */ IPage<PointsFlow> selectPage(Page<PointsFlow> page, @Param("userId") Long userId, @Param("unitId") Long unitId, @Param("dataCategory") String dataCategory, @Param("dataType") String dataType, @Param("startTime") String startTime, @Param("endTime") String endTime, @Param("year") String year, @Param("month") String month, @Param("day") String day); } src/main/java/com/webmanage/mapper/PointsRuleDetailMapper.java
File was deleted src/main/java/com/webmanage/mapper/PointsRuleMapper.java
@@ -3,6 +3,10 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.webmanage.entity.PointsRule; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; import org.springframework.web.bind.annotation.RequestParam; import java.util.List; /** * 积分规则Mapper接口 @@ -12,4 +16,5 @@ */ @Mapper public interface PointsRuleMapper extends BaseMapper<PointsRule> { } src/main/java/com/webmanage/service/PointsFlowService.java
@@ -5,6 +5,7 @@ import com.webmanage.dto.AddPointsFlowDTO; import com.webmanage.dto.PointsFlowQueryDTO; import com.webmanage.entity.PointsFlow; import com.webmanage.entity.UserPoints; import java.util.List; @@ -33,11 +34,6 @@ */ List<PointsFlow> getPointsFlowByUnitId(Long unitId); /** * 记录积分流水 */ boolean recordPointsFlow(Long userId, Long unitId, String flowType, String pointsSource, Integer pointsValue, String orderId, String description); /** * 新增积分流水(根据规则自动计算) @@ -47,10 +43,15 @@ /** * 获取用户积分统计 */ Integer getUserPointsTotal(Long userId); UserPoints getUserPointsTotal(Long userId); /** * 获取单位积分统计 */ Integer getUnitPointsTotal(Long unitId); UserPoints getUnitPointsTotal(Long unitId); /** * 获取积分流水数据类目列表 */ List<String> getPointsFlowCategories(); } src/main/java/com/webmanage/service/PointsRuleDetailService.java
File was deleted src/main/java/com/webmanage/service/PointsRuleService.java
@@ -27,7 +27,7 @@ /** * 修改积分规则 */ boolean updatePointsRule(PointsRuleDTO pointsRuleDTO); boolean updatePointsRule(List<PointsRuleDTO> pointsRuleDetailsVOS); /** * 删除积分规则 src/main/java/com/webmanage/service/impl/PointsFlowServiceImpl.java
@@ -8,6 +8,7 @@ import com.webmanage.common.PageResult; import com.webmanage.dto.AddPointsFlowDTO; import com.webmanage.dto.PointsFlowQueryDTO; import com.webmanage.emun.RuleTypeEnum; import com.webmanage.entity.PointsFlow; import com.webmanage.entity.PointsRule; import com.webmanage.entity.UserPoints; @@ -24,6 +25,7 @@ import java.time.LocalDate; import java.time.LocalDateTime; import java.util.List; import java.util.stream.Collectors; /** * 积分流水Service实现类 @@ -47,8 +49,7 @@ Page<PointsFlow> page = new Page<>(queryDTO.getPageNum(), queryDTO.getPageSize()); QueryWrapper<PointsFlow> wrapper = new QueryWrapper<>(); wrapper.eq("deleted", 0) .eq("user_id", queryDTO.getUserId()); wrapper.eq("user_id", queryDTO.getUserId()); buildQueryWrapper(wrapper, queryDTO); @@ -72,8 +73,7 @@ Page<PointsFlow> page = new Page<>(queryDTO.getPageNum(), queryDTO.getPageSize()); QueryWrapper<PointsFlow> wrapper = new QueryWrapper<>(); wrapper.eq("deleted", 0) .eq("unit_id", queryDTO.getUnitId()); wrapper.eq("unit_id", queryDTO.getUnitId()); buildQueryWrapper(wrapper, queryDTO); @@ -118,36 +118,6 @@ @Override @Transactional(rollbackFor = Exception.class) public boolean recordPointsFlow(Long userId, Long unitId, String flowType, String pointsSource, Integer pointsValue, String orderId, String description) { if (userId == null || unitId == null || !StringUtils.hasText(flowType) || !StringUtils.hasText(pointsSource) || pointsValue == null) { throw new BusinessException("参数不完整"); } // 创建积分流水记录 PointsFlow pointsFlow = new PointsFlow(); pointsFlow.setUserId(userId); pointsFlow.setUnitId(unitId); pointsFlow.setDataType(flowType); pointsFlow.setDataCategory(pointsSource); pointsFlow.setPoints(pointsValue); pointsFlow.setName(description); pointsFlow.setFlowTime(LocalDateTime.now()); boolean saved = save(pointsFlow); if (!saved) { throw new BusinessException("保存积分流水失败"); } // 更新用户积分 updateUserPoints(userId, unitId, pointsValue); return true; } @Override @Transactional(rollbackFor = Exception.class) public boolean addPointsFlowByRule(AddPointsFlowDTO addPointsFlowDTO) { if (addPointsFlowDTO == null) { throw new BusinessException("参数不能为空"); @@ -155,14 +125,15 @@ Long userId = addPointsFlowDTO.getUserId(); Long unitId = addPointsFlowDTO.getUnitId(); String ruleType = addPointsFlowDTO.getRuleType(); String ruleName = addPointsFlowDTO.getRuleName(); Integer ruleType = addPointsFlowDTO.getRuleType(); String category = addPointsFlowDTO.getCategory(); String ruleNameCode = addPointsFlowDTO.getRuleNameCode(); Integer count = addPointsFlowDTO.getCount() != null ? addPointsFlowDTO.getCount() : 1; // 查询积分规则 PointsRule pointsRule = pointsRuleService.getRuleByTriggerCondition(ruleName); // 根据ruleType、ruleNameCode、category查询生效时间最新的积分规则 PointsRule pointsRule = getLatestEffectiveRule(ruleType, ruleNameCode, category); if (pointsRule == null) { throw new BusinessException("积分规则不存在或未启用: " + ruleName); throw new BusinessException("积分规则不存在或未启用: ruleType=" + ruleType + ", ruleNameCode=" + ruleNameCode + ", category=" + category); } // 验证规则类型是否匹配 @@ -171,17 +142,22 @@ } // 计算积分值 Integer basePoints = 0; //pointsRule.getPointsValue() != null ? pointsRule.getPointsValue() : 0; Integer basePoints = pointsRule.getPointsValue() != null ? pointsRule.getPointsValue() : 0; Integer totalPoints = basePoints * count; // 如果是消费类型,积分为负数 if ("消费".equals(ruleType)) { if (ruleType == RuleTypeEnum.CONSUME.getCode()) { // 1表示消费类型 totalPoints = -totalPoints; } // 检查每日积分上限 if (basePoints > 0) { checkDailyLimit(userId, unitId, ruleName, totalPoints, 0); if (pointsRule.getIsLimit() != null && pointsRule.getIsLimit() == 0) { // 0表示有每日上限 checkDailyLimitByRule(userId, unitId, pointsRule, totalPoints); } // 如果是扣积分操作,先检查余额是否足够 if (totalPoints < 0) { checkBalanceSufficient(userId, unitId, Math.abs(totalPoints)); } // 创建积分流水记录 @@ -189,10 +165,11 @@ pointsFlow.setUserId(userId); pointsFlow.setUnitId(unitId); pointsFlow.setDataType(ruleType); pointsFlow.setDataCategory(ruleName); pointsFlow.setDataCategory(addPointsFlowDTO.getCategory()); pointsFlow.setPoints(totalPoints); pointsFlow.setName(addPointsFlowDTO.getDescription() != null ? addPointsFlowDTO.getDescription() : pointsRule.getRuleDescription()); pointsFlow.setFlowTime(LocalDateTime.now()); pointsFlow.setRlueId(pointsRule.getId()); boolean saved = save(pointsFlow); if (!saved) { @@ -200,15 +177,15 @@ } // 更新用户积分账户 updateUserPointsByRule(userId, unitId, totalPoints, ruleType); updateUserPointsByRule(userId, unitId, totalPoints); return true; } @Override public Integer getUserPointsTotal(Long userId) { public UserPoints getUserPointsTotal(Long userId) { if (userId == null) { return 0; throw new BusinessException("用户ID不能为null"); } QueryWrapper<UserPoints> wrapper = new QueryWrapper<>(); @@ -216,13 +193,13 @@ .eq("user_id", userId); UserPoints userPoints = userPointsMapper.selectOne(wrapper); return userPoints != null ? userPoints.getBalance() : 0; return userPoints ; } @Override public Integer getUnitPointsTotal(Long unitId) { public UserPoints getUnitPointsTotal(Long unitId) { if (unitId == null) { return 0; throw new BusinessException("用户ID不能为null"); } QueryWrapper<UserPoints> wrapper = new QueryWrapper<>(); @@ -230,15 +207,37 @@ .eq("unit_id", unitId); UserPoints userPoints = userPointsMapper.selectOne(wrapper); return userPoints != null ? userPoints.getBalance() : 0; return userPoints; } @Override public List<String> getPointsFlowCategories() { QueryWrapper<PointsFlow> wrapper = new QueryWrapper<>(); wrapper.select("DISTINCT data_category") .isNotNull("data_category") .ne("data_category", "") .ne("data_category", "null") .eq("deleted", 0) .orderByAsc("data_category"); List<PointsFlow> flows = list(wrapper); return flows.stream() .map(PointsFlow::getDataCategory) .filter(category -> category != null && !category.trim().isEmpty()) .distinct() .sorted() .collect(Collectors.toList()); } /** * 构建查询条件 */ private void buildQueryWrapper(QueryWrapper<PointsFlow> wrapper, PointsFlowQueryDTO queryDTO) { if (StringUtils.hasText(queryDTO.getFlowType())) { wrapper.eq("flow_type", queryDTO.getFlowType()); if(StringUtils.hasText(queryDTO.getDataCategory())){ wrapper.eq("data_category", queryDTO.getDataCategory()); } if (queryDTO.getDataType()!=null) { wrapper.eq("data_type", queryDTO.getDataType()); } if (StringUtils.hasText(queryDTO.getPointsSource())) { wrapper.eq("points_source", queryDTO.getPointsSource()); @@ -246,18 +245,100 @@ if (StringUtils.hasText(queryDTO.getOrderId())) { wrapper.eq("order_id", queryDTO.getOrderId()); } if (queryDTO.getStartTime() != null) { wrapper.ge("flow_time", queryDTO.getStartTime()); if (queryDTO.getFlowEndTime() != null) { wrapper.ge("flow_time", queryDTO.getFlowStartTime()); } if (queryDTO.getEndTime() != null) { wrapper.le("flow_time", queryDTO.getEndTime()); if (queryDTO.getFlowEndTime() != null) { wrapper.le("flow_time", queryDTO.getFlowEndTime()); } wrapper.orderByDesc("flow_time"); } /** * 检查每日积分上限 * 根据ruleType、ruleNameCode、category查询生效时间最新的积分规则 */ private PointsRule getLatestEffectiveRule(Integer ruleType, String ruleNameCode, String category) { QueryWrapper<PointsRule> wrapper = new QueryWrapper<>(); wrapper.eq("deleted", 0) .eq("is_enabled", 0) // 0表示启用 .eq("rule_type", ruleType) .eq("rule_name_code", ruleNameCode) .eq("category", category) .orderByDesc("created_at") // 按创建时间倒序,获取最新的规则 .last("LIMIT 1"); return pointsRuleService.getOne(wrapper); } /** * 检查每日积分上限(基于规则) */ private void checkDailyLimitByRule(Long userId, Long unitId, PointsRule pointsRule, Integer currentPoints) { // 获取今日开始和结束时间 LocalDate today = LocalDate.now(); LocalDateTime startOfDay = today.atStartOfDay(); LocalDateTime endOfDay = today.atTime(23, 59, 59); // 查询今日该规则的积分流水 QueryWrapper<PointsFlow> wrapper = new QueryWrapper<>(); wrapper.eq("deleted", 0) .eq("user_id", userId) .eq("unit_id", unitId) // .eq("data_category", pointsRule.getRuleName()) .eq("rule_id",pointsRule.getId()) .ge("flow_time", startOfDay) .le("flow_time", endOfDay); List<PointsFlow> todayFlows = list(wrapper); // 计算今日累计积分 int todayTotal = todayFlows.stream() .mapToInt(flow -> flow.getPoints() != null ? flow.getPoints() : 0) .sum(); // 获取规则的每日积分上限 Integer dailyLimit = pointsRule.getDailyLimit(); if (dailyLimit != null && dailyLimit > 0) { // 如果今日累计积分超过每日上限,则抛出异常 if (Math.abs(todayTotal) >= dailyLimit) { throw new BusinessException("今日该规则积分已达上限: " + dailyLimit); } // 如果加上当前积分会超过每日上限,则抛出异常 if (Math.abs(todayTotal + currentPoints) > dailyLimit) { throw new BusinessException("本次积分操作将超过每日上限: " + dailyLimit + ",当前已累计: " + Math.abs(todayTotal)); } } } /** * 检查积分余额是否足够 */ private void checkBalanceSufficient(Long userId, Long unitId, Integer requiredPoints) { // 检查个人积分余额 QueryWrapper<UserPoints> userWrapper = new QueryWrapper<>(); userWrapper.eq("deleted", 0) .eq("user_id", userId); UserPoints userPoints = userPointsMapper.selectOne(userWrapper); if (userPoints == null || userPoints.getBalance() < requiredPoints) { throw new BusinessException("个人积分余额不足,当前余额: " + (userPoints != null ? userPoints.getBalance() : 0) + ",需要扣除: " + requiredPoints); } // 检查单位积分余额 QueryWrapper<UserPoints> unitWrapper = new QueryWrapper<>(); unitWrapper.eq("deleted", 0) .eq("unit_id", unitId); UserPoints unitPoints = userPointsMapper.selectOne(unitWrapper); if (unitPoints == null || unitPoints.getBalance() < requiredPoints) { throw new BusinessException("单位积分余额不足,当前余额: " + (unitPoints != null ? unitPoints.getBalance() : 0) + ",需要扣除: " + requiredPoints); } } /** * 检查每日积分上限(旧方法,保留兼容性) */ private void checkDailyLimit(Long userId, Long unitId, String ruleName, Integer currentPoints, Integer priority) { // 获取今日开始和结束时间 @@ -331,7 +412,7 @@ /** * 根据规则更新用户积分账户 */ private void updateUserPointsByRule(Long userId, Long unitId, Integer pointsValue, String ruleType) { private void updateUserPointsByRule(Long userId, Long unitId, Integer pointsValue) { // 更新个人积分账户 QueryWrapper<UserPoints> userWrapper = new QueryWrapper<>(); userWrapper.eq("deleted", 0) @@ -339,6 +420,11 @@ UserPoints userPoints = userPointsMapper.selectOne(userWrapper); if (userPoints == null) { // 如果是新用户且是扣积分操作,余额不足 if (pointsValue < 0) { throw new BusinessException("积分余额不足,无法扣除积分"); } userPoints = new UserPoints(); userPoints.setUserId(userId); userPoints.setUnitId(unitId); @@ -347,6 +433,11 @@ userPoints.setTotalConsumed(pointsValue < 0 ? Math.abs(pointsValue) : 0); userPointsMapper.insert(userPoints); } else { // 检查扣积分时余额是否足够 if (pointsValue < 0 && userPoints.getBalance() + pointsValue < 0) { throw new BusinessException("积分余额不足,当前余额: " + userPoints.getBalance() + ",需要扣除: " + Math.abs(pointsValue)); } userPoints.setBalance(userPoints.getBalance() + pointsValue); // 更新累计获取积分 @@ -372,6 +463,11 @@ UserPoints unitPoints = userPointsMapper.selectOne(unitWrapper); if (unitPoints == null) { // 如果是新单位且是扣积分操作,余额不足 if (pointsValue < 0) { throw new BusinessException("单位积分余额不足,无法扣除积分"); } unitPoints = new UserPoints(); unitPoints.setUserId(userId); unitPoints.setUnitId(unitId); @@ -380,6 +476,11 @@ unitPoints.setTotalConsumed(pointsValue < 0 ? Math.abs(pointsValue) : 0); userPointsMapper.insert(unitPoints); } else { // 检查扣积分时余额是否足够 if (pointsValue < 0 && unitPoints.getBalance() + pointsValue < 0) { throw new BusinessException("单位积分余额不足,当前余额: " + unitPoints.getBalance() + ",需要扣除: " + Math.abs(pointsValue)); } unitPoints.setBalance(unitPoints.getBalance() + pointsValue); // 更新累计获取积分 src/main/java/com/webmanage/service/impl/PointsRuleDetailServiceImpl.java
File was deleted src/main/java/com/webmanage/service/impl/PointsRuleServiceImpl.java
@@ -5,24 +5,30 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.webmanage.common.BusinessException; import com.webmanage.dto.PointsRuleDTO; import com.webmanage.emun.RuleTypeEnum; import com.webmanage.entity.Points; import com.webmanage.entity.PointsRule; import com.webmanage.entity.PointsRuleDetail; import com.webmanage.mapper.PointsRuleMapper; import com.webmanage.service.PointsRuleService; import com.webmanage.service.PointsService; import com.webmanage.service.PointsRuleDetailService; import com.webmanage.vo.PointsRuleResultVO; import com.webmanage.vo.PointsRuleVO; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; import java.beans.Transient; import java.text.DateFormat; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.Comparator; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -37,8 +43,6 @@ @Autowired private PointsService pointsService; @Autowired private PointsRuleDetailService pointsRuleDetailService; @Override public PointsRuleResultVO getPointsRuleList(Long ruleId) { @@ -54,7 +58,7 @@ List<PointsRule> list = list(wrapper); PointsRuleResultVO pointsRuleResultVO = new PointsRuleResultVO(); if (!CollectionUtil.isEmpty(list)) { Map<Long, List<PointsRule>> collect = list.stream().collect(Collectors.groupingBy(PointsRule::getRuleType)); Map<Integer, List<PointsRule>> collect = list.stream().collect(Collectors.groupingBy(PointsRule::getRuleType)); Map<String, List<PointsRule>> getRules = collect.get(RuleTypeEnum.GET.getCode()).stream().collect(Collectors.groupingBy(PointsRule::getCategory)); Map<String, List<PointsRule>> consumeRules = collect.get(RuleTypeEnum.CONSUME.getCode()).stream().collect(Collectors.groupingBy(PointsRule::getCategory)); @@ -62,6 +66,7 @@ List<PointsRuleVO> consumePointsRuleVOList = new ArrayList<>(); getRules.forEach((k,v)->{ PointsRuleVO pointsRuleVO = new PointsRuleVO(); pointsRuleVO.setRlueSort(v.get(0).getRuleOrder()); pointsRuleVO.setCategory(k); pointsRuleVO.setPointsRules(v); getPointsRuleVOList.add(pointsRuleVO); @@ -69,11 +74,14 @@ }); consumeRules.forEach((k,v)->{ PointsRuleVO pointsRuleVO = new PointsRuleVO(); pointsRuleVO.setRlueSort(v.get(0).getRuleOrder()); pointsRuleVO.setCategory(k); pointsRuleVO.setPointsRules(v); consumePointsRuleVOList.add(pointsRuleVO); }); getPointsRuleVOList.sort(Comparator.comparing(PointsRuleVO::getRlueSort)); consumePointsRuleVOList.sort(Comparator.comparing(PointsRuleVO::getRlueSort)); pointsRuleResultVO.setGetPointsRuleList(getPointsRuleVOList); pointsRuleResultVO.setConsumePointsRuleList(consumePointsRuleVOList); } @@ -99,48 +107,42 @@ } @Override public boolean updatePointsRule(PointsRuleDTO pointsRuleDTO) { if (pointsRuleDTO.getId() == null) { throw new BusinessException("规则ID不能为空"); @Transactional(rollbackFor = Exception.class) public boolean updatePointsRule(List<PointsRuleDTO> pointsRuleDTO) { if (CollectionUtils.isEmpty(pointsRuleDTO)){ return false; } PointsRule existingRule = getById(pointsRuleDTO.getId()); if (existingRule == null) { throw new BusinessException("积分规则不存在"); } // 验证规则名称是否重复(排除自身) QueryWrapper<PointsRule> wrapper = new QueryWrapper<>(); wrapper.eq("rule_name", pointsRuleDTO.getRuleName()) .eq("deleted", 0) .ne("id", pointsRuleDTO.getId()); if (count(wrapper) > 0) { throw new BusinessException("规则名称已存在"); } // 查询规则名称 Points pointsOld = pointsService.query().eq("id", pointsRuleDTO.get(0).getPointsId()) .eq("deleted", 0).one(); // 查询当天是否有版本更新记录 DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("YYYY-MM-DD HH:mm:ss"); LocalDateTime nowDatetime = LocalDateTime.now(); LocalDateTime localDateTimeStart = nowDatetime.toLocalDate().atStartOfDay(); LocalDateTime localDateTimeEnd = nowDatetime.toLocalDate().atStartOfDay(); // dateTimeFormatter.format(localDateTimeStart), dateTimeFormatter.format(localDateTimeEnd) Long counts = pointsService.query().between("created_at", localDateTimeStart, localDateTimeEnd).count(); // 创建新的积分主表记录 Points points = new Points(); points.setPointsName(pointsRuleDTO.getRuleName() + "_" + System.currentTimeMillis()); points.setPointsName(pointsOld.getPointsName()); points.setEffectiveStart(LocalDateTime.now()); points.setModifierId(1L); // 这里应该从上下文中获取当前用户ID points.setModifierId(pointsOld.getModifierId()); // 这里应该从上下文中获取当前用户ID points.setModifierName("admin"); // 这里应该从上下文中获取当前用户名 points.setVersion(1.0f); points.setVersion(counts>0 ? pointsOld.getVersion() + 0.1f: 1.0f); points.setStatus(0); pointsService.save(points); // 创建积分规则详情记录 PointsRuleDetail pointsRuleDetail = new PointsRuleDetail(); pointsRuleDetail.setRuleId(pointsRuleDTO.getId()); pointsRuleDetail.setPointsId(points.getId()); pointsRuleDetail.setPointsValue(pointsRuleDTO.getPointsValue()); pointsRuleDetail.setEffectiveStart(LocalDateTime.now()); pointsRuleDetailService.save(pointsRuleDetail); // 创建积分规则记录 for (PointsRuleDTO ruleDTO : pointsRuleDTO) { PointsRule pointsRule = new PointsRule(); BeanUtils.copyProperties(ruleDTO,pointsRule); pointsRule.setPointsId(points.getId()); pointsRule.setUpdatedAt(LocalDateTime.now()); save(pointsRule); } BeanUtils.copyProperties(pointsRuleDTO, existingRule); existingRule.setUpdatedAt(LocalDateTime.now()); return updateById(existingRule); return true; } @Override @@ -168,7 +170,7 @@ throw new BusinessException("积分规则不存在"); } pointsRule.setIsEnabled(isEnabled); pointsRule.setIsEnabled(isEnabled ? 0: 1); pointsRule.setUpdatedAt(LocalDateTime.now()); return updateById(pointsRule); src/main/java/com/webmanage/vo/PointsRuleVO.java
New file @@ -0,0 +1,20 @@ package com.webmanage.vo; import com.webmanage.entity.PointsRule; import lombok.Data; import java.util.List; /** * @ClassName PointsRuleVO * @Description TODO * @Author wangxudong * @Date 2025/8/14 21:05 * @Version 1.0 **/ @Data public class PointsRuleVO { private String category; List<PointsRule> pointsRules; private Integer rlueSort; } src/main/resources/mapper/PointsFlowMapper.xml
File was deleted