Просмотр исходного кода

信用卡权益"设置显示页面"改为"编辑",新增是否启用/权益名称/权益图标,列表与批次增加分页

- 信用卡权益:行操作"设置显示页面"改为"编辑",弹窗新增"是否启用"(不启用/启用,默认不启用),"权益首页/列表页"改为"权益首页"
- 编辑弹窗在组装页下方新增"权益名称"(最长40字)与"权益图标"(建议尺寸80x80px),二者始终必填并在确定时校验
- 列表新增"是否启用"状态列;组装页多选框拉宽至整行
- 审核列表/券码审核列表/券码批次列表增加前端分页,补充券码审核 mock 数据
- 同步更新 FSD(信用卡权益章节)与借记卡移动端需求文档

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
csk 1 месяц назад
Родитель
Сommit
7df74d6e67

BIN
.resources/image-1780651125157.png


BIN
.resources/image-1780651234602.png


BIN
.resources/image-1780651374993.png


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

@@ -1,25 +1,31 @@
 <template>
   <el-dialog
-    title="设置显示页面"
+    title="编辑"
     v-model="dialogVisible"
     width="560px"
     @open="onOpen"
   >
     <el-form :model="form" label-width="140px" label-position="left">
-      <el-form-item label="权益首页/列表页">
+      <el-form-item label="是否启用">
+        <el-radio-group v-model="form.enabled">
+          <el-radio label="不启用">不启用</el-radio>
+          <el-radio label="启用">启用</el-radio>
+        </el-radio-group>
+      </el-form-item>
+      <el-form-item label="权益首页">
         <el-radio-group v-model="form.showOnHome">
           <el-radio label="显示">显示</el-radio>
           <el-radio label="不显示">不显示</el-radio>
         </el-radio-group>
       </el-form-item>
-      <el-form-item label="组装页">
+      <el-form-item label="组装页" class="assembly-item">
         <el-radio-group v-model="form.showOnAssembly">
           <el-radio label="显示">显示</el-radio>
           <el-radio label="不显示">不显示</el-radio>
         </el-radio-group>
         <div
           v-if="form.showOnAssembly === '显示'"
-          style="background: #f1f2f5;padding: 16px;margin-top: 10px;"
+          class="assembly-select-box"
         >
           <el-select
             v-model="form.assemblyPages"
@@ -37,7 +43,36 @@
           </el-select>
         </div>
       </el-form-item>
+      <el-form-item label="权益名称" required>
+        <el-input
+          v-model="form.equityName"
+          maxlength="40"
+          placeholder="请输入权益名称"
+          style="width: 100%"
+        ></el-input>
+      </el-form-item>
+      <el-form-item label="权益图标" required>
+        <el-upload
+          action=""
+          :auto-upload="false"
+          :file-list="form.listIcon"
+          :on-change="file => handleUpload(file, 'listIcon')"
+          :on-preview="handlePreviewImage"
+          :on-remove="() => form.listIcon = []"
+          :class="{ 'upload-hide-trigger': form.listIcon.length >= 1 }"
+          :limit="1"
+          list-type="picture-card"
+        >
+          <el-icon><Plus /></el-icon>
+        </el-upload>
+        <div class="upload-size-tip">建议尺寸:80x80px</div>
+      </el-form-item>
     </el-form>
+
+    <el-dialog v-model="previewVisible" title="预览" width="400px" append-to-body>
+      <img v-if="previewImageUrl" :src="previewImageUrl" style="width: 100%" />
+    </el-dialog>
+
     <template #footer>
       <span>
         <el-button @click="dialogVisible = false">取消</el-button>
@@ -49,6 +84,7 @@
 
 <script>
 import request from '@/utils/request'
