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

feat(store): 实现立减金退款功能

- 新增立减金退款申请接口,支持用户申请未使用立减金的退款
- 新增立减金退款审核接口,支持管理员审核退款申请- 新增立减金直接退款接口,支持后台直接执行退款操作
- 集成汇付支付退款接口,实现原路退款功能
- 新增立减金购买记录关联查询,确保退款准确性- 新增立减金状态校验逻辑,防止重复退款或非法操作- 修改立减金查询方法名以区分不同场景使用- 完善支付记录创建逻辑,补充交易流水号和支付时间字段
-优化立减金重复购买检查逻辑,提升用户体验
- 添加详细的退款日志记录,便于问题追踪和审计
xw 3 hete
szülő
commit
5367c17f3c

+ 26 - 0
fs-admin/src/main/java/com/fs/hisStore/controller/FsStoreCouponUserScrmController.java

@@ -3,17 +3,23 @@ package com.fs.hisStore.controller;
 import com.fs.common.annotation.Log;
 import com.fs.common.core.controller.BaseController;
 import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.core.domain.R;
 import com.fs.common.core.page.TableDataInfo;
 import com.fs.common.enums.BusinessType;
 import com.fs.common.utils.ParseUtils;
 import com.fs.common.utils.poi.ExcelUtil;
 import com.fs.hisStore.domain.FsStoreCouponUserScrm;
+import com.fs.hisStore.param.FsStoreCashCouponRefundApprovalParam;
+import com.fs.hisStore.param.FsStoreCashCouponRefundParam;
+import com.fs.hisStore.service.IFsStoreCouponIssueScrmService;
 import com.fs.hisStore.service.IFsStoreCouponUserScrmService;
 import com.fs.hisStore.vo.FsStoreCouponUserVO;
+import io.swagger.annotations.ApiOperation;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.web.bind.annotation.*;
 
+import javax.servlet.http.HttpServletRequest;
 import java.util.List;
 
 /**
@@ -28,6 +34,8 @@ public class FsStoreCouponUserScrmController extends BaseController
 {
     @Autowired
     private IFsStoreCouponUserScrmService fsStoreCouponUserService;
+    @Autowired
+    private IFsStoreCouponIssueScrmService fsStoreCouponIssueService;
 
     /**
      * 查询优惠券发放记录列表
@@ -106,4 +114,22 @@ public class FsStoreCouponUserScrmController extends BaseController
     {
         return toAjax(fsStoreCouponUserService.deleteFsStoreCouponUserByIds(ids));
     }
+
+
+    @PreAuthorize("@ss.hasPermi('store:storeCouponUser:refundCashCoupon')")
+    @ApiOperation("立减金退款")
+    @PostMapping("/refundCashCoupon")
+    public R refundCashCoupon(@RequestBody FsStoreCashCouponRefundParam param, HttpServletRequest request) {
+        return fsStoreCouponIssueService.refundCashCoupon(getUserId(), param);
+    }
+
+     /**
+     * 审批立减金退款
+     */
+    @PreAuthorize("@ss.hasPermi('store:storeCouponUser:approveCashCouponRefund')")
+    @ApiOperation("审批立减金退款")
+    @PostMapping("/approveCashCouponRefund")
+    public R approveCashCouponRefund(@RequestBody FsStoreCashCouponRefundApprovalParam param, HttpServletRequest request) {
+        return fsStoreCouponIssueService.approveCashCouponRefund(param);
+    }
 }

+ 3 - 0
fs-service/src/main/java/com/fs/his/service/impl/FsStorePaymentServiceImpl.java

