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.7",
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.7"
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
- if (result && result.data) {
145
- this.enumList = result.data
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
- this.loadEnumList()
178
+ // 移除mounted中的调用,由watch的immediate处理
157
179
  }
158
180
  }
159
181
  </script>
@@ -59,6 +59,7 @@ export default {
59
59
  if (this.private) {
60
60
  $api.admin.file.download(this.url)
61
61
  } else {
62
+ console.log('=====>')
62
63
  //通过模拟a标签点击事件下载文件
63
64
  const link = document.createElement('a')
64
65
  link.href = this.url
@@ -1,12 +1,15 @@
1
1
  <template>
2
2
  <div class="file-preview">
3
- <!-- 图片预览链接 -->
4
- <a v-if="isImage" class="preview-link" @click="showPreviewDialog">
5
- 查看
6
- </a>
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
- <nm-file-download v-else :url="downloadUrl" :private="isPrivate" :fileName="fileName" :text="downloadText" :icon="downloadIcon" :size="downloadSize" :type="downloadType" @click="onDownload" />
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
- // return false;
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
- <a v-if="isImage" class="preview-link" @click="showPreviewDialog">
5
- 查看
6
- </a>
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
- <nm-file-download v-else :url="downloadUrl" :private="isPrivate" :fileName="fileName" :text="downloadText" :icon="downloadIcon" :size="downloadSize" :type="downloadType" @click="onDownload" />
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
- <nm-file-download :url="downloadUrl" :private="isPrivate" :fileName="fileName" :text="downloadText" :icon="downloadIcon" :size="downloadSize" :type="downloadType" @click="onDownload" />
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
- // return false;
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" :fileName="row.fileName" :ext="row.ext" :isPrivate="row.accessMode !== 1" />
39
+ <nm-file-preview :fullPath="row.fullPath" :isPrivate="row.accessMode !== 1" />
40
40
  <!-- <nm-file-preview :fullPath="row.fullPath"/> -->
41
41
  </template>
42
42