haiwei-ui 1.0.98 → 1.0.99
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
|
@@ -38,29 +38,26 @@
|
|
|
38
38
|
</div>
|
|
39
39
|
</div>
|
|
40
40
|
|
|
41
|
-
<div v-if="fileInfo" class="file-info
|
|
42
|
-
<el-descriptions :column="2" border size="
|
|
41
|
+
<div v-if="fileInfo" class="file-info">
|
|
42
|
+
<el-descriptions :column="2" border size="small">
|
|
43
43
|
<el-descriptions-item label="文件名">
|
|
44
|
-
<el-tag type="success">{{ fileInfo.fileName }}</el-tag>
|
|
44
|
+
<el-tag type="success" size="small">{{ fileInfo.fileName }}</el-tag>
|
|
45
45
|
</el-descriptions-item>
|
|
46
46
|
<el-descriptions-item label="文件大小">
|
|
47
|
-
<el-tag type="info">{{ formatFileSize(fileInfo.fileSize) }}</el-tag>
|
|
47
|
+
<el-tag type="info" size="small">{{ formatFileSize(fileInfo.fileSize) }}</el-tag>
|
|
48
48
|
</el-descriptions-item>
|
|
49
49
|
<el-descriptions-item label="工作表数量">
|
|
50
|
-
<el-tag>{{ fileInfo.sheets.length }}个</el-tag>
|
|
51
|
-
</el-descriptions-item>
|
|
52
|
-
<el-descriptions-item label="解析时间">
|
|
53
|
-
<el-tag type="warning">{{ fileInfo.parseTime }}</el-tag>
|
|
50
|
+
<el-tag size="small">{{ fileInfo.sheets.length }}个</el-tag>
|
|
54
51
|
</el-descriptions-item>
|
|
55
52
|
</el-descriptions>
|
|
56
53
|
|
|
57
54
|
<div v-if="fileInfo.sheets && fileInfo.sheets.length > 0" class="sheet-select">
|
|
58
|
-
<el-form :model="model" label-width="
|
|
59
|
-
<el-form-item label="选择工作表:"
|
|
55
|
+
<el-form :model="model" label-width="100px" size="small">
|
|
56
|
+
<el-form-item label="选择工作表:">
|
|
60
57
|
<el-select v-model="model.selectedSheet" placeholder="请选择要导入的工作表" style="width: 100%">
|
|
61
58
|
<el-option v-for="sheet in fileInfo.sheets" :key="sheet.index" :label="sheet.name" :value="sheet.index">
|
|
62
59
|
<span style="float: left">{{ sheet.name }}</span>
|
|
63
|
-
<span style="float: right; color: #8492a6; font-size:
|
|
60
|
+
<span style="float: right; color: #8492a6; font-size: 12px">
|
|
64
61
|
{{ sheet.rowCount }}行 × {{ sheet.columnCount }}列
|
|
65
62
|
</span>
|
|
66
63
|
</el-option>
|
|
@@ -74,7 +71,6 @@
|
|
|
74
71
|
<div class="placeholder-content">
|
|
75
72
|
<i class="el-icon-document placeholder-icon"></i>
|
|
76
73
|
<div class="placeholder-text">请选择要导入的Excel文件</div>
|
|
77
|
-
<div class="placeholder-tip">支持 .xlsx 和 .xls 格式,文件大小不超过10MB</div>
|
|
78
74
|
</div>
|
|
79
75
|
</div>
|
|
80
76
|
</el-card>
|
|
@@ -86,83 +82,50 @@
|
|
|
86
82
|
<div slot="header" class="step-header">
|
|
87
83
|
<div class="header-left">
|
|
88
84
|
<span class="step-title">配置解析选项</span>
|
|
89
|
-
<span class="step-subtitle">设置Excel解析参数</span>
|
|
90
85
|
</div>
|
|
91
86
|
</div>
|
|
92
87
|
|
|
93
|
-
<el-form ref="optionsForm" :model="model"
|
|
94
|
-
<el-
|
|
95
|
-
<el-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
style="width: 100%"
|
|
128
|
-
placeholder="表头所在行号(从0开始)"
|
|
129
|
-
/>
|
|
130
|
-
</el-form-item>
|
|
131
|
-
</el-col>
|
|
132
|
-
<el-col :span="12">
|
|
133
|
-
<el-form-item label="最大预览行数:" prop="maxPreviewRows">
|
|
134
|
-
<el-input-number
|
|
135
|
-
v-model="model.maxPreviewRows"
|
|
136
|
-
:min="1"
|
|
137
|
-
:max="1000"
|
|
138
|
-
controls-position="right"
|
|
139
|
-
style="width: 100%"
|
|
140
|
-
placeholder="最多预览多少行数据"
|
|
141
|
-
/>
|
|
142
|
-
</el-form-item>
|
|
143
|
-
</el-col>
|
|
144
|
-
</el-row>
|
|
145
|
-
|
|
146
|
-
<el-row :gutter="30">
|
|
147
|
-
<el-col :span="12">
|
|
148
|
-
<el-form-item label="数据去重:" prop="deduplicate">
|
|
149
|
-
<el-switch
|
|
150
|
-
v-model="model.deduplicate"
|
|
151
|
-
active-text="是"
|
|
152
|
-
inactive-text="否"
|
|
153
|
-
active-color="#13ce66"
|
|
154
|
-
inactive-color="#ff4949"
|
|
155
|
-
/>
|
|
156
|
-
</el-form-item>
|
|
157
|
-
</el-col>
|
|
158
|
-
</el-row>
|
|
88
|
+
<el-form ref="optionsForm" :model="model" label-width="120px" size="small">
|
|
89
|
+
<el-form-item label="是否包含表头:">
|
|
90
|
+
<el-switch v-model="model.hasHeader" />
|
|
91
|
+
</el-form-item>
|
|
92
|
+
|
|
93
|
+
<el-form-item label="跳过空行:">
|
|
94
|
+
<el-switch v-model="model.skipEmptyRows" />
|
|
95
|
+
</el-form-item>
|
|
96
|
+
|
|
97
|
+
<el-form-item label="表头行行号:">
|
|
98
|
+
<el-input-number
|
|
99
|
+
v-model="model.headerRowIndex"
|
|
100
|
+
:min="0"
|
|
101
|
+
:max="100"
|
|
102
|
+
controls-position="right"
|
|
103
|
+
style="width: 100%"
|
|
104
|
+
size="small"
|
|
105
|
+
/>
|
|
106
|
+
</el-form-item>
|
|
107
|
+
|
|
108
|
+
<el-form-item label="最大预览行数:">
|
|
109
|
+
<el-input-number
|
|
110
|
+
v-model="model.maxPreviewRows"
|
|
111
|
+
:min="1"
|
|
112
|
+
:max="1000"
|
|
113
|
+
controls-position="right"
|
|
114
|
+
style="width: 100%"
|
|
115
|
+
size="small"
|
|
116
|
+
/>
|
|
117
|
+
</el-form-item>
|
|
118
|
+
|
|
119
|
+
<el-form-item label="数据去重:">
|
|
120
|
+
<el-switch v-model="model.deduplicate" />
|
|
121
|
+
</el-form-item>
|
|
159
122
|
|
|
160
123
|
<div class="form-actions">
|
|
161
124
|
<el-button type="primary" :loading="parsing" @click="onParse" style="width: 200px;">
|
|
162
|
-
|
|
125
|
+
解析文件
|
|
163
126
|
</el-button>
|
|
164
127
|
<el-button @click="currentStep = 1" style="margin-left: 20px;">
|
|
165
|
-
|
|
128
|
+
返回上一步
|
|
166
129
|
</el-button>
|
|
167
130
|
</div>
|
|
168
131
|
</el-form>
|
|
@@ -175,12 +138,10 @@
|
|
|
175
138
|
<div slot="header" class="step-header">
|
|
176
139
|
<div class="header-left">
|
|
177
140
|
<span class="step-title">配置字段映射</span>
|
|
178
|
-
<span class="step-subtitle">将Excel列映射到目标字段</span>
|
|
179
141
|
</div>
|
|
180
142
|
</div>
|
|
181
143
|
|
|
182
144
|
<div v-if="parseResult" class="mapping-container">
|
|
183
|
-
<!-- 数据预览 -->
|
|
184
145
|
<div class="preview-section">
|
|
185
146
|
<el-alert
|
|
186
147
|
:title="`已解析 ${parseResult.basicInfo.rowCount} 行数据,${parseResult.basicInfo.columnCount} 列`"
|
|
@@ -194,8 +155,8 @@
|
|
|
194
155
|
:data="parseResult.previewData"
|
|
195
156
|
border
|
|
196
157
|
stripe
|
|
197
|
-
size="
|
|
198
|
-
max-height="
|
|
158
|
+
size="small"
|
|
159
|
+
max-height="200"
|
|
199
160
|
v-loading="parsing"
|
|
200
161
|
class="preview-table"
|
|
201
162
|
>
|
|
@@ -206,33 +167,20 @@
|
|
|
206
167
|
:label="col.label"
|
|
207
168
|
:width="col.width"
|
|
208
169
|
show-overflow-tooltip
|
|
209
|
-
|
|
210
|
-
<template v-slot:header>
|
|
211
|
-
<div class="column-header">
|
|
212
|
-
<div class="column-label">{{ col.label }}</div>
|
|
213
|
-
<div class="column-name">({{ col.name }})</div>
|
|
214
|
-
</div>
|
|
215
|
-
</template>
|
|
216
|
-
</el-table-column>
|
|
170
|
+
/>
|
|
217
171
|
</el-table>
|
|
218
|
-
|
|
219
|
-
<div v-if="parseResult.basicInfo && parseResult.basicInfo.totalRows > parseResult.basicInfo.rowCount" class="preview-tip">
|
|
220
|
-
仅显示前{{ parseResult.basicInfo.rowCount }}行,共{{ parseResult.basicInfo.totalRows }}行数据
|
|
221
|
-
</div>
|
|
222
172
|
</div>
|
|
223
173
|
|
|
224
|
-
<!-- 列映射配置 -->
|
|
225
174
|
<div class="mapping-section">
|
|
226
|
-
<el-table :data="columnMapping" border stripe size="
|
|
227
|
-
<el-table-column prop="excelColumn" label="Excel列" width="
|
|
175
|
+
<el-table :data="columnMapping" border stripe size="small" max-height="200" class="mapping-table">
|
|
176
|
+
<el-table-column prop="excelColumn" label="Excel列" width="150">
|
|
228
177
|
<template v-slot="{ row }">
|
|
229
178
|
<div class="excel-column">
|
|
230
179
|
<div class="column-label">{{ row.excelColumn.label }}</div>
|
|
231
|
-
<div class="column-name">{{ row.excelColumn.name }}</div>
|
|
232
180
|
</div>
|
|
233
181
|
</template>
|
|
234
182
|
</el-table-column>
|
|
235
|
-
<el-table-column prop="targetColumn" label="目标字段" width="
|
|
183
|
+
<el-table-column prop="targetColumn" label="目标字段" width="180">
|
|
236
184
|
<template v-slot="{ row }">
|
|
237
185
|
<el-select
|
|
238
186
|
v-model="row.targetColumn"
|
|
@@ -240,6 +188,7 @@
|
|
|
240
188
|
style="width: 100%"
|
|
241
189
|
clearable
|
|
242
190
|
filterable
|
|
191
|
+
size="small"
|
|
243
192
|
>
|
|
244
193
|
<el-option label="不导入此列" :value="null"></el-option>
|
|
245
194
|
<el-option
|
|
@@ -247,26 +196,13 @@
|
|
|
247
196
|
:key="col.name"
|
|
248
197
|
:label="col.label"
|
|
249
198
|
:value="col.name"
|
|
250
|
-
|
|
251
|
-
<span style="float: left">{{ col.label }}</span>
|
|
252
|
-
<span style="float: right; color: #8492a6; font-size: 13px">{{ col.name }}</span>
|
|
253
|
-
</el-option>
|
|
199
|
+
/>
|
|
254
200
|
</el-select>
|
|
255
201
|
</template>
|
|
256
202
|
</el-table-column>
|
|
257
|
-
<el-table-column prop="required" label="必填" width="
|
|
203
|
+
<el-table-column prop="required" label="必填" width="60" align="center">
|
|
258
204
|
<template v-slot="{ row }">
|
|
259
|
-
<el-checkbox v-model="row.required" :disabled="!row.targetColumn"
|
|
260
|
-
</template>
|
|
261
|
-
</el-table-column>
|
|
262
|
-
<el-table-column prop="defaultValue" label="默认值" min-width="150">
|
|
263
|
-
<template v-slot="{ row }">
|
|
264
|
-
<el-input
|
|
265
|
-
v-model="row.defaultValue"
|
|
266
|
-
:disabled="!row.targetColumn"
|
|
267
|
-
placeholder="当Excel为空时使用此默认值"
|
|
268
|
-
size="mini"
|
|
269
|
-
/>
|
|
205
|
+
<el-checkbox v-model="row.required" :disabled="!row.targetColumn" size="small" />
|
|
270
206
|
</template>
|
|
271
207
|
</el-table-column>
|
|
272
208
|
</el-table>
|
|
@@ -274,13 +210,13 @@
|
|
|
274
210
|
|
|
275
211
|
<div class="form-actions">
|
|
276
212
|
<el-button type="primary" @click="currentStep = 4" style="width: 200px;">
|
|
277
|
-
|
|
213
|
+
下一步:确认导入
|
|
278
214
|
</el-button>
|
|
279
215
|
<el-button @click="currentStep = 2" style="margin-left: 20px;">
|
|
280
|
-
|
|
216
|
+
返回上一步
|
|
281
217
|
</el-button>
|
|
282
218
|
<el-button type="info" @click="onParse" :loading="parsing" style="margin-left: 20px;">
|
|
283
|
-
|
|
219
|
+
重新解析
|
|
284
220
|
</el-button>
|
|
285
221
|
</div>
|
|
286
222
|
</div>
|
|
@@ -293,7 +229,6 @@
|
|
|
293
229
|
<div slot="header" class="step-header">
|
|
294
230
|
<div class="header-left">
|
|
295
231
|
<span class="step-title">确认导入</span>
|
|
296
|
-
<span class="step-subtitle">确认数据映射并执行导入</span>
|
|
297
232
|
</div>
|
|
298
233
|
</div>
|
|
299
234
|
|
|
@@ -306,25 +241,18 @@
|
|
|
306
241
|
/>
|
|
307
242
|
|
|
308
243
|
<div class="mapping-summary">
|
|
309
|
-
<el-descriptions :column="2" border size="
|
|
244
|
+
<el-descriptions :column="2" border size="small">
|
|
310
245
|
<el-descriptions-item label="Excel文件">
|
|
311
|
-
<el-tag type="success">{{ fileInfo.fileName }}</el-tag>
|
|
246
|
+
<el-tag type="success" size="small">{{ fileInfo.fileName }}</el-tag>
|
|
312
247
|
</el-descriptions-item>
|
|
313
248
|
<el-descriptions-item label="工作表">
|
|
314
|
-
<el-tag>{{ getSelectedSheetName() }}</el-tag>
|
|
249
|
+
<el-tag size="small">{{ getSelectedSheetName() }}</el-tag>
|
|
315
250
|
</el-descriptions-item>
|
|
316
251
|
<el-descriptions-item label="总行数">
|
|
317
|
-
<el-tag type="info">{{ parseResult.basicInfo.totalRows }}</el-tag>
|
|
318
|
-
</el-descriptions-item>
|
|
319
|
-
<el-descriptions-item label="总列数">
|
|
320
|
-
<el-tag type="info">{{ parseResult.basicInfo.totalColumns }}</el-tag>
|
|
252
|
+
<el-tag type="info" size="small">{{ parseResult.basicInfo.totalRows }}</el-tag>
|
|
321
253
|
</el-descriptions-item>
|
|
322
254
|
<el-descriptions-item label="已配置映射">
|
|
323
|
-
<el-tag type="success">{{ getMappedColumnsCount() }}列</el-tag>
|
|
324
|
-
</el-descriptions-item>
|
|
325
|
-
<el-descriptions-item label="未配置映射">
|
|
326
|
-
<el-tag v-if="getUnmappedColumnsCount() > 0" type="danger">{{ getUnmappedColumnsCount() }}列</el-tag>
|
|
327
|
-
<el-tag v-else type="success">全部已配置</el-tag>
|
|
255
|
+
<el-tag type="success" size="small">{{ getMappedColumnsCount() }}列</el-tag>
|
|
328
256
|
</el-descriptions-item>
|
|
329
257
|
</el-descriptions>
|
|
330
258
|
</div>
|
|
@@ -332,10 +260,10 @@
|
|
|
332
260
|
|
|
333
261
|
<div class="form-actions">
|
|
334
262
|
<el-button type="success" :loading="importing" @click="onImport" style="width: 200px;">
|
|
335
|
-
|
|
263
|
+
开始导入
|
|
336
264
|
</el-button>
|
|
337
265
|
<el-button @click="currentStep = 3" style="margin-left: 20px;">
|
|
338
|
-
|
|
266
|
+
返回上一步
|
|
339
267
|
</el-button>
|
|
340
268
|
</div>
|
|
341
269
|
</el-card>
|
|
@@ -346,13 +274,13 @@
|
|
|
346
274
|
<template v-slot:footer>
|
|
347
275
|
<el-button-group>
|
|
348
276
|
<el-button v-if="currentStep > 1" @click="currentStep--">
|
|
349
|
-
|
|
277
|
+
上一步
|
|
350
278
|
</el-button>
|
|
351
279
|
<el-button v-if="currentStep < 4 && fileInfo" type="primary" @click="currentStep++">
|
|
352
|
-
下一步
|
|
280
|
+
下一步
|
|
353
281
|
</el-button>
|
|
354
282
|
<el-button type="info" @click="hide">
|
|
355
|
-
|
|
283
|
+
取消
|
|
356
284
|
</el-button>
|
|
357
285
|
</el-button-group>
|
|
358
286
|
</template>
|
|
@@ -370,8 +298,8 @@ export default {
|
|
|
370
298
|
return {
|
|
371
299
|
title: '数据导入',
|
|
372
300
|
icon: 'import',
|
|
373
|
-
width: '
|
|
374
|
-
height: '
|
|
301
|
+
width: '900px',
|
|
302
|
+
height: '650px',
|
|
375
303
|
currentStep: 1,
|
|
376
304
|
model: {
|
|
377
305
|
file: null,
|
|
@@ -380,13 +308,7 @@ export default {
|
|
|
380
308
|
skipEmptyRows: false,
|
|
381
309
|
headerRowIndex: 0,
|
|
382
310
|
maxPreviewRows: 100,
|
|
383
|
-
deduplicate: true
|
|
384
|
-
deduplicateFields: []
|
|
385
|
-
},
|
|
386
|
-
rules: {
|
|
387
|
-
selectedSheet: [{ required: true, message: '请选择工作表', trigger: 'change' }],
|
|
388
|
-
headerRowIndex: [{ required: true, message: '请输入表头行行号', trigger: 'blur' }],
|
|
389
|
-
maxPreviewRows: [{ required: true, message: '请输入最大预览行数', trigger: 'blur' }]
|
|
311
|
+
deduplicate: true
|
|
390
312
|
},
|
|
391
313
|
fileList: [],
|
|
392
314
|
fileInfo: null,
|
|
@@ -507,26 +429,11 @@ export default {
|
|
|
507
429
|
const selectedSheet = this.fileInfo.sheets.find(sheet => sheet.index === this.model.selectedSheet)
|
|
508
430
|
const sheetName = selectedSheet ? selectedSheet.name : null
|
|
509
431
|
|
|
510
|
-
// 添加解析参数
|
|
511
|
-
formData.append('hasHeader', this.model.hasHeader)
|
|
512
|
-
formData.append('skipEmptyRows', this.model.skipEmptyRows)
|
|
513
|
-
formData.append('headerRowIndex', this.model.headerRowIndex)
|
|
514
|
-
formData.append('maxPreviewRows', this.model.maxPreviewRows)
|
|
515
|
-
if (sheetName) {
|
|
516
|
-
formData.append('sheetName', sheetName)
|
|
517
|
-
}
|
|
518
|
-
|
|
519
432
|
// 从token模块获取token
|
|
520
433
|
const t = token.get()
|
|
521
434
|
const accessToken = t && t.accessToken ? t.accessToken : ''
|
|
522
|
-
const config = {
|
|
523
|
-
headers: {
|
|
524
|
-
'Content-Type': 'multipart/form-data',
|
|
525
|
-
'Authorization': `Bearer ${accessToken}`
|
|
526
|
-
}
|
|
527
|
-
}
|
|
528
435
|
|
|
529
|
-
// 构建解析URL
|
|
436
|
+
// 构建解析URL - 使用与uploadUrl相同的方式
|
|
530
437
|
let baseURL = this.$http?.axios?.defaults?.baseURL || window.__HAIWEI_API_BASE_URL__ || '/api'
|
|
531
438
|
if (!baseURL.endsWith('/')) {
|
|
532
439
|
baseURL += '/'
|
|
@@ -546,47 +453,47 @@ export default {
|
|
|
546
453
|
|
|
547
454
|
const fullUrl = `${parseUrl}?${queryParams.toString()}`
|
|
548
455
|
|
|
549
|
-
// 使用axios
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
})
|
|
574
|
-
return obj
|
|
456
|
+
// 使用fetch API发送请求,避免axios依赖问题
|
|
457
|
+
fetch(fullUrl, {
|
|
458
|
+
method: 'POST',
|
|
459
|
+
body: formData,
|
|
460
|
+
headers: {
|
|
461
|
+
'Authorization': `Bearer ${accessToken}`
|
|
462
|
+
// 注意:不要设置Content-Type,让浏览器自动设置multipart/form-data的boundary
|
|
463
|
+
}
|
|
464
|
+
})
|
|
465
|
+
.then(response => response.json())
|
|
466
|
+
.then(data => {
|
|
467
|
+
if (data && data.code === 1) {
|
|
468
|
+
this.fileInfo = data.data.basicInfo
|
|
469
|
+
this.parseResult = {
|
|
470
|
+
basicInfo: data.data.basicInfo,
|
|
471
|
+
columns: data.data.headers.map((header, index) => ({
|
|
472
|
+
name: `col${index}`,
|
|
473
|
+
label: header.name,
|
|
474
|
+
width: 120
|
|
475
|
+
})),
|
|
476
|
+
previewData: data.data.data.map(row => {
|
|
477
|
+
const obj = {}
|
|
478
|
+
data.data.headers.forEach((header, colIndex) => {
|
|
479
|
+
obj[`col${colIndex}`] = row[colIndex]
|
|
575
480
|
})
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
this.currentStep = 3
|
|
579
|
-
this._success('文件解析成功')
|
|
580
|
-
} else {
|
|
581
|
-
this._error(response.data.msg || '文件解析失败')
|
|
481
|
+
return obj
|
|
482
|
+
})
|
|
582
483
|
}
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
this.
|
|
586
|
-
}
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
484
|
+
this.initColumnMapping()
|
|
485
|
+
this.currentStep = 3
|
|
486
|
+
this._success('文件解析成功')
|
|
487
|
+
} else {
|
|
488
|
+
this._error(data.msg || '文件解析失败')
|
|
489
|
+
}
|
|
490
|
+
})
|
|
491
|
+
.catch(error => {
|
|
492
|
+
this._error('文件解析失败:' + (error.message || '未知错误'))
|
|
493
|
+
})
|
|
494
|
+
.finally(() => {
|
|
495
|
+
this.parsing = false
|
|
496
|
+
})
|
|
590
497
|
},
|
|
591
498
|
|
|
592
499
|
initColumnMapping() {
|
|
@@ -595,8 +502,7 @@ export default {
|
|
|
595
502
|
this.columnMapping = this.parseResult.columns.map(col => ({
|
|
596
503
|
excelColumn: col,
|
|
597
504
|
targetColumn: this.findBestMatch(col),
|
|
598
|
-
required: false
|
|
599
|
-
defaultValue: ''
|
|
505
|
+
required: false
|
|
600
506
|
}))
|
|
601
507
|
},
|
|
602
508
|
|
|
@@ -604,17 +510,12 @@ export default {
|
|
|
604
510
|
if (!this.targetColumns || this.targetColumns.length === 0) return null
|
|
605
511
|
|
|
606
512
|
const excelLabel = excelColumn.label.toLowerCase()
|
|
607
|
-
const excelName = excelColumn.name.toLowerCase()
|
|
608
513
|
|
|
609
|
-
//
|
|
514
|
+
// 尝试完全匹配标签
|
|
610
515
|
let match = this.targetColumns.find(col => col.label.toLowerCase() === excelLabel)
|
|
611
516
|
if (match) return match.name
|
|
612
517
|
|
|
613
|
-
//
|
|
614
|
-
match = this.targetColumns.find(col => col.name.toLowerCase() === excelName)
|
|
615
|
-
if (match) return match.name
|
|
616
|
-
|
|
617
|
-
// 3. 尝试包含匹配
|
|
518
|
+
// 尝试包含匹配
|
|
618
519
|
match = this.targetColumns.find(col =>
|
|
619
520
|
excelLabel.includes(col.label.toLowerCase()) ||
|
|
620
521
|
col.label.toLowerCase().includes(excelLabel)
|
|
@@ -694,11 +595,6 @@ export default {
|
|
|
694
595
|
const targetColumn = mapping.targetColumn
|
|
695
596
|
let value = row[excelColumnName]
|
|
696
597
|
|
|
697
|
-
// 如果值为空且设置了默认值,使用默认值
|
|
698
|
-
if ((value === null || value === undefined || value === '') && mapping.defaultValue) {
|
|
699
|
-
value = mapping.defaultValue
|
|
700
|
-
}
|
|
701
|
-
|
|
702
598
|
// 设置到AddModel中
|
|
703
599
|
addModel[targetColumn] = value
|
|
704
600
|
})
|
|
@@ -729,8 +625,7 @@ export default {
|
|
|
729
625
|
return addModels
|
|
730
626
|
}
|
|
731
627
|
|
|
732
|
-
//
|
|
733
|
-
// 在实际应用中,可能需要更复杂的去重逻辑,比如多个字段组合
|
|
628
|
+
// 使用第一个目标字段作为去重依据
|
|
734
629
|
const deduplicateField = targetFields[0]
|
|
735
630
|
|
|
736
631
|
// 使用Map进行去重,保留第一次出现的数据
|
|
@@ -750,9 +645,6 @@ export default {
|
|
|
750
645
|
if (!uniqueMap.has(key)) {
|
|
751
646
|
uniqueMap.set(key, true)
|
|
752
647
|
deduplicatedModels.push(model)
|
|
753
|
-
} else {
|
|
754
|
-
// 重复数据,记录日志(可选)
|
|
755
|
-
console.log(`发现重复数据,字段 ${deduplicateField} = ${key},已跳过`)
|
|
756
648
|
}
|
|
757
649
|
}
|
|
758
650
|
|
|
@@ -785,11 +677,6 @@ export default {
|
|
|
785
677
|
getMappedColumnsCount() {
|
|
786
678
|
if (!this.columnMapping) return 0
|
|
787
679
|
return this.columnMapping.filter(mapping => mapping.targetColumn).length
|
|
788
|
-
},
|
|
789
|
-
|
|
790
|
-
getUnmappedColumnsCount() {
|
|
791
|
-
if (!this.columnMapping) return 0
|
|
792
|
-
return this.columnMapping.filter(mapping => !mapping.targetColumn).length
|
|
793
680
|
}
|
|
794
681
|
},
|
|
795
682
|
created() {
|
|
@@ -863,24 +750,15 @@ export default {
|
|
|
863
750
|
margin-bottom: 8px;
|
|
864
751
|
font-weight: 500;
|
|
865
752
|
}
|
|
866
|
-
|
|
867
|
-
.placeholder-tip {
|
|
868
|
-
font-size: 12px;
|
|
869
|
-
color: #909399;
|
|
870
|
-
}
|
|
871
753
|
}
|
|
872
754
|
}
|
|
873
755
|
|
|
874
|
-
.file-info
|
|
756
|
+
.file-info {
|
|
875
757
|
margin-top: 16px;
|
|
876
758
|
padding: 16px;
|
|
877
759
|
background-color: #f8f9fa;
|
|
878
760
|
border-radius: 4px;
|
|
879
761
|
|
|
880
|
-
.file-info {
|
|
881
|
-
margin-bottom: 16px;
|
|
882
|
-
}
|
|
883
|
-
|
|
884
762
|
.sheet-select {
|
|
885
763
|
margin-top: 16px;
|
|
886
764
|
}
|
|
@@ -904,26 +782,6 @@ export default {
|
|
|
904
782
|
|
|
905
783
|
.preview-table {
|
|
906
784
|
margin-bottom: 8px;
|
|
907
|
-
|
|
908
|
-
.column-header {
|
|
909
|
-
text-align: center;
|
|
910
|
-
|
|
911
|
-
.column-label {
|
|
912
|
-
font-weight: 500;
|
|
913
|
-
}
|
|
914
|
-
|
|
915
|
-
.column-name {
|
|
916
|
-
font-size: 11px;
|
|
917
|
-
color: #909399;
|
|
918
|
-
}
|
|
919
|
-
}
|
|
920
|
-
}
|
|
921
|
-
|
|
922
|
-
.preview-tip {
|
|
923
|
-
text-align: center;
|
|
924
|
-
font-size: 12px;
|
|
925
|
-
color: #909399;
|
|
926
|
-
margin-top: 8px;
|
|
927
785
|
}
|
|
928
786
|
}
|
|
929
787
|
|
|
@@ -932,12 +790,6 @@ export default {
|
|
|
932
790
|
.excel-column {
|
|
933
791
|
.column-label {
|
|
934
792
|
font-weight: 500;
|
|
935
|
-
margin-bottom: 2px;
|
|
936
|
-
}
|
|
937
|
-
|
|
938
|
-
.column-name {
|
|
939
|
-
font-size: 11px;
|
|
940
|
-
color: #909399;
|
|
941
793
|
}
|
|
942
794
|
}
|
|
943
795
|
}
|