@@ -1234,10 +1234,13 @@ public class FsStorePaymentServiceImpl implements IFsStorePaymentService {
         storePayment.setPayCode(IdUtil.getSnowflake(0, 0).nextIdStr());
         storePayment.setPayMoney(payParam.getCouponPrice());
         storePayment.setCreateTime(new Date());
+        storePayment.setPayTime(new Date());
         storePayment.setPayTypeCode("weixin");
         storePayment.setBusinessType(3);
         storePayment.setRemark("购买立减金");
+        storePayment.setBusinessOrderId(payParam.getCouponId().toString());
         storePayment.setOpenId(user.getMaOpenId());
+        storePayment.setTradeNo(IdUtil.getSnowflake(0, 0).nextIdStr());
         storePayment.setUserId(user.getUserId());
         //支付订单创建失败
         if (fsStorePaymentScrmMapper.insertFsStorePayment(storePayment) <= 0) {

+ 16 - 1
fs-service/src/main/java/com/fs/hisStore/mapper/FsStoreCouponIssueUserScrmMapper.java

@@ -1,10 +1,11 @@
 package com.fs.hisStore.mapper;
 
-import java.util.List;
 import com.fs.hisStore.domain.FsStoreCouponIssueUserScrm;
 import org.apache.ibatis.annotations.Param;
 import org.apache.ibatis.annotations.Select;
 
+import java.util.List;
+
 /**
  * 优惠券用户领取记录Mapper接口
  * 
@@ -62,4 +63,18 @@ public interface FsStoreCouponIssueUserScrmMapper
     public int deleteFsStoreCouponIssueUserByIds(Long[] ids);
     @Select("select ifnull(count(1),0) from fs_store_coupon_issue_user_scrm where user_id=#{userId} and issue_id=#{id} ")
     int checkReceive(@Param("userId") String userId,@Param("id") Long id);
+
+    /**
+     * 检查用户是否已购买过相同立减金且未使用
+     * @param userId 用户ID
+     * @param issueId 发放记录ID
+     * @param couponId 立减金ID
+     * @return 未使用的立减金数量
+     */
+    @Select("select ifnull(count(1),0) from fs_store_coupon_user_scrm " +
+            "where user_id=#{userId} and coupon_id=#{couponId} " +
+            "and type='purchase' and status=0 and is_del=0")
+    int checkReceiveLjjc(@Param("userId") String userId, @Param("issueId") Long issueId, @Param("couponId") Long couponId);
+
+
 }

+ 16 - 1
fs-service/src/main/java/com/fs/hisStore/mapper/FsStoreCouponUserScrmMapper.java

@@ -107,7 +107,7 @@ public interface FsStoreCouponUserScrmMapper
     List<FsStoreCouponUserVO> selectFsStoreCouponUserListVO(@Param("maps") FsStoreCouponUserScrm fsStoreCouponUser);
     @Select({"<script> " +
             "select cu.*,u.nickname,u.phone from fs_store_coupon_user_scrm cu inner join fs_user u  on u.user_id=cu.user_id inner join fs_store_coupon_scrm c on c.coupon_id = cu.coupon_id   " +
-            "where  cu.is_del=0 and c.type=3 and cu.status=0 " +
+            "where  cu.is_del=0 and c.type=3   " +
             "<if test = 'maps.status != null     '> " +
             "and cu.status =#{maps.status} " +
             "</if>" +
@@ -138,4 +138,19 @@ public interface FsStoreCouponUserScrmMapper
             "</if>" +
             "</script>"})
     List<FsStoreCouponUserScrm> selectFsStoreCouponUserListByEnableForCash(@Param("maps") FsCouponUserEnableParam param);
+
+    @Select({"<script> " +
+            "select cu.*,u.nickname,u.phone from fs_store_coupon_user_scrm cu inner join fs_user u  on u.user_id=cu.user_id inner join fs_store_coupon_scrm c on c.coupon_id = cu.coupon_id   " +
+            "where  cu.is_del=0 and c.type=3 and cu.status=0  " +
+            "<if test = 'maps.status != null     '> " +
+            "and cu.status =#{maps.status} " +
+            "</if>" +
+            "<if test = 'maps.isDel != null     '> " +
+            "and cu.is_del =#{maps.isDel} " +
+            "</if>" +
+            "<if test = 'maps.userId != null     '> " +
+            "and cu.user_id =#{maps.userId} " +
+            "</if>" +
+            "</script>"})
+    List<FsStoreCouponUserVO> selectFsStoreCouponUserListAppVOForCash(@Param("maps") FsStoreCouponUserScrm map);
 }

+ 8 - 0
fs-service/src/main/java/com/fs/hisStore/service/IFsStoreCouponIssueScrmService.java

@@ -3,6 +3,8 @@ package com.fs.hisStore.service;
 import com.fs.common.core.domain.R;
 import com.fs.hisStore.domain.FsStoreCouponIssueScrm;
 import com.fs.hisStore.param.FsCouponIssueParam;
