3个文件已添加
10个文件已修改
342 ■■■■■ 已修改文件
src/main/java/com/webmanage/controller/OrderController.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/webmanage/controller/PointsController.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/webmanage/dto/DeductUserPointsDTO.java 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/webmanage/entity/OrderInfo.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/webmanage/entity/PointsTransaction.java 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/webmanage/mapper/PointsTransactionMapper.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/webmanage/service/OrderInfoService.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/webmanage/service/PointsFlowService.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/webmanage/service/impl/OrderInfoServiceImpl.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/webmanage/service/impl/PointsFlowServiceImpl.java 142 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/webmanage/vo/OrderDetailVO.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application.yml 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/OrderInfoMapper.xml 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/webmanage/controller/OrderController.java
@@ -373,4 +373,16 @@
            return Result.error("查询失败:" + e.getMessage());
        }
    }
    @PostMapping("/status/isEvaluate")
    @ApiOperation("更新评价状态")
    public Result<Object> updateOrderInfoIsEvaluate(@ApiParam("订单ID") @RequestParam @NotBlank String orderId){
        try {
            boolean success = orderInfoService.updateOrderIsEvaluate(orderId);
            return success ? Result.success("评价状态更新成功") : Result.error("评价状态更新失败");
        } catch (Exception e) {
            log.error("评价状态更新失败", e);
            return Result.error("评价状态更新失败:" + e.getMessage());
        }
    }
}
src/main/java/com/webmanage/controller/PointsController.java
@@ -272,6 +272,24 @@
        }
    }
    // ==================== 积分扣减 ====================
    @PostMapping("/user/deduct")
    @ApiOperation("扣减用户积分")
    public Result<Object> deductUserPoints(@Valid @RequestBody DeductUserPointsDTO deductDTO) {
        try {
            boolean result = pointsFlowService.deductUserPoints(deductDTO);
            if (result) {
                return Result.success("积分扣减成功");
            } else {
                return Result.error("积分扣减失败");
            }
        } catch (Exception e) {
            log.error("积分扣减失败", e);
            return Result.error("积分扣减失败:" + e.getMessage());
        }
    }
    // ==================== 积分流水数据类目 ====================
    @GetMapping("/flow/categories")
src/main/java/com/webmanage/dto/DeductUserPointsDTO.java
New file
@@ -0,0 +1,44 @@
package com.webmanage.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Positive;
/**
 * 扣减用户积分DTO
 */
@Data
@ApiModel(value = "DeductUserPointsDTO", description = "扣减用户积分")
public class DeductUserPointsDTO {
    @ApiModelProperty("用户ID")
    @NotBlank(message = "用户ID不能为空")
    private String userId;
    @ApiModelProperty("单位ID")
    private String unitId;
    @ApiModelProperty("扣减积分数量")
    @NotNull(message = "扣减积分数量不能为空")
    @Positive(message = "扣减积分数量必须大于0")
    private Integer points;
    @ApiModelProperty("订单ID")
    private String orderId;
    @ApiModelProperty("扣减原因/备注")
    private String remark;
    @ApiModelProperty("数据类目")
    private String dataCategory = "resource_transaction";
    @ApiModelProperty("数据类型")
    private Integer dataType = 1; // 1表示消耗
    @ApiModelProperty("提供者")
    private String providerId;
}
src/main/java/com/webmanage/entity/OrderInfo.java
@@ -141,4 +141,11 @@
    @TableLogic
    @TableField("deleted")
    private Integer deleted;
    /**
     *是否评论
     */
    @TableField("is_evaluate")
    private String isEvaluate;
}
src/main/java/com/webmanage/entity/PointsTransaction.java
New file
@@ -0,0 +1,74 @@
package com.webmanage.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.time.LocalDateTime;
/**
 * 积分交易记录实体,对应表 tb_points_transaction
 */