+import { ElMessage } from 'element-plus'
 
 export default {
   name: 'ShowPagesDialog',
@@ -60,10 +96,15 @@ export default {
   data() {
     return {
       assemblyPageOptions: [],
+      previewVisible: false,
+      previewImageUrl: '',
       form: {
+        enabled: '不启用',
         showOnHome: '显示',
         showOnAssembly: '不显示',
-        assemblyPages: []
+        assemblyPages: [],
+        equityName: '',
+        listIcon: []
       }
     }
   },
@@ -85,21 +126,73 @@ export default {
     onOpen() {
       this.fetchAssemblyPages()
       if (this.row) {
+        this.form.enabled = this.row.enabled || '不启用'
         this.form.showOnHome = this.row.showOnHome || '显示'
         this.form.showOnAssembly = this.row.showOnAssembly || '不显示'
         this.form.assemblyPages = Array.isArray(this.row.assemblyPages)
           ? [...this.row.assemblyPages]
           : []
+        this.form.equityName = this.row.equityName || ''
+        this.form.listIcon = this.row.equityIcon
+          ? [{ name: '权益图标', url: this.row.equityIcon }]
+          : []
       } else {
+        this.form.enabled = '不启用'
         this.form.showOnHome = '显示'
         this.form.showOnAssembly = '不显示'
         this.form.assemblyPages = []
+        this.form.equityName = ''
+        this.form.listIcon = []
       }
     },
+    handleUpload(file, field) {
+      if (!file || !file.raw) return
+      const reader = new FileReader()
+      reader.onload = (e) => {
+        this.form[field] = [{ name: file.name, url: e.target.result, uid: file.uid }]
+      }
+      reader.readAsDataURL(file.raw)
+    },
+    handlePreviewImage(file) {
+      this.previewImageUrl = file.url || ''
+      this.previewVisible = !!this.previewImageUrl
+    },
     handleConfirm() {
-      this.$emit('confirm', { ...this.form, assemblyPages: [...this.form.assemblyPages] })
+      if (!this.form.equityName) {
+        ElMessage.warning('请填写权益名称')
+        return
+      }
+      if (!this.form.listIcon.length) {
+        ElMessage.warning('请上传权益图标')
+        return
+      }
+      const equityIcon = this.form.listIcon.length ? this.form.listIcon[0].url : ''
+      this.$emit('confirm', {
+        ...this.form,
+        assemblyPages: [...this.form.assemblyPages],
+        equityIcon
+      })
       this.dialogVisible = false
     }
   }
 }
 </script>
+
+<style scoped>
+.assembly-item >>> .el-form-item__content { flex-wrap: wrap; }
+.assembly-select-box {
+  width: 100%;
+  box-sizing: border-box;
+  background: #f1f2f5;
+  padding: 16px;
+  margin-top: 10px;
+}
+.upload-hide-trigger >>> .el-upload--picture-card { display: none; }
+.upload-size-tip {
+  width: 100%;
+  margin-top: 4px;
+  font-size: 12px;
+  color: #909399;
+  line-height: 1.5;
+}
+</style>

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

@@ -1573,6 +1573,118 @@ const couponAuditList = [
     auditTime: '',
     auditStatus: 'pending'
   },
+  {
+    id: 'CPA202606010001',
+    type: 'import',
+    productName: '权益C',
+    productId: 'Q100003',
+    importCount: 1500,
+    effectiveTime: '2026-06-08 00:00:00',
+    expireTime: '2026-12-31 23:59:59',
+    creator: '王五',
+    createTime: '2026-06-01 09:15:00',
+    auditorName: '',
+    auditTime: '',
+    auditStatus: 'pending'
+  },
+  {
+    id: 'CPA202605310001',
+    type: 'recycle_wrong',
+    productName: '权益A',
+    productId: 'Q100001',
+    importCount: 20,
+    effectiveTime: '2026-04-16 00:00:00',
+    expireTime: '2026-12-31 23:59:59',
+    creator: '李四',
+    createTime: '2026-05-31 14:22:00',
+    auditorName: '',
+    auditTime: '',
+    auditStatus: 'pending'
+  },
+  {
+    id: 'CPA202605300001',
+    type: 'import',
+    productName: '权益D',
+    productId: 'Q100004',
+    importCount: 800,
+    effectiveTime: '2026-06-15 00:00:00',
+    expireTime: '2026-11-30 23:59:59',
+    creator: '赵六',
+    createTime: '2026-05-30 10:05:00',
+    auditorName: '',
+    auditTime: '',
+    auditStatus: 'pending'
+  },
+  {
+    id: 'CPA202605290001',
+    type: 'recycle_unissued',
+    productName: '权益A',
+    productId: 'Q100001',
+    importCount: 60,
+    effectiveTime: '2026-04-16 00:00:00',
+    expireTime: '2026-12-31 23:59:59',
+    creator: '张三',
+    createTime: '2026-05-29 16:48:00',
+    auditorName: '',
+    auditTime: '',
+    auditStatus: 'pending'
+  },
+  {
+    id: 'CPA202605270001',
+    type: 'import',
+    productName: '微信立减金 5元(满10减5)',
+    productId: 'Q100007',
+    importCount: 3000,
+    effectiveTime: '2026-06-01 00:00:00',
+    expireTime: '2026-09-30 23:59:59',
+    creator: '李四',
+    createTime: '2026-05-27 11:30:00',
+    auditorName: '',
+    auditTime: '',
+    auditStatus: 'pending'
+  },
+  {
+    id: 'CPA202605260001',
+    type: 'recycle_expired',
+    productName: '权益B',
+    productId: 'Q100002',
+    importCount: 35,
+    effectiveTime: '2026-04-21 00:00:00',
+    expireTime: '2026-05-20 23:59:59',
+    creator: '王五',
+    createTime: '2026-05-26 09:55:00',
+    auditorName: '',
+    auditTime: '',
+    auditStatus: 'pending'
+  },
+  {
+    id: 'CPA202605250001',
+    type: 'import',
+    productName: '权益E',
+    productId: 'Q100005',
+    importCount: 1200,
+    effectiveTime: '2026-06-01 00:00:00',
+    expireTime: '2026-10-31 23:59:59',
+    creator: '张三',
+    createTime: '2026-05-25 15:12:00',
+    auditorName: '',
+    auditTime: '',
+    auditStatus: 'pending'
+  },
+  {
+    id: 'CPA202605240001',
+    type: 'recycle_unissued',
+    productName: '权益C',
+    productId: 'Q100003',
+    importCount: 90,
+    effectiveTime: '2026-05-25 00:00:00',
+    expireTime: '2026-10-31 23:59:59',
+    creator: '赵六',
+    createTime: '2026-05-24 10:40:00',
+    auditorName: '',
+    auditTime: '',
+    auditStatus: 'pending'
+  },
   {
     id: 'CPA202605220001',
     type: 'recycle_wrong',

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

@@ -23,7 +23,7 @@
         </div>
       </div>
 
-      <el-table :data="tableData" stripe style="width: 100%">
+      <el-table :data="pagedTableData" stripe style="width: 100%">
         <el-table-column label="操作" min-width="140" fixed="left">
           <template #default="scope">
             <el-button
@@ -67,8 +67,9 @@
       <div class="pagination-section">
         <span>Total {{ tableData.length }}</span>
         <el-pagination
+          v-model:current-page="currentPage"
+          v-model:page-size="pageSize"
           layout="prev, pager, next, sizes, jumper"
-          :page-size="10"
           :page-sizes="[10, 20, 50]"
           :total="tableData.length"
         ></el-pagination>
@@ -89,7 +90,15 @@ export default {
         bizName: '',
         bizId: ''
       },
-      tableData: []
+      tableData: [],
+      currentPage: 1,
+      pageSize: 10
+    }
+  },
+  computed: {
+    pagedTableData() {
+      const start = (this.currentPage - 1) * this.pageSize
+      return this.tableData.slice(start, start + this.pageSize)
     }
   },
   created() {
@@ -113,6 +122,7 @@ export default {
       if (this.searchForm.bizId) params.append('bizId', this.searchForm.bizId)
       request.get('/api/audit/list?' + params.toString()).then(res => {
         this.tableData = res.data || []
+        this.currentPage = 1
       }).catch(() => {})
     },
     handleReset() {

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

@@ -20,7 +20,7 @@
         </div>
       </div>
 
-      <el-table :data="tableData" stripe style="width: 100%">
+      <el-table :data="pagedTableData" stripe style="width: 100%">
         <el-table-column label="操作" min-width="100" fixed="left">
           <template #default="scope">
             <el-button
@@ -62,8 +62,9 @@
       <div class="pagination-section">
         <span>Total {{ tableData.length }}</span>
         <el-pagination
+          v-model:current-page="currentPage"
+          v-model:page-size="pageSize"
           layout="prev, pager, next, sizes, jumper"
-          :page-size="10"
           :page-sizes="[10, 20, 50]"
           :total="tableData.length"
         />
@@ -122,6 +123,8 @@ export default {
       activeTab: 'pending',
       searchForm: { productId: '' },
       tableData: [],
+      currentPage: 1,
+      pageSize: 10,
       auditDialogVisible: false,
       currentRow: null
     }
@@ -132,6 +135,12 @@ export default {
   activated() {
     this.loadData()
   },
+  computed: {
+    pagedTableData() {
+      const start = (this.currentPage - 1) * this.pageSize
+      return this.tableData.slice(start, start + this.pageSize)
+    }
+  },
   methods: {
     loadData() {
       const params = new URLSearchParams()
@@ -139,6 +148,7 @@ export default {
       if (this.searchForm.productId) params.append('productId', this.searchForm.productId)
       request.get('/api/coupon-audit/list?' + params.toString()).then(res => {
         this.tableData = res.data || []
+        this.currentPage = 1
       }).catch(() => {})
     },
     handleReset() {

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

@@ -52,7 +52,7 @@
                   <el-button v-if="scope.row.shelfStatus === '已上架'" type="text" size="small">调整显示顺序</el-button>
                 </template>
               </el-popover>
-              <el-button type="text" size="small" @click="openShowPagesDialog(scope.row)">设置显示页面</el-button>
+              <el-button type="text" size="small" @click="openShowPagesDialog(scope.row)">编辑</el-button>
               <el-popover
                 placement="bottom"
                 trigger="click"
@@ -73,6 +73,11 @@
           </template>
         </el-table-column>
         <el-table-column prop="equityName" label="权益名称" min-width="220" show-overflow-tooltip></el-table-column>
+        <el-table-column label="是否启用" width="120">
+          <template #default="scope">
+            <el-tag :type="scope.row.enabled === '启用' ? 'success' : 'info'" size="small">{{ scope.row.enabled || '不启用' }}</el-tag>
+          </template>
+        </el-table-column>
         <el-table-column label="显示页面" min-width="240">
           <template #default="scope">
             <template v-if="visiblePages(scope.row).length">
@@ -140,6 +145,7 @@ export default {
           merchantName: '环亚机场贵宾',
           createTime: '2026-01-10 09:32:15',
           shelfStatus: '已上架',
+          enabled: '不启用',
           showOnHome: '显示',
           showOnAssembly: '不显示',
           assemblyPages: []
@@ -151,6 +157,7 @@ export default {
           merchantName: '尊享高尔夫俱乐部',
           createTime: '2026-01-15 14:08:42',
           shelfStatus: '已上架',
+          enabled: '不启用',
           showOnHome: '显示',
           showOnAssembly: '不显示',
           assemblyPages: []
@@ -162,6 +169,7 @@ export default {
           merchantName: '车之家精洗服务',
           createTime: '2026-02-01 11:20:05',
           shelfStatus: '已上架',
+          enabled: '不启用',
           showOnHome: '显示',
           showOnAssembly: '不显示',
           assemblyPages: []
@@ -213,10 +221,13 @@ export default {
     },
     onShowPagesConfirm(values) {
       if (this.showPagesRow) {
+        this.showPagesRow.enabled = values.enabled
         this.showPagesRow.showOnHome = values.showOnHome
         this.showPagesRow.showOnAssembly = values.showOnAssembly
         this.showPagesRow.assemblyPages = [...values.assemblyPages]
-        ElMessage.success('显示页面已更新')
+        this.showPagesRow.equityName = values.equityName
+        this.showPagesRow.equityIcon = values.equityIcon
+        ElMessage.success('已保存')
       }
     },
     getPopoverInstance(name) {

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

@@ -4,7 +4,7 @@
       <template #header>
         <div class="header-title">
           <span>券码管理</span>
-          <span class="product-id">权益名称:{{ equityName }}</span>
+          <span class="product-id">{{ equityName }}</span>
         </div>
       </template>
 
@@ -14,7 +14,7 @@
         </el-button>
       </div>
 
-      <el-table :data="batchList" stripe style="width: 100%">
+      <el-table :data="pagedBatchList" stripe style="width: 100%">
         <el-table-column prop="importCount" label="导入数量" width="100"></el-table-column>
         <el-table-column prop="actualImportCount" label="实际导入数量" width="120"></el-table-column>
         <el-table-column prop="failCount" label="导入失败数量" width="120"></el-table-column>
@@ -45,6 +45,17 @@
           </template>
         </el-table-column>
       </el-table>
+
+      <div class="pagination-section">
+        <span>Total {{ batchList.length }}</span>
+        <el-pagination
+          v-model:current-page="currentPage"
+          v-model:page-size="pageSize"
+          layout="prev, pager, next, sizes, jumper"
+          :page-sizes="[10, 20, 50]"
+          :total="batchList.length"
+        />
+      </div>
     </el-card>
 
     <el-dialog
@@ -128,6 +139,8 @@ export default {
     return {
       importDialogVisible: false,
       recycleDialogVisible: false,
+      currentPage: 1,
+      pageSize: 10,
       recycleRow: null,
       recycleForm: {
         type: 'unissued',
@@ -185,6 +198,94 @@ export default {
           fileStatus: '处理失败',
           importTime: '2026-05-01 16:45:30',
           creator: '赵六'
+        },
+        {
+          importCount: 1500,
+          actualImportCount: 1500,
+          failCount: 0,
+          remainingCount: 1280,
+          effectiveTime: '2026-04-10 00:00:00',
+          expireTime: '2026-12-31 23:59:59',
+          fileStatus: '处理成功',
+          importTime: '2026-04-09 09:21:05',
+          creator: '张三'
+        },
+        {
+          importCount: 600,
+          actualImportCount: 598,
+          failCount: 2,
+          remainingCount: 420,
+          effectiveTime: '2026-04-05 00:00:00',
+          expireTime: '2026-11-30 23:59:59',
+          fileStatus: '处理成功',
+          importTime: '2026-04-04 14:02:33',
+          creator: '李四'
+        },
+        {
+          importCount: 300,
+          actualImportCount: 300,
+          failCount: 0,
+          remainingCount: 0,
+          effectiveTime: '2026-03-20 00:00:00',
+          expireTime: '2026-09-30 23:59:59',
+          fileStatus: '处理成功',
+          importTime: '2026-03-19 10:45:12',
+          creator: '王五'
+        },
+        {
+          importCount: 2000,
+          actualImportCount: 1995,
+          failCount: 5,
+          remainingCount: 1620,
+          effectiveTime: '2026-03-15 00:00:00',
+          expireTime: '2026-12-31 23:59:59',
+          fileStatus: '处理成功',
+          importTime: '2026-03-14 16:30:48',
+          creator: '张三'
+        },
+        {
+          importCount: 450,
+          actualImportCount: 450,
+          failCount: 0,
+          remainingCount: 130,
+          effectiveTime: '2026-03-01 00:00:00',
+          expireTime: '2026-08-31 23:59:59',
+          fileStatus: '处理成功',
+          importTime: '2026-02-28 11:18:27',
+          creator: '李四'
+        },
+        {
+          importCount: 800,
+          actualImportCount: 796,
+          failCount: 4,
+          remainingCount: 510,
+          effectiveTime: '2026-02-20 00:00:00',
+          expireTime: '2026-10-31 23:59:59',
+          fileStatus: '处理成功',
+          importTime: '2026-02-19 15:55:09',
+          creator: '王五'
+        },
+        {
+          importCount: 1200,
+          actualImportCount: 1200,
+          failCount: 0,
+          remainingCount: 60,
+          effectiveTime: '2026-02-10 00:00:00',
+          expireTime: '2026-07-31 23:59:59',
+          fileStatus: '处理成功',
+          importTime: '2026-02-09 09:40:51',
+          creator: '赵六'
+        },
+        {
+          importCount: 350,
+          actualImportCount: 348,
+          failCount: 2,
+          remainingCount: 0,
+          effectiveTime: '2026-01-15 00:00:00',
+          expireTime: '2026-06-30 23:59:59',
+          fileStatus: '处理成功',
+          importTime: '2026-01-14 13:27:36',
+          creator: '张三'
         }
       ]
     }
@@ -193,6 +294,10 @@ export default {
     productId() {
       return this.$route.params.id || ''
     },
+    pagedBatchList() {
+      const start = (this.currentPage - 1) * this.pageSize
+      return this.batchList.slice(start, start + this.pageSize)
+    },
     equityName() {
       const map = {
         'Q100001': '权益A',
@@ -375,4 +480,12 @@ export default {
   justify-content: center;
   gap: 24px;
 }
+
+.pagination-section {
+  display: flex;
+  justify-content: flex-end;
+  align-items: center;
+  gap: 20px;
+  margin-top: 20px;
+}
 </style>

+ 8 - 35
工作空间/产研/权益/汇丰全行/需求文档/汇丰借记卡移动端——权益.md

@@ -222,41 +222,14 @@
         
     -   **开启了领取时间限制且超过领取结束时间:** 显示【已失效】,按钮无法点击
         
--   **其他:** 显示【领取权益】
-    
-    <br>
-    
-    <br>
-    
-    <br>
-    
-    <br>
-    
-    <br>
-    
-    <br>
-    
-    <br>
-    
-    <br>
-    
-    <br>
-    
-    <br>
-    
-    <br>
-    
-    <br>
-    
-    <br>
-    
-    <br>
-    
-    <br>
-    
-    <br>
-    
-    ![|50%](../../../../../.resources/image-1776678923546.png)![|50%](../../../../../.resources/image-1776678942001.png)
+
+**其他:** 显示【领取权益】
+
+<br>
+
+<br>
+
+![|50%](../../../../../.resources/image-1776678923546.png)![|50%](../../../../../.resources/image-1776678942001.png)
 
 **(2)领取权益**
 

Разница между файлами не показана из-за своего большого размера
+ 60 - 27
工作空间/产研/权益/汇丰全行/需求文档/汇丰银行权益中台-FSD.md


Некоторые файлы не были показаны из-за большого количества измененных файлов