sohelp-eleplus 1.1.24 → 1.1.25

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.
@@ -12,17 +12,11 @@
12
12
  </div>
13
13
  </div>
14
14
  <div class="upload-area" @drop.prevent="onDrop" @dragover.prevent>
15
- <el-upload
16
- drag
17
- :auto-upload="false"
18
- :show-file-list="false"
19
- :on-change="onFileChange"
20
- :on-remove="onRemove"
21
- :limit="1"
22
- accept=".xls,.xlsx"
23
- class="uploader"
24
- >
25
- <i class="el-icon"><UploadFilled /></i>
15
+ <el-upload drag :auto-upload="false" :show-file-list="false" :on-change="onFileChange" :on-remove="onRemove"
16
+ :limit="1" accept=".xls,.xlsx" class="uploader">
17
+ <i class="el-icon">
18
+ <UploadFilled />
19
+ </i>
26
20
  <div class="el-upload__text">拖拽文件到此处或点击上传</div>
27
21
  <div class="el-upload__tip">仅限 .xls/.xlsx,大小不超过 50MB</div>
28
22
  </el-upload>
@@ -66,14 +60,9 @@
66
60
  <el-button type="primary" @click="saveConfig">保存</el-button>
67
61
  </template>
68
62
  </ele-modal>
69
- <ele-modal
70
- :model-value="historyVisible"
71
- title="导入历史"
72
- :width="800"
73
- @update:modelValue="(v) => (historyVisible = v)"
74
- >
63
+ <ele-modal :model-value="historyVisible" title="导入历史" :width="800" @update:modelValue="(v) => (historyVisible = v)">
75
64
  <div class="history-wrap">
76
- <vxe-grid :columns="historyColumns" :data="historyList" size="mini" border>
65
+ <sohelp-vxe-grid :gridOptions="gridOptions" :url="`/engine/web/import/history?refid=${props.refid}`" size="mini" border>
77
66
  <template #op="{ row }">
78
67
  <el-space :size="6">
79
68
  <el-button size="small" plain @click="downloadHistoryFile(row)">下载文件</el-button>
@@ -81,7 +70,7 @@
81
70
  <el-button size="small" plain type="danger" @click="deleteHistoryFile(row)">删除文件</el-button>
82
71
  </el-space>
83
72
  </template>
84
- </vxe-grid>
73
+ </sohelp-vxe-grid>
85
74
  </div>
86
75
  <template #footer>
87
76
  <el-button @click="historyVisible = false">关闭</el-button>
@@ -89,382 +78,400 @@
89
78
  </ele-modal>
90
79
  </template>
91
80
  <script setup>
92
- import { ref, computed } from 'vue';
93
- import { ElMessage } from 'element-plus/es';
94
- import { EleMessage } from '@/components/ele-admin-plus/components';
95
- import { UploadFilled } from '@element-plus/icons-vue';
96
- import SohelpHttp from '../http/SohelpHttp.js';
81
+ import { ref, computed } from 'vue';
82
+ import { ElMessage } from 'element-plus/es';
83
+ import { EleMessage } from '@/components/ele-admin-plus/components';
84
+ import { UploadFilled } from '@element-plus/icons-vue';
85
+ import SohelpHttp from '../http/SohelpHttp.js';
97
86
 
98
- const MAX_ROWS = 10000;
87
+ const MAX_ROWS = 10000;
99
88
 
100
- const props = defineProps({
101
- modelValue: Boolean,
102
- refid: {
103
- type: String,
104
- required: true
105
- },
106
- fields: {
107
- type: Array,
108
- default: () => []
109
- }
110
- });
111
- const emit = defineEmits(['update:modelValue', 'close']);
89
+ const props = defineProps({
90
+ modelValue: Boolean,
91
+ refid: {
92
+ type: String,
93
+ required: true
94
+ },
95
+ fields: {
96
+ type: Array,
97
+ default: () => []
98
+ }
99
+ });
100
+ const emit = defineEmits(['update:modelValue', 'close']);
112
101
 