@Data
@TableName("tb_points_transaction")
@ApiModel(value = "PointsTransaction", description = "积分交易记录")
public class PointsTransaction {
    @ApiModelProperty("主键ID")
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    @ApiModelProperty("数据类目")
    @TableField("data_category")
    private String dataCategory;
    @ApiModelProperty("名称")
    @TableField("transaction_name")
    private String transactionName;
    @ApiModelProperty("时间")
    @TableField("transaction_time")
    private LocalDateTime transactionTime;
    @ApiModelProperty("积分变动值")
    @TableField("points_change")
    private Integer pointsChange;
    @ApiModelProperty("积分规则类型:获取/消耗")
    @TableField("rule_type")
    private String ruleType;
    @ApiModelProperty("用户ID")
    @TableField("user_id")
    private Long userId;
    @ApiModelProperty("企业ID")
    @TableField("unit_id")
    private Long unitId;
    @ApiModelProperty("用户类型:个人用户/单位用户")
    @TableField("user_type")
    private String userType;
    @ApiModelProperty("关联规则ID")
    @TableField("rule_id")
    private Long ruleId;
    @ApiModelProperty("关联规则详情ID")
    @TableField("detail_id")
    private Long detailId;
    @ApiModelProperty("创建时间")
    @TableField("created_at")
    private LocalDateTime createdAt;
    @ApiModelProperty("逻辑删除")
    @TableField("deleted")
    private Integer deleted;
}
src/main/java/com/webmanage/mapper/PointsTransactionMapper.java
New file
@@ -0,0 +1,11 @@
package com.webmanage.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.webmanage.entity.PointsTransaction;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface PointsTransactionMapper extends BaseMapper<PointsTransaction> {
}
src/main/java/com/webmanage/service/OrderInfoService.java
@@ -152,4 +152,6 @@
     * @return 存在返回true,不存在返回false
     */
    boolean existsCompletedNotCancelledOrderByProductId(String productId);
    boolean updateOrderIsEvaluate(String orderId);
}
src/main/java/com/webmanage/service/PointsFlowService.java
@@ -3,6 +3,7 @@
import com.baomidou.mybatisplus.extension.service.IService;
import com.webmanage.common.PageResult;
import com.webmanage.dto.AddPointsFlowDTO;
import com.webmanage.dto.DeductUserPointsDTO;
import com.webmanage.dto.PointsFlowQueryDTO;
import com.webmanage.entity.PointsFlow;
import com.webmanage.entity.UserPoints;
@@ -41,6 +42,11 @@
    boolean addPointsFlowByRule(AddPointsFlowDTO addPointsFlowDTO);
    /**
     * 扣减用户积分
     */
    boolean deductUserPoints(DeductUserPointsDTO deductDTO);
    /**
     * 获取用户积分统计
     */
    UserPoints getUserPointsTotal(String userId);
src/main/java/com/webmanage/service/impl/OrderInfoServiceImpl.java
@@ -464,6 +464,7 @@
        orderInfo.setPaymentType(createOrderDTO.getPaymentType());
        orderInfo.setPaymentStatus("未支付");
        orderInfo.setBuyerRemarks(createOrderDTO.getBuyerRemarks());
        orderInfo.setIsEvaluate("未评价");
        orderInfo.setCreatedAt(LocalDateTime.now());
        orderInfo.setUpdatedAt(LocalDateTime.now());
