Forráskód Böngészése

feat(store): 添加退款审核功能- 在 FsStorePaymentScrm 实体中新增退款审核相关字段(状态、审核人、审核时间、审核备注)
- 在控制器层增加退款审核前的状态检查逻辑- 新增退款审核接口,支持审核通过或拒绝,并记录审核信息
- 新增查询退款审核详情接口
- 在 Mapper XML 中补充退款审核字段的映射与 CRUD 操作-服务层实现退款审核业务逻辑,包括参数校验、状态更新及数据一致性验证
- 引入 SecurityUtils 工具类以安全获取当前操作用户作为审核人- 控制器和服务层均支持带审核人参数的退款审核方法- 增加对退款审核状态的权限控制和日志记录

xw 2 hete
szülő
commit
71600b0904

+ 42 - 0
fs-admin/src/main/java/com/fs/hisStore/controller/FsStorePaymentScrmController.java

@@ -173,6 +173,12 @@ public class FsStorePaymentScrmController extends BaseController
         if(payment.getStatus()!=1){
             return R.error("非法操作");
         }
+        
+        // 检查退款审核状态
+        if(payment.getRefundAuditStatus() == null || payment.getRefundAuditStatus() != 1){
+            return R.error("退款申请尚未审核或审核未通过,不能执行退款");
+        }
+        
         if(fsStorePayment.getRefundMoney().compareTo(new BigDecimal(0))<1){
             return R.error("退款金额必须大于0");
         }
@@ -295,4 +301,40 @@ public class FsStorePaymentScrmController extends BaseController
     {
         return toAjax(fsStorePaymentService.deleteFsStorePaymentByIds(paymentIds));
     }
+
+    /**
+     * 退款审核
+     */
+    @PreAuthorize("@ss.hasPermi('store:storePayment:refundAudit')")
+    @Log(title = "退款审核", businessType = BusinessType.UPDATE)
+    @PutMapping("/refund/audit")
+    public R auditRefund(@RequestBody Map<String, Object> auditData)
+    {
+        Long paymentId = Long.valueOf(auditData.get("paymentId").toString());
+        Integer auditStatus = Integer.valueOf(auditData.get("auditStatus").toString());
+        String auditRemark = auditData.get("auditRemark") != null ? auditData.get("auditRemark").toString() : "";
+        
+        // 在控制器层直接获取当前用户名
+        String currentUser = "system"; // 默认值
+        try {
+            currentUser = getUsername(); // 使用父类 BaseController 的方法
+            logger.info("控制器层获取到的用户名: {}", currentUser);
+        } catch (Exception e) {
+            logger.warn("控制器层获取用户名失败: {}", e.getMessage());
+        }
+        
+        // 传递用户名到服务层
+        return fsStorePaymentService.auditRefund(paymentId, auditStatus, auditRemark, currentUser);
+    }
+
+    /**
+     * 获取退款审核详情
+     */
+    @PreAuthorize("@ss.hasPermi('store:storePayment:query')")
+    @GetMapping("/refund/audit/{paymentId}")
+    public AjaxResult getRefundAuditDetail(@PathVariable("paymentId") Long paymentId)
+    {
+        FsStorePaymentScrm paymentDetail = fsStorePaymentService.getRefundAuditDetail(paymentId);
+        return AjaxResult.success(paymentDetail);
+    }
 }

+ 32 - 0
fs-company/src/main/java/com/fs/hisStore/controller/FsStorePaymentScrmController.java

@@ -170,6 +170,11 @@ public class FsStorePaymentScrmController extends BaseController
         if(payment.getStatus()!=1){
             return R.error("非法操作");
         }
+        // 检查退款审核状态
+        if(payment.getRefundAuditStatus() == null || payment.getRefundAuditStatus() != 1){
+            return R.error("退款申请尚未审核或审核未通过,不能执行退款");
+        }
+
         if(fsStorePayment.getRefundMoney().compareTo(new BigDecimal(0))<1){
             return R.error("退款金额必须大于0");
         }