+import com.fs.hisStore.param.FsStoreCashCouponRefundApprovalParam;
+import com.fs.hisStore.param.FsStoreCashCouponRefundParam;
 import com.fs.hisStore.param.FsStoreCouponPurchaseParam;
 import com.fs.hisStore.param.FsStoreCouponReceiveParam;
 import com.fs.hisStore.vo.FsStoreCouponIssueVO;
@@ -78,4 +80,10 @@ public interface IFsStoreCouponIssueScrmService
     List<FsStoreCouponIssueVO> selectFsStoreCouponIssueListVOForCash(FsStoreCouponIssueScrm fsStoreCouponIssue);
 
     R purchaseCashCoupon(String userId, FsStoreCouponPurchaseParam param);
+
+    R refundCashCoupon(Long userId, FsStoreCashCouponRefundParam param);
+
+    R applyCashCouponRefund(String userId, FsStoreCashCouponRefundParam param);
+
+    R approveCashCouponRefund(FsStoreCashCouponRefundApprovalParam param);
 }

+ 2 - 0
fs-service/src/main/java/com/fs/hisStore/service/IFsStoreCouponUserScrmService.java

@@ -71,4 +71,6 @@ public interface IFsStoreCouponUserScrmService
     List<FsStoreCouponUserVO> selectFsStoreCouponUserListVOForCash(FsStoreCouponUserScrm fsStoreCouponUser);
 
     List<FsStoreCouponUserScrm> selectFsStoreCouponUserListByEnableForCash(FsCouponUserEnableParam param);
+
+    List<FsStoreCouponUserVO> selectFsStoreCouponUserListAppVOForCash(FsStoreCouponUserScrm map);
 }

+ 321 - 4
fs-service/src/main/java/com/fs/hisStore/service/impl/FsStoreCouponIssueScrmServiceImpl.java

@@ -8,11 +8,18 @@ import com.fs.his.service.IFsStorePaymentService;
 import com.fs.hisStore.domain.*;
 import com.fs.hisStore.mapper.*;
 import com.fs.hisStore.param.FsCouponIssueParam;
+import com.fs.hisStore.param.FsStoreCashCouponRefundApprovalParam;
+import com.fs.hisStore.param.FsStoreCashCouponRefundParam;
 import com.fs.hisStore.param.FsStoreCouponPurchaseParam;
 import com.fs.hisStore.param.FsStoreCouponReceiveParam;
 import com.fs.hisStore.param.FsStorePaymentPayParam;
 import com.fs.hisStore.service.IFsStoreCouponIssueScrmService;
+import com.fs.hisStore.service.IFsStoreCouponUserScrmService;
+import com.fs.hisStore.service.IFsStorePaymentScrmService;
 import com.fs.hisStore.vo.FsStoreCouponIssueVO;
+import com.fs.huifuPay.sdk.opps.core.request.V2TradePaymentScanpayRefundRequest;
+import com.fs.huifuPay.domain.HuiFuRefundResult;
+import com.fs.huifuPay.service.HuiFuService;
 
 import lombok.Synchronized;
 import lombok.extern.slf4j.Slf4j;
@@ -20,8 +27,10 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
+import java.text.SimpleDateFormat;
 import java.util.Calendar;
 import java.util.Date;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
@@ -49,6 +58,12 @@ public class FsStoreCouponIssueScrmServiceImpl implements IFsStoreCouponIssueScr
     private FsUserScrmMapper userMapper;
     @Autowired
     private IFsStorePaymentService storePaymentService;
