Procházet zdrojové kódy

fix: 待退款队列可见性 + 退款到帐中状态 + 防重复审核

- ProductOrderService.approveRefund: NOT_ENOUGH时 order.status=refund_pending + refundStatus=4(退款到帐中),防止管理员重复审核
- ProductOrder实体: refundStatus注释补充 4=退款到帐中
- PendingRefund实体: status注释补充 cancelled(已中止)
- AdminCommissionController + PendingRefundService: getAllPendingRefunds 支持 orderType 过滤
- OrderManage.vue: 新增 refund_pending 状态(退款到帐中)文案/样式/筛选选项,隐藏退款审核按钮
- PendingRefund.vue: loadList 传 orderType 到后端
- router/index.js: 注册 pending-refund 路由
- Layout.vue: 商城营销菜单加'待退款管理'入口
Xiaogang Liao před 3 měsíci
rodič
revize
2c81fa8f98

+ 2 - 1
cfc-backend/src/main/java/com/etotem/cfc/controller/admin/AdminCommissionController.java

@@ -81,9 +81,10 @@ public class AdminCommissionController {
     @PostMapping("/refunds/pending")
     public Result<Page<PendingRefund>> pendingRefunds(@RequestBody Map<String, Object> params) {
         String status = (String) params.get("status");
+        String orderType = (String) params.get("orderType");
         int page = params.get("page") != null ? ((Number) params.get("page")).intValue() : 1;
         int size = params.get("size") != null ? ((Number) params.get("size")).intValue() : 20;
-        return Result.success(pendingRefundService.getAllPendingRefunds(status, page, size));
+        return Result.success(pendingRefundService.getAllPendingRefunds(status, orderType, page, size));
     }
 
     @PostMapping("/refunds/summary")

+ 1 - 1
cfc-backend/src/main/java/com/etotem/cfc/entity/PendingRefund.java

@@ -43,7 +43,7 @@ public class PendingRefund implements Serializable {
     /** 下次重试时间 */
     private Date nextRetryTime;
 
-    /** 状态:pending(待处理)/processing(处理中)/success(成功)/failed(失败) */
+    /** 状态:pending(待处理)/processing(处理中)/success(成功)/failed(失败)/cancelled(已中止) */
     private String status;
 
     /** 失败原因 */

+ 1 - 1
cfc-backend/src/main/java/com/etotem/cfc/entity/ProductOrder.java

@@ -42,7 +42,7 @@ public class ProductOrder implements Serializable {
     private Date confirmTime;          // 确认收货时间
     private Date paidAt;
     // 退款相关字段
-    private Integer refundStatus;      // 退款状态:0无 1申请中 2已退款 3拒绝
+    private Integer refundStatus;      // 退款状态:0无 1申请中 2已退款 3拒绝 4退款到帐中
     private String refundReason;       // 退款原因
     private Integer refundAmount;      // 退款金额(分)
     private Date refundTime;           // 退款时间

+ 4 - 1
cfc-backend/src/main/java/com/etotem/cfc/service/PendingRefundService.java

@@ -150,7 +150,7 @@ public class PendingRefundService {
     /**
      * 获取所有待退款列表(管理员)
      */
-    public Page<PendingRefund> getAllPendingRefunds(String status, int page, int size) {
+    public Page<PendingRefund> getAllPendingRefunds(String status, String orderType, int page, int size) {
         Page<PendingRefund> pageParam = new Page<>(page, size);
         LambdaQueryWrapper<PendingRefund> wrapper = new LambdaQueryWrapper<PendingRefund>()
                 .orderByDesc(PendingRefund::getCreatedAt);
@@ -158,6 +158,9 @@ public class PendingRefundService {
         if (status != null && !status.isEmpty()) {
             wrapper.eq(PendingRefund::getStatus, status);
         }
+        if (orderType != null && !orderType.isEmpty()) {
+            wrapper.eq(PendingRefund::getOrderType, orderType);
+        }
         
         return pendingRefundMapper.selectPage(pageParam, wrapper);
     }

+ 2 - 1
cfc-backend/src/main/java/com/etotem/cfc/service/ProductOrderService.java

@@ -413,7 +413,8 @@ public class ProductOrderService {
         } catch (Exception e) {
             if (e.getMessage() != null && e.getMessage().contains("NOT_ENOUGH")) {
                 pendingRefundService.createPendingRefund(order.getBuyerId(), null, order.getTotalAmount(), "product", orderNo);
-                order.setStatus("refunding");
+                order.setStatus("refund_pending");
+                order.setRefundStatus(4);
                 order.setUpdatedAt(new Date());
                 orderMapper.updateById(order);
                 log.info("微信退款余额不足,已加入待退款队列: orderNo={}", orderNo);

+ 6 - 0
cfc-web/src/router/index.js

@@ -258,6 +258,12 @@ const routes = [
         component: () => import('@/views/admin/OrderManage.vue'),
         meta: { title: '订单管理', perm: 'commerce:orders' }
       },
+      {
+        path: 'pending-refund',
+        name: 'PendingRefund',
+        component: () => import('@/views/admin/PendingRefund.vue'),
+        meta: { title: '待退款管理', perm: 'commerce:orders' }
+      },
       {
         path: 'order-detail/:orderNo',
         name: 'OrderDetail',

+ 1 - 0
cfc-web/src/views/Layout.vue

@@ -192,6 +192,7 @@ export default {
           children: [
             { path: '/product-manage', label: '商品管理', icon: 'el-icon-s-goods', perm: 'commerce:products' },
             { path: '/order-manage', label: '订单管理', icon: 'el-icon-s-order', perm: 'commerce:orders' },
+            { path: '/pending-refund', label: '待退款管理', icon: 'el-icon-warning', perm: 'commerce:orders' },
             { path: '/product-profit-rate', label: '产品利润率', icon: 'el-icon-data-line', perm: 'commerce:profit' },
             { path: '/coupon', label: '优惠券管理', icon: 'el-icon-ticket', perm: 'marketing:coupon' },
             { path: '/promotion', label: '推广管理', icon: 'el-icon-s-marketing', perm: 'marketing:promotion' },

+ 6 - 3
cfc-web/src/views/admin/OrderManage.vue

@@ -12,6 +12,7 @@
           <el-option label="已完成" value="completed" />
           <el-option label="已取消" value="cancelled" />
           <el-option label="退款中" value="refunding" />
+          <el-option label="退款到帐中" value="refund_pending" />
           <el-option label="已退款" value="refunded" />
           <el-option label="已关闭" value="closed" />
         </el-select>
@@ -62,6 +63,7 @@
               <el-dropdown-item v-if="row.status === 'paid'" command="ship" icon="el-icon-s-cooperation">发货</el-dropdown-item>
               <el-dropdown-item v-if="row.status === 'paid' || row.status === 'refunding'" command="close" icon="el-icon-circle-close">关闭</el-dropdown-item>
               <el-dropdown-item v-if="row.status === 'refunding'" command="refund" icon="el-icon-warning-outline">退款审核</el-dropdown-item>
+              <el-dropdown-item v-if="row.status === 'refund_pending'" command="view-pending-refund" icon="el-icon-warning">退款到帐中</el-dropdown-item>
             </el-dropdown-menu>
           </el-dropdown>
         </template>
@@ -284,14 +286,14 @@ export default {
       }
     },
     canClose(status) {
-      return ['pending', 'paid', 'pending_receipt', 'refunding'].includes(status)
+      return ['pending', 'paid', 'pending_receipt', 'refunding'].includes(status);
     },
     statusType(status) {
-      var map = { pending: 'warning', paid: 'primary', pending_receipt: '', completed: 'success', cancelled: 'info', refunding: 'danger', refunded: 'danger', closed: 'info' }
+      var map = { pending: 'warning', paid: 'primary', pending_receipt: '', completed: 'success', cancelled: 'info', refunding: 'danger', refunded: 'danger', closed: 'info', refund_pending: 'warning' }
       return map[status] || 'info'
     },
     statusLabel(status) {
-      var map = { pending: '待支付', paid: '待发货', pending_receipt: '待收货', completed: '已完成', cancelled: '已取消', refunding: '退款中', refunded: '已退款', closed: '已关闭' }
+      var map = { pending: '待支付', paid: '待发货', pending_receipt: '待收货', completed: '已完成', cancelled: '已取消', refunding: '退款中', refunded: '已退款', closed: '已关闭', refund_pending: '退款到帐中' }
       return map[status] || status
     },
     payMethodLabel(method) {
@@ -315,6 +317,7 @@ export default {
         case 'ship': this.showShipDialog(row); break;
         case 'close': this.handleClose(row); break;
         case 'refund': this.showRefundDialog(row); break;
+        case 'view-pending-refund': this.$router.push('/pending-refund'); break;
       }
     }
   }

+ 1 - 0
cfc-web/src/views/admin/PendingRefund.vue

@@ -150,6 +150,7 @@ export default {
       try {
         const res = await getPendingRefundList({
           status: this.statusFilter || undefined,
+          orderType: this.typeFilter || undefined,
           page: this.currentPage,
           size: this.pageSize
         })