113
- const loading = ref(false);
114
- const fileName = ref('');
115
- const fileSize = ref(0);
116
- const progress = ref(0);
117
- const progressStatus = ref('success');
118
- const rowCount = ref(0);
119
- const fileId = ref('');
120
- const previewVisible = ref(false);
121
- const previewData = ref([]);
122
- const previewColumns = ref([]);
102
+ const loading = ref(false);
103
+ const fileName = ref('');
104
+ const fileSize = ref(0);
105
+ const progress = ref(0);
106
+ const progressStatus = ref('success');
107
+ const rowCount = ref(0);
108
+ const fileId = ref('');
109
+ const previewVisible = ref(false);
110
+ const previewData = ref([]);
111
+ const previewColumns = ref([]);
123
112
 
124
- const configVisible = ref(false);
125
- const whitelist = ref([]);
126
- const mapping = ref({});
127
- const historyVisible = ref(false);
128
- const historyList = ref([]);
129
- const downloadingTemplate = ref(false);
130
- const historyColumns = ref([
131
- { field: 'file', title: '文件名', align: 'center', minWidth: 160 },
132
- { field: 'size', title: '大小', align: 'center', minWidth: 100 },
133
- { field: 'rows', title: '记录数', align: 'center', minWidth: 90 },
134
- { field: 'upload_user', title: '导入人员', align: 'center', minWidth: 120 },
135
- { field: 'update_time', title: '导入时间', align: 'center', minWidth: 180 },
113
+ const configVisible = ref(false);
114
+ const whitelist = ref([]);
115
+ const mapping = ref({});
116
+ const historyVisible = ref(false);
117
+ const historyList = ref([]);
118
+ const downloadingTemplate = ref(false);
119
+ const gridOptions = ref({
120
+ maxHeight: 500,
121
+ columns: [
122
+ { field: 'id', title: 'ID', align: 'center', width: 160 },
123
+ { field: 'filename', title: '文件名', align: 'center', minWidth: 160 },
124
+ { field: 'size', title: '大小', align: 'center', minWidth: 100,
125
+ formatter: ({ cellValue }) => formatSize(cellValue)
126
+ },
127
+ // { field: 'rows', title: '记录数', align: 'center', minWidth: 90 },
128
+ { field: 'upload_usernamme', title: '导入人员', align: 'center', minWidth: 120 },
129
+ { field: 'upload_time', title: '导入时间', align: 'center', minWidth: 180 },
136
130
  { field: 'op', title: '操作', align: 'center', minWidth: 220, slots: { default: 'op' } }
137
- ]);
138
-
139
- const canImport = computed(() => !!fileId.value && rowCount.value > 0 && rowCount.value <= MAX_ROWS);
131
+ ]
132
+ });
140
133
 
141
- const updateModelValue = (val) => {
142
- emit('update:modelValue', val);
143
- if (!val) {
144
- onRemove();
145
- }
146
- };
134
+ const canImport = computed(() => !!fileId.value && rowCount.value > 0 && rowCount.value <= MAX_ROWS);
147
135
 
148
- const onClose = () => {
149
- emit('update:modelValue', false);
150
- emit('close');
136
+ const updateModelValue = (val) => {
137
+ emit('update:modelValue', val);
138
+ if (!val) {
151
139
  onRemove();
152
- };
140
+ }
141
+ };
153
142
 
154
- const formatSize = (n) => {
155
- if (n < 1024) return n + 'B';
156
- if (n < 1024 * 1024) return (n / 1024).toFixed(1) + 'KB';
157
- return (n / 1024 / 1024).toFixed(1) + 'MB';
158
- };
143
+ const onClose = () => {
144
+ emit('update:modelValue', false);
145
+ emit('close');
146
+ onRemove();
147
+ };
159
148
 
160
- const openConfig = () => {
161
- if (!whitelist.value.length) {
162
- whitelist.value = props.fields.map((f) => f.name);
163
- }
164
- if (Object.keys(mapping.value).length === 0) {
165
- props.fields.forEach((f) => (mapping.value[f.name] = f.label || f.name));
166
- }
167
- configVisible.value = true;
168
- };
169
- const updateConfigVisible = (v) => (configVisible.value = v);
170
- const saveConfig = () => {
171
- configVisible.value = false;
172
- };
173
- const getFieldLabel = (name) => props.fields.find((f) => f.name === name)?.label || name;
149
+ const formatSize = (n) => {
150
+ if (n < 1024) return n + 'B';
151
+ if (n < 1024 * 1024) return (n / 1024).toFixed(1) + 'KB';
152
+ return (n / 1024 / 1024).toFixed(1) + 'MB';
153
+ };
174
154
 