@@ -269,4 +274,31 @@ public class FsStorePaymentScrmController extends BaseController
         }
         return R.error("非法操作");
     }
+
+
+    /**
+     * 退款审核
+     */
+    @PreAuthorize("@ss.hasPermi('store:storePayment:refundAudit')")
+    @Log(title = "退款审核", businessType = BusinessType.UPDATE)
+    @PutMapping("/refund/audit")
+    public R auditRefund(@RequestBody Map<String, Object> auditData)
+    {
+        Long paymentId = Long.valueOf(auditData.get("paymentId").toString());
+        Integer auditStatus = Integer.valueOf(auditData.get("auditStatus").toString());
+        String auditRemark = auditData.get("auditRemark") != null ? auditData.get("auditRemark").toString() : "";
+
+        return fsStorePaymentService.auditRefund(paymentId, auditStatus, auditRemark);
+    }
+
+    /**
+     * 获取退款审核详情
+     */
+    @PreAuthorize("@ss.hasPermi('store:storePayment:query')")
+    @GetMapping("/refund/audit/{paymentId}")
+    public AjaxResult getRefundAuditDetail(@PathVariable("paymentId") Long paymentId)
+    {
+        FsStorePaymentScrm paymentDetail = fsStorePaymentService.getRefundAuditDetail(paymentId);
+        return AjaxResult.success(paymentDetail);
+    }
 }

+ 17 - 2
fs-service/src/main/java/com/fs/hisStore/domain/FsStorePaymentScrm.java

@@ -1,13 +1,14 @@
 package com.fs.hisStore.domain;
 
-import java.math.BigDecimal;
-import java.util.Date;
 import com.fasterxml.jackson.annotation.JsonFormat;
 import com.fs.common.annotation.Excel;
 import com.fs.common.core.domain.BaseEntity;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 
+import java.math.BigDecimal;
+import java.util.Date;
+
 /**
  * 支付明细对象 fs_store_payment
  *
@@ -110,6 +111,20 @@ public class FsStorePaymentScrm extends BaseEntity
      * **/
     private BigDecimal reductionAmount;
 
+    /** 退款审核状态 0-待审核 1-审核通过 2-审核拒绝 */
+    @Excel(name = "退款审核状态")
+    private Integer refundAuditStatus;
+
+    /** 退款审核人 */
+    @Excel(name = "退款审核人")
+    private String refundAuditBy;
 
+    /** 退款审核时间 */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @Excel(name = "退款审核时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
+    private Date refundAuditTime;
 
+    /** 退款审核备注 */
+    @Excel(name = "退款审核备注")
+    private String refundAuditRemark;
 }

+ 26 - 0
fs-service/src/main/java/com/fs/hisStore/service/IFsStorePaymentScrmService.java

@@ -132,4 +132,30 @@ public interface IFsStorePaymentScrmService
      * @return 扫码流水日统计
      * **/
     List<FsStoreScanPaymentStatDetailsVo> getScanPaymentStatPage(FsStoreScanPaymentStatParam param);
+
+    /**
+     * 退款审核
+     * @param paymentId 支付ID
+     * @param auditStatus 审核状态 1-通过 2-拒绝
+     * @param auditRemark 审核备注
+     * @return 审核结果
+     */
+    R auditRefund(Long paymentId, Integer auditStatus, String auditRemark);
+
+    /**
+     * 退款审核(带审核人参数)
+     * @param paymentId 支付ID
+     * @param auditStatus 审核状态 1-通过 2-拒绝
+     * @param auditRemark 审核备注
+     * @param auditBy 审核人
+     * @return 审核结果
+     */
+    R auditRefund(Long paymentId, Integer auditStatus, String auditRemark, String auditBy);
+
+    /**
+     * 获取退款审核详情
+     * @param paymentId 支付ID
+     * @return 退款审核详情
+     */
+    FsStorePaymentScrm getRefundAuditDetail(Long paymentId);
 }

