Browse Source

新增券码审核模块(类型/数量/审批弹窗),修复审核列表Tab切换数据不刷新,隐藏权益商品下单成功短信

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
csk 1 month ago
parent
commit
b8fec497eb

+ 3 - 0
工作空间/产研/权益/汇丰全行/产品原型/pc-demo/src/components/Layout.vue

@@ -44,6 +44,9 @@
               <el-menu-item index="/customization/hsbc/audit">
                 权益审核
               </el-menu-item>
+              <el-menu-item index="/customization/hsbc/coupon-audit">
+                券码审核
+              </el-menu-item>
             </el-sub-menu>
             <el-sub-menu index="customization-hsbc-campaign">
               <template #title>发放计划管理</template>

+ 146 - 0
工作空间/产研/权益/汇丰全行/产品原型/pc-demo/src/mock/index.js

@@ -1473,4 +1473,150 @@ Mock.mock(/\/api\/campaign-audit\/reject/, 'post', (options) => {
   return { code: 200, data: null, msg: '已驳回' }
 })
 
+// ==================== 券码审核 ====================
+const couponAuditList = [
+  {
+    id: 'CPA202606040001',
+    type: 'import',
+    productName: '权益A',
+    productId: 'Q100001',
+    importCount: 1000,
+    effectiveTime: '2026-06-05 00:00:00',
+    expireTime: '2026-12-31 23:59:59',
+    creator: '张三',
+    createTime: '2026-06-04 10:32:18',
+    auditorName: '',
+    auditTime: '',
+    auditStatus: 'pending'
+  },
+  {
+    id: 'CPA202606030001',
+    type: 'import',
+    productName: '微信立减金 5元(满10减5)',
+    productId: 'Q100007',
+    importCount: 5000,
+    effectiveTime: '2026-06-10 00:00:00',
+    expireTime: '2026-09-30 23:59:59',
+    creator: '李四',
+    createTime: '2026-06-03 15:08:42',
+    auditorName: '',
+    auditTime: '',
+    auditStatus: 'pending'
+  },
+  {
+    id: 'CPA202605280001',
+    type: 'import',
+    productName: '权益B',
+    productId: 'Q100002',
+    importCount: 500,
+    effectiveTime: '2026-06-01 00:00:00',
+    expireTime: '2026-12-31 23:59:59',
+    creator: '李四',
+    createTime: '2026-05-28 14:15:42',
+    auditorName: '王五',
+    auditTime: '2026-05-29 09:20:00',
+    auditStatus: 'approved'
+  },
+  {
+    id: 'CPA202605200001',
+    type: 'import',
+    productName: '权益C',
+    productId: 'Q100003',
+    importCount: 800,
+    effectiveTime: '2026-05-25 00:00:00',
+    expireTime: '2026-10-31 23:59:59',
+    creator: '王五',
+    createTime: '2026-05-20 09:08:11',
+    auditorName: '赵管理',
+    auditTime: '2026-05-21 16:30:00',
+    auditStatus: 'approved'
+  },
+  {
+    id: 'CPA202605150001',
+    type: 'import',
+    productName: '权益D',
+    productId: 'Q100004',
+    importCount: 200,
+    effectiveTime: '2026-05-20 00:00:00',
+    expireTime: '2026-08-31 23:59:59',
+    creator: '赵六',
+    createTime: '2026-05-15 16:45:30',
+    auditorName: '王五',
+    auditTime: '2026-05-16 10:05:00',
+    auditStatus: 'rejected'
+  },
+  {
+    id: 'CPA202606040002',
+    type: 'recycle_unissued',
+    productName: '权益B',
+    productId: 'Q100002',
+    importCount: 100,
+    effectiveTime: '2026-06-01 00:00:00',
+    expireTime: '2026-12-31 23:59:59',
+    creator: '张三',
+    createTime: '2026-06-04 16:40:00',
+    auditorName: '',
+    auditTime: '',
+    auditStatus: 'pending'
+  },
+  {
+    id: 'CPA202606020001',
+    type: 'recycle_expired',
+    productName: '权益C',
+    productId: 'Q100003',
+    importCount: 50,
+    effectiveTime: '2026-05-25 00:00:00',
+    expireTime: '2026-06-01 23:59:59',
+    creator: '王五',
+    createTime: '2026-06-02 11:20:00',
+    auditorName: '',
+    auditTime: '',
+    auditStatus: 'pending'
+  },
+  {
+    id: 'CPA202605220001',
+    type: 'recycle_wrong',
+    productName: '权益D',
+    productId: 'Q100004',
+    importCount: 200,
+    effectiveTime: '2026-05-20 00:00:00',
+    expireTime: '2026-08-31 23:59:59',
+    creator: '赵六',
+    createTime: '2026-05-22 10:10:00',
+    auditorName: '王五',
+    auditTime: '2026-05-23 09:30:00',
+    auditStatus: 'approved'
+  }
+]
+
+Mock.mock(/\/api\/coupon-audit\/list/, 'get', (options) => {
+  const url = new URL(options.url, 'http://localhost')
+  const auditStatus = url.searchParams.get('auditStatus') || ''
+  const productId = url.searchParams.get('productId') || ''
+  let filtered = couponAuditList
+  if (auditStatus) filtered = filtered.filter(a => a.auditStatus === auditStatus)
+  if (productId) filtered = filtered.filter(a => a.productId === productId)
+  return { code: 200, data: filtered, msg: 'ok' }
+})
+
+Mock.mock(/\/api\/coupon-audit\/approve/, 'post', (options) => {
+  const body = JSON.parse(options.body)
+  const idx = couponAuditList.findIndex(a => a.id === body.id)
+  if (idx < 0) return { code: 404, data: null, msg: '审核单不存在' }
+  const audit = couponAuditList[idx]
+  if (audit.auditStatus !== 'pending') return { code: 400, data: null, msg: '该审核单已完成' }
+  couponAuditList[idx] = { ...audit, auditStatus: 'approved', auditorName: body.auditorName || '王五', auditTime: nowStr() }
+  return { code: 200, data: null, msg: '审核通过' }
+})
+
+Mock.mock(/\/api\/coupon-audit\/reject/, 'post', (options) => {
+  const body = JSON.parse(options.body)
+  const idx = couponAuditList.findIndex(a => a.id === body.id)
+  if (idx < 0) return { code: 404, data: null, msg: '审核单不存在' }
+  const audit = couponAuditList[idx]
+  if (audit.auditStatus !== 'pending') return { code: 400, data: null, msg: '该审核单已完成' }
+  couponAuditList[idx] = { ...audit, auditStatus: 'rejected', auditorName: body.auditorName || '王五', auditTime: nowStr() }
+  return { code: 200, data: null, msg: '已驳回' }
+})
+
 export default Mock