+    @Autowired
+    private IFsStoreCouponUserScrmService couponUserService;
+    @Autowired
+    private IFsStorePaymentScrmService paymentService;
+    @Autowired
+    private HuiFuService huiFuService;
     /**
      * 查询优惠券领取
      *
@@ -216,10 +231,10 @@ public class FsStoreCouponIssueScrmServiceImpl implements IFsStoreCouponIssueScr
             return R.error("此立减金已停止购买");
         }
 
-//        // 检查用户是否已购买过
-//        if (fsStoreCouponIssueUserMapper.checkReceive(userId, param.getId()) > 0) {
-//            return R.error("您已购买此立减金,使用后再购买哦!");
-//        }
+        // 检查用户是否已购买过
+        if (fsStoreCouponIssueUserMapper.checkReceiveLjjc(userId, param.getId(), couponIssue.getCouponId()) > 0) {
+            return R.error("您已购买此立减金,使用后再购买哦!");
+        }
 
         // 获取立减金详细信息
         FsStoreCouponScrm coupon = couponMapper.selectFsStoreCouponById(couponIssue.getCouponId());
@@ -280,4 +295,306 @@ public class FsStoreCouponIssueScrmServiceImpl implements IFsStoreCouponIssueScr
         }
     }
 
+    @Override
+    @Transactional
+    public R refundCashCoupon(Long userId, FsStoreCashCouponRefundParam param) {
+        try {
+            // 验证用户和立减金记录
+            FsStoreCouponUserScrm couponUser = couponUserService.selectFsStoreCouponUserById(param.getId());
+            if (couponUser == null) {
+                return R.error("立减金记录不存在");
+            }
+
+            // 验诃立减金类型
+            if (param.getCouponType() == null || param.getCouponType() != 3) {
+                return R.error("该记录不是立减金");
+            }
+
+            // 验证立减金状态 - 只有未使用的立减金可以退款
+            if (couponUser.getStatus() != 0) {
+                return R.error("立减金已使用或已过期,无法退款");
+            }
+
+            // 验证立减金是否是购买获得的(只有购买的立减金才能退款)
+            if (!"purchase".equals(couponUser.getType())) {
+                return R.error("非购买立减金无法退款");
+            }
+
+            // 查找对应的支付记录(根据立减金所属用户ID、业务类型3、支付金额、已支付状态)
+            // 需要通过couponUser找到对应的issueId,因为支付时存储的businessOrderId是issueId而不是couponId
+            FsStoreCouponIssueUserScrm issueUserQuery = new FsStoreCouponIssueUserScrm();
+            issueUserQuery.setUserId(couponUser.getUserId());
+            issueUserQuery.setIsDel(0);
+            
+            List<FsStoreCouponIssueUserScrm> issueUsers = fsStoreCouponIssueUserMapper.selectFsStoreCouponIssueUserList(issueUserQuery);
+            Long targetIssueId = null;
+            
+            // 找到对应couponId的issueId
+            for (FsStoreCouponIssueUserScrm issueUser : issueUsers) {
+                FsStoreCouponIssueScrm issue = fsStoreCouponIssueMapper.selectFsStoreCouponIssueById(issueUser.getIssueId());
+                if (issue != null && issue.getCouponId().equals(couponUser.getCouponId()) && "purchase".equals(couponUser.getType())) {
+                    // 找到了匹配的issueId,且是购买类型的立减金
+                    targetIssueId = issueUser.getIssueId();
+                    break;
+                }
+            }
+            
+            if (targetIssueId == null) {
+                return R.error("未找到对应的立减金购买记录");
+            }
+            
+            FsStorePaymentScrm queryParam = new FsStorePaymentScrm();
+            queryParam.setUserId(couponUser.getUserId()); // 使用立减金所属的用户ID
+            queryParam.setBusinessType(3); // 立减金购买
+            queryParam.setBusinessOrderId(targetIssueId.toString()); // 使用issueId而不是couponId
+            queryParam.setPayMoney(couponUser.getCouponPrice());
+            queryParam.setStatus(1); // 已支付
+            
+            List<FsStorePaymentScrm> payments = paymentService.selectFsStorePaymentList(queryParam);
+            if (payments == null || payments.isEmpty()) {
+                return R.error("未找到对应的支付记录");
+            }
+
+            FsStorePaymentScrm targetPayment = null;
+            
+
+            for (FsStorePaymentScrm payment : payments) {
+                if (targetPayment == null || payment.getCreateTime().after(targetPayment.getCreateTime())) {
+                    targetPayment = payment;
+                }
+            }
+            
+            // 调用汇付退款接口
+            try {
+                V2TradePaymentScanpayRefundRequest refundRequest = new V2TradePaymentScanpayRefundRequest();
+                refundRequest.setOrdAmt(targetPayment.getPayMoney().toString());
+                refundRequest.setOrgReqDate(new SimpleDateFormat("yyyyMMdd").format(targetPayment.getCreateTime()));
+                refundRequest.setReqSeqId("refund-cash-" + targetPayment.getPayCode());
+                
+                Map<String, Object> extendInfoMap = new HashMap<>();
+                extendInfoMap.put("org_req_seq_id", "payment-" + targetPayment.getPayCode());
+                refundRequest.setExtendInfo(extendInfoMap);
+                
+                HuiFuRefundResult refundResult = huiFuService.refund(refundRequest);
+                log.info("立减金退款返回结果: userId={}, couponUserId={}, result={}", userId, param.getId(), refundResult);
+                
+                // 添加详细的调试日志
+                log.info("退款响应详情: resp_code={}, trans_stat={}, resp_desc={}", 
+                    refundResult.getResp_code(), refundResult.getTrans_stat(), refundResult.getResp_desc());
+
+                if (("00000000".equals(refundResult.getResp_code()) || "00000100".equals(refundResult.getResp_code())) 
+                    && ("S".equals(refundResult.getTrans_stat()) || "P".equals(refundResult.getTrans_stat()))) {
+                    // 退款成功,更新支付记录状态
+                    FsStorePaymentScrm paymentUpdate = new FsStorePaymentScrm();
+                    paymentUpdate.setPaymentId(targetPayment.getPaymentId());
+                    paymentUpdate.setStatus(-1); // 已退款
+                    paymentUpdate.setRefundTime(new Date());
+                    paymentUpdate.setRefundMoney(targetPayment.getPayMoney());
+                    paymentService.updateFsStorePayment(paymentUpdate);
+                    
+                    // 更新立减金状态为已退款
+                    couponUser.setStatus(3); // 3表示已退款状态
+                    couponUser.setUseTime(new Date());
+                    couponUserService.updateFsStoreCouponUser(couponUser);
+                    
+                    return R.ok("立减金退款成功,金额已原路退回");
+                } else {
+                    return R.error("退款失败: " + refundResult.getResp_desc());
+                }
+                
+            } catch (Exception refundException) {
+                log.error("调用汇付退款接口异常: userId={}, paymentId={}", userId, targetPayment.getPaymentId(), refundException);
+                return R.error("退款接口调用失败,请联系客服处理");
+            }
+
+        } catch (Exception e) {
+            log.error("立减金退款异常: userId={}, couponUserId={}", userId, param.getId(), e);
+            return R.error("退款处理异常,请联系客服");
+        }
+    }
+
+    @Override
+    @Transactional
+    public R applyCashCouponRefund(String userId, FsStoreCashCouponRefundParam param) {
+        try {
+            // 验证用户和立减金记录
+            FsStoreCouponUserScrm couponUser = couponUserService.selectFsStoreCouponUserById(param.getId());
+            if (couponUser == null) {
+                return R.error("立减金记录不存在");
+            }
+
+            // 验证立减金归属
+            if (!couponUser.getUserId().toString().equals(userId)) {
+                return R.error("无权限操作此立减金");
+            }
+
+            // 验证立减金类型
+            if (couponUser.getCouponType() == null || couponUser.getCouponType() != 3) {
+                return R.error("该记录不是立减金");
+            }
+
+            // 验证立减金状态 - 只有未使用的立减金可以申请退款
+            if (couponUser.getStatus() != 0) {
+                return R.error("立减金已使用或已过期,无法申请退款");
+            }
+
+            // 验证立减金是否是购买获得的(只有购买的立减金才能退款)
+            if (!"purchase".equals(couponUser.getType())) {
+                return R.error("非购买立减金无法申请退款");
+            }
+
+            // 检查是否已经申请过退款
+            if (couponUser.getStatus() == 4) {
+                return R.error("您已申请过此立减金的退款,请耐心等待审核");
+            }
+
+            // 更新立减金状态为退款申请中
+            couponUser.setStatus(4); // 4表示退款申请中
+            couponUser.setUseTime(new Date()); // 记录申请时间
+            couponUserService.updateFsStoreCouponUser(couponUser);
+            
+            return R.ok("立减金退款申请已提交,请耐心等待审核结果");
+
+        } catch (Exception e) {
+            log.error("立减金退款申请异常: userId={}, couponUserId={}", userId, param.getId(), e);
+            return R.error("退款申请处理异常,请联系客服");
+        }
+    }
+
+    @Override
+    @Transactional
+    public R approveCashCouponRefund(FsStoreCashCouponRefundApprovalParam param) {
+        try {
+            // 验证立减金记录
+            FsStoreCouponUserScrm couponUser = couponUserService.selectFsStoreCouponUserById(param.getId());
+            if (couponUser == null) {
+                return R.error("立减金记录不存在");
+            }
+
+            // 验证立减金类型
+            if (param.getCouponType() == null || param.getCouponType() != 3) {
+                return R.error("该记录不是立减金");
+            }
+
+            // 验证立减金状态 - 只有退款申请中的才能审核
+            if (couponUser.getStatus() != 4) {
+                return R.error("该立减金不是退款申请中状态,无法审核");
+            }
+
+            // 验证立减金是否是购买获得的
+            if (!"purchase".equals(couponUser.getType())) {
+                return R.error("非购买立减金无法退款");
+            }
+
+            if (param.getApprovalStatus() == 1) {
+                // 审核通过,执行退款操作
+                return processRefund(couponUser, param);
+            } else if (param.getApprovalStatus() == 2) {
+                // 审核拒绝,恢复立减金状态
+                couponUser.setStatus(0); // 恢复为未使用状态
+                couponUser.setUseTime(null); // 清除使用时间
+                couponUserService.updateFsStoreCouponUser(couponUser);
+                
+                return R.ok("退款申请已拒绝,立减金已恢复可用");
+            } else {
+                return R.error("无效的审核状态");
+            }
+
+        } catch (Exception e) {
+            log.error("立减金退款审核异常: couponUserId={}, approvalStatus={}", param.getId(), param.getApprovalStatus(), e);
+            return R.error("退款审核处理异常,请联系技术人员");
+        }
+    }
+
+    /**
+     * 处理退款操作
+     */
+    private R processRefund(FsStoreCouponUserScrm couponUser, FsStoreCashCouponRefundApprovalParam param) {
+        try {
+            // 查找对应的支付记录
+            // 需要通过couponUser找到对应的issueId,因为支付时存储的businessOrderId是issueId而不是couponId
+            FsStoreCouponIssueUserScrm issueUserQuery = new FsStoreCouponIssueUserScrm();
+            issueUserQuery.setUserId(couponUser.getUserId());
+            issueUserQuery.setIsDel(0);
+            
+            List<FsStoreCouponIssueUserScrm> issueUsers = fsStoreCouponIssueUserMapper.selectFsStoreCouponIssueUserList(issueUserQuery);
+            Long targetIssueId = null;
+            
+            // 找到对应couponId的issueId
+            for (FsStoreCouponIssueUserScrm issueUser : issueUsers) {
+                FsStoreCouponIssueScrm issue = fsStoreCouponIssueMapper.selectFsStoreCouponIssueById(issueUser.getIssueId());
+                if (issue != null && issue.getCouponId().equals(couponUser.getCouponId()) && "purchase".equals(couponUser.getType())) {
+                    // 找到了匹配的issueId,且是购买类型的立减金
+                    targetIssueId = issueUser.getIssueId();
+                    break;
+                }
+            }
+            
+            if (targetIssueId == null) {
+                return R.error("未找到对应的立减金购买记录");
+            }
+            
+            FsStorePaymentScrm queryParam = new FsStorePaymentScrm();
+            queryParam.setUserId(couponUser.getUserId());
+            queryParam.setBusinessType(3); // 立减金购买
+            queryParam.setBusinessOrderId(targetIssueId.toString()); // 使用issueId而不是couponId
+            queryParam.setPayMoney(couponUser.getCouponPrice());
+            queryParam.setStatus(1); // 已支付
+            
+            List<FsStorePaymentScrm> payments = paymentService.selectFsStorePaymentList(queryParam);
+            if (payments == null || payments.isEmpty()) {
+                return R.error("未找到对应的支付记录");
+            }
+
+            // 选择最近的支付记录
+            FsStorePaymentScrm targetPayment = null;
+            for (FsStorePaymentScrm payment : payments) {
+                if (targetPayment == null || payment.getCreateTime().after(targetPayment.getCreateTime())) {
+                    targetPayment = payment;
+                }
+            }
+            
+            // 调用汇付退款接口
+            V2TradePaymentScanpayRefundRequest refundRequest = new V2TradePaymentScanpayRefundRequest();
+            refundRequest.setOrdAmt(targetPayment.getPayMoney().toString());
+            refundRequest.setOrgReqDate(new SimpleDateFormat("yyyyMMdd").format(targetPayment.getCreateTime()));
+            refundRequest.setReqSeqId("refund-approval-" + targetPayment.getPayCode());
+            
+            Map<String, Object> extendInfoMap = new HashMap<>();
+            extendInfoMap.put("org_req_seq_id", "payment-" + targetPayment.getPayCode());
+            refundRequest.setExtendInfo(extendInfoMap);
+            
+            HuiFuRefundResult refundResult = huiFuService.refund(refundRequest);
+            log.info("立减金退款审核通过返回结果: couponUserId={}, result={}", param.getId(), refundResult);
+            
+            // 添加详细的调试日志
+            log.info("退款响应详情: resp_code={}, trans_stat={}, resp_desc={}", 
+                refundResult.getResp_code(), refundResult.getTrans_stat(), refundResult.getResp_desc());
+
+            if (("00000000".equals(refundResult.getResp_code()) || "00000100".equals(refundResult.getResp_code())) 
+                && ("S".equals(refundResult.getTrans_stat()) || "P".equals(refundResult.getTrans_stat()))) {
+                // 退款成功,更新支付记录和立减金状态
+                FsStorePaymentScrm paymentUpdate = new FsStorePaymentScrm();
+                paymentUpdate.setPaymentId(targetPayment.getPaymentId());
+                paymentUpdate.setStatus(-1); // 已退款
+                paymentUpdate.setRefundTime(new Date());
+                paymentUpdate.setRefundMoney(targetPayment.getPayMoney());
+                paymentService.updateFsStorePayment(paymentUpdate);
+                
+                // 更新立减金状态为已退款
+                couponUser.setStatus(3); // 3表示已退款状态
+                couponUser.setUseTime(new Date());
+                couponUserService.updateFsStoreCouponUser(couponUser);
+                
+                return R.ok("退款审核通过,金额已原路退回用户");
+            } else {
+                return R.error("退款失败: " + refundResult.getResp_desc());
+            }
+            
+        } catch (Exception refundException) {
+            log.error("退款操作异常: couponUserId={}", param.getId(), refundException);
+            return R.error("退款操作失败,请联系技术人员");
+        }
+    }
+
 }

