leisure-core 0.6.82 → 0.6.83
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/le-home/src/sub.vue +82 -0
- package/le-report/src/main.vue +2 -2
- package/le-report/src/rmixins.js +30 -0
- package/le-upload-table/src/main.vue +182 -89
- package/package.json +4 -2
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div>
|
|
3
|
+
<!-- 有子菜单 → 渲染 el-submenu -->
|
|
4
|
+
<el-submenu v-if="hasChildren" :index="getIndex" :key="menuItem.id">
|
|
5
|
+
<template slot="title">
|
|
6
|
+
<i v-if="menuItem.icon" :class="menuItem.icon"></i>
|
|
7
|
+
<span>{{ menuItem.title }}</span>
|
|
8
|
+
</template>
|
|
9
|
+
<!-- 递归渲染子节点 -->
|
|
10
|
+
<menu-node
|
|
11
|
+
v-for="child in menuItem.children"
|
|
12
|
+
:key="child.id"
|
|
13
|
+
:menu-item="child"
|
|
14
|
+
:parent-index="getIndex"
|
|
15
|
+
@menu-click="handleChildClick"
|
|
16
|
+
/>
|
|
17
|
+
</el-submenu>
|
|
18
|
+
|
|
19
|
+
<!-- 叶子菜单 → 渲染 el-menu-item -->
|
|
20
|
+
<el-menu-item
|
|
21
|
+
v-else
|
|
22
|
+
:index="getIndex"
|
|
23
|
+
@click="emitClick"
|
|
24
|
+
:title="shouldShowTooltip ? menuItem.title : ''"
|
|
25
|
+
>
|
|
26
|
+
<span class="menu-item-text">{{ menuItem.title }}</span>
|
|
27
|
+
</el-menu-item>
|
|
28
|
+
</div>
|
|
29
|
+
</template>
|
|
30
|
+
|
|
31
|
+
<script>
|
|
32
|
+
export default {
|
|
33
|
+
name: "MenuNode",
|
|
34
|
+
props: {
|
|
35
|
+
// 当前菜单项数据
|
|
36
|
+
menuItem: {
|
|
37
|
+
type: Object,
|
|
38
|
+
required: true,
|
|
39
|
+
},
|
|
40
|
+
// 父级 index,用于构建唯一层级路径
|
|
41
|
+
parentIndex: {
|
|
42
|
+
type: String,
|
|
43
|
+
default: "",
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
computed: {
|
|
47
|
+
// 是否有子菜单(且子菜单未被全部过滤掉)
|
|
48
|
+
hasChildren() {
|
|
49
|
+
return this.menuItem.children && this.menuItem.children.length > 0;
|
|
50
|
+
},
|
|
51
|
+
// 构建唯一 index,使用 id 拼接,避免同名冲突
|
|
52
|
+
getIndex() {
|
|
53
|
+
const base = this.parentIndex ? this.parentIndex + "-" : "";
|
|
54
|
+
return base + this.menuItem.id;
|
|
55
|
+
},
|
|
56
|
+
// 是否显示 tooltip(文字超长)
|
|
57
|
+
shouldShowTooltip() {
|
|
58
|
+
return this.menuItem.title && this.menuItem.title.length > 8;
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
methods: {
|
|
62
|
+
// 点击叶子菜单
|
|
63
|
+
emitClick() {
|
|
64
|
+
this.$emit("menu-click", this.menuItem);
|
|
65
|
+
},
|
|
66
|
+
// 子节点触发点击,向上冒泡
|
|
67
|
+
handleChildClick(item) {
|
|
68
|
+
this.$emit("menu-click", item);
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
};
|
|
72
|
+
</script>
|
|
73
|
+
|
|
74
|
+
<style scoped>
|
|
75
|
+
.menu-item-text {
|
|
76
|
+
display: inline-block;
|
|
77
|
+
max-width: calc(100% + 25px);
|
|
78
|
+
overflow: hidden;
|
|
79
|
+
text-overflow: ellipsis;
|
|
80
|
+
white-space: nowrap;
|
|
81
|
+
}
|
|
82
|
+
</style>
|
package/le-report/src/main.vue
CHANGED
|
@@ -161,13 +161,13 @@
|
|
|
161
161
|
</template>
|
|
162
162
|
|
|
163
163
|
<script>
|
|
164
|
-
import
|
|
164
|
+
import rMixins from "./rmixins.js";
|
|
165
165
|
import ExcelJS from "exceljs";
|
|
166
166
|
import FileSaver from "file-saver";
|
|
167
167
|
|
|
168
168
|
export default {
|
|
169
169
|
name: "le-report",
|
|
170
|
-
mixins: [
|
|
170
|
+
mixins: [rMixins],
|
|
171
171
|
props: {
|
|
172
172
|
showIndex: {
|
|
173
173
|
type: Boolean,
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
const rMixins = {
|
|
2
|
+
data() {
|
|
3
|
+
return {
|
|
4
|
+
elTableMaxHeight: 200,
|
|
5
|
+
};
|
|
6
|
+
},
|
|
7
|
+
|
|
8
|
+
mounted() {
|
|
9
|
+
window.addEventListener("resize", this.changeHeight);
|
|
10
|
+
this.changeHeight();
|
|
11
|
+
},
|
|
12
|
+
|
|
13
|
+
destroyed() {
|
|
14
|
+
window.removeEventListener("resize", this.changeHeight);
|
|
15
|
+
},
|
|
16
|
+
methods: {
|
|
17
|
+
changeHeight() {
|
|
18
|
+
this.$nextTick(() => {
|
|
19
|
+
if (!this.$refs.eltablemain) return;
|
|
20
|
+
let dyHeight = this.elTableMaxHeight;
|
|
21
|
+
let all = window.innerHeight;
|
|
22
|
+
let top = this.$refs.eltablemain.$el.getBoundingClientRect().top;
|
|
23
|
+
dyHeight = all - top - 30;
|
|
24
|
+
this.elTableMaxHeight = dyHeight - 50;
|
|
25
|
+
});
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export default rMixins;
|
|
@@ -114,14 +114,14 @@
|
|
|
114
114
|
</template>
|
|
115
115
|
|
|
116
116
|
<script>
|
|
117
|
-
import {
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
} from "@/api/attachment/attachment.js";
|
|
124
|
-
import { downLoadSimple } from "@/utils/downLoadFile.js";
|
|
117
|
+
// import {
|
|
118
|
+
// upload,
|
|
119
|
+
// create,
|
|
120
|
+
// del,
|
|
121
|
+
// list,
|
|
122
|
+
// download,
|
|
123
|
+
// } from "@/api/attachment/attachment.js";
|
|
124
|
+
// import { downLoadSimple } from "@/utils/downLoadFile.js";
|
|
125
125
|
|
|
126
126
|
export default {
|
|
127
127
|
name: "le-upload-table",
|
|
@@ -183,6 +183,30 @@ export default {
|
|
|
183
183
|
type: Boolean,
|
|
184
184
|
default: true,
|
|
185
185
|
},
|
|
186
|
+
uploadApi: {
|
|
187
|
+
type: Function,
|
|
188
|
+
required: true, // 强制父组件提供
|
|
189
|
+
},
|
|
190
|
+
// 批量创建附件记录(接收参数数组,返回 Promise<{ data: { data: [...] } }>)
|
|
191
|
+
createApi: {
|
|
192
|
+
type: Function,
|
|
193
|
+
required: true,
|
|
194
|
+
},
|
|
195
|
+
// 删除附件(接收 { id },返回 Promise)
|
|
196
|
+
deleteApi: {
|
|
197
|
+
type: Function,
|
|
198
|
+
required: true,
|
|
199
|
+
},
|
|
200
|
+
// 查询附件列表(接收 { mid, mtype },返回 Promise<{ data: { data: [...] } }>)
|
|
201
|
+
listApi: {
|
|
202
|
+
type: Function,
|
|
203
|
+
required: true,
|
|
204
|
+
},
|
|
205
|
+
// 下载文件(接收参数,通常为 fileName 等,返回 void 或 Promise)
|
|
206
|
+
downloadApi: {
|
|
207
|
+
type: Function,
|
|
208
|
+
required: true,
|
|
209
|
+
},
|
|
186
210
|
},
|
|
187
211
|
watch: {
|
|
188
212
|
showPop: {
|
|
@@ -212,7 +236,7 @@ export default {
|
|
|
212
236
|
currentTotalSize() {
|
|
213
237
|
return this.localAttachments.reduce(
|
|
214
238
|
(total, file) => total + (file.size || 0),
|
|
215
|
-
0
|
|
239
|
+
0,
|
|
216
240
|
);
|
|
217
241
|
},
|
|
218
242
|
// currentTotalSize() {
|
|
@@ -224,24 +248,36 @@ export default {
|
|
|
224
248
|
},
|
|
225
249
|
mounted() {},
|
|
226
250
|
methods: {
|
|
251
|
+
// getList(callback) {
|
|
252
|
+
// let param = {};
|
|
253
|
+
// param.mid = this.mid;
|
|
254
|
+
// param.mtype = this.mtype;
|
|
255
|
+
// const formData = new URLSearchParams(param);
|
|
256
|
+
// list(formData).then((res) => {
|
|
257
|
+
// this.localAttachments = res.data.data;
|
|
258
|
+
// if (callback) {
|
|
259
|
+
// callback();
|
|
260
|
+
// }
|
|
261
|
+
// });
|
|
262
|
+
// },
|
|
227
263
|
getList(callback) {
|
|
228
|
-
|
|
229
|
-
param.mid = this.mid;
|
|
230
|
-
param.mtype = this.mtype;
|
|
264
|
+
const param = { mid: this.mid, mtype: this.mtype };
|
|
231
265
|
const formData = new URLSearchParams(param);
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
callback();
|
|
236
|
-
}
|
|
237
|
-
|
|
266
|
+
this.listApi(formData)
|
|
267
|
+
.then((res) => {
|
|
268
|
+
this.localAttachments = res.data.data || [];
|
|
269
|
+
if (callback) callback();
|
|
270
|
+
})
|
|
271
|
+
.catch(() => {
|
|
272
|
+
this.$message.error("获取附件列表失败");
|
|
273
|
+
});
|
|
238
274
|
},
|
|
239
275
|
// 上传前校验
|
|
240
276
|
beforeUpload(file) {
|
|
241
277
|
// 检查文件大小
|
|
242
278
|
if (file.size / 1024 / 1024 > this.maxSize) {
|
|
243
279
|
this.$message.error(
|
|
244
|
-
`文件 "${file.name}" 大小不能超过 ${this.maxSize}MB
|
|
280
|
+
`文件 "${file.name}" 大小不能超过 ${this.maxSize}MB`,
|
|
245
281
|
);
|
|
246
282
|
return false;
|
|
247
283
|
}
|
|
@@ -263,58 +299,98 @@ export default {
|
|
|
263
299
|
},
|
|
264
300
|
|
|
265
301
|
// 上传文件
|
|
302
|
+
// async uploadFile(param) {
|
|
303
|
+
// if (this.uploading) {
|
|
304
|
+
// this.$message.warning("正在上传中,请稍候...");
|
|
305
|
+
// return;
|
|
306
|
+
// }
|
|
307
|
+
|
|
308
|
+
// this.uploading = true;
|
|
309
|
+
|
|
310
|
+
// try {
|
|
311
|
+
// const formData = new FormData();
|
|
312
|
+
// formData.append("files", param.file);
|
|
313
|
+
|
|
314
|
+
// if (this.dir) {
|
|
315
|
+
// formData.append("dir", this.dir);
|
|
316
|
+
// }
|
|
317
|
+
|
|
318
|
+
// const res = await upload(formData);
|
|
319
|
+
|
|
320
|
+
// if (res.data && res.data.data) {
|
|
321
|
+
// const urlList = res.data.data;
|
|
322
|
+
|
|
323
|
+
// if (urlList && urlList.length > 0) {
|
|
324
|
+
// let newFiles = [];
|
|
325
|
+
// urlList.forEach((ele) => {
|
|
326
|
+
// const newFile = {
|
|
327
|
+
// id: Date.now(),
|
|
328
|
+
// mid: this.mid,
|
|
329
|
+
// mtype: this.mtype,
|
|
330
|
+
// mtype_name: this.mname,
|
|
331
|
+
// attach_name_ori: ele.filesOriginal,
|
|
332
|
+
// attach_name: ele.filesNew,
|
|
333
|
+
// attach_size: ele.fileSize,
|
|
334
|
+
// attach_path: ele.filesUrlPath,
|
|
335
|
+
// create_at: new Date(),
|
|
336
|
+
// };
|
|
337
|
+
// newFiles.push(newFile);
|
|
338
|
+
// });
|
|
339
|
+
|
|
340
|
+
// this._saveData(newFiles, (res) => {
|
|
341
|
+
// const uploadFiles = res.data.data;
|
|
342
|
+
// const localData = [...this.localAttachments, ...uploadFiles];
|
|
343
|
+
// this.localAttachments = localData;
|
|
344
|
+
// this.$message.success(`文件上传成功`);
|
|
345
|
+
// });
|
|
346
|
+
// } else {
|
|
347
|
+
// this.$message.error("上传成功但未返回文件URL");
|
|
348
|
+
// }
|
|
349
|
+
// } else {
|
|
350
|
+
// this.$message.error(res.data?.msg || "上传失败");
|
|
351
|
+
// }
|
|
352
|
+
// } catch (error) {
|
|
353
|
+
// this.$message.error(`文件上传失败`);
|
|
354
|
+
// } finally {
|
|
355
|
+
// this.uploading = false;
|
|
356
|
+
// }
|
|
357
|
+
// },
|
|
358
|
+
|
|
266
359
|
async uploadFile(param) {
|
|
267
360
|
if (this.uploading) {
|
|
268
361
|
this.$message.warning("正在上传中,请稍候...");
|
|
269
362
|
return;
|
|
270
363
|
}
|
|
271
|
-
|
|
272
364
|
this.uploading = true;
|
|
273
|
-
|
|
274
365
|
try {
|
|
275
366
|
const formData = new FormData();
|
|
276
367
|
formData.append("files", param.file);
|
|
368
|
+
if (this.dir) formData.append("dir", this.dir);
|
|
277
369
|
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
if (res.data && res.data.data) {
|
|
285
|
-
const urlList = res.data.data;
|
|
286
|
-
|
|
287
|
-
if (urlList && urlList.length > 0) {
|
|
288
|
-
let newFiles = [];
|
|
289
|
-
urlList.forEach((ele) => {
|
|
290
|
-
const newFile = {
|
|
291
|
-
id: Date.now(),
|
|
292
|
-
mid: this.mid,
|
|
293
|
-
mtype: this.mtype,
|
|
294
|
-
mtype_name: this.mname,
|
|
295
|
-
attach_name_ori: ele.filesOriginal,
|
|
296
|
-
attach_name: ele.filesNew,
|
|
297
|
-
attach_size: ele.fileSize,
|
|
298
|
-
attach_path: ele.filesUrlPath,
|
|
299
|
-
create_at: new Date(),
|
|
300
|
-
};
|
|
301
|
-
newFiles.push(newFile);
|
|
302
|
-
});
|
|
303
|
-
|
|
304
|
-
this._saveData(newFiles, (res) => {
|
|
305
|
-
const uploadFiles = res.data.data;
|
|
306
|
-
const localData = [...this.localAttachments, ...uploadFiles];
|
|
307
|
-
this.localAttachments = localData;
|
|
308
|
-
this.$message.success(`文件上传成功`);
|
|
309
|
-
});
|
|
310
|
-
} else {
|
|
311
|
-
this.$message.error("上传成功但未返回文件URL");
|
|
312
|
-
}
|
|
313
|
-
} else {
|
|
314
|
-
this.$message.error(res.data?.msg || "上传失败");
|
|
370
|
+
const res = await this.uploadApi(formData);
|
|
371
|
+
const urlList = res?.data?.data;
|
|
372
|
+
if (!urlList || urlList.length === 0) {
|
|
373
|
+
this.$message.error("上传成功但未返回文件URL");
|
|
374
|
+
return;
|
|
315
375
|
}
|
|
376
|
+
const newFiles = urlList.map((ele) => ({
|
|
377
|
+
id: Date.now(),
|
|
378
|
+
mid: this.mid,
|
|
379
|
+
mtype: this.mtype,
|
|
380
|
+
mtype_name: this.mname,
|
|
381
|
+
attach_name_ori: ele.filesOriginal,
|
|
382
|
+
attach_name: ele.filesNew,
|
|
383
|
+
attach_size: ele.fileSize,
|
|
384
|
+
attach_path: ele.filesUrlPath,
|
|
385
|
+
create_at: new Date(),
|
|
386
|
+
}));
|
|
387
|
+
// 调用创建 API
|
|
388
|
+
await this._createRecords(newFiles);
|
|
389
|
+
// 刷新列表
|
|
390
|
+
await this.getList();
|
|
391
|
+
this.$message.success("文件上传成功");
|
|
316
392
|
} catch (error) {
|
|
317
|
-
this.$message.error(
|
|
393
|
+
this.$message.error(error.message || "文件上传失败");
|
|
318
394
|
} finally {
|
|
319
395
|
this.uploading = false;
|
|
320
396
|
}
|
|
@@ -331,7 +407,7 @@ export default {
|
|
|
331
407
|
// 直接更新本地数据
|
|
332
408
|
let param = { id: file.id };
|
|
333
409
|
const formData = new URLSearchParams(param);
|
|
334
|
-
|
|
410
|
+
this.deleteApi(formData).then(() => {
|
|
335
411
|
const updatedAttachments = [...this.localAttachments];
|
|
336
412
|
updatedAttachments.splice(index, 1);
|
|
337
413
|
this.localAttachments = updatedAttachments;
|
|
@@ -370,12 +446,15 @@ export default {
|
|
|
370
446
|
handleDownLoad(row) {
|
|
371
447
|
let params = {};
|
|
372
448
|
params.fileName = row.attach_name;
|
|
373
|
-
downLoadSimple(
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
).catch((error) => {
|
|
378
|
-
|
|
449
|
+
// downLoadSimple(
|
|
450
|
+
// "/system-attachment/download",
|
|
451
|
+
// row.attach_name_ori,
|
|
452
|
+
// params,
|
|
453
|
+
// ).catch((error) => {
|
|
454
|
+
// this.$message.error(error);
|
|
455
|
+
// });
|
|
456
|
+
this.downloadApi(row.attach_name_ori, params).catch((err) => {
|
|
457
|
+
this.$message.error(err.message || "下载失败");
|
|
379
458
|
});
|
|
380
459
|
},
|
|
381
460
|
|
|
@@ -430,29 +509,43 @@ export default {
|
|
|
430
509
|
this.closeBtn();
|
|
431
510
|
},
|
|
432
511
|
|
|
433
|
-
_saveData(datas, callBack) {
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
512
|
+
// _saveData(datas, callBack) {
|
|
513
|
+
// if (datas && datas.length > 0) {
|
|
514
|
+
// let params = [];
|
|
515
|
+
// datas.forEach((ele) => {
|
|
516
|
+
// let param = {};
|
|
517
|
+
// param.mid = ele.mid;
|
|
518
|
+
// param.mtype = ele.mtype;
|
|
519
|
+
// param.mtype_name = ele.mtype_name;
|
|
520
|
+
// param.attach_name = ele.attach_name;
|
|
521
|
+
// param.attach_name_ori = ele.attach_name_ori;
|
|
522
|
+
// param.attach_size = ele.attach_size;
|
|
523
|
+
// param.attach_path = ele.attach_path;
|
|
524
|
+
// params.push(param);
|
|
525
|
+
// });
|
|
526
|
+
// create(params)
|
|
527
|
+
// .then((res) => {
|
|
528
|
+
// if (callBack) callBack(res);
|
|
529
|
+
// this.$message.success("上传服务器成功");
|
|
530
|
+
// })
|
|
531
|
+
// .catch((err) => {
|
|
532
|
+
// this.$message.error("上传失败");
|
|
533
|
+
// });
|
|
534
|
+
// }
|
|
535
|
+
// },
|
|
536
|
+
|
|
537
|
+
_createRecords(datas) {
|
|
538
|
+
if (!datas || datas.length === 0) return Promise.resolve();
|
|
539
|
+
const params = datas.map((ele) => ({
|
|
540
|
+
mid: ele.mid,
|
|
541
|
+
mtype: ele.mtype,
|
|
542
|
+
mtype_name: ele.mtype_name,
|
|
543
|
+
attach_name: ele.attach_name,
|
|
544
|
+
attach_name_ori: ele.attach_name_ori,
|
|
545
|
+
attach_size: ele.attach_size,
|
|
546
|
+
attach_path: ele.attach_path,
|
|
547
|
+
}));
|
|
548
|
+
return this.createApi(params);
|
|
456
549
|
},
|
|
457
550
|
|
|
458
551
|
closeBtn() {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "leisure-core",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.83",
|
|
4
4
|
"description": "leisure-core是京心数据基于vue2.x开发的一套后台管理系统桌面端组件库,封装了大量实用的UI控件模板,非常方便开发者快速搭建前端应用",
|
|
5
5
|
"private": false,
|
|
6
6
|
"author": "北方乐逍遥(zcx7878)",
|
|
@@ -21,7 +21,9 @@
|
|
|
21
21
|
"vue-router": "^3.5.1",
|
|
22
22
|
"vuex": "^3.6.2",
|
|
23
23
|
"vxe-table": "~3.19.28",
|
|
24
|
-
"lodash": "^4.17.21"
|
|
24
|
+
"lodash": "^4.17.21",
|
|
25
|
+
"exceljs": "^4.4.0",
|
|
26
|
+
"file-saver": "^2.0.5"
|
|
25
27
|
},
|
|
26
28
|
"devDependencies": {}
|
|
27
29
|
}
|