@@ -1199,4 +1200,17 @@
        Long count = this.baseMapper.selectCount(wrapper);
        return count != null && count > 0;
    }
    @Override
    public boolean updateOrderIsEvaluate(String orderId) {
        if (!StringUtils.hasText(orderId)) {
            throw new BusinessException("订单ID不能为空");
        }
        OrderInfo orderInfo = this.getById(orderId);
        if (orderInfo == null) {
            throw new BusinessException("订单不存在");
        }
        orderInfo.setIsEvaluate("已评价");
        return this.updateById(orderInfo);
    }
}
src/main/java/com/webmanage/service/impl/PointsFlowServiceImpl.java
@@ -7,6 +7,7 @@
import com.webmanage.common.BusinessException;
import com.webmanage.common.PageResult;
import com.webmanage.dto.AddPointsFlowDTO;
import com.webmanage.dto.DeductUserPointsDTO;
import com.webmanage.dto.PointsFlowQueryDTO;
import com.webmanage.emun.RuleTypeEnum;
import com.webmanage.entity.PointsFlow;
@@ -14,6 +15,9 @@
import com.webmanage.entity.UserPoints;
import com.webmanage.mapper.PointsFlowMapper;
import com.webmanage.mapper.UserPointsMapper;
import com.webmanage.mapper.PointsTransactionMapper;
import com.webmanage.entity.PointsTransaction;
import com.webmanage.service.OrderInfoService;
import com.webmanage.service.PointsFlowService;
import com.webmanage.service.PointsRuleService;
import lombok.extern.slf4j.Slf4j;
@@ -39,6 +43,10 @@
    @Resource
    private PointsRuleService pointsRuleService;
    @Resource
    private PointsTransactionMapper pointsTransactionMapper;
    @Override
    public PageResult<PointsFlow> getPersonalPointsFlowPage(PointsFlowQueryDTO queryDTO) {
@@ -381,7 +389,7 @@
     * 检查积分余额是否足够
     */
    private void checkBalanceSufficient(String userId, String unitId, Integer requiredPoints) {
        // 检查个人积分余额
        // 仅检查个人积分余额(移除单位余额判定)
        QueryWrapper<UserPoints> userWrapper = new QueryWrapper<>();
        userWrapper.eq("deleted", 0)
                  .eq("user_id", userId);
@@ -391,15 +399,7 @@
            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);
        }
        // 原单位余额校验已移除
    }
    /**
@@ -566,6 +566,92 @@
    }
    /**
     * 扣减用户积分
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deductUserPoints(DeductUserPointsDTO deductDTO) {
        try {
            String userId = deductDTO.getUserId();
            String providerId = deductDTO.getProviderId();
            String unitId = deductDTO.getUnitId();
            Integer points = deductDTO.getPoints();
            String orderId = deductDTO.getOrderId();
            String remark = deductDTO.getRemark();
            String dataCategory = deductDTO.getDataCategory();
            Integer dataType = deductDTO.getDataType();
            if (!StringUtils.hasText(userId)) {
                throw new BusinessException("用户ID不能为空");
            }
            if (points == null || points <= 0) {
                throw new BusinessException("扣减积分数量必须大于0");
            }
            // 检查用户积分余额是否充足
            checkBalanceSufficient(userId, unitId, points);
            // 创建积分流水记录
            PointsFlow pointsFlow = new PointsFlow();
            pointsFlow.setUserId(userId);
            pointsFlow.setUnitId(unitId);
            pointsFlow.setDataCategory(dataCategory != null ? dataCategory : "积分交易");
            pointsFlow.setDataType(dataType != null ? dataType : 1);
            pointsFlow.setPoints(-points); // 负数表示扣减
            pointsFlow.setName(remark != null ? remark : "积分扣减"); // name字段存储remark内容
            pointsFlow.setFlowTime(LocalDateTime.now());
            pointsFlow.setRlueId(null); // 直接扣减,不关联规则
            boolean saved = save(pointsFlow);
            if (!saved) {
                throw new BusinessException("保存积分流水失败");
            }
            // 更新用户积分账户
            updateUserPointsOnly(userId, -points);
            // 新增积分交易记录(与流水同事务)
            PointsTransaction trans = new PointsTransaction();
            // tb_points_transaction 的 chk_data_category 仅允许 '用户参与'、'其他'
            // 这里将业务类目映射为数据库允许的值
            trans.setDataCategory("用户参与");
            trans.setTransactionName(pointsFlow.getName());
            trans.setTransactionTime(LocalDateTime.now());
            trans.setPointsChange(-points);
            trans.setRuleType("消耗");
            try {
                trans.setUserId(Long.valueOf(userId));
            } catch (Exception ignore) {}
            try {
                if (StringUtils.hasText(unitId)) trans.setUnitId(Long.valueOf(unitId));
            } catch (Exception ignore) {}
            trans.setUserType("个人用户");
            trans.setRuleId(null);
            trans.setDetailId(null);
            trans.setCreatedAt(LocalDateTime.now());
            trans.setDeleted(0);
            int inserted = pointsTransactionMapper.insert(trans);
            log.info("Points transaction inserted rows={}, id={}", inserted, trans.getId());
            if (inserted <= 0 || trans.getId() == null) {
                throw new BusinessException("保存积分交易记录失败");
            }
            // 为提供者新增积分
            AddPointsFlowDTO addPointsFlowDTO = new AddPointsFlowDTO();
            addPointsFlowDTO.setCategory("资源交易");
            addPointsFlowDTO.setCount(1);
            addPointsFlowDTO.setProviderId(providerId);
            addPointsFlowDTO.setRuleType(0);
            addPointsFlowDTO.setRuleNameCode("digital_product_transaction");
            addPointsFlowDTO.setDescription("产品交易");
            addPointsFlowByRule(addPointsFlowDTO);
            return true;
        } catch (Exception e) {
            log.error("扣减用户积分失败", e);
            throw new BusinessException("扣减用户积分失败:" + e.getMessage());
        }
    }
    /**
     * 仅更新提供者(单位)积分账户
     */
    private void updateProviderUnitPoints(String providerUnitId, Integer pointsValue) {
@@ -606,4 +692,40 @@
            userPointsMapper.updateById(unitPoints);
        }
    }
    /**
     * 仅更新个人积分账户(不操作单位账户)
     */
    private void updateUserPointsOnly(String userId, Integer pointsValue) {
        // 更新个人积分账户
        QueryWrapper<UserPoints> userWrapper = new QueryWrapper<>();
        userWrapper.eq("deleted", 0)
                  .eq("user_id", userId);
        UserPoints userPoints = userPointsMapper.selectOne(userWrapper);
        if (userPoints == null) {
            if (pointsValue < 0) {
                throw new BusinessException("个人积分余额不足,无法扣除积分");
            }
            userPoints = new UserPoints();
            userPoints.setUserId(userId);
            userPoints.setUnitId(null);
            userPoints.setBalance(pointsValue);
            userPoints.setTotalEarned(pointsValue > 0 ? pointsValue : 0);
            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);
            if (pointsValue > 0) {
                userPoints.setTotalEarned(userPoints.getTotalEarned() != null ? userPoints.getTotalEarned() + pointsValue : pointsValue);
            }
            if (pointsValue < 0) {
                userPoints.setTotalConsumed(userPoints.getTotalConsumed() != null ? userPoints.getTotalConsumed() + Math.abs(pointsValue) : Math.abs(pointsValue));
            }
            userPoints.setUpdateTime(LocalDateTime.now());
            userPointsMapper.updateById(userPoints);
        }
    }
}
src/main/java/com/webmanage/vo/OrderDetailVO.java
@@ -80,4 +80,7 @@
    @ApiModelProperty("订单评价")
    private OrderEvaluationVO evaluation;
    @ApiModelProperty("是否评价")
    private String isEvaluate;
}
src/main/resources/application.yml
@@ -1,13 +1,13 @@
server:
  port: 8080
  port: 8089
  servlet:
    context-path: /admin
spring:
  application:
    name: web-manage-back
    name: trade-back
  profiles:
    active: dev
    active: test
  jackson:
    date-format: yyyy-MM-dd HH:mm:ss
    time-zone: GMT+8
src/main/resources/mapper/OrderInfoMapper.xml
@@ -24,13 +24,14 @@
        <result column="created_at" property="createdAt" jdbcType="TIMESTAMP"/>
        <result column="updated_at" property="updatedAt" jdbcType="TIMESTAMP"/>
        <result column="deleted" property="deleted" jdbcType="INTEGER"/>
        <result column="is_evaluate" property="isEvaluate" jdbcType="VARCHAR"/>
    </resultMap>
    <!-- 基础字段列表 -->
    <sql id="Base_Column_List">
        order_id, product_id, user_id, unit_id, product_name, provider_name, provider_id,
        apply_time, order_status, total_amount, payment_type, payment_status, workflow_id,
        current_step, approval_flow, buyer_remarks, seller_remarks, created_at, updated_at, deleted
        current_step, approval_flow, buyer_remarks, seller_remarks, created_at, updated_at, deleted, is_evaluate
    </sql>
    <!-- 分页查询买家订单列表 -->