+ 5 - 0
fs-service/src/main/java/com/fs/hisStore/service/impl/FsStoreCouponUserScrmServiceImpl.java

@@ -121,4 +121,9 @@ public class FsStoreCouponUserScrmServiceImpl implements IFsStoreCouponUserScrmS
     public List<FsStoreCouponUserScrm> selectFsStoreCouponUserListByEnableForCash(FsCouponUserEnableParam param) {
         return fsStoreCouponUserMapper.selectFsStoreCouponUserListByEnableForCash(param);
     }
+
+    @Override
+    public List<FsStoreCouponUserVO> selectFsStoreCouponUserListAppVOForCash(FsStoreCouponUserScrm map) {
+        return fsStoreCouponUserMapper.selectFsStoreCouponUserListAppVOForCash(map);
+    }
 }

+ 9 - 1
fs-user-app/src/main/java/com/fs/app/controller/store/CouponScrmController.java

@@ -71,7 +71,7 @@ public class CouponScrmController extends AppBaseController {
             List<FsStoreCouponUserVO> list;
             if (param.getCouponType() != null && param.getCouponType() == 3) {
                 // 处理 couponType=3 的情况,查询立减金
-                list = fsStoreCouponUserService.selectFsStoreCouponUserListVOForCash(map);
+                list = fsStoreCouponUserService.selectFsStoreCouponUserListAppVOForCash(map);
             } else {
                 // 处理其他 couponType 的情况,查询普通优惠券
                 list = fsStoreCouponUserService.selectFsStoreCouponUserListVO(map);
@@ -162,5 +162,13 @@ public class CouponScrmController extends AppBaseController {
         }
     }
 
+    @Login
+    @ApiOperation("申请立减金退款")
+    @PostMapping("/applyCashCouponRefund")
+    public R applyCashCouponRefund(@RequestBody FsStoreCashCouponRefundParam param, HttpServletRequest request) {
+        return fsStoreCouponIssueService.applyCashCouponRefund(getUserId(), param);
+    }
+
+
 
 }