+ 82 - 1
fs-service/src/main/java/com/fs/hisStore/service/impl/FsStorePaymentScrmServiceImpl.java

@@ -1,6 +1,5 @@
 package com.fs.hisStore.service.impl;
 
-
 import cn.binarywang.wx.miniapp.api.WxMaService;
 import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
 import cn.hutool.core.util.IdUtil;
@@ -15,6 +14,7 @@ import com.fs.common.core.page.TableDataInfo;
 import com.fs.common.core.redis.RedisCache;
 import com.fs.common.exception.ServiceException;
 import com.fs.common.utils.DateUtils;
+import com.fs.common.utils.SecurityUtils;
 import com.fs.common.utils.StringUtils;
 import com.fs.company.domain.Company;
 import com.fs.company.domain.CompanyUser;
@@ -1012,4 +1012,85 @@ public class FsStorePaymentScrmServiceImpl implements IFsStorePaymentScrmService
                 && config.getScanCodeDiscountAmount() != null
                 && config.getScanCodeDiscountAmount().compareTo(BigDecimal.ZERO) > 0;
     }
+
+    @Override
+    @Transactional
+    public R auditRefund(Long paymentId, Integer auditStatus, String auditRemark) {
+        // 安全获取当前用户名,如果获取失败则使用系统默认值
+        String auditBy;
+        try {
+            auditBy = SecurityUtils.getUsername();
+            logger.info("服务层SecurityUtils获取的用户名: {}", auditBy);
+        } catch (Exception e) {
+            auditBy = "system";
+            logger.warn("服务层SecurityUtils获取用户名失败,异常信息: {}", e.getMessage());
+            logger.warn("异常类型: {}", e.getClass().getSimpleName());
+        }
+        return auditRefund(paymentId, auditStatus, auditRemark, auditBy);
+    }
+
+    @Override
+    @Transactional
+    public R auditRefund(Long paymentId, Integer auditStatus, String auditRemark, String auditBy) {
+        logger.info("开始退款审核,paymentId: {}, auditStatus: {}, auditRemark: {}, auditBy: {}", 
+                    paymentId, auditStatus, auditRemark, auditBy);
+        
+        // 参数校验
+        if (paymentId == null) {
+            return R.error("支付ID不能为空");
+        }
+        if (auditStatus == null || (auditStatus != 1 && auditStatus != 2)) {
+            return R.error("审核状态错误,1-通过,2-拒绝");
+        }
+
+        // 查询支付记录
+        FsStorePaymentScrm payment = fsStorePaymentMapper.selectFsStorePaymentById(paymentId);
+        if (payment == null) {
+            return R.error("支付记录不存在");
+        }
+
+        // 检查支付状态
+        if (payment.getStatus() != 1) {
+            return R.error("只有已支付的订单才能申请退款");
+        }
+
+        // 检查是否已经审核过
+        if (payment.getRefundAuditStatus() != null && payment.getRefundAuditStatus() != 0) {
+            return R.error("该退款申请已经审核过,不能重复审核");
+        }
+
+        // 更新审核信息
+        payment.setRefundAuditStatus(auditStatus);
+        payment.setRefundAuditBy(auditBy);
+        payment.setRefundAuditTime(new Date());
+        payment.setRefundAuditRemark(auditRemark);
+        
+        logger.info("即将更新数据库,审核人: {}", auditBy);
+
+        int updateResult = fsStorePaymentMapper.updateFsStorePayment(payment);
+        if (updateResult > 0) {
+            logger.info("数据库更新成功,更新行数: {}", updateResult);
+            
+            // 验证数据是否正确写入
+            FsStorePaymentScrm updatedPayment = fsStorePaymentMapper.selectFsStorePaymentById(paymentId);
+            logger.info("数据库中的审核人: {}, 审核状态: {}, 审核时间: {}", 
+                        updatedPayment.getRefundAuditBy(), 
+                        updatedPayment.getRefundAuditStatus(), 
+                        updatedPayment.getRefundAuditTime());
+            
+            String statusText = auditStatus == 1 ? "通过" : "拒绝";
+            return R.ok("退款审核" + statusText + "成功");
+        } else {
+            logger.error("数据库更新失败,更新行数: {}", updateResult);
+            return R.error("审核失败,请重试");
+        }
+    }
+
+    @Override
+    public FsStorePaymentScrm getRefundAuditDetail(Long paymentId) {
+        if (paymentId == null) {
+            return null;
+        }
+        return fsStorePaymentMapper.selectFsStorePaymentById(paymentId);
+    }
 }

