haiwei-module-admin 1.0.7 → 1.0.9
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
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
"id": 0,
|
|
3
3
|
"name": "haiwei-module-admin",
|
|
4
4
|
"code": "admin",
|
|
5
|
-
"version": "1.0.
|
|
5
|
+
"version": "1.0.9",
|
|
6
6
|
"description": "haiwei前端Admin模块组件",
|
|
7
7
|
"author": "Eric",
|
|
8
|
-
"license": "ISC",
|
|
8
|
+
"license": "ISC",
|
|
9
9
|
"main": "src/index.js",
|
|
10
10
|
"scripts": {
|
|
11
|
-
"serve": "vue-cli-service serve",
|
|
11
|
+
"serve": "vue-cli-service lint && vue-cli-service serve",
|
|
12
12
|
"build": "vue-cli-service build",
|
|
13
13
|
"lint": "vue-cli-service lint",
|
|
14
14
|
"cm": "rimraf node_modules",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|
|
21
21
|
"haiwei-skins-classics": "^1.0.2",
|
|
22
|
-
"haiwei-ui": "^1.0.
|
|
22
|
+
"haiwei-ui": "^1.0.8"
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
25
25
|
"@vue/cli-plugin-babel": "^4.4.4",
|
|
@@ -6,6 +6,9 @@
|
|
|
6
6
|
</template>
|
|
7
7
|
|
|
8
8
|
<script>
|
|
9
|
+
// 全局缓存,避免重复请求相同的枚举
|
|
10
|
+
const enumCache = new Map()
|
|
11
|
+
|
|
9
12
|
export default {
|
|
10
13
|
props: {
|
|
11
14
|
/** 枚举值 */
|
|
@@ -24,10 +27,7 @@ export default {
|
|
|
24
27
|
required: true
|
|
25
28
|
},
|
|
26
29
|
/** 所在库 */
|
|
27
|
-
libName:
|
|
28
|
-
type: String,
|
|
29
|
-
default: ''
|
|
30
|
-
},
|
|
30
|
+
libName: String,
|
|
31
31
|
/** 空值显示文本 */
|
|
32
32
|
emptyText: {
|
|
33
33
|
type: String,
|
|
@@ -56,7 +56,8 @@ export default {
|
|
|
56
56
|
},
|
|
57
57
|
data() {
|
|
58
58
|
return {
|
|
59
|
-
enumList: []
|
|
59
|
+
enumList: [],
|
|
60
|
+
loading: false
|
|
60
61
|
}
|
|
61
62
|
},
|
|
62
63
|
computed: {
|
|
@@ -68,11 +69,11 @@ export default {
|
|
|
68
69
|
const enumItem = this.enumList.find(item => item.value == this.value)
|
|
69
70
|
return enumItem ? enumItem.label : this.value
|
|
70
71
|
},
|
|
71
|
-
|
|
72
|
+
|
|
72
73
|
showTag() {
|
|
73
74
|
return this.useTag && this.value !== null && this.value !== undefined && this.value !== ''
|
|
74
75
|
},
|
|
75
|
-
|
|
76
|
+
|
|
76
77
|
// 计算tag颜色类型
|
|
77
78
|
computedTagType() {
|
|
78
79
|
// 如果用户指定了tagType
|
|
@@ -81,14 +82,14 @@ export default {
|
|
|
81
82
|
if (typeof this.tagType === 'string') {
|
|
82
83
|
return this.tagType
|
|
83
84
|
}
|
|
84
|
-
|
|
85
|
+
|
|
85
86
|
// 如果是对象,根据枚举值查找对应的颜色
|
|
86
87
|
if (typeof this.tagType === 'object' && this.tagType !== null) {
|
|
87
88
|
// 首先尝试精确匹配
|
|
88
89
|
if (this.tagType[this.value] !== undefined) {
|
|
89
90
|
return this.tagType[this.value]
|
|
90
91
|
}
|
|
91
|
-
|
|
92
|
+
|
|
92
93
|
// 尝试数字匹配
|
|
93
94
|
const numValue = Number(this.value)
|
|
94
95
|
if (this.tagType[numValue] !== undefined) {
|
|
@@ -96,21 +97,21 @@ export default {
|
|
|
96
97
|
}
|
|
97
98
|
}
|
|
98
99
|
}
|
|
99
|
-
|
|
100
|
+
|
|
100
101
|
// 如果没有指定或未找到匹配,根据枚举值自动计算
|
|
101
102
|
if (this.value === null || this.value === undefined || this.value === '') {
|
|
102
103
|
return 'info'
|
|
103
104
|
}
|
|
104
|
-
|
|
105
|
+
|
|
105
106
|
// 将值转换为数字
|
|
106
107
|
const numValue = Number(this.value)
|
|
107
|
-
|
|
108
|
+
|
|
108
109
|
// 简单的颜色映射
|
|
109
|
-
if (numValue === 0) return 'primary'
|
|
110
|
-
if (numValue === 1) return 'success'
|
|
111
|
-
if (numValue === 2) return 'warning'
|
|
112
|
-
if (numValue === 3) return 'danger'
|
|
113
|
-
|
|
110
|
+
if (numValue === 0) return 'primary' // 默认/初始状态
|
|
111
|
+
if (numValue === 1) return 'success' // 成功/确认状态
|
|
112
|
+
if (numValue === 2) return 'warning' // 警告状态
|
|
113
|
+
if (numValue === 3) return 'danger' // 失败/错误状态
|
|
114
|
+
|
|
114
115
|
// 其他值使用循环颜色
|
|
115
116
|
const colors = ['primary', 'success', 'warning', 'danger', 'info']
|
|
116
117
|
return colors[numValue % colors.length] || 'info'
|
|
@@ -137,23 +138,44 @@ export default {
|
|
|
137
138
|
return
|
|
138
139
|
}
|
|
139
140
|
|
|
141
|
+
// 生成缓存键
|
|
142
|
+
const cacheKey = `${this.moduleCode}_${this.enumName}_${this.libName || ''}`
|
|
143
|
+
|
|
144
|
+
// 检查缓存
|
|
145
|
+
if (enumCache.has(cacheKey)) {
|
|
146
|
+
this.enumList = enumCache.get(cacheKey)
|
|
147
|
+
return
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// 防止重复请求
|
|
151
|
+
if (this.loading) {
|
|
152
|
+
return
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
this.loading = true
|
|
156
|
+
|
|
140
157
|
try {
|
|
141
158
|
const { moduleCode, enumName, libName } = this
|
|
142
159
|
const result = await $api.admin.tool.enumSelect({ moduleCode, enumName, libName })
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
160
|
+
|
|
161
|
+
// API返回的是数组格式:[{label: '出仓', value: 0}, {label: '入仓', value: 1}]
|
|
162
|
+
if (result && Array.isArray(result)) {
|
|
163
|
+
this.enumList = result
|
|
164
|
+
// 缓存结果
|
|
165
|
+
enumCache.set(cacheKey, result)
|
|
146
166
|
} else {
|
|
147
167
|
this.enumList = []
|
|
148
168
|
}
|
|
149
169
|
} catch (error) {
|
|
150
170
|
console.error('加载枚举列表失败:', error)
|
|
151
171
|
this.enumList = []
|
|
172
|
+
} finally {
|
|
173
|
+
this.loading = false
|
|
152
174
|
}
|
|
153
175
|
}
|
|
154
176
|
},
|
|
155
177
|
mounted() {
|
|
156
|
-
|
|
178
|
+
// 移除mounted中的调用,由watch的immediate处理
|
|
157
179
|
}
|
|
158
180
|
}
|
|
159
181
|
</script>
|
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="file-preview">
|
|
3
|
-
<!--
|
|
4
|
-
<
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
<!-- 当fullPath有效时显示内容 -->
|
|
4
|
+
<template v-if="hasValidFullPath">
|
|
5
|
+
<!-- 图片预览链接 -->
|
|
6
|
+
<a v-if="isImage" class="preview-link" @click="showPreviewDialog">
|
|
7
|
+
查看
|
|
8
|
+
</a>
|
|
7
9
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
+
<!-- 非图片文件下载 -->
|
|
11
|
+
<nm-file-download v-else :url="downloadUrl" :private="isPrivate" :fileName="fileName" :text="downloadText" :icon="downloadIcon" :size="downloadSize" :type="downloadType" @click="onDownload" />
|
|
12
|
+
</template>
|
|
10
13
|
|
|
11
14
|
<!-- 图片预览对话框 -->
|
|
12
15
|
<nm-dialog
|
|
@@ -52,6 +55,18 @@
|
|
|
52
55
|
<span class="icon">⟳</span>
|
|
53
56
|
<span class="text">重置</span>
|
|
54
57
|
</button>
|
|
58
|
+
<!-- 非图片文件下载 -->
|
|
59
|
+
<nm-file-download
|
|
60
|
+
v-if="hasValidFullPath"
|
|
61
|
+
:url="downloadUrl"
|
|
62
|
+
:private="isPrivate"
|
|
63
|
+
:fileName="fileName"
|
|
64
|
+
:text="downloadText"
|
|
65
|
+
:icon="downloadIcon"
|
|
66
|
+
:size="downloadSize"
|
|
67
|
+
:type="downloadType"
|
|
68
|
+
@click="onDownload"
|
|
69
|
+
/>
|
|
55
70
|
</div>
|
|
56
71
|
</div>
|
|
57
72
|
</nm-dialog>
|
|
@@ -63,9 +78,7 @@ export default {
|
|
|
63
78
|
name: 'FilePreview',
|
|
64
79
|
props: {
|
|
65
80
|
fullPath: { type: String, required: true },
|
|
66
|
-
fileName: String,
|
|
67
81
|
isPrivate: { type: Boolean, default: false },
|
|
68
|
-
ext: String,
|
|
69
82
|
downloadText: { type: String, default: '下载' },
|
|
70
83
|
downloadIcon: { type: String, default: 'download' },
|
|
71
84
|
downloadSize: String,
|
|
@@ -101,10 +114,46 @@ export default {
|
|
|
101
114
|
},
|
|
102
115
|
|
|
103
116
|
computed: {
|
|
117
|
+
hasValidFullPath() {
|
|
118
|
+
// 检查fullPath是否有效:不为空且不是空字符串
|
|
119
|
+
if (!this.fullPath || this.fullPath.trim() === '') {
|
|
120
|
+
return false
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// 检查是否是目录路径(以斜杠结尾)
|
|
124
|
+
if (this.fullPath.endsWith('/') || this.fullPath.endsWith('\\')) {
|
|
125
|
+
return false
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// 检查是否有文件名(路径的最后一部分)
|
|
129
|
+
const path = this.fullPath.replace(/\\/g, '/')
|
|
130
|
+
const filename = path.split('/').pop()
|
|
131
|
+
|
|
132
|
+
// 文件名不能为空
|
|
133
|
+
if (!filename || filename.trim() === '') {
|
|
134
|
+
return false
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
return true
|
|
138
|
+
},
|
|
139
|
+
|
|
140
|
+
fileName() {
|
|
141
|
+
// 从fullPath中提取文件名
|
|
142
|
+
if (!this.fullPath) return ''
|
|
143
|
+
const path = this.fullPath.replace(/\\/g, '/')
|
|
144
|
+
const filename = path.split('/').pop()
|
|
145
|
+
return filename || ''
|
|
146
|
+
},
|
|
147
|
+
|
|
148
|
+
fileExt() {
|
|
149
|
+
// 从fullPath中提取文件扩展名
|
|
150
|
+
const filename = this.fileName
|
|
151
|
+
const dotIndex = filename.lastIndexOf('.')
|
|
152
|
+
return dotIndex > -1 ? filename.slice(dotIndex + 1).toLowerCase() : ''
|
|
153
|
+
},
|
|
154
|
+
|
|
104
155
|
isImage() {
|
|
105
|
-
|
|
106
|
-
const ext = this.ext || (this.fileName || '').split('.').pop() || ''
|
|
107
|
-
return this.imageExtensions.includes(ext.toLowerCase())
|
|
156
|
+
return this.imageExtensions.includes(this.fileExt)
|
|
108
157
|
},
|
|
109
158
|
|
|
110
159
|
downloadUrl() {
|
|
@@ -153,13 +202,6 @@ export default {
|
|
|
153
202
|
},
|
|
154
203
|
|
|
155
204
|
methods: {
|
|
156
|
-
getFileExtension() {
|
|
157
|
-
if (this.ext) return this.ext.toLowerCase()
|
|
158
|
-
const name = this.fileName || this.fullPath || ''
|
|
159
|
-
const dotIndex = name.lastIndexOf('.')
|
|
160
|
-
return dotIndex > -1 ? name.slice(dotIndex + 1).toLowerCase() : ''
|
|
161
|
-
},
|
|
162
|
-
|
|
163
205
|
async getFileInfo() {
|
|
164
206
|
if (!this.fullPath) return null
|
|
165
207
|
|
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="file-preview">
|
|
3
|
-
<!--
|
|
4
|
-
<
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
<!-- 当fullPath有效时显示内容 -->
|
|
4
|
+
<template v-if="hasValidFullPath">
|
|
5
|
+
<!-- 图片预览链接 -->
|
|
6
|
+
<a v-if="isImage" class="preview-link" @click="showPreviewDialog">
|
|
7
|
+
查看
|
|
8
|
+
</a>
|
|
7
9
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
+
<!-- 非图片文件下载 -->
|
|
11
|
+
<nm-file-download v-else :url="downloadUrl" :private="isPrivate" :fileName="fileName" :text="downloadText" :icon="downloadIcon" :size="downloadSize" :type="downloadType" @click="onDownload" />
|
|
12
|
+
</template>
|
|
10
13
|
|
|
11
14
|
<!-- 图片预览对话框 -->
|
|
12
15
|
<nm-dialog
|
|
@@ -53,8 +56,17 @@
|
|
|
53
56
|
<span class="text">重置</span>
|
|
54
57
|
</button>
|
|
55
58
|
<!-- 非图片文件下载 -->
|
|
56
|
-
|
|
57
|
-
|
|
59
|
+
<nm-file-download
|
|
60
|
+
v-if="hasValidFullPath"
|
|
61
|
+
:url="downloadUrl"
|
|
62
|
+
:private="isPrivate"
|
|
63
|
+
:fileName="fileName"
|
|
64
|
+
:text="downloadText"
|
|
65
|
+
:icon="downloadIcon"
|
|
66
|
+
:size="downloadSize"
|
|
67
|
+
:type="downloadType"
|
|
68
|
+
@click="onDownload"
|
|
69
|
+
/>
|
|
58
70
|
</div>
|
|
59
71
|
</div>
|
|
60
72
|
</nm-dialog>
|
|
@@ -66,9 +78,7 @@ export default {
|
|
|
66
78
|
name: 'FilePreview',
|
|
67
79
|
props: {
|
|
68
80
|
fullPath: { type: String, required: true },
|
|
69
|
-
fileName: String,
|
|
70
81
|
isPrivate: { type: Boolean, default: false },
|
|
71
|
-
ext: String,
|
|
72
82
|
downloadText: { type: String, default: '下载' },
|
|
73
83
|
downloadIcon: { type: String, default: 'download' },
|
|
74
84
|
downloadSize: String,
|
|
@@ -104,10 +114,46 @@ export default {
|
|
|
104
114
|
},
|
|
105
115
|
|
|
106
116
|
computed: {
|
|
117
|
+
hasValidFullPath() {
|
|
118
|
+
// 检查fullPath是否有效:不为空且不是空字符串
|
|
119
|
+
if (!this.fullPath || this.fullPath.trim() === '') {
|
|
120
|
+
return false
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// 检查是否是目录路径(以斜杠结尾)
|
|
124
|
+
if (this.fullPath.endsWith('/') || this.fullPath.endsWith('\\')) {
|
|
125
|
+
return false
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// 检查是否有文件名(路径的最后一部分)
|
|
129
|
+
const path = this.fullPath.replace(/\\/g, '/')
|
|
130
|
+
const filename = path.split('/').pop()
|
|
131
|
+
|
|
132
|
+
// 文件名不能为空
|
|
133
|
+
if (!filename || filename.trim() === '') {
|
|
134
|
+
return false
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
return true
|
|
138
|
+
},
|
|
139
|
+
|
|
140
|
+
fileName() {
|
|
141
|
+
// 从fullPath中提取文件名
|
|
142
|
+
if (!this.fullPath) return ''
|
|
143
|
+
const path = this.fullPath.replace(/\\/g, '/')
|
|
144
|
+
const filename = path.split('/').pop()
|
|
145
|
+
return filename || ''
|
|
146
|
+
},
|
|
147
|
+
|
|
148
|
+
fileExt() {
|
|
149
|
+
// 从fullPath中提取文件扩展名
|
|
150
|
+
const filename = this.fileName
|
|
151
|
+
const dotIndex = filename.lastIndexOf('.')
|
|
152
|
+
return dotIndex > -1 ? filename.slice(dotIndex + 1).toLowerCase() : ''
|
|
153
|
+
},
|
|
154
|
+
|
|
107
155
|
isImage() {
|
|
108
|
-
|
|
109
|
-
const ext = this.ext || (this.fileName || '').split('.').pop() || ''
|
|
110
|
-
return this.imageExtensions.includes(ext.toLowerCase())
|
|
156
|
+
return this.imageExtensions.includes(this.fileExt)
|
|
111
157
|
},
|
|
112
158
|
|
|
113
159
|
downloadUrl() {
|
|
@@ -156,13 +202,6 @@ export default {
|
|
|
156
202
|
},
|
|
157
203
|
|
|
158
204
|
methods: {
|
|
159
|
-
getFileExtension() {
|
|
160
|
-
if (this.ext) return this.ext.toLowerCase()
|
|
161
|
-
const name = this.fileName || this.fullPath || ''
|
|
162
|
-
const dotIndex = name.lastIndexOf('.')
|
|
163
|
-
return dotIndex > -1 ? name.slice(dotIndex + 1).toLowerCase() : ''
|
|
164
|
-
},
|
|
165
|
-
|
|
166
205
|
async getFileInfo() {
|
|
167
206
|
if (!this.fullPath) return null
|
|
168
207
|
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
|
|
37
37
|
<!-- 文件预览列 -->
|
|
38
38
|
<template v-slot:col-fullPath="{ row }">
|
|
39
|
-
<nm-file-preview :fullPath="row.fullPath" :
|
|
39
|
+
<nm-file-preview :fullPath="row.fullPath" :isPrivate="row.accessMode !== 1" />
|
|
40
40
|
<!-- <nm-file-preview :fullPath="row.fullPath"/> -->
|
|
41
41
|
</template>
|
|
42
42
|
|