+ 6 - 0
工作空间/产研/权益/汇丰全行/产品原型/pc-demo/src/router/index.js

@@ -282,6 +282,12 @@ const routes = [
         component: () => import('@/views/GrantTaskDetail.vue'),
         meta: { title: '执行发放任务' }
       },
+      {
+        path: 'customization/hsbc/coupon-audit',
+        name: 'CouponAuditList',
+        component: () => import('@/views/CouponAuditList.vue'),
+        meta: { title: '券码审核' }
+      },
       {
         path: 'customization/hsbc/campaign-audit',
         name: 'CampaignAuditList',

+ 2 - 0
工作空间/产研/权益/汇丰全行/产品原型/pc-demo/src/views/AddEquityProduct.vue

@@ -304,6 +304,7 @@
               </el-col>
             </el-row>
             <template v-if="form.isPlatformExchange === '是'">
+              <!-- 下单成功短信已隐藏
               <el-row :gutter="20">
                 <el-col :span="24">
                   <el-form-item>
@@ -346,6 +347,7 @@
                   </el-form-item>
                 </el-col>
               </el-row>
+              -->
               <el-row :gutter="20" v-if="form.productType === '券码'">
                 <el-col :span="8">
                   <el-form-item label="领取成功按钮" required>

+ 2 - 0
工作空间/产研/权益/汇丰全行/产品原型/pc-demo/src/views/AuditEquityProduct.vue

@@ -236,6 +236,7 @@
               </el-col>
             </el-row>
             <template v-if="form.isPlatformExchange === '是'">
+              <!-- 下单成功短信已隐藏
               <el-row :gutter="20">
                 <el-col :span="24">
                   <el-form-item label="下单成功短信">
@@ -261,6 +262,7 @@
                   </el-form-item>
                 </el-col>
               </el-row>
+              -->
               <el-row :gutter="20">
                 <el-col :span="8">
                   <el-form-item label="领取成功按钮">

+ 1 - 1
工作空间/产研/权益/汇丰全行/产品原型/pc-demo/src/views/AuditList.vue

@@ -1,7 +1,7 @@
 <template>
   <div class="audit-list">
     <el-card>
-      <el-tabs v-model="activeTab" @tab-click="loadData">
+      <el-tabs v-model="activeTab" @tab-change="loadData">
         <el-tab-pane label="待审核" name="pending"></el-tab-pane>
         <el-tab-pane label="审核通过" name="approved"></el-tab-pane>
         <el-tab-pane label="审核驳回" name="rejected"></el-tab-pane>

+ 1 - 1
工作空间/产研/权益/汇丰全行/产品原型/pc-demo/src/views/CampaignAuditList.vue

@@ -1,7 +1,7 @@
 <template>
   <div class="campaign-audit-list">
     <el-card>
-      <el-tabs v-model="activeTab" @tab-click="loadData">
+      <el-tabs v-model="activeTab" @tab-change="loadData">
         <el-tab-pane label="待审核" name="pending"></el-tab-pane>
         <el-tab-pane label="审核通过" name="approved"></el-tab-pane>
         <el-tab-pane label="审核驳回" name="rejected"></el-tab-pane>

+ 199 - 0
工作空间/产研/权益/汇丰全行/产品原型/pc-demo/src/views/CouponAuditList.vue

@@ -0,0 +1,199 @@
+<template>
+  <div class="coupon-audit-list">
+    <el-card>
+      <el-tabs v-model="activeTab" @tab-change="loadData">
+        <el-tab-pane label="待审核" name="pending"></el-tab-pane>
+        <el-tab-pane label="审核通过" name="approved"></el-tab-pane>
+        <el-tab-pane label="审核驳回" name="rejected"></el-tab-pane>
+      </el-tabs>
+      <div class="search-section">
+        <div class="search-row">
+          <el-form :model="searchForm" label-width="120px" inline>
+            <el-form-item label="权益编号:">
+              <el-input v-model="searchForm.productId" placeholder="请输入" style="width: 200px" />
+            </el-form-item>
+            <div class="button-group" style="margin-left: 20px;">
+              <el-button type="primary" @click="loadData">查询</el-button>
+              <el-button @click="handleReset">重置</el-button>
+            </div>
+          </el-form>
+        </div>
+      </div>
+
+      <el-table :data="tableData" stripe style="width: 100%">
+        <el-table-column label="操作" min-width="100" fixed="left">
+          <template #default="scope">
+            <el-button
+              v-if="activeTab === 'pending'"
+              type="text"
+              size="small"
+              @click="openAudit(scope.row)"
+            >审批</el-button>
+            <el-button
+              v-else
+              type="text"
+              size="small"
+              @click="openAudit(scope.row)"
+            >查看</el-button>
+          </template>
+        </el-table-column>
+        <el-table-column prop="productName" label="权益商品名称" min-width="160" show-overflow-tooltip />
+        <el-table-column prop="productId" label="权益编号" width="140" align="center" />
+        <el-table-column label="类型" width="150" align="center">
+          <template #default="scope">
+            <el-tag :type="typeTag(scope.row.type)" size="small">{{ typeLabel(scope.row.type) }}</el-tag>
+          </template>
+        </el-table-column>
+        <el-table-column prop="importCount" label="数量" width="120" align="center" />
+        <el-table-column prop="creator" label="创建人" width="120" align="center" />
+        <el-table-column prop="createTime" label="创建时间" width="180" align="center" />
+        <el-table-column prop="auditorName" label="审核人" width="120" align="center">
+          <template #default="scope">
+            <span>{{ scope.row.auditorName || '-' }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="auditTime" label="审核时间" width="180" align="center">
+          <template #default="scope">
+            <span>{{ scope.row.auditTime || '-' }}</span>
+          </template>
+        </el-table-column>
+      </el-table>
+
+      <div class="pagination-section">
+        <span>Total {{ tableData.length }}</span>
+        <el-pagination
+          layout="prev, pager, next, sizes, jumper"
+          :page-size="10"
+          :page-sizes="[10, 20, 50]"
+          :total="tableData.length"
+        />
+      </div>
+    </el-card>
+
+    <el-dialog
+      :title="currentRow && currentRow.auditStatus === 'pending' ? '券码审批' : '审核详情'"
+      v-model="auditDialogVisible"
+      width="560px"
+      @closed="resetAuditDialog"
+    >
+      <el-form v-if="currentRow" label-width="150px" label-position="left" class="audit-detail-form">
+        <el-form-item label="权益商品名称">{{ currentRow.productName }}</el-form-item>
+        <el-form-item label="权益编号">{{ currentRow.productId }}</el-form-item>
+        <el-form-item label="类型">
+          <el-tag :type="typeTag(currentRow.type)" size="small">{{ typeLabel(currentRow.type) }}</el-tag>
+        </el-form-item>
+        <el-form-item label="数量">{{ currentRow.importCount }}</el-form-item>
+        <el-form-item label="使用有效期开始时间">{{ currentRow.effectiveTime || '-' }}</el-form-item>
+        <el-form-item label="使用有效期结束时间">{{ currentRow.expireTime || '-' }}</el-form-item>
+        <el-form-item label="创建人">{{ currentRow.creator }}</el-form-item>
+        <el-form-item label="创建时间">{{ currentRow.createTime }}</el-form-item>
+        <template v-if="currentRow.auditStatus !== 'pending'">
+          <el-form-item label="审核人">{{ currentRow.auditorName || '-' }}</el-form-item>
+          <el-form-item label="审核时间">{{ currentRow.auditTime || '-' }}</el-form-item>
+          <el-form-item label="审核结果">
+            <el-tag :type="currentRow.auditStatus === 'approved' ? 'success' : 'danger'" size="small">
+              {{ currentRow.auditStatus === 'approved' ? '审核通过' : '审核驳回' }}
+            </el-tag>
+          </el-form-item>
+        </template>
+      </el-form>
+
+      <template #footer>
+        <span v-if="currentRow && currentRow.auditStatus === 'pending'">
+          <el-button type="danger" @click="confirmAudit('reject')">驳回</el-button>
+          <el-button type="primary" @click="confirmAudit('approve')">通过</el-button>
+        </span>
+        <span v-else>
+          <el-button @click="auditDialogVisible = false">关闭</el-button>
+        </span>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { ElMessage } from 'element-plus'
+import request from '@/utils/request'
+
+export default {
+  name: 'CouponAuditList',
+  data() {
+    return {
+      activeTab: 'pending',
+      searchForm: { productId: '' },
+      tableData: [],
+      auditDialogVisible: false,
+      currentRow: null
+    }
+  },
+  created() {
+    this.loadData()
+  },
+  activated() {
+    this.loadData()
+  },
+  methods: {
+    loadData() {
+      const params = new URLSearchParams()
+      params.append('auditStatus', this.activeTab)
+      if (this.searchForm.productId) params.append('productId', this.searchForm.productId)
+      request.get('/api/coupon-audit/list?' + params.toString()).then(res => {
+        this.tableData = res.data || []
+      }).catch(() => {})
+    },
+    handleReset() {
+      this.searchForm = { productId: '' }
+      this.loadData()
+    },
+    typeLabel(t) {
+      return {
+        import: '导入',
+        recycle_unissued: '未发放券码回收',
+        recycle_expired: '已过期券码回收',
+        recycle_wrong: '导错码券码回收'
+      }[t] || t
+    },
+    typeTag(t) {
+      return {
+        import: 'success',
+        recycle_unissued: 'warning',
+        recycle_expired: 'info',
+        recycle_wrong: 'danger'
+      }[t] || ''
+    },
+    openAudit(row) {
+      this.currentRow = row
+      this.auditDialogVisible = true
+    },
+    resetAuditDialog() {
+      this.currentRow = null
+    },
+    confirmAudit(action) {
+      request.post(`/api/coupon-audit/${action}`, {
+        id: this.currentRow.id
+      }).then(() => {
+        ElMessage.success(action === 'approve' ? '审核通过' : '已驳回')
+        this.auditDialogVisible = false
+        this.loadData()
+      }).catch(() => {})
+    }
+  }
+}
+</script>
+
+<style scoped>
+.coupon-audit-list { padding: 0; }
+.search-section { display: flex; flex-direction: column; }
+.search-row { margin-bottom: 0; }
+.search-row .el-form { display: flex; flex-wrap: wrap; gap: 0; }
+.search-row .el-form-item { margin-right: 0; margin-bottom: 8px; }
+.button-group { display: flex; gap: 5px; }
+.audit-detail-form .el-form-item { margin-bottom: 8px; }
+.pagination-section {
+  display: flex;
+  justify-content: flex-end;
+  align-items: center;
+  gap: 20px;
+  margin-top: 20px;
+}
+</style>

+ 2 - 0
工作空间/产研/权益/汇丰全行/产品原型/pc-demo/src/views/EditEquityProduct.vue

@@ -304,6 +304,7 @@
             </el-col>
           </el-row>
           <template v-if="form.isPlatformExchange === '是'">
+            <!-- 下单成功短信已隐藏
             <el-row :gutter="20">
               <el-col :span="24">
                 <el-form-item>
@@ -348,6 +349,7 @@
                 </el-form-item>
               </el-col>
             </el-row>
+            -->
             <el-row :gutter="20" v-if="form.productType === '券码'">
               <el-col :span="8">
                 <el-form-item label="领取成功按钮" required>

+ 1 - 1
工作空间/产研/权益/汇丰全行/产品原型/pc-demo/src/views/RuleGroupAuditList.vue

@@ -1,7 +1,7 @@
 <template>
   <div class="rule-group-audit-list">
     <el-card>
-      <el-tabs v-model="activeTab" @tab-click="loadData">
+      <el-tabs v-model="activeTab" @tab-change="loadData">
         <el-tab-pane label="待审核" name="pending"></el-tab-pane>
         <el-tab-pane label="审核通过" name="approved"></el-tab-pane>
         <el-tab-pane label="审核驳回" name="rejected"></el-tab-pane>

+ 2 - 0
工作空间/产研/权益/汇丰全行/产品原型/pc-demo/src/views/ViewEquityProduct.vue

@@ -242,6 +242,7 @@
               </el-col>
             </el-row>
             <template v-if="form.isPlatformExchange === '是'">
+              <!-- 下单成功短信已隐藏
               <el-row :gutter="20">
                 <el-col :span="24">
                   <el-form-item label="下单成功短信">
@@ -267,6 +268,7 @@
                   </el-form-item>
                 </el-col>
               </el-row>
+              -->
               <el-row :gutter="20" v-if="form.productType === '券码'">
                 <el-col :span="8">
                   <el-form-item label="领取成功按钮">