175
- /**
176
- * 下载导入模板
177
- * - 绑定click事件监听器到 button 元素
178
- * - 在事件处理函数中动态获取当前列表的refid值
179
- * - 构造完整下载URL:/engine/web/import/downloadTemplate?refid=${动态获取的refid}
180
- * - 使用SohelpHttp.download方法发起请求,参数格式为:{refid: '动态refid值'}
181
- * - 错误处理:捕获refid无效、网络错误、服务器错误,并实现重试
182
- * - 用户体验:显示loading,下载进度
183
- */
184
- const downloadTemplate = async () => {
185
- // 验证 refid 参数
186
- if (!props.refid) {
187
- EleMessage.error('请选择有效的模板');
188
- return;
189
- }
155
+ const openConfig = () => {
156
+ if (!whitelist.value.length) {
157
+ whitelist.value = props.fields.map((f) => f.name);
158
+ }
159
+ if (Object.keys(mapping.value).length === 0) {
160
+ props.fields.forEach((f) => (mapping.value[f.name] = f.label || f.name));
161
+ }
162
+ configVisible.value = true;
163
+ };
164
+ const updateConfigVisible = (v) => (configVisible.value = v);
165
+ const saveConfig = () => {
166
+ configVisible.value = false;
167
+ };
168
+ const getFieldLabel = (name) => props.fields.find((f) => f.name === name)?.label || name;
190
169
 
191
- downloadingTemplate.value = true;
192
- const maxRetries = 3;
193
- let retryCount = 0;
194
- let lastError = null;
170
+ /**
171
+ * 下载导入模板
172
+ * - 绑定click事件监听器到 button 元素
173
+ * - 在事件处理函数中动态获取当前列表的refid值
174
+ * - 构造完整下载URL:/engine/web/import/downloadTemplate?refid=${动态获取的refid}
175
+ * - 使用SohelpHttp.download方法发起请求,参数格式为:{refid: '动态refid值'}
176
+ * - 错误处理:捕获refid无效、网络错误、服务器错误,并实现重试
177
+ * - 用户体验:显示loading,下载进度
178
+ */
179
+ const downloadTemplate = async () => {
180
+ // 验证 refid 参数
181
+ if (!props.refid) {
182
+ EleMessage.error('请选择有效的模板');
183
+ return;
184
+ }
185
+
186
+ downloadingTemplate.value = true;
187
+ const maxRetries = 3;
188
+ let retryCount = 0;
189
+ let lastError = null;
195
190
 
196
- // 错误重试机制(最多3次)
197
- while (retryCount <= maxRetries) {
198
- try {
199
- await SohelpHttp.download(
200
- '/engine/web/import/downloadTemplate',
201
- { refid: props.refid },
202
- '导入模板.xlsx',
203
- (loaded, total) => {
204
- // 大文件下载时显示进度条
205
- // 这里可以对接UI的进度条,目前简单处理,如果需要更复杂的UI交互可以扩展
206
- if (total > 0) {
207
- const percent = Math.floor((loaded / total) * 100);
208
- // console.log(`下载进度: ${percent}%`);
209
- }
210
- },
211
- { timeout: 30000 } // 实现请求超时机制,默认设置为30秒
212
- );
213
- EleMessage.success('模板下载成功');
214
- downloadingTemplate.value = false;
215
- return;
216
- } catch (error) {
217
- lastError = error;
218
- retryCount++;
219
- if (retryCount <= maxRetries) {
220
- // 简单的指数退避或固定等待
221
- await new Promise((resolve) => setTimeout(resolve, 1000));
222
- }
191
+ // 错误重试机制(最多3次)
192
+ while (retryCount <= maxRetries) {
193
+ try {
194
+ await SohelpHttp.download(
195
+ '/engine/web/import/downloadTemplate',
196
+ { refid: props.refid },
197
+ '导入模板.xlsx',
198
+ (loaded, total) => {
199
+ // 大文件下载时显示进度条
200
+ // 这里可以对接UI的进度条,目前简单处理,如果需要更复杂的UI交互可以扩展
201
+ if (total > 0) {
202
+ const percent = Math.floor((loaded / total) * 100);
203
+ console.log(`下载进度: ${percent}%`);
204
+ }
205
+ },
206
+ { timeout: 30000 } // 实现请求超时机制,默认设置为30秒
207
+ );
208
+ EleMessage.success('模板下载成功');
209
+ downloadingTemplate.value = false;
210
+ return;
211
+ } catch (error) {
212
+ lastError = error;
213
+ retryCount++;
214
+ if (retryCount <= maxRetries) {
215
+ // 简单的指数退避或固定等待
216
+ await new Promise((resolve) => setTimeout(resolve, 1000));
223
217
  }
224
218
  }
219
+ }
225
220
 
226
- downloadingTemplate.value = false;
227
- // 错误处理机制
228
- const errorMsg = String(lastError);
229
- if (errorMsg.includes('timeout') || errorMsg.includes('Network Error')) {
230
- EleMessage.error('网络连接异常,请稍后重试');
231
- } else {
232
- EleMessage.error(errorMsg || '下载失败');
233
- }
234
- };
221
+ downloadingTemplate.value = false;
222
+ // 错误处理机制
223
+ const errorMsg = String(lastError);
224
+ if (errorMsg.includes('timeout') || errorMsg.includes('Network Error')) {
225
+ EleMessage.error('网络连接异常,请稍后重试');
226
+ } else {
227
+ EleMessage.error(errorMsg || '下载失败');
228
+ }
229
+ };
235
230
 
236
- const onDrop = async (e) => {
237
- const file = e.dataTransfer.files?.[0];
238
- if (file) await handleFile(file);
239
- };
240
- const onFileChange = async (file) => {
241
- const f = file?.raw || file;
242
- if (f) await handleFile(f);
243
- };
244
- const onRemove = () => {
245
- fileName.value = '';
246
- fileSize.value = 0;
247
- progress.value = 0;
248
- rowCount.value = 0;
249
- previewVisible.value = false;
250
- fileId.value = '';
251
- previewData.value = [];
252
- previewColumns.value = [];
253
- progressStatus.value = 'success';
254
- loading.value = false;
255
- };
231
+ const onDrop = async (e) => {
232
+ const file = e.dataTransfer.files?.[0];
233
+ if (file) await handleFile(file);
234
+ };
235
+ const onFileChange = async (file) => {
236
+ const f = file?.raw || file;
237
+ if (f) await handleFile(f);
238
+ };
239
+ const onRemove = () => {
240
+ fileName.value = '';
241
+ fileSize.value = 0;
242
+ progress.value = 0;
243
+ rowCount.value = 0;
244
+ previewVisible.value = false;
245
+ fileId.value = '';
246
+ previewData.value = [];
247
+ previewColumns.value = [];
248
+ progressStatus.value = 'success';
249
+ loading.value = false;
250
+ };
256
251
 
257
- const handleFile = async (file) => {
258
- const ext = file.name.toLowerCase().split('.').pop();
259
- if (!['xls', 'xlsx'].includes(ext)) {
260
- ElMessage.error('仅支持 .xls 或 .xlsx 文件');
261
- return;
262
- }
263
- if (file.size > 50 * 1024 * 1024) {
264
- ElMessage.error('文件大小超过 50MB 限制');
252
+ const handleFile = async (file) => {
253
+ const ext = file.name.toLowerCase().split('.').pop();
254
+ if (!['xls', 'xlsx'].includes(ext)) {
255
+ ElMessage.error('仅支持 .xls 或 .xlsx 文件');
256
+ return;
257
+ }
258
+ if (file.size > 50 * 1024 * 1024) {
259
+ ElMessage.error('文件大小超过 50MB 限制');
260
+ return;
261
+ }
262
+ fileName.value = file.name;
263
+ fileSize.value = file.size;
264
+ progress.value = 10;
265
+ const form = new FormData();
266
+ form.append('refid', props.refid);
267
+ form.append('file', file);
268
+ try {
269
+ const res = await SohelpHttp.post('/engine/web/import/upload', form);
270
+ if (!res.meta.success) {
271
+ progressStatus.value = 'exception';
272
+ ElMessage.error(res.meta.message || '上传失败');
265
273
  return;
266
274
  }
267
- fileName.value = file.name;
268
- fileSize.value = file.size;
269
- progress.value = 10;
270
- const form = new FormData();
271
- form.append('refid', props.refid);
272
- form.append('file', file);
273
- try {
274
- const res = await SohelpHttp.post('/engine/web/import/upload', form);
275
- if (!res.meta.success) {
276
- progressStatus.value = 'exception';
277
- ElMessage.error(res.meta.message || '上传失败');
278
- return;
279
- }
280
- fileId.value = res.data?.fileId || '';
281
- rowCount.value = res.data?.rows || 0;
282
- if (rowCount.value > MAX_ROWS) {
283
- progressStatus.value = 'exception';
284
- ElMessage.error('超过最大行数限制(10,000)');
285
- return;
286
- }
287
- progress.value = 60;
288
- await loadPreview();
289
- progress.value = 100;
290
- progressStatus.value = 'success';
291
- // 默认不显示预览数据
292
- previewVisible.value = false;
293
- } catch (e) {
275
+ fileId.value = res.data?.fileId || '';
276
+ rowCount.value = res.data?.rows || 0;
277
+ if (rowCount.value > MAX_ROWS) {
294
278
  progressStatus.value = 'exception';
295
- ElMessage.error(String(e));
296
- }
297
- };
298
-
299
- const togglePreview = () => {
300
- previewVisible.value = !previewVisible.value;
301
- };
302
- const downloadProcessed = () => {
303
- if (!fileId.value) {
304
- ElMessage.error('请先上传导入文件');
279
+ ElMessage.error('超过最大行数限制(10,000)');
305
280
  return;
306
281
  }
307
- SohelpHttp.download(
308
- '/engine/web/import/download',
309
- { fileId: fileId.value },
310
- fileName.value || '导入数据.xlsx'
311
- ).catch((e) => ElMessage.error(String(e)));
312
- };
313
- const viewHistory = async () => {
314
- try {
315
- const res = await SohelpHttp.get('/engine/web/import/history', { refid: props.refid });
316
- if (res.meta.success) {
317
- const list = res.data?.results || [];
318
- historyList.value = list;
319
- historyVisible.value = true;
320
- } else {
321
- ElMessage.error(res.meta.message || '获取历史失败');
322
- }
323
- } catch (e) {
324
- ElMessage.error(String(e));
325
- }
326
- };
327
- const commitImport = async () => {
328
- if (!canImport.value) {
329
- ElMessage.error('请上传有效的导入文件');
330
- return;
282
+ progress.value = 60;
283
+ await loadPreview();
284
+ progress.value = 100;
285
+ progressStatus.value = 'success';
286
+ // 默认不显示预览数据
287
+ previewVisible.value = false;
288
+ } catch (e) {
289
+ progressStatus.value = 'exception';
290
+ ElMessage.error(String(e));
291
+ }
292
+ };
293
+
294
+ const togglePreview = () => {
295
+ previewVisible.value = !previewVisible.value;
296
+ };
297
+ const downloadProcessed = () => {
298
+ if (!fileId.value) {
299
+ ElMessage.error('请先上传导入文件');
300
+ return;
301
+ }
302
+ SohelpHttp.download(
303
+ '/engine/web/import/download',
304
+ { fileId: fileId.value },
305
+ fileName.value || '导入数据.xlsx'
306
+ ).catch((e) => ElMessage.error(String(e)));
307
+ };
308
+ const viewHistory = async () => {
309
+ try {
310
+ const res = await SohelpHttp.get('/engine/web/import/history', { refid: props.refid });
311
+ if (res.meta.success) {
312
+ const list = res.data?.results || [];
313
+ historyList.value = list;
314
+ historyVisible.value = true;
315
+ } else {
316
+ ElMessage.error(res.meta.message || '获取历史失败');
331
317
  }
332
- const loadingTip = EleMessage.loading('导入中..');
333
- try {
334
- loading.value = true;
335
- const res = await SohelpHttp.post('/engine/web/import/confirm', { fileId: fileId.value, refid: props.refid });
336
- if (res.meta.success) {
337
- ElMessage.success(res.meta.message || '导入完成');
338
- emit('update:modelValue', false);
339
- } else {
340
- ElMessage.error(res.meta.message || '导入失败');
341
- }
342
- } catch (e) {
343
- ElMessage.error(String(e));
344
- } finally {
345
- loadingTip.close();
346
- loading.value = false;
318
+ } catch (e) {
319
+ ElMessage.error(String(e));
320
+ }
321
+ };
322
+ const commitImport = async () => {
323
+ if (!canImport.value) {
324
+ ElMessage.error('请上传有效的导入文件');
325
+ return;
326
+ }
327
+ const loadingTip = EleMessage.loading('导入中..');
328
+ try {
329
+ loading.value = true;
330
+ const res = await SohelpHttp.post('/engine/web/import/confirm', { fileId: fileId.value, refid: props.refid });
331
+ if (res.meta.success) {
332
+ ElMessage.success(res.meta.message || '导入完成');
333
+ emit('update:modelValue', false);
334
+ } else {
335
+ ElMessage.error(res.meta.message || '导入失败');
347
336
  }
348
- };
337
+ } catch (e) {
338
+ ElMessage.error(String(e));
339
+ } finally {
340
+ loadingTip.close();
341
+ loading.value = false;
342
+ }
343
+ };
349
344
 
350
- const loadPreview = async () => {
351
- try {
352
- const res = await SohelpHttp.get('/engine/web/import/preview', { refid: props.refid, fileId: fileId.value });
353
- if (res.meta.success) {
354
- const rows = Array.isArray(res.data.results) ? res.data.results : [];
355
- previewData.value = rows.slice(0, 50);
356
- const keys = rows.length
357
- ? Object.keys(rows[0])
358
- : whitelist.value.length
359
- ? whitelist.value
360
- : props.fields.map((f) => f.name);
361
- previewColumns.value = keys.map((k) => ({
362
- field: k,
363
- title: getFieldLabel(k),
364
- align: 'center',
365
- minWidth: 120
366
- }));
367
- // previewVisible.value = true; // 加载数据后不自动显示
368
- } else {
369
- ElMessage.error(res.meta.message || '预览失败');
370
- }
371
- } catch (e) {
372
- ElMessage.error(String(e));
345
+ const loadPreview = async () => {
346
+ try {
347
+ const res = await SohelpHttp.get('/engine/web/import/preview', { refid: props.refid, fileId: fileId.value });
348
+ if (res.meta.success) {
349
+ const rows = Array.isArray(res.data.results) ? res.data.results : [];
350
+ previewData.value = rows.slice(0, 50);
351
+ const keys = rows.length
352
+ ? Object.keys(rows[0])
353
+ : whitelist.value.length
354
+ ? whitelist.value
355
+ : props.fields.map((f) => f.name);
356
+ previewColumns.value = keys.map((k) => ({
357
+ field: k,
358
+ title: getFieldLabel(k),
359
+ align: 'center',
360
+ minWidth: 120
361
+ }));
362
+ // previewVisible.value = true; // 加载数据后不自动显示
363
+ } else {
364
+ ElMessage.error(res.meta.message || '预览失败');
373
365
  }
374
- };
366
+ } catch (e) {
367
+ ElMessage.error(String(e));
368
+ }
369
+ };
375
370
 
376
- const downloadHistoryFile = (row) => {
377
- SohelpHttp.download('/engine/web/import/download', { fileId: row.file_uuid }, row.file).catch((e) =>
378
- ElMessage.error(String(e))
379
- );
380
- };
381
- const restoreHistoryFile = async (row) => {
382
- try {
383
- const res = await SohelpHttp.post('/engine/web/import/restore', { fileId: row.file_uuid, refid: props.refid });
384
- if (res.meta.success) {
385
- ElMessage.success(res.meta.message || '恢复成功');
386
- } else {
387
- ElMessage.error(res.meta.message || '恢复失败');
388
- }
389
- } catch (e) {
390
- ElMessage.error(String(e));
371
+ const downloadHistoryFile = (row) => {
372
+ SohelpHttp.download('/engine/web/import/download', { fileId: row.file_uuid }, row.file).catch((e) =>
373
+ ElMessage.error(String(e))
374
+ );
375
+ };
376
+ const restoreHistoryFile = async (row) => {
377
+ try {
378
+ const res = await SohelpHttp.post('/engine/web/import/restore', { fileId: row.file_uuid, refid: props.refid });
379
+ if (res.meta.success) {
380
+ ElMessage.success(res.meta.message || '恢复成功');
381
+ } else {
382
+ ElMessage.error(res.meta.message || '恢复失败');
391
383
  }
392
- };
393
- const deleteHistoryFile = async (row) => {
394
- try {
395
- const res = await SohelpHttp.post('/engine/web/import/delete', { fileId: row.file_uuid, refid: props.refid });
396
- if (res.meta.success) {
397
- ElMessage.success(res.meta.message || '删除成功');
398
- await viewHistory();
399
- } else {
400
- ElMessage.error(res.meta.message || '删除失败');
401
- }
402
- } catch (e) {
403
- ElMessage.error(String(e));
384
+ } catch (e) {
385
+ ElMessage.error(String(e));
386
+ }
387
+ };
388
+ const deleteHistoryFile = async (row) => {
389
+ try {
390
+ const res = await SohelpHttp.post('/engine/web/import/delete', { fileId: row.file_uuid, refid: props.refid });
391
+ if (res.meta.success) {
392
+ ElMessage.success(res.meta.message || '删除成功');
393
+ await viewHistory();
394
+ } else {
395
+ ElMessage.error(res.meta.message || '删除失败');
404
396
  }
405
- };
397
+ } catch (e) {
398
+ ElMessage.error(String(e));
399
+ }
400
+ };
406
401
  </script>
407
402
  <style scoped lang="scss">
408
- .import-wrap {
409
- display: flex;
410
- flex-direction: column;
411
- gap: 12px;
412
- }
413
- .import-header {
414
- display: flex;
415
- align-items: center;
416
- justify-content: space-between;
417
- }
418
- .actions {
419
- display: flex;
420
- gap: 10px;
421
- }
422
- .actions :deep(.el-button:hover) {
423
- opacity: 0.9;
424
- }
425
- .upload-area {
426
- min-width: 300px;
427
- min-height: 200px;
428
- border: 1px dashed #bbb;
429
- display: flex;
430
- flex-direction: column;
431
- align-items: center;
432
- justify-content: center;
433
- padding: 20px;
434
- border-radius: 6px;
435
- }
436
- .uploader {
437
- width: 100%;
438
- }
439
- .status {
440
- width: 100%;
441
- margin-top: 10px;
442
- }
443
- .result-actions {
444
- display: flex;
445
- gap: 10px;
446
- }
447
- .config-wrap {
448
- display: flex;
449
- flex-direction: column;
450
- gap: 12px;
451
- }
452
- .mapping {
453
- display: flex;
454
- flex-direction: column;
455
- gap: 8px;
456
- }
457
- .mapping .row {
458
- display: flex;
459
- align-items: center;
460
- gap: 10px;
461
- }
462
- .mapping .label {
463
- width: 160px;
464
- }
465
- .history-wrap {
466
- display: flex;
467
- flex-direction: column;
468
- gap: 10px;
469
- }
403
+ .import-wrap {
404
+ display: flex;
405
+ flex-direction: column;
406
+ gap: 12px;
407
+ }
408
+
409
+ .import-header {
410
+ display: flex;
411
+ align-items: center;
412
+ justify-content: space-between;
413
+ }
414
+
415
+ .actions {
416
+ display: flex;
417
+ gap: 10px;
418
+ }
419
+
420
+ .actions :deep(.el-button:hover) {
421
+ opacity: 0.9;
422
+ }
423
+
424
+ .upload-area {
425
+ min-width: 300px;
426
+ min-height: 200px;
427
+ border: 1px dashed #bbb;
428
+ display: flex;
429
+ flex-direction: column;
430
+ align-items: center;
431
+ justify-content: center;
432
+ padding: 20px;
433
+ border-radius: 6px;
434
+ }
435
+
436
+ .uploader {
437
+ width: 100%;
438
+ }
439
+
440
+ .status {
441
+ width: 100%;
442
+ margin-top: 10px;
443
+ }
444
+
445
+ .result-actions {
446
+ display: flex;
447
+ gap: 10px;
448
+ }
449
+
450
+ .config-wrap {
451
+ display: flex;
452
+ flex-direction: column;
453
+ gap: 12px;
454
+ }
455
+
456
+ .mapping {
457
+ display: flex;
458
+ flex-direction: column;
459
+ gap: 8px;
460
+ }
461
+
462
+ .mapping .row {
463
+ display: flex;
464
+ align-items: center;
465
+ gap: 10px;
466
+ }
467
+
468
+ .mapping .label {
469
+ width: 160px;
470
+ }
471
+
472
+ .history-wrap {
473
+ display: flex;
474
+ flex-direction: column;
475
+ gap: 10px;
476
+ }
470
477
  </style>