+ 17 - 1
fs-service/src/main/resources/mapper/hisStore/FsStorePaymentScrmMapper.xml

@@ -28,10 +28,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <result property="orderId"    column="order_id"    />
         <result property="isPayRemain"    column="is_pay_remain"    />
         <result property="payMode"    column="pay_mode"    />
+        <result property="refundAuditStatus"    column="refund_audit_status"    />
+        <result property="refundAuditRemark"    column="refund_audit_remark"    />
+        <result property="refundAuditBy"    column="refund_audit_by"    />
+        <result property="refundAuditTime"    column="refund_audit_time"    />
     </resultMap>
 
     <sql id="selectFsStorePaymentVo">
-        select payment_id,pay_mode, pay_code, pay_type_code, pay_money, pay_time, create_time, trade_no, user_id, open_id, business_type, business_order_id, status,remark,company_id,company_user_id,dept_id,bank_transaction_id,bank_serial_no,refund_money,refund_time,order_id,is_pay_remain from fs_store_payment_scrm
+        select payment_id,pay_mode, pay_code, pay_type_code, pay_money, pay_time, create_time, trade_no, user_id, open_id, business_type, business_order_id, status,remark,company_id,company_user_id,dept_id,bank_transaction_id,bank_serial_no,refund_money,refund_time,order_id,is_pay_remain,refund_audit_status,refund_audit_remark,refund_audit_by,refund_audit_time from fs_store_payment_scrm
 
     </sql>
 
@@ -90,6 +94,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="payMode != null">pay_mode,</if>
             <if test="originalAmount != null">original_amount,</if>
             <if test="reductionAmount != null">reduction_amount,</if>
+            <if test="refundAuditStatus != null">refund_audit_status,</if>
+            <if test="refundAuditBy != null">refund_audit_by,</if>
+            <if test="refundAuditTime != null">refund_audit_time,</if>
+            <if test="refundAuditRemark != null">refund_audit_remark,</if>
         </trim>
         <trim prefix="values (" suffix=")" suffixOverrides=",">
             <if test="payCode != null">#{payCode},</if>
@@ -116,6 +124,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="payMode != null">#{payMode},</if>
             <if test="originalAmount != null">#{originalAmount},</if>
             <if test="reductionAmount != null">#{reductionAmount},</if>
+            <if test="refundAuditStatus != null">#{refundAuditStatus},</if>
+            <if test="refundAuditBy != null">#{refundAuditBy},</if>
+            <if test="refundAuditTime != null">#{refundAuditTime},</if>
+            <if test="refundAuditRemark != null">#{refundAuditRemark},</if>
         </trim>
     </insert>
 
@@ -146,6 +158,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="payMode != null">pay_mode = #{payMode},</if>
             <if test="originalAmount != null">original_amount=#{originalAmount},</if>
             <if test="reductionAmount != null">reduction_amount=#{reductionAmount},</if>
+            <if test="refundAuditStatus != null">refund_audit_status = #{refundAuditStatus},</if>
+            <if test="refundAuditBy != null">refund_audit_by = #{refundAuditBy},</if>
+            <if test="refundAuditTime != null">refund_audit_time = #{refundAuditTime},</if>
+            <if test="refundAuditRemark != null">refund_audit_remark = #{refundAuditRemark},</if>
         </trim>
         where payment_id = #{paymentId}
     </update>