appsnbcbweicheng 1.2.21 → 1.2.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -0,0 +1,413 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="auto-verification">
|
|
3
|
+
<!-- 查询条件:核对时间 + 核对结果 -->
|
|
4
|
+
<el-form :inline="true" :model="searchForm" class="search-form" label-width="90px" size="small">
|
|
5
|
+
<el-form-item label="核对时间">
|
|
6
|
+
<el-date-picker
|
|
7
|
+
v-model="searchForm.checkTimeRange"
|
|
8
|
+
type="datetimerange"
|
|
9
|
+
range-separator="至"
|
|
10
|
+
start-placeholder="开始时间"
|
|
11
|
+
end-placeholder="结束时间"
|
|
12
|
+
value-format="yyyy-MM-dd HH:mm:ss"
|
|
13
|
+
:default-time="['00:00:00', '23:59:59']"
|
|
14
|
+
/>
|
|
15
|
+
</el-form-item>
|
|
16
|
+
<el-form-item label="核对结果">
|
|
17
|
+
<el-select
|
|
18
|
+
v-model="searchForm.checkResult"
|
|
19
|
+
placeholder="请选择结果"
|
|
20
|
+
clearable
|
|
21
|
+
style="width: 160px"
|
|
22
|
+
>
|
|
23
|
+
<el-option label="成功" value="成功" />
|
|
24
|
+
<el-option label="存在不一致" value="存在不一致" />
|
|
25
|
+
</el-select>
|
|
26
|
+
</el-form-item>
|
|
27
|
+
<el-form-item>
|
|
28
|
+
<el-button type="primary" @click="handleSearch">查询</el-button>
|
|
29
|
+
<el-button @click="handleReset">重置</el-button>
|
|
30
|
+
</el-form-item>
|
|
31
|
+
</el-form>
|
|
32
|
+
|
|
33
|
+
<!-- 自动核对列表 -->
|
|
34
|
+
<el-table :data="tableDataFiltered" border stripe class="result-table" size="small">
|
|
35
|
+
<el-table-column prop="startTime" label="核对起始时间" width="180" />
|
|
36
|
+
<el-table-column prop="endTime" label="核对终止时间" width="180" />
|
|
37
|
+
<el-table-column prop="checkResult" label="核对结果" width="120">
|
|
38
|
+
<template slot-scope="{ row }">
|
|
39
|
+
<el-tag :type="row.checkResult === '成功' ? 'success' : 'warning'">
|
|
40
|
+
{{ row.checkResult }}
|
|
41
|
+
</el-tag>
|
|
42
|
+
</template>
|
|
43
|
+
</el-table-column>
|
|
44
|
+
<el-table-column prop="productTotal" label="产品总数" width="100" />
|
|
45
|
+
<el-table-column prop="mismatchCount" label="不一致数量" width="110" />
|
|
46
|
+
<el-table-column prop="productType" label="产品类型" width="120" />
|
|
47
|
+
<el-table-column label="操作" width="120" fixed="right">
|
|
48
|
+
<template slot-scope="{ row }">
|
|
49
|
+
<el-button type="text" size="mini" @click="openDetailList(row)"> 查看明细 </el-button>
|
|
50
|
+
</template>
|
|
51
|
+
</el-table-column>
|
|
52
|
+
</el-table>
|
|
53
|
+
|
|
54
|
+
<!-- 核对明细弹窗 -->
|
|
55
|
+
<el-dialog
|
|
56
|
+
title="核对明细"
|
|
57
|
+
:visible.sync="detailListVisible"
|
|
58
|
+
width="900px"
|
|
59
|
+
:close-on-click-modal="false"
|
|
60
|
+
>
|
|
61
|
+
<!-- 明细查询 -->
|
|
62
|
+
<el-form
|
|
63
|
+
:inline="true"
|
|
64
|
+
:model="detailSearchForm"
|
|
65
|
+
class="search-form"
|
|
66
|
+
label-width="90px"
|
|
67
|
+
size="small"
|
|
68
|
+
>
|
|
69
|
+
<el-form-item label="产品代码">
|
|
70
|
+
<el-input
|
|
71
|
+
v-model="detailSearchForm.productCode"
|
|
72
|
+
placeholder="请输入产品代码"
|
|
73
|
+
clearable
|
|
74
|
+
style="width: 200px"
|
|
75
|
+
/>
|
|
76
|
+
</el-form-item>
|
|
77
|
+
<el-form-item label="核对结果">
|
|
78
|
+
<el-select
|
|
79
|
+
v-model="detailSearchForm.checkResult"
|
|
80
|
+
placeholder="请选择结果"
|
|
81
|
+
clearable
|
|
82
|
+
style="width: 160px"
|
|
83
|
+
>
|
|
84
|
+
<el-option label="一致" value="一致" />
|
|
85
|
+
<el-option label="不一致" value="不一致" />
|
|
86
|
+
</el-select>
|
|
87
|
+
</el-form-item>
|
|
88
|
+
<el-form-item>
|
|
89
|
+
<el-button type="primary" @click="handleDetailSearch">查询</el-button>
|
|
90
|
+
<el-button @click="handleDetailReset">重置</el-button>
|
|
91
|
+
</el-form-item>
|
|
92
|
+
</el-form>
|
|
93
|
+
|
|
94
|
+
<!-- 明细列表 -->
|
|
95
|
+
<el-table :data="detailTableFiltered" border stripe class="result-table" size="small">
|
|
96
|
+
<el-table-column prop="productCode" label="产品代码" width="120" />
|
|
97
|
+
<el-table-column prop="productName" label="产品名称" min-width="160" />
|
|
98
|
+
<el-table-column prop="checkResult" label="核对结果" width="100">
|
|
99
|
+
<template slot-scope="{ row }">
|
|
100
|
+
<el-tag :type="row.checkResult === '一致' ? 'success' : 'danger'">
|
|
101
|
+
{{ row.checkResult }}
|
|
102
|
+
</el-tag>
|
|
103
|
+
</template>
|
|
104
|
+
</el-table-column>
|
|
105
|
+
<el-table-column prop="startTime" label="核对开始时间" width="180" />
|
|
106
|
+
<el-table-column prop="endTime" label="核对结束时间" width="180" />
|
|
107
|
+
<el-table-column label="操作" width="100" fixed="right">
|
|
108
|
+
<template slot-scope="{ row }">
|
|
109
|
+
<el-button type="text" size="mini" @click="openDetailCompare(row)"> 详情 </el-button>
|
|
110
|
+
</template>
|
|
111
|
+
</el-table-column>
|
|
112
|
+
</el-table>
|
|
113
|
+
|
|
114
|
+
<span slot="footer" class="dialog-footer">
|
|
115
|
+
<el-button @click="detailListVisible = false">关 闭</el-button>
|
|
116
|
+
</span>
|
|
117
|
+
</el-dialog>
|
|
118
|
+
|
|
119
|
+
<!-- 详情对比弹窗:复用手动核对的对比样式 -->
|
|
120
|
+
<el-dialog
|
|
121
|
+
title="产品信息核对详情"
|
|
122
|
+
:visible.sync="detailDialogVisible"
|
|
123
|
+
width="800px"
|
|
124
|
+
:close-on-click-modal="false"
|
|
125
|
+
>
|
|
126
|
+
<div class="compare-wrapper">
|
|
127
|
+
<div class="compare-header">
|
|
128
|
+
<div class="compare-title compare-title-left">产品中心</div>
|
|
129
|
+
<div class="compare-title compare-title-right">代销系统</div>
|
|
130
|
+
</div>
|
|
131
|
+
<div class="compare-body">
|
|
132
|
+
<div class="compare-column compare-column-left">
|
|
133
|
+
<div v-for="item in compareItems" :key="`left-${item.key}`" class="compare-row">
|
|
134
|
+
<span class="compare-label">{{ item.label }}</span>
|
|
135
|
+
<span class="compare-value" :class="{ 'is-diff': isDiff(item.key) }">
|
|
136
|
+
{{ currentDetail.productCenter[item.key] || '-' }}
|
|
137
|
+
</span>
|
|
138
|
+
</div>
|
|
139
|
+
</div>
|
|
140
|
+
<div class="compare-divider" />
|
|
141
|
+
<div class="compare-column compare-column-right">
|
|
142
|
+
<div v-for="item in compareItems" :key="`right-${item.key}`" class="compare-row">
|
|
143
|
+
<span class="compare-label">{{ item.label }}</span>
|
|
144
|
+
<span class="compare-value" :class="{ 'is-diff': isDiff(item.key) }">
|
|
145
|
+
{{ currentDetail.agencySystem[item.key] || '-' }}
|
|
146
|
+
</span>
|
|
147
|
+
</div>
|
|
148
|
+
</div>
|
|
149
|
+
</div>
|
|
150
|
+
</div>
|
|
151
|
+
|
|
152
|
+
<span slot="footer" class="dialog-footer">
|
|
153
|
+
<el-button @click="detailDialogVisible = false">关 闭</el-button>
|
|
154
|
+
</span>
|
|
155
|
+
</el-dialog>
|
|
156
|
+
</div>
|
|
157
|
+
</template>
|
|
158
|
+
|
|
159
|
+
<script>
|
|
160
|
+
export default {
|
|
161
|
+
name: 'AutoVerification',
|
|
162
|
+
data() {
|
|
163
|
+
return {
|
|
164
|
+
// 顶层查询
|
|
165
|
+
searchForm: {
|
|
166
|
+
checkTimeRange: [],
|
|
167
|
+
checkResult: '',
|
|
168
|
+
},
|
|
169
|
+
// 模拟自动核对批次数据
|
|
170
|
+
tableData: [
|
|
171
|
+
{
|
|
172
|
+
id: 1,
|
|
173
|
+
startTime: '2026-01-09 09:00:00',
|
|
174
|
+
endTime: '2026-01-09 09:05:00',
|
|
175
|
+
checkResult: '成功',
|
|
176
|
+
productTotal: 100,
|
|
177
|
+
mismatchCount: 0,
|
|
178
|
+
productType: '公募基金',
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
id: 2,
|
|
182
|
+
startTime: '2026-01-09 10:00:00',
|
|
183
|
+
endTime: '2026-01-09 10:08:30',
|
|
184
|
+
checkResult: '存在不一致',
|
|
185
|
+
productTotal: 80,
|
|
186
|
+
mismatchCount: 5,
|
|
187
|
+
productType: '理财产品',
|
|
188
|
+
},
|
|
189
|
+
],
|
|
190
|
+
// 当前选中的批次对应的明细
|
|
191
|
+
detailListVisible: false,
|
|
192
|
+
detailSearchForm: {
|
|
193
|
+
productCode: '',
|
|
194
|
+
checkResult: '',
|
|
195
|
+
},
|
|
196
|
+
detailTableData: [],
|
|
197
|
+
|
|
198
|
+
// 详情对比弹窗
|
|
199
|
+
detailDialogVisible: false,
|
|
200
|
+
currentDetail: {
|
|
201
|
+
productCenter: {},
|
|
202
|
+
agencySystem: {},
|
|
203
|
+
},
|
|
204
|
+
compareItems: [
|
|
205
|
+
{ label: '产品代码', key: 'productCode' },
|
|
206
|
+
{ label: '产品名称', key: 'productName' },
|
|
207
|
+
{ label: '产品类型', key: 'productType' },
|
|
208
|
+
{ label: '机构代码', key: 'orgCode' },
|
|
209
|
+
{ label: '准入状态', key: 'accessStatus' },
|
|
210
|
+
{ label: '市场代码', key: 'marketCode' },
|
|
211
|
+
{ label: '市场名称', key: 'marketName' },
|
|
212
|
+
],
|
|
213
|
+
}
|
|
214
|
+
},
|
|
215
|
+
computed: {
|
|
216
|
+
tableDataFiltered() {
|
|
217
|
+
const { checkTimeRange, checkResult } = this.searchForm
|
|
218
|
+
return this.tableData.filter(item => {
|
|
219
|
+
let matchResult = true
|
|
220
|
+
let matchTime = true
|
|
221
|
+
if (checkResult) {
|
|
222
|
+
matchResult = item.checkResult === checkResult
|
|
223
|
+
}
|
|
224
|
+
if (checkTimeRange && checkTimeRange.length === 2) {
|
|
225
|
+
const [start, end] = checkTimeRange
|
|
226
|
+
matchTime = item.startTime >= start && item.endTime <= end
|
|
227
|
+
}
|
|
228
|
+
return matchResult && matchTime
|
|
229
|
+
})
|
|
230
|
+
},
|
|
231
|
+
detailTableFiltered() {
|
|
232
|
+
const { productCode, checkResult } = this.detailSearchForm
|
|
233
|
+
return this.detailTableData.filter(item => {
|
|
234
|
+
const matchCode = productCode ? item.productCode.indexOf(productCode) > -1 : true
|
|
235
|
+
const matchResult = checkResult ? item.checkResult === checkResult : true
|
|
236
|
+
return matchCode && matchResult
|
|
237
|
+
})
|
|
238
|
+
},
|
|
239
|
+
},
|
|
240
|
+
methods: {
|
|
241
|
+
handleSearch() {
|
|
242
|
+
// 使用 computed 过滤即可,这里预留给后续接口调用
|
|
243
|
+
},
|
|
244
|
+
handleReset() {
|
|
245
|
+
this.searchForm.checkTimeRange = []
|
|
246
|
+
this.searchForm.checkResult = ''
|
|
247
|
+
},
|
|
248
|
+
openDetailList(row) {
|
|
249
|
+
// 实际场景下这里根据 row.id 请求明细数据
|
|
250
|
+
// 这里使用模拟数据演示
|
|
251
|
+
this.detailTableData = [
|
|
252
|
+
{
|
|
253
|
+
id: 1,
|
|
254
|
+
productCode: '000001',
|
|
255
|
+
productName: '华夏成长混合',
|
|
256
|
+
checkResult: '不一致',
|
|
257
|
+
startTime: row.startTime,
|
|
258
|
+
endTime: row.endTime,
|
|
259
|
+
productCenter: {
|
|
260
|
+
productCode: '000001',
|
|
261
|
+
productName: '华夏成长混合',
|
|
262
|
+
productType: row.productType,
|
|
263
|
+
orgCode: 'ORG001',
|
|
264
|
+
accessStatus: '已准入',
|
|
265
|
+
marketCode: 'MKT001',
|
|
266
|
+
marketName: '上海证券交易所',
|
|
267
|
+
},
|
|
268
|
+
agencySystem: {
|
|
269
|
+
productCode: '000001',
|
|
270
|
+
productName: '华夏成长混合A',
|
|
271
|
+
productType: row.productType,
|
|
272
|
+
orgCode: 'ORG001',
|
|
273
|
+
accessStatus: '已准入',
|
|
274
|
+
marketCode: 'MKT001',
|
|
275
|
+
marketName: '上交所',
|
|
276
|
+
},
|
|
277
|
+
},
|
|
278
|
+
{
|
|
279
|
+
id: 2,
|
|
280
|
+
productCode: 'LCP123',
|
|
281
|
+
productName: '稳健理财一年期',
|
|
282
|
+
checkResult: '一致',
|
|
283
|
+
startTime: row.startTime,
|
|
284
|
+
endTime: row.endTime,
|
|
285
|
+
productCenter: {
|
|
286
|
+
productCode: 'LCP123',
|
|
287
|
+
productName: '稳健理财一年期',
|
|
288
|
+
productType: row.productType,
|
|
289
|
+
orgCode: 'ORG002',
|
|
290
|
+
accessStatus: '待准入',
|
|
291
|
+
marketCode: 'MKT002',
|
|
292
|
+
marketName: '银行间市场',
|
|
293
|
+
},
|
|
294
|
+
agencySystem: {
|
|
295
|
+
productCode: 'LCP123',
|
|
296
|
+
productName: '稳健理财一年期',
|
|
297
|
+
productType: row.productType,
|
|
298
|
+
orgCode: 'ORG002',
|
|
299
|
+
accessStatus: '待准入',
|
|
300
|
+
marketCode: 'MKT002',
|
|
301
|
+
marketName: '银行间市场',
|
|
302
|
+
},
|
|
303
|
+
},
|
|
304
|
+
]
|
|
305
|
+
this.detailListVisible = true
|
|
306
|
+
},
|
|
307
|
+
handleDetailSearch() {
|
|
308
|
+
// 使用 computed 过滤即可,这里预留给后续接口调用
|
|
309
|
+
},
|
|
310
|
+
handleDetailReset() {
|
|
311
|
+
this.detailSearchForm.productCode = ''
|
|
312
|
+
this.detailSearchForm.checkResult = ''
|
|
313
|
+
},
|
|
314
|
+
openDetailCompare(row) {
|
|
315
|
+
this.currentDetail = {
|
|
316
|
+
productCenter: row.productCenter || {},
|
|
317
|
+
agencySystem: row.agencySystem || {},
|
|
318
|
+
}
|
|
319
|
+
this.detailDialogVisible = true
|
|
320
|
+
},
|
|
321
|
+
isDiff(key) {
|
|
322
|
+
const left = (this.currentDetail.productCenter || {})[key]
|
|
323
|
+
const right = (this.currentDetail.agencySystem || {})[key]
|
|
324
|
+
return left !== right
|
|
325
|
+
},
|
|
326
|
+
},
|
|
327
|
+
}
|
|
328
|
+
</script>
|
|
329
|
+
|
|
330
|
+
<style scoped>
|
|
331
|
+
.auto-verification {
|
|
332
|
+
padding: 16px 0;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
.search-form {
|
|
336
|
+
margin-bottom: 16px;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
.result-table {
|
|
340
|
+
width: 100%;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
.compare-wrapper {
|
|
344
|
+
border-radius: 12px;
|
|
345
|
+
border: 1px solid #e4e7ed;
|
|
346
|
+
padding: 16px 24px 8px;
|
|
347
|
+
background-color: #fafbff;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
.compare-header {
|
|
351
|
+
display: flex;
|
|
352
|
+
justify-content: space-between;
|
|
353
|
+
margin-bottom: 12px;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
.compare-title {
|
|
357
|
+
font-size: 14px;
|
|
358
|
+
font-weight: 600;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
.compare-title-left {
|
|
362
|
+
color: #409eff;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
.compare-title-right {
|
|
366
|
+
color: #67c23a;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
.compare-body {
|
|
370
|
+
display: flex;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
.compare-column {
|
|
374
|
+
flex: 1;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
.compare-column-left {
|
|
378
|
+
padding-right: 16px;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
.compare-column-right {
|
|
382
|
+
padding-left: 16px;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
.compare-divider {
|
|
386
|
+
width: 1px;
|
|
387
|
+
background-color: #dcdfe6;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
.compare-row {
|
|
391
|
+
display: flex;
|
|
392
|
+
align-items: center;
|
|
393
|
+
margin-bottom: 8px;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
.compare-label {
|
|
397
|
+
width: 80px;
|
|
398
|
+
font-size: 13px;
|
|
399
|
+
color: #606266;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
.compare-value {
|
|
403
|
+
flex: 1;
|
|
404
|
+
font-size: 13px;
|
|
405
|
+
color: #303133;
|
|
406
|
+
word-break: break-all;
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
.compare-value.is-diff {
|
|
410
|
+
color: #f56c6c;
|
|
411
|
+
font-weight: 600;
|
|
412
|
+
}
|
|
413
|
+
</style>
|
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="manual-verification">
|
|
3
|
+
<!-- 查询条件 -->
|
|
4
|
+
<el-form :inline="true" :model="searchForm" class="search-form" label-width="80px" size="small">
|
|
5
|
+
<el-form-item label="产品类型">
|
|
6
|
+
<el-select
|
|
7
|
+
v-model="searchForm.productType"
|
|
8
|
+
placeholder="请选择产品类型"
|
|
9
|
+
clearable
|
|
10
|
+
style="width: 180px"
|
|
11
|
+
>
|
|
12
|
+
<el-option
|
|
13
|
+
v-for="item in productTypeOptions"
|
|
14
|
+
:key="item.value"
|
|
15
|
+
:label="item.label"
|
|
16
|
+
:value="item.value"
|
|
17
|
+
/>
|
|
18
|
+
</el-select>
|
|
19
|
+
</el-form-item>
|
|
20
|
+
<el-form-item label="产品代码">
|
|
21
|
+
<el-input
|
|
22
|
+
v-model="searchForm.productCode"
|
|
23
|
+
placeholder="请输入产品代码"
|
|
24
|
+
clearable
|
|
25
|
+
style="width: 200px"
|
|
26
|
+
/>
|
|
27
|
+
</el-form-item>
|
|
28
|
+
<el-form-item>
|
|
29
|
+
<el-button type="primary" @click="handleSearch">查询</el-button>
|
|
30
|
+
<el-button @click="handleReset">重置</el-button>
|
|
31
|
+
</el-form-item>
|
|
32
|
+
</el-form>
|
|
33
|
+
|
|
34
|
+
<!-- 列表 -->
|
|
35
|
+
<el-table :data="tableDataFiltered" border stripe class="result-table" size="small">
|
|
36
|
+
<el-table-column prop="productType" label="产品类型" width="120" />
|
|
37
|
+
<el-table-column prop="productName" label="产品名称" min-width="160" />
|
|
38
|
+
<el-table-column prop="orgCode" label="机构代码" width="120" />
|
|
39
|
+
<el-table-column prop="accessStatus" label="准入状态" width="100" />
|
|
40
|
+
<el-table-column prop="marketCode" label="市场代码" width="120" />
|
|
41
|
+
<el-table-column prop="marketName" label="市场名称" min-width="120" />
|
|
42
|
+
<el-table-column label="操作" width="100" fixed="right">
|
|
43
|
+
<template slot-scope="{ row }">
|
|
44
|
+
<el-button type="text" size="mini" @click="openDetail(row)"> 详情 </el-button>
|
|
45
|
+
</template>
|
|
46
|
+
</el-table-column>
|
|
47
|
+
</el-table>
|
|
48
|
+
|
|
49
|
+
<!-- 详情弹窗:产品中心 vs 代销系统 对比 -->
|
|
50
|
+
<el-dialog
|
|
51
|
+
title="产品信息核对详情"
|
|
52
|
+
:visible.sync="detailDialogVisible"
|
|
53
|
+
width="800px"
|
|
54
|
+
:close-on-click-modal="false"
|
|
55
|
+
>
|
|
56
|
+
<div class="compare-wrapper">
|
|
57
|
+
<div class="compare-header">
|
|
58
|
+
<div class="compare-title compare-title-left">产品中心</div>
|
|
59
|
+
<div class="compare-title compare-title-right">代销系统</div>
|
|
60
|
+
</div>
|
|
61
|
+
<div class="compare-body">
|
|
62
|
+
<div class="compare-column compare-column-left">
|
|
63
|
+
<div v-for="item in compareItems" :key="`left-${item.key}`" class="compare-row">
|
|
64
|
+
<span class="compare-label">{{ item.label }}</span>
|
|
65
|
+
<span class="compare-value" :class="{ 'is-diff': isDiff(item.key) }">
|
|
66
|
+
{{ currentDetail.productCenter[item.key] || '-' }}
|
|
67
|
+
</span>
|
|
68
|
+
</div>
|
|
69
|
+
</div>
|
|
70
|
+
<div class="compare-divider" />
|
|
71
|
+
<div class="compare-column compare-column-right">
|
|
72
|
+
<div v-for="item in compareItems" :key="`right-${item.key}`" class="compare-row">
|
|
73
|
+
<span class="compare-label">{{ item.label }}</span>
|
|
74
|
+
<span class="compare-value" :class="{ 'is-diff': isDiff(item.key) }">
|
|
75
|
+
{{ currentDetail.agencySystem[item.key] || '-' }}
|
|
76
|
+
</span>
|
|
77
|
+
</div>
|
|
78
|
+
</div>
|
|
79
|
+
</div>
|
|
80
|
+
</div>
|
|
81
|
+
|
|
82
|
+
<span slot="footer" class="dialog-footer">
|
|
83
|
+
<el-button @click="detailDialogVisible = false">关 闭</el-button>
|
|
84
|
+
</span>
|
|
85
|
+
</el-dialog>
|
|
86
|
+
</div>
|
|
87
|
+
</template>
|
|
88
|
+
|
|
89
|
+
<script>
|
|
90
|
+
export default {
|
|
91
|
+
name: 'ManualVerification',
|
|
92
|
+
data() {
|
|
93
|
+
return {
|
|
94
|
+
// 查询表单
|
|
95
|
+
searchForm: {
|
|
96
|
+
productType: '',
|
|
97
|
+
productCode: '',
|
|
98
|
+
},
|
|
99
|
+
productTypeOptions: [
|
|
100
|
+
{ label: '公募基金', value: '公募基金' },
|
|
101
|
+
{ label: '私募基金', value: '私募基金' },
|
|
102
|
+
{ label: '理财产品', value: '理财产品' },
|
|
103
|
+
],
|
|
104
|
+
// 模拟列表数据
|
|
105
|
+
tableData: [
|
|
106
|
+
{
|
|
107
|
+
id: 1,
|
|
108
|
+
productType: '公募基金',
|
|
109
|
+
productCode: '000001',
|
|
110
|
+
productName: '华夏成长混合',
|
|
111
|
+
orgCode: 'ORG001',
|
|
112
|
+
accessStatus: '已准入',
|
|
113
|
+
marketCode: 'MKT001',
|
|
114
|
+
marketName: '上海证券交易所',
|
|
115
|
+
// 对比详情数据
|
|
116
|
+
productCenter: {
|
|
117
|
+
productCode: '000001',
|
|
118
|
+
productName: '华夏成长混合',
|
|
119
|
+
productType: '公募基金',
|
|
120
|
+
orgCode: 'ORG001',
|
|
121
|
+
accessStatus: '已准入',
|
|
122
|
+
marketCode: 'MKT001',
|
|
123
|
+
marketName: '上海证券交易所',
|
|
124
|
+
},
|
|
125
|
+
agencySystem: {
|
|
126
|
+
productCode: '000001',
|
|
127
|
+
productName: '华夏成长混合A',
|
|
128
|
+
productType: '公募基金',
|
|
129
|
+
orgCode: 'ORG001',
|
|
130
|
+
accessStatus: '已准入',
|
|
131
|
+
marketCode: 'MKT001',
|
|
132
|
+
marketName: '上交所',
|
|
133
|
+
},
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
id: 2,
|
|
137
|
+
productType: '理财产品',
|
|
138
|
+
productCode: 'LCP123',
|
|
139
|
+
productName: '稳健理财一年期',
|
|
140
|
+
orgCode: 'ORG002',
|
|
141
|
+
accessStatus: '待准入',
|
|
142
|
+
marketCode: 'MKT002',
|
|
143
|
+
marketName: '银行间市场',
|
|
144
|
+
productCenter: {
|
|
145
|
+
productCode: 'LCP123',
|
|
146
|
+
productName: '稳健理财一年期',
|
|
147
|
+
productType: '理财产品',
|
|
148
|
+
orgCode: 'ORG002',
|
|
149
|
+
accessStatus: '待准入',
|
|
150
|
+
marketCode: 'MKT002',
|
|
151
|
+
marketName: '银行间市场',
|
|
152
|
+
},
|
|
153
|
+
agencySystem: {
|
|
154
|
+
productCode: 'LCP123',
|
|
155
|
+
productName: '稳健理财一年期',
|
|
156
|
+
productType: '理财产品',
|
|
157
|
+
orgCode: 'ORG002',
|
|
158
|
+
accessStatus: '已准入',
|
|
159
|
+
marketCode: 'MKT002',
|
|
160
|
+
marketName: '银行间市场',
|
|
161
|
+
},
|
|
162
|
+
},
|
|
163
|
+
],
|
|
164
|
+
detailDialogVisible: false,
|
|
165
|
+
currentDetail: {
|
|
166
|
+
productCenter: {},
|
|
167
|
+
agencySystem: {},
|
|
168
|
+
},
|
|
169
|
+
compareItems: [
|
|
170
|
+
{ label: '产品代码', key: 'productCode' },
|
|
171
|
+
{ label: '产品名称', key: 'productName' },
|
|
172
|
+
{ label: '产品类型', key: 'productType' },
|
|
173
|
+
{ label: '机构代码', key: 'orgCode' },
|
|
174
|
+
{ label: '准入状态', key: 'accessStatus' },
|
|
175
|
+
{ label: '市场代码', key: 'marketCode' },
|
|
176
|
+
{ label: '市场名称', key: 'marketName' },
|
|
177
|
+
],
|
|
178
|
+
}
|
|
179
|
+
},
|
|
180
|
+
computed: {
|
|
181
|
+
tableDataFiltered() {
|
|
182
|
+
const { productType, productCode } = this.searchForm
|
|
183
|
+
return this.tableData.filter(item => {
|
|
184
|
+
const matchType = productType ? item.productType === productType : true
|
|
185
|
+
const matchCode = productCode ? item.productCode.indexOf(productCode) > -1 : true
|
|
186
|
+
return matchType && matchCode
|
|
187
|
+
})
|
|
188
|
+
},
|
|
189
|
+
},
|
|
190
|
+
methods: {
|
|
191
|
+
handleSearch() {
|
|
192
|
+
// 由于使用 computed 过滤,这里无需额外逻辑,保留以便后续接入接口
|
|
193
|
+
},
|
|
194
|
+
handleReset() {
|
|
195
|
+
this.searchForm.productType = ''
|
|
196
|
+
this.searchForm.productCode = ''
|
|
197
|
+
},
|
|
198
|
+
openDetail(row) {
|
|
199
|
+
this.currentDetail = {
|
|
200
|
+
productCenter: row.productCenter || {},
|
|
201
|
+
agencySystem: row.agencySystem || {},
|
|
202
|
+
}
|
|
203
|
+
this.detailDialogVisible = true
|
|
204
|
+
},
|
|
205
|
+
isDiff(key) {
|
|
206
|
+
const left = (this.currentDetail.productCenter || {})[key]
|
|
207
|
+
const right = (this.currentDetail.agencySystem || {})[key]
|
|
208
|
+
return left !== right
|
|
209
|
+
},
|
|
210
|
+
},
|
|
211
|
+
}
|
|
212
|
+
</script>
|
|
213
|
+
|
|
214
|
+
<style scoped>
|
|
215
|
+
.manual-verification {
|
|
216
|
+
padding: 16px 0;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
.search-form {
|
|
220
|
+
margin-bottom: 16px;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
.result-table {
|
|
224
|
+
width: 100%;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
.compare-wrapper {
|
|
228
|
+
border-radius: 12px;
|
|
229
|
+
border: 1px solid #e4e7ed;
|
|
230
|
+
padding: 16px 24px 8px;
|
|
231
|
+
background-color: #fafbff;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
.compare-header {
|
|
235
|
+
display: flex;
|
|
236
|
+
justify-content: space-between;
|
|
237
|
+
margin-bottom: 12px;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
.compare-title {
|
|
241
|
+
font-size: 14px;
|
|
242
|
+
font-weight: 600;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
.compare-title-left {
|
|
246
|
+
color: #409eff;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
.compare-title-right {
|
|
250
|
+
color: #67c23a;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
.compare-body {
|
|
254
|
+
display: flex;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
.compare-column {
|
|
258
|
+
flex: 1;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
.compare-column-left {
|
|
262
|
+
padding-right: 16px;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
.compare-column-right {
|
|
266
|
+
padding-left: 16px;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
.compare-divider {
|
|
270
|
+
width: 1px;
|
|
271
|
+
background-color: #dcdfe6;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
.compare-row {
|
|
275
|
+
display: flex;
|
|
276
|
+
align-items: center;
|
|
277
|
+
margin-bottom: 8px;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
.compare-label {
|
|
281
|
+
width: 80px;
|
|
282
|
+
font-size: 13px;
|
|
283
|
+
color: #606266;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
.compare-value {
|
|
287
|
+
flex: 1;
|
|
288
|
+
font-size: 13px;
|
|
289
|
+
color: #303133;
|
|
290
|
+
word-break: break-all;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
.compare-value.is-diff {
|
|
294
|
+
color: #f56c6c;
|
|
295
|
+
font-weight: 600;
|
|
296
|
+
}
|
|
297
|
+
</style>
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
产品信息核对系统 - 前端设计文档
|
|
2
|
+
**
|
|
3
|
+
1. 文档概述
|
|
4
|
+
1.1 文档目的
|
|
5
|
+
本文档用于明确产品信息核对系统的前端实现方案,包括技术选型、架构设计、页面交互、组件封装等核心内容,为前端开发、测试及协作提供依据。
|
|
6
|
+
1.2 适用范围
|
|
7
|
+
适用于前端开发人员、测试人员、产品经理及相关协作人员,作为开发落地、需求校验的参考标准。
|
|
8
|
+
1.3 核心需求
|
|
9
|
+
系统包含两大核心功能模块:手动核对和自动核对,支持产品信息搜索、列表展示、详情对比(不一致标红)等核心操作,具体需求如下:
|
|
10
|
+
手动核对:按产品类型 / 产品代码搜索,列表展示产品基础信息,详情弹窗双栏对比产品中心与代销系统数据;
|
|
11
|
+
自动核对:按核对时间 / 核对结果搜索,列表展示核对任务概览,支持跳转至明细页面;
|
|
12
|
+
自动核对明细:按产品代码 / 核对结果搜索,列表展示单产品核对记录,复用详情对比弹窗。
|
|
13
|
+
2. 技术选型
|
|
14
|
+
技术栈
|
|
15
|
+
版本 / 说明
|
|
16
|
+
选型理由
|
|
17
|
+
核心框架
|
|
18
|
+
Vue 2.x
|
|
19
|
+
满足业务复杂度,团队技术栈匹配
|
|
20
|
+
UI 组件库
|
|
21
|
+
Element UI
|
|
22
|
+
组件丰富、文档完善,适配 Vue2
|
|
23
|
+
路由管理
|
|
24
|
+
Vue Router 3.x
|
|
25
|
+
Vue2 生态标配,路由控制稳定
|
|
26
|
+
样式解决方案
|
|
27
|
+
Scoped CSS + Element 原生样式
|
|
28
|
+
轻量高效,避免样式污染
|
|
29
|
+
数据模拟
|
|
30
|
+
本地静态数据(待对接接口)
|
|
31
|
+
开发阶段快速验证功能逻辑
|
|
32
|
+
|
|
33
|
+
3. 系统架构设计
|
|
34
|
+
3.1 整体架构
|
|
35
|
+
采用「页面 - 组件 - 工具」三层架构,确保代码复用性和可维护性:
|
|
36
|
+
产品信息核对系统
|
|
37
|
+
├── 页面层(Views):承载核心业务逻辑和页面展示
|
|
38
|
+
│ ├── ManualCheck.vue(手动核对页面)
|
|
39
|
+
│ ├── AutoCheck.vue(自动核对页面)
|
|
40
|
+
│ └── AutoCheckDetail.vue(自动核对明细页面)
|
|
41
|
+
├── 组件层(Components):封装通用/业务组件
|
|
42
|
+
│ └── CheckDetailModal.vue(详情对比弹窗组件)
|
|
43
|
+
├── 路由层(Router):控制页面跳转和参数传递
|
|
44
|
+
│ └── index.js(路由配置)
|
|
45
|
+
└── 入口层(Main):初始化 Vue 实例、注册依赖
|
|
46
|
+
└── main.js(项目入口)
|
|
47
|
+
|
|
48
|
+
3.2 目录结构
|
|
49
|
+
src/
|
|
50
|
+
├── views/ # 页面组件
|
|
51
|
+
│ ├── ManualCheck.vue # 手动核对页面
|
|
52
|
+
│ ├── AutoCheck.vue # 自动核对页面
|
|
53
|
+
│ └── AutoCheckDetail.vue # 自动核对明细页面
|
|
54
|
+
├── components/ # 通用组件
|
|
55
|
+
│ └── CheckDetailModal.vue # 详情对比弹窗
|
|
56
|
+
├── router/ # 路由配置
|
|
57
|
+
│ └── index.js
|
|
58
|
+
├── main.js # 项目入口
|
|
59
|
+
└── App.vue # 根组件(导航栏 + 路由视图)
|
|
60
|
+
|
|
61
|
+
4. 页面设计
|
|
62
|
+
4.1 根组件(App.vue)
|
|
63
|
+
功能定位
|
|
64
|
+
系统入口页面,包含顶部导航栏和路由视图容器,负责页面切换控制。
|
|
65
|
+
核心设计
|
|
66
|
+
顶部导航栏:采用 Element UI 的 el-menu 组件,水平布局,包含「手动核对」「自动核对」两个菜单选项;
|
|
67
|
+
路由视图:通过 `` 渲染当前路由对应的页面,导航栏点击触发路由跳转。
|
|
68
|
+
4.2 手动核对页面(ManualCheck.vue)
|
|
69
|
+
页面结构
|
|
70
|
+
分为「搜索区域」和「列表区域」两部分,底部挂载详情弹窗组件:
|
|
71
|
+
搜索区域:
|
|
72
|
+
采用 el-form 组件(inline 模式),包含产品类型输入框、产品代码输入框、搜索按钮、重置按钮;
|
|
73
|
+
样式:浅灰色背景(#f5f5f5),15px 内边距,4px 圆角。
|
|
74
|
+
列表区域:
|
|
75
|
+
采用 el-table 组件(带边框),100% 宽度,与搜索区域间距 20px;
|
|
76
|
+
列配置:产品类型、产品名称、机构代码、准入状态、市场代码、市场名称、操作(详情按钮);
|
|
77
|
+
操作列:「详情」文本按钮,点击触发详情弹窗。
|
|
78
|
+
4.3 自动核对页面(AutoCheck.vue)
|
|
79
|
+
页面结构
|
|
80
|
+
与手动核对页面一致,分为「搜索区域」和「列表区域」:
|
|
81
|
+
搜索区域:
|
|
82
|
+
采用 el-form 组件(inline 模式),包含核对时间范围选择器、核对结果下拉选择器、搜索按钮、重置按钮;
|
|
83
|
+
核对时间:el-date-picker(daterange 类型),格式为 yyyy-MM-dd;
|
|
84
|
+
核对结果:el-select 组件,选项为「全部」「一致」「不一致」。
|
|
85
|
+
列表区域:
|
|
86
|
+
采用 el-table 组件(带边框);
|
|
87
|
+
列配置:核对起始时间、核对终止时间、核对结果、产品总数、不一致数量、产品类型、操作(查看明细按钮);
|
|
88
|
+
操作列:「查看明细」文本按钮,点击跳转至自动核对明细页面并携带参数。
|
|
89
|
+
4.4 自动核对明细页面(AutoCheckDetail.vue)
|
|
90
|
+
页面结构
|
|
91
|
+
与手动核对页面结构一致,分为「搜索区域」和「列表区域」:
|
|
92
|
+
搜索区域:
|
|
93
|
+
采用 el-form 组件(inline 模式),包含产品代码输入框、核对结果下拉选择器、搜索按钮、重置按钮;
|
|
94
|
+
核对结果下拉选择器与自动核对页面一致。
|
|
95
|
+
列表区域:
|
|
96
|
+
采用 el-table 组件(带边框);
|
|
97
|
+
列配置:产品代码、产品名称、核对结果、核对开始时间、核对结束时间、操作(详情按钮);
|
|
98
|
+
操作列:「详情」文本按钮,点击触发详情弹窗。
|
|
99
|
+
5. 组件设计
|
|
100
|
+
5.1 详情对比弹窗(CheckDetailModal.vue)
|
|
101
|
+
组件定位
|
|
102
|
+
通用组件,被手动核对页面和自动核对明细页面复用,用于展示产品中心与代销系统的信息对比。
|
|
103
|
+
核心设计
|
|
104
|
+
弹窗基础配置:
|
|
105
|
+
标题:「产品信息核对详情」;
|
|
106
|
+
宽度:80%;
|
|
107
|
+
关闭时销毁 DOM(destroy-on-close: true);
|
|
108
|
+
遮罩层不插入 body(modal-append-to-body: false)。
|
|
109
|
+
内部布局:
|
|
110
|
+
整体容器:1px 灰色边框,8px 圆角,20px 内边距,flex 布局;
|
|
111
|
+
双栏结构:左侧「产品中心」、右侧「代销系统」,中间用 1px 灰色竖线分割;
|
|
112
|
+
列标题:16px 字体,加粗,颜色 #1989fa,底部间距 20px;
|
|
113
|
+
对比项:每行展示一个字段,包含标签(灰色,#666)和值,标签与值间距 8px;
|
|
114
|
+
不一致标红:通过 isDiff 方法判断字段是否一致,不一致时添加 text-red 类(颜色 #f56c6c,加粗)。
|
|
115
|
+
字段配置:
|
|
116
|
+
产品类型、产品名称、机构代码、准入状态、市场代码、市场名称。
|
|
117
|
+
Props 定义:
|
|
118
|
+
Prop 名称
|
|
119
|
+
类型
|
|
120
|
+
说明
|
|
121
|
+
visible
|
|
122
|
+
Boolean
|
|
123
|
+
弹窗显示 / 隐藏控制(双向绑定)
|
|
124
|
+
productData
|
|
125
|
+
Object
|
|
126
|
+
对比数据(包含 center 和 agency 字段)
|
|
127
|
+
|
|
128
|
+
6. 交互设计
|
|
129
|
+
6.1 通用交互
|
|
130
|
+
搜索功能:
|
|
131
|
+
点击「搜索」按钮,根据表单参数过滤列表数据;
|
|
132
|
+
输入框 / 选择器支持回车触发搜索。
|
|
133
|
+
重置功能:
|
|
134
|
+
点击「重置」按钮,清空表单所有输入 / 选择项;
|
|
135
|
+
重置后自动加载原始列表数据(未过滤状态)。
|
|
136
|
+
弹窗交互:
|
|
137
|
+
点击「详情」按钮,加载当前行对应的对比数据并显示弹窗;
|
|
138
|
+
弹窗支持右上角关闭按钮、点击遮罩层关闭、ESC 键关闭。
|
|
139
|
+
6.2 页面跳转交互
|
|
140
|
+
自动核对页面 → 自动核对明细页面:
|
|
141
|
+
点击「查看明细」按钮,通过 $router.push 跳转,携带参数:checkStartTime(核对起始时间)、checkResult(核对结果)、productType(产品类型);
|
|
142
|
+
明细页面加载时,接收路由参数并初始化搜索表单和列表数据。
|
|
143
|
+
7. 数据设计
|
|
144
|
+
7.1 核心数据模型
|
|
145
|
+
7.1.1 手动核对列表数据(tableData)
|
|
146
|
+
{
|
|
147
|
+
productType: String, // 产品类型(如:理财产品、基金产品)
|
|
148
|
+
productCode: String, // 产品代码(如:LC001、JJ002)
|
|
149
|
+
productName: String, // 产品名称(如:XX稳健理财)
|
|
150
|
+
orgCode: String, // 机构代码(如:ORG001)
|
|
151
|
+
accessStatus: String, // 准入状态(如:已准入、未准入)
|
|
152
|
+
marketCode: String, // 市场代码(如:M001)
|
|
153
|
+
marketName: String // 市场名称(如:上海市场)
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
7.1.2 自动核对列表数据(tableData)
|
|
157
|
+
{
|
|
158
|
+
checkStartTime: String, // 核对起始时间(如:2026-01-01 09:00:00)
|
|
159
|
+
checkEndTime: String, // 核对终止时间(如:2026-01-01 10:00:00)
|
|
160
|
+
checkResult: String, // 核对结果(一致/不一致)
|
|
161
|
+
productTotal: Number, // 产品总数(如:100)
|
|
162
|
+
diffCount: Number, // 不一致数量(如:5)
|
|
163
|
+
productType: String // 产品类型(如:理财产品)
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
7.1.3 自动核对明细列表数据(tableData)
|
|
167
|
+
{
|
|
168
|
+
productCode: String, // 产品代码(如:LC001)
|
|
169
|
+
productName: String, // 产品名称(如:XX稳健理财)
|
|
170
|
+
checkResult: String, // 核对结果(一致/不一致)
|
|
171
|
+
checkStartTime: String, // 核对开始时间(如:2026-01-01 09:01:00)
|
|
172
|
+
checkEndTime: String // 核对结束时间(如:2026-01-01 09:02:00)
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
7.1.4 对比数据(productData)
|
|
176
|
+
{
|
|
177
|
+
center: { // 产品中心数据
|
|
178
|
+
productType: String,
|
|
179
|
+
productName: String,
|
|
180
|
+
orgCode: String,
|
|
181
|
+
accessStatus: String,
|
|
182
|
+
marketCode: String,
|
|
183
|
+
marketName: String
|
|
184
|
+
},
|
|
185
|
+
agency: { // 代销系统数据(字段与 center 一致)
|
|
186
|
+
productType: String,
|
|
187
|
+
productName: String,
|
|
188
|
+
orgCode: String,
|
|
189
|
+
accessStatus: String,
|
|
190
|
+
marketCode: String,
|
|
191
|
+
marketName: String
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
7.2 数据来源
|
|
196
|
+
开发阶段:本地静态模拟数据(在 loadTableData 方法中定义);
|
|
197
|
+
生产阶段:对接后端接口,替换模拟数据方法为接口请求(如 axios)。
|
|
198
|
+
8. 样式设计规范
|
|
199
|
+
8.1 颜色规范
|
|
200
|
+
用途
|
|
201
|
+
颜色值
|
|
202
|
+
说明
|
|
203
|
+
主色调
|
|
204
|
+
#1989fa
|
|
205
|
+
导航栏背景、列标题颜色
|
|
206
|
+
辅助色(错误)
|
|
207
|
+
#f56c6c
|
|
208
|
+
不一致字段标红、错误提示
|
|
209
|
+
背景色(搜索区域)
|
|
210
|
+
#f5f5f5
|
|
211
|
+
搜索表单背景
|
|
212
|
+
边框色
|
|
213
|
+
#e6e6e6
|
|
214
|
+
弹窗边框、分割线
|
|
215
|
+
文本色(常规)
|
|
216
|
+
#2c3e50
|
|
217
|
+
页面主文本
|
|
218
|
+
文本色(标签)
|
|
219
|
+
#666666
|
|
220
|
+
对比项标签文本
|
|
221
|
+
|
|
222
|
+
8.2 字体规范
|
|
223
|
+
全局字体:Avenir, Helvetica, Arial, sans-serif;
|
|
224
|
+
标题字体:16px,加粗;
|
|
225
|
+
正文字体:14px;
|
|
226
|
+
表格文本:14px;
|
|
227
|
+
按钮文本:14px。
|
|
228
|
+
8.3 间距规范
|
|
229
|
+
页面内边距:20px;
|
|
230
|
+
搜索区域内边距:15px;
|
|
231
|
+
搜索区域与列表区域间距:20px;
|
|
232
|
+
对比项间距:15px(垂直);
|
|
233
|
+
标签与值间距:8px(水平);
|
|
234
|
+
弹窗内边距:20px;
|
|
235
|
+
双栏对比间距:20px(水平)。
|
|
236
|
+
9. 接口对接预留
|
|
237
|
+
9.1 核心接口需求(待后端提供)
|
|
238
|
+
接口功能
|
|
239
|
+
入参
|
|
240
|
+
出参
|
|
241
|
+
手动核对列表查询
|
|
242
|
+
productType(可选)、productCode(可选)
|
|
243
|
+
手动核对列表数据(见 7.1.1)
|
|
244
|
+
自动核对列表查询
|
|
245
|
+
checkTimeStart(可选)、checkTimeEnd(可选)、checkResult(可选)
|
|
246
|
+
自动核对列表数据(见 7.1.2)
|
|
247
|
+
自动核对明细查询
|
|
248
|
+
productCode(可选)、checkResult(可选)、productType(可选)
|
|
249
|
+
自动核对明细数据(见 7.1.3)
|
|
250
|
+
产品对比数据查询
|
|
251
|
+
productCode(必填)
|
|
252
|
+
对比数据(见 7.1.4)
|
|
253
|
+
|
|
254
|
+
9.2 对接方式
|
|
255
|
+
替换各页面 loadTableData 方法中的静态数据,通过 axios 发起 HTTP 请求;
|
|
256
|
+
新增接口请求工具类(如 api/checkApi.js),统一管理接口地址和请求逻辑;
|
|
257
|
+
处理加载状态、错误提示(可通过 Element UI 的 el-loading el-message 组件实现)。
|
|
258
|
+
10. 兼容性与性能要求
|
|
259
|
+
10.1 浏览器兼容性
|
|
260
|
+
支持 Chrome、Firefox、Edge 最新版本;
|
|
261
|
+
支持 IE 11 及以上版本(Element UI 兼容)。
|
|
262
|
+
10.2 性能要求
|
|
263
|
+
页面加载时间:≤ 2s;
|
|
264
|
+
列表渲染时间:≤ 500ms(数据量 ≤ 1000 条);
|
|
265
|
+
弹窗打开时间:≤ 300ms;
|
|
266
|
+
搜索响应时间:≤ 500ms。
|
package/readme.md
CHANGED
|
Binary file
|