leisure-core 0.6.81 → 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/index.js CHANGED
@@ -47,6 +47,10 @@ import LeInputAdvanced from "./le-input-advanced/index.js";
47
47
  import LeInputValidate from "./le-input-validate/index.js";
48
48
  import LeDatePickerAuto from "./le-date-picker-auto/index.js";
49
49
  import LeTableEdit from "./le-table-edit/index.js";
50
+ import LeButtonAttach from "./le-button-attach/index.js";
51
+ import LeSelectMulti from "./le-select-multi/index.js";
52
+ import LeUploadTable from "./le-upload-table/index.js";
53
+ import LeReport from "./le-report/index.js";
50
54
 
51
55
  const components = [
52
56
  LeArea,
@@ -92,6 +96,10 @@ const components = [
92
96
  LeInputValidate,
93
97
  LeDatePickerAuto,
94
98
  LeTableEdit,
99
+ LeButtonAttach,
100
+ LeSelectMulti,
101
+ LeUploadTable,
102
+ LeReport,
95
103
  ];
96
104
 
97
105
  const install = function (Vue) {
@@ -206,4 +214,8 @@ export default {
206
214
  LeInputValidate,
207
215
  LeDatePickerAuto,
208
216
  LeTableEdit,
217
+ LeButtonAttach,
218
+ LeSelectMulti,
219
+ LeUploadTable,
220
+ LeReport,
209
221
  };
@@ -0,0 +1,6 @@
1
+ import LeButtonAttach from "./src/main.vue";
2
+
3
+ LeButtonAttach.install = function (Vue) {
4
+ Vue.component(LeButtonAttach.name, LeButtonAttach);
5
+ };
6
+ export default LeButtonAttach;
@@ -0,0 +1,171 @@
1
+ <template>
2
+ <div class="le-button-attach">
3
+ <el-upload
4
+ action=""
5
+ :http-request="uploadFile"
6
+ :before-upload="beforeUpload"
7
+ :show-file-list="false"
8
+ :multiple="multiple"
9
+ :accept="acceptTypes"
10
+ :disabled="disabled"
11
+ :class="{ 'is-disabled': disabled }"
12
+ >
13
+ <el-button
14
+ :type="type"
15
+ :size="size"
16
+ :icon="icon"
17
+ :disabled="disabled"
18
+ :loading="loading"
19
+ v-if="false"
20
+ >
21
+ {{ buttonText }}
22
+ </el-button>
23
+ </el-upload>
24
+ </div>
25
+ </template>
26
+
27
+ <script>
28
+ export default {
29
+ name: "le-button-attach",
30
+ props: {
31
+ // 是否允许多选
32
+ multiple: {
33
+ type: Boolean,
34
+ default: false,
35
+ },
36
+ // 按钮文字
37
+ buttonText: {
38
+ type: String,
39
+ default: "导入Excel",
40
+ },
41
+ // 按钮类型
42
+ type: {
43
+ type: String,
44
+ default: "primary",
45
+ },
46
+ // 按钮尺寸
47
+ size: {
48
+ type: String,
49
+ default: "small",
50
+ },
51
+ // 按钮图标
52
+ icon: {
53
+ type: String,
54
+ default: "el-icon-upload",
55
+ },
56
+ // 是否禁用
57
+ disabled: {
58
+ type: Boolean,
59
+ default: false,
60
+ },
61
+ // 文件大小限制(MB)
62
+ maxSize: {
63
+ type: Number,
64
+ default: 10,
65
+ },
66
+ // 上传函数,接收文件
67
+ uploadFunction: {
68
+ type: Function,
69
+ required: true,
70
+ },
71
+ },
72
+ data() {
73
+ return {
74
+ // 接受的Excel文件类型
75
+ acceptTypes: ".xlsx, .xls, .csv",
76
+ // 加载状态
77
+ loading: false,
78
+ // 上传中状态
79
+ uploading: false,
80
+ };
81
+ },
82
+ methods: {
83
+ /**
84
+ * 上传前校验
85
+ */
86
+ beforeUpload(file) {
87
+ // 校验文件类型
88
+ const isExcel = /\.(xlsx|xls|csv)$/i.test(file.name);
89
+ if (!isExcel) {
90
+ this.$message.error("只能上传Excel文件(.xlsx, .xls, .csv)!");
91
+ return false;
92
+ }
93
+
94
+ // 校验文件大小
95
+ const isLt10M = file.size / 1024 / 1024 < this.maxSize;
96
+ if (!isLt10M) {
97
+ this.$message.error(`上传文件大小不能超过 ${this.maxSize}MB!`);
98
+ return false;
99
+ }
100
+
101
+ this.loading = true;
102
+
103
+ // 触发上传前事件
104
+ this.$emit("before-upload", file);
105
+
106
+ return true;
107
+ },
108
+
109
+ /**
110
+ * 上传文件
111
+ */
112
+ async uploadFile(param) {
113
+ if (this.uploading) {
114
+ this.$message.warning("正在上传中,请稍候...");
115
+ return;
116
+ }
117
+
118
+ this.uploading = true;
119
+
120
+ try {
121
+ // 调用上传函数,只传入文件
122
+ const res = await this.uploadFunction(param.file);
123
+
124
+ // 上传成功处理
125
+ this.loading = false;
126
+ this.uploading = false;
127
+
128
+ // 触发成功事件
129
+ this.$emit("success", res.data, param.file);
130
+ } catch (error) {
131
+ this.loading = false;
132
+ this.uploading = false;
133
+
134
+ // 上传失败
135
+ const errorMessage =
136
+ error.message ||
137
+ error.response?.data?.info ||
138
+ error.response?.data?.message ||
139
+ "文件上传失败,请重试";
140
+ this.$message.error(errorMessage);
141
+ this.$emit("error", error, param.file);
142
+ }
143
+ },
144
+
145
+ /**
146
+ * 手动触发上传(用于外部调用)
147
+ */
148
+ triggerUpload() {
149
+ this.$el.querySelector(".el-upload__input").click();
150
+ },
151
+ },
152
+ };
153
+ </script>
154
+
155
+ <style lang="scss" scoped>
156
+ .le-button-attach {
157
+ display: inline-block;
158
+
159
+ ::v-deep .el-upload {
160
+ display: inline-block;
161
+ }
162
+
163
+ &.is-disabled {
164
+ cursor: not-allowed;
165
+
166
+ ::v-deep .el-upload {
167
+ cursor: not-allowed;
168
+ }
169
+ }
170
+ }
171
+ </style>
@@ -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>
@@ -0,0 +1,6 @@
1
+ import LeReport from "./src/main.vue";
2
+
3
+ LeReport.install = function (Vue) {
4
+ Vue.component(LeReport.name, LeReport);
5
+ };
6
+ export default LeReport;