vue2-client 1.18.63 → 1.18.65

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.
Files changed (87) hide show
  1. package/.claude/settings.local.json +28 -28
  2. package/.eslintrc.js +74 -74
  3. package/Components.md +60 -60
  4. package/docs/index.md +30 -30
  5. package/index.js +31 -31
  6. package/jest-transform-stub.js +8 -8
  7. package/jest.setup.js +7 -7
  8. package/package.json +1 -1
  9. package/src/assets/img/querySlotDemo.svg +15 -15
  10. package/src/base-client/components/common/AmapMarker/AmapPointRendering.vue +120 -120
  11. package/src/base-client/components/common/CitySelect/index.js +3 -3
  12. package/src/base-client/components/common/CitySelect/index.md +109 -109
  13. package/src/base-client/components/common/FormGroupEdit/index.js +3 -3
  14. package/src/base-client/components/common/FormGroupEdit/index.md +43 -43
  15. package/src/base-client/components/common/JSONToTree/jsontotree.vue +271 -271
  16. package/src/base-client/components/common/PersonSetting/index.js +3 -3
  17. package/src/base-client/components/common/Tree/Tree.vue +149 -149
  18. package/src/base-client/components/common/Tree/index.js +2 -2
  19. package/src/base-client/components/common/Upload/index.js +3 -3
  20. package/src/base-client/components/common/XAddNativeForm/XAddNativeForm.vue +9 -4
  21. package/src/base-client/components/common/XAddNativeForm/index.md +146 -146
  22. package/src/base-client/components/common/XCard/XCard.vue +64 -64
  23. package/src/base-client/components/common/XDataDrawer/XDataDrawer.vue +180 -180
  24. package/src/base-client/components/common/XDataDrawer/index.js +3 -3
  25. package/src/base-client/components/common/XDataDrawer/index.md +41 -41
  26. package/src/base-client/components/common/XDescriptions/index.js +3 -3
  27. package/src/base-client/components/common/XDescriptions/index.md +322 -322
  28. package/src/base-client/components/common/XForm/index.md +178 -178
  29. package/src/base-client/components/common/XFormGroup/demo.vue +8 -11
  30. package/src/base-client/components/common/XStepView/XStepView.vue +252 -252
  31. package/src/base-client/components/common/XStepView/index.js +3 -3
  32. package/src/base-client/components/common/XStepView/index.md +31 -31
  33. package/src/base-client/components/common/XTable/XTable.vue +1715 -1715
  34. package/src/base-client/components/common/XTable/XTableWrapper.vue +786 -786
  35. package/src/base-client/components/common/XTable/index.md +255 -255
  36. package/src/base-client/components/system/DictionaryDetailsView/DictionaryDetailsView.vue +232 -232
  37. package/src/base-client/plugins/Config.js +19 -19
  38. package/src/base-client/plugins/tabs-page-plugin.js +39 -39
  39. package/src/components/Charts/Bar.vue +62 -62
  40. package/src/components/Charts/ChartCard.vue +134 -134
  41. package/src/components/Charts/Liquid.vue +67 -67
  42. package/src/components/Charts/MiniArea.vue +39 -39
  43. package/src/components/Charts/MiniBar.vue +39 -39
  44. package/src/components/Charts/MiniProgress.vue +75 -75
  45. package/src/components/Charts/MiniSmoothArea.vue +40 -40
  46. package/src/components/Charts/Radar.vue +68 -68
  47. package/src/components/Charts/RankList.vue +77 -77
  48. package/src/components/Charts/TagCloud.vue +113 -113
  49. package/src/components/Charts/TransferBar.vue +64 -64
  50. package/src/components/Charts/Trend.vue +82 -82
  51. package/src/components/Charts/chart.less +12 -12
  52. package/src/components/Charts/smooth.area.less +13 -13
  53. package/src/components/NumberInfo/NumberInfo.vue +54 -54
  54. package/src/components/NumberInfo/index.js +3 -3
  55. package/src/components/NumberInfo/index.less +54 -54
  56. package/src/components/NumberInfo/index.md +43 -43
  57. package/src/components/card/ChartCard.vue +79 -79
  58. package/src/components/chart/Bar.vue +60 -60
  59. package/src/components/chart/MiniArea.vue +67 -67
  60. package/src/components/chart/MiniBar.vue +59 -59
  61. package/src/components/chart/MiniProgress.vue +57 -57
  62. package/src/components/chart/Radar.vue +80 -80
  63. package/src/components/chart/RankingList.vue +60 -60
  64. package/src/components/chart/Trend.vue +79 -79
  65. package/src/components/chart/index.less +9 -9
  66. package/src/components/checkbox/ColorCheckbox.vue +157 -157
  67. package/src/components/input/IInput.vue +66 -66
  68. package/src/components/menu/SideMenu.vue +75 -75
  69. package/src/components/menu/menu.js +273 -273
  70. package/src/components/tool/AStepItem.vue +60 -60
  71. package/src/layouts/BlankView.vue +16 -14
  72. package/src/layouts/CommonLayout.vue +56 -56
  73. package/src/layouts/header/HeaderNotice.vue +177 -177
  74. package/src/lib.js +1 -1
  75. package/src/mock/extend/index.js +84 -84
  76. package/src/mock/goods/index.js +108 -108
  77. package/src/pages/dashboard/workplace/WorkPlace.vue +141 -141
  78. package/src/pages/system/dictionary/index.vue +44 -44
  79. package/src/pages/system/monitor/loginInfor/index.vue +37 -37
  80. package/src/pages/system/monitor/operLog/index.vue +37 -37
  81. package/src/pages/userInfoDetailManage/uploadFilesHistory/index.vue +212 -212
  82. package/src/router/async/router.map.js +2 -2
  83. package/src/services/api/cas.js +79 -79
  84. package/src/store/modules/setting.js +119 -119
  85. package/src/utils/authority-utils.js +85 -85
  86. package/src/utils/errorCode.js +6 -6
  87. package//350/277/201/347/247/273/346/227/245/345/277/227.md +15 -15
@@ -1,44 +1,44 @@
1
- <template>
2
- <a-card :bordered="false">
3
- <dictionary-details-view
4
- v-if="selectId"
5
- :id="selectId"
6
- :visible.sync="detailVisible"
7
- />
8
- <x-form-table
9
- serviceName="af-system"
10
- :queryParamsName="queryParamsName"
11
- title="字典"
12
- @action="toDetail">
13
- </x-form-table>
14
- </a-card>
15
- </template>
16
-
17
- <script>
18
- import XFormTable from '@vue2-client/base-client/components/common/XFormTable/XFormTable'
19
- import DictionaryDetailsView from '@vue2-client/base-client/components/system/DictionaryDetailsView'
20
-
21
- export default {
22
- name: 'Dictionary',
23
- components: {
24
- XFormTable,
25
- DictionaryDetailsView
26
- },
27
- data () {
28
- return {
29
- // 选中的编号
30
- selectId: undefined,
31
- // 查询配置文件名
32
- queryParamsName: 'crud_dictionary_manage',
33
- // 是否显示详情抽屉
34
- detailVisible: false
35
- }
36
- },
37
- methods: {
38
- toDetail (record, id) {
39
- this.selectId = id + ''
40
- this.detailVisible = true
41
- }
42
- }
43
- }
44
- </script>
1
+ <template>
2
+ <a-card :bordered="false">
3
+ <dictionary-details-view
4
+ v-if="selectId"
5
+ :id="selectId"
6
+ :visible.sync="detailVisible"
7
+ />
8
+ <x-form-table
9
+ serviceName="af-system"
10
+ :queryParamsName="queryParamsName"
11
+ title="字典"
12
+ @action="toDetail">
13
+ </x-form-table>
14
+ </a-card>
15
+ </template>
16
+
17
+ <script>
18
+ import XFormTable from '@vue2-client/base-client/components/common/XFormTable/XFormTable'
19
+ import DictionaryDetailsView from '@vue2-client/base-client/components/system/DictionaryDetailsView'
20
+
21
+ export default {
22
+ name: 'Dictionary',
23
+ components: {
24
+ XFormTable,
25
+ DictionaryDetailsView
26
+ },
27
+ data () {
28
+ return {
29
+ // 选中的编号
30
+ selectId: undefined,
31
+ // 查询配置文件名
32
+ queryParamsName: 'crud_dictionary_manage',
33
+ // 是否显示详情抽屉
34
+ detailVisible: false
35
+ }
36
+ },
37
+ methods: {
38
+ toDetail (record, id) {
39
+ this.selectId = id + ''
40
+ this.detailVisible = true
41
+ }
42
+ }
43
+ }
44
+ </script>
@@ -1,37 +1,37 @@
1
- <template>
2
- <a-card :bordered="false">
3
- <x-form-table
4
- title="登录日志"
5
- serviceName="af-system"
6
- :queryParamsName="queryParamsName"
7
- @action="toDetail">
8
- </x-form-table>
9
- </a-card>
10
- </template>
11
-
12
- <script>
13
- import XFormTable from '@vue2-client/base-client/components/common/XFormTable/XFormTable'
14
-
15
- export default {
16
- name: 'LoginInfor',
17
- components: {
18
- XFormTable
19
- },
20
- data () {
21
- return {
22
- // 选中的编号
23
- selectNo: undefined,
24
- // 查询配置文件名
25
- queryParamsName: 'crud_login_infor_manage',
26
- // 是否显示详情抽屉
27
- detailVisible: false
28
- }
29
- },
30
- methods: {
31
- toDetail (record, id) {
32
- this.selectNo = id + ''
33
- this.detailVisible = true
34
- }
35
- }
36
- }
37
- </script>
1
+ <template>
2
+ <a-card :bordered="false">
3
+ <x-form-table
4
+ title="登录日志"
5
+ serviceName="af-system"
6
+ :queryParamsName="queryParamsName"
7
+ @action="toDetail">
8
+ </x-form-table>
9
+ </a-card>
10
+ </template>
11
+
12
+ <script>
13
+ import XFormTable from '@vue2-client/base-client/components/common/XFormTable/XFormTable'
14
+
15
+ export default {
16
+ name: 'LoginInfor',
17
+ components: {
18
+ XFormTable
19
+ },
20
+ data () {
21
+ return {
22
+ // 选中的编号
23
+ selectNo: undefined,
24
+ // 查询配置文件名
25
+ queryParamsName: 'crud_login_infor_manage',
26
+ // 是否显示详情抽屉
27
+ detailVisible: false
28
+ }
29
+ },
30
+ methods: {
31
+ toDetail (record, id) {
32
+ this.selectNo = id + ''
33
+ this.detailVisible = true
34
+ }
35
+ }
36
+ }
37
+ </script>
@@ -1,37 +1,37 @@
1
- <template>
2
- <a-card :bordered="false">
3
- <x-form-table
4
- title="操作日志"
5
- :queryParamsName="queryParamsName"
6
- serviceName="af-system"
7
- @action="toDetail">
8
- </x-form-table>
9
- </a-card>
10
- </template>
11
-
12
- <script>
13
- import XFormTable from '@vue2-client/base-client/components/common/XFormTable/XFormTable'
14
-
15
- export default {
16
- name: 'OperLog',
17
- components: {
18
- XFormTable
19
- },
20
- data () {
21
- return {
22
- // 选中的编号
23
- selectNo: undefined,
24
- // 查询配置文件名
25
- queryParamsName: 'crud_oper_log_manage',
26
- // 是否显示详情抽屉
27
- detailVisible: false
28
- }
29
- },
30
- methods: {
31
- toDetail (record, id) {
32
- this.selectNo = id + ''
33
- this.detailVisible = true
34
- }
35
- }
36
- }
37
- </script>
1
+ <template>
2
+ <a-card :bordered="false">
3
+ <x-form-table
4
+ title="操作日志"
5
+ :queryParamsName="queryParamsName"
6
+ serviceName="af-system"
7
+ @action="toDetail">
8
+ </x-form-table>
9
+ </a-card>
10
+ </template>
11
+
12
+ <script>
13
+ import XFormTable from '@vue2-client/base-client/components/common/XFormTable/XFormTable'
14
+
15
+ export default {
16
+ name: 'OperLog',
17
+ components: {
18
+ XFormTable
19
+ },
20
+ data () {
21
+ return {
22
+ // 选中的编号
23
+ selectNo: undefined,
24
+ // 查询配置文件名
25
+ queryParamsName: 'crud_oper_log_manage',
26
+ // 是否显示详情抽屉
27
+ detailVisible: false
28
+ }
29
+ },
30
+ methods: {
31
+ toDetail (record, id) {
32
+ this.selectNo = id + ''
33
+ this.detailVisible = true
34
+ }
35
+ }
36
+ }
37
+ </script>
@@ -1,212 +1,212 @@
1
- <template>
2
- <div>
3
- <div class="filter-bar">
4
- <a-date-picker v-model="upload_date" placeholder="上传日期" @change="selfSearch" />
5
- <a-select
6
- style="width: 200px"
7
- v-model="fusetype"
8
- :options="fusetypes"
9
- placeholder="分类"
10
- @change="selfSearch"
11
- allow-clear
12
- />
13
- <a-button type="primary" @click="selfSearch">查询</a-button>
14
- </div>
15
- <a-list bordered>
16
- <a-list-item v-for="item in files" :key="item.days">
17
- <div class="file-group">
18
- <h4>{{ item.days }}</h4>
19
- <div class="file-items">
20
- <div v-for="file in item.arrays" :key="file.id" class="file-card">
21
- <img
22
- :src="getFileUrl(file.f_downloadpath)"
23
- class="file-image"
24
- v-if="file.f_filetype.includes('jpg') || file.f_filetype.includes('png')"
25
- @click="openPreview(file.f_downloadpath)"
26
- @error="(e) => handleImageError(e, file.f_downloadpath)"
27
- style="cursor: pointer"
28
- />
29
- <p>上传时间: {{ file.f_uploaddate }}</p>
30
- <p>操作员: {{ file.f_username }}</p>
31
- <p>分类: {{ file.fusetype }}</p>
32
- <p>说明: {{ file.fremarks }}</p>
33
- <a :href="getFileUrl(file.f_downloadpath)" target="_blank">预览</a>
34
- <a-button v-if="isDelete === '1'" @click="delet(file.id)">删除</a-button>
35
- </div>
36
- </div>
37
- </div>
38
- </a-list-item>
39
- </a-list>
40
- <ImagePreview :src="previewImg" :original-path="previewOriginalPath" :visible="previewVisible" @close="previewVisible = false" @src-updated="handleSrcUpdated" />
41
- </div>
42
- </template>
43
-
44
- <script>
45
- import { post } from '@vue2-client/services/api'
46
- import { del } from '@vue2-client/services/api/restTools'
47
- import ImagePreview from './ImagePreview.vue'
48
- export default {
49
- props: {
50
- currUserInfo: {
51
- type: Object,
52
- default: () => undefined
53
- }
54
- },
55
- components: { ImagePreview },
56
- data() {
57
- return {
58
- upload_date: null,
59
- fusetype: null,
60
- files: [],
61
- fusetypes: [],
62
- isDelete: '0',
63
- previewVisible: false,
64
- previewImg: '',
65
- previewOriginalPath: ''
66
- }
67
- },
68
- methods: {
69
- async getfusetypes() {
70
- this.fusetypes = [{ label: '全部', value: '' }]
71
- const res = await post('/api/af-revenue/logic/getFileUseType', {})
72
- this.fusetypes.push(...res.map(item => ({ label: item.fusetype, value: item.fusetype })))
73
- },
74
- async getFiles() {
75
- if (!this.currUserInfo) return
76
- this.files = []
77
- let condition = `f_blobid = '${this.currUserInfo.f_userinfo_id}'`
78
- if (this.upload_date) {
79
- condition += ` and CONVERT(VARCHAR(100), f_uploaddate, 23) = '${this.upload_date}'`
80
- }
81
- if (this.fusetype) {
82
- condition += ` and fusetype = '${this.fusetype}'`
83
- }
84
- const res = await post('/api/af-revenue/logic/getAllFiles', { data: { condition } })
85
- this.files = res.days.map(day => ({
86
- days: day.uploadday,
87
- arrays: res.array.filter(file => file.uploadday === day.uploadday)
88
- }))
89
- },
90
- async delet(fileId) {
91
- await del('api/af-revenue/entity/save/t_files', { id: fileId }, { resolveMsg: '删除成功', rejectMsg: '删除失败' })
92
- this.getFiles()
93
- },
94
- selfSearch() {
95
- this.getFiles()
96
- },
97
- openPreview(src) {
98
- this.previewOriginalPath = src
99
- this.previewImg = this.getFileUrl(src)
100
- this.previewVisible = true
101
- },
102
- handleImageError(event, path) {
103
- if (!path || !event.target) return
104
- const currentSrc = event.target.src || ''
105
- console.log('列表图片error - currentSrc:', currentSrc, 'path:', path)
106
-
107
- if (currentSrc.includes('/files/')) {
108
- console.log('列表图片: 已经是新格式,不再处理')
109
- return
110
- }
111
- if (!currentSrc.includes('/rs/image/file/')) {
112
- console.log('列表图片: 不是旧格式,不再处理')
113
- return
114
- }
115
- const baseUrl = `${window.location.protocol}//${window.location.host}`
116
- // 如果是本地文件路径,尝试新格式(保留目录结构)
117
- if (path.match(/^[A-Za-z]:[/\\]/)) {
118
- const normalizedPath = path.replace(/\\/g, '/')
119
- const filesIndex = normalizedPath.toLowerCase().indexOf('/files/')
120
- if (filesIndex !== -1) {
121
- const relativePath = normalizedPath.substring(filesIndex + 1)
122
- const newUrl = `${baseUrl}/${relativePath}`
123
- console.log('列表图片: 切换到新格式URL:', newUrl)
124
- event.target.src = newUrl
125
- }
126
- }
127
- },
128
- handleSrcUpdated(newUrl) {
129
- console.log('ImagePreview通知更新路径:', newUrl)
130
- this.previewImg = newUrl
131
- },
132
- getFileUrl(path) {
133
- if (!path) return ''
134
- console.log('原始路径:', path)
135
- // 获取当前域名和端口
136
- const baseUrl = `${window.location.protocol}//${window.location.host}`
137
- // 如果是本地文件路径,优先使用新格式(/files/...保留目录结构)
138
- if (path.match(/^[A-Za-z]:[/\\]/)) {
139
- const normalizedPath = path.replace(/\\/g, '/')
140
- const filesIndex = normalizedPath.toLowerCase().indexOf('/files/')
141
- if (filesIndex !== -1) {
142
- // 找到 /files/ 位置,使用新格式(保留目录结构)
143
- const relativePath = normalizedPath.substring(filesIndex + 1)
144
- const newUrl = `${baseUrl}/${relativePath}`
145
- console.log('使用新格式路径:', newUrl)
146
- return newUrl
147
- } else {
148
- // 如果路径中没有 /files/,使用旧格式
149
- const fileName = normalizedPath.split('/').pop()
150
- const newUrl = `${baseUrl}/rs/image/file/${encodeURIComponent(fileName)}`
151
- console.log('使用旧格式路径:', newUrl)
152
- return newUrl
153
- }
154
- }
155
- // 如果已经是HTTP路径,直接返回
156
- if (path.startsWith('http')) {
157
- console.log('HTTP路径,直接返回:', path)
158
- return path
159
- }
160
- // 如果是相对路径,添加域名前缀
161
- if (path.startsWith('/resource/')) {
162
- const newUrl = `${baseUrl}${path}`
163
- console.log('相对路径转换:', newUrl)
164
- return newUrl
165
- }
166
- // 如果已经是 /files/ 开头的相对路径,直接添加域名前缀
167
- if (path.startsWith('/files/')) {
168
- const newUrl = `${baseUrl}${path}`
169
- console.log('files相对路径转换:', newUrl)
170
- return newUrl
171
- }
172
- console.log('其他路径,直接返回:', path)
173
- return path
174
- }
175
- },
176
- mounted() {
177
- if (this.$login.r.includes('上传附件删除')) {
178
- this.isDelete = '1'
179
- }
180
- this.getFiles()
181
- this.getfusetypes()
182
- }
183
- }
184
- </script>
185
-
186
- <style scoped>
187
- .filter-bar {
188
- display: flex;
189
- gap: 10px;
190
- margin-bottom: 15px;
191
- }
192
- .file-group {
193
- margin-bottom: 15px;
194
- }
195
- .file-items {
196
- display: flex;
197
- flex-wrap: wrap;
198
- gap: 10px;
199
- }
200
- .file-card {
201
- border: 1px solid #ddd;
202
- padding: 10px;
203
- border-radius: 5px;
204
- width: 200px;
205
- }
206
- .file-image {
207
- width: 100%; /* 让图片填充整个容器 */
208
- height: 150px; /* 调整高度 */
209
- object-fit: cover; /* 保持图片比例,填充整个区域 */
210
- border-radius: 5px; /* 圆角边框 */
211
- }
212
- </style>
1
+ <template>
2
+ <div>
3
+ <div class="filter-bar">
4
+ <a-date-picker v-model="upload_date" placeholder="上传日期" @change="selfSearch" />
5
+ <a-select
6
+ style="width: 200px"
7
+ v-model="fusetype"
8
+ :options="fusetypes"
9
+ placeholder="分类"
10
+ @change="selfSearch"
11
+ allow-clear
12
+ />
13
+ <a-button type="primary" @click="selfSearch">查询</a-button>
14
+ </div>
15
+ <a-list bordered>
16
+ <a-list-item v-for="item in files" :key="item.days">
17
+ <div class="file-group">
18
+ <h4>{{ item.days }}</h4>
19
+ <div class="file-items">
20
+ <div v-for="file in item.arrays" :key="file.id" class="file-card">
21
+ <img
22
+ :src="getFileUrl(file.f_downloadpath)"
23
+ class="file-image"
24
+ v-if="file.f_filetype.includes('jpg') || file.f_filetype.includes('png')"
25
+ @click="openPreview(file.f_downloadpath)"
26
+ @error="(e) => handleImageError(e, file.f_downloadpath)"
27
+ style="cursor: pointer"
28
+ />
29
+ <p>上传时间: {{ file.f_uploaddate }}</p>
30
+ <p>操作员: {{ file.f_username }}</p>
31
+ <p>分类: {{ file.fusetype }}</p>
32
+ <p>说明: {{ file.fremarks }}</p>
33
+ <a :href="getFileUrl(file.f_downloadpath)" target="_blank">预览</a>
34
+ <a-button v-if="isDelete === '1'" @click="delet(file.id)">删除</a-button>
35
+ </div>
36
+ </div>
37
+ </div>
38
+ </a-list-item>
39
+ </a-list>
40
+ <ImagePreview :src="previewImg" :original-path="previewOriginalPath" :visible="previewVisible" @close="previewVisible = false" @src-updated="handleSrcUpdated" />
41
+ </div>
42
+ </template>
43
+
44
+ <script>
45
+ import { post } from '@vue2-client/services/api'
46
+ import { del } from '@vue2-client/services/api/restTools'
47
+ import ImagePreview from './ImagePreview.vue'
48
+ export default {
49
+ props: {
50
+ currUserInfo: {
51
+ type: Object,
52
+ default: () => undefined
53
+ }
54
+ },
55
+ components: { ImagePreview },
56
+ data() {
57
+ return {
58
+ upload_date: null,
59
+ fusetype: null,
60
+ files: [],
61
+ fusetypes: [],
62
+ isDelete: '0',
63
+ previewVisible: false,
64
+ previewImg: '',
65
+ previewOriginalPath: ''
66
+ }
67
+ },
68
+ methods: {
69
+ async getfusetypes() {
70
+ this.fusetypes = [{ label: '全部', value: '' }]
71
+ const res = await post('/api/af-revenue/logic/getFileUseType', {})
72
+ this.fusetypes.push(...res.map(item => ({ label: item.fusetype, value: item.fusetype })))
73
+ },
74
+ async getFiles() {
75
+ if (!this.currUserInfo) return
76
+ this.files = []
77
+ let condition = `f_blobid = '${this.currUserInfo.f_userinfo_id}'`
78
+ if (this.upload_date) {
79
+ condition += ` and CONVERT(VARCHAR(100), f_uploaddate, 23) = '${this.upload_date}'`
80
+ }
81
+ if (this.fusetype) {
82
+ condition += ` and fusetype = '${this.fusetype}'`
83
+ }
84
+ const res = await post('/api/af-revenue/logic/getAllFiles', { data: { condition } })
85
+ this.files = res.days.map(day => ({
86
+ days: day.uploadday,
87
+ arrays: res.array.filter(file => file.uploadday === day.uploadday)
88
+ }))
89
+ },
90
+ async delet(fileId) {
91
+ await del('api/af-revenue/entity/save/t_files', { id: fileId }, { resolveMsg: '删除成功', rejectMsg: '删除失败' })
92
+ this.getFiles()
93
+ },
94
+ selfSearch() {
95
+ this.getFiles()
96
+ },
97
+ openPreview(src) {
98
+ this.previewOriginalPath = src
99
+ this.previewImg = this.getFileUrl(src)
100
+ this.previewVisible = true
101
+ },
102
+ handleImageError(event, path) {
103
+ if (!path || !event.target) return
104
+ const currentSrc = event.target.src || ''
105
+ console.log('列表图片error - currentSrc:', currentSrc, 'path:', path)
106
+
107
+ if (currentSrc.includes('/files/')) {
108
+ console.log('列表图片: 已经是新格式,不再处理')
109
+ return
110
+ }
111
+ if (!currentSrc.includes('/rs/image/file/')) {
112
+ console.log('列表图片: 不是旧格式,不再处理')
113
+ return
114
+ }
115
+ const baseUrl = `${window.location.protocol}//${window.location.host}`
116
+ // 如果是本地文件路径,尝试新格式(保留目录结构)
117
+ if (path.match(/^[A-Za-z]:[/\\]/)) {
118
+ const normalizedPath = path.replace(/\\/g, '/')
119
+ const filesIndex = normalizedPath.toLowerCase().indexOf('/files/')
120
+ if (filesIndex !== -1) {
121
+ const relativePath = normalizedPath.substring(filesIndex + 1)
122
+ const newUrl = `${baseUrl}/${relativePath}`
123
+ console.log('列表图片: 切换到新格式URL:', newUrl)
124
+ event.target.src = newUrl
125
+ }
126
+ }
127
+ },
128
+ handleSrcUpdated(newUrl) {
129
+ console.log('ImagePreview通知更新路径:', newUrl)
130
+ this.previewImg = newUrl
131
+ },
132
+ getFileUrl(path) {
133
+ if (!path) return ''
134
+ console.log('原始路径:', path)
135
+ // 获取当前域名和端口
136
+ const baseUrl = `${window.location.protocol}//${window.location.host}`
137
+ // 如果是本地文件路径,优先使用新格式(/files/...保留目录结构)
138
+ if (path.match(/^[A-Za-z]:[/\\]/)) {
139
+ const normalizedPath = path.replace(/\\/g, '/')
140
+ const filesIndex = normalizedPath.toLowerCase().indexOf('/files/')
141
+ if (filesIndex !== -1) {
142
+ // 找到 /files/ 位置,使用新格式(保留目录结构)
143
+ const relativePath = normalizedPath.substring(filesIndex + 1)
144
+ const newUrl = `${baseUrl}/${relativePath}`
145
+ console.log('使用新格式路径:', newUrl)
146
+ return newUrl
147
+ } else {
148
+ // 如果路径中没有 /files/,使用旧格式
149
+ const fileName = normalizedPath.split('/').pop()
150
+ const newUrl = `${baseUrl}/rs/image/file/${encodeURIComponent(fileName)}`
151
+ console.log('使用旧格式路径:', newUrl)
152
+ return newUrl
153
+ }
154
+ }
155
+ // 如果已经是HTTP路径,直接返回
156
+ if (path.startsWith('http')) {
157
+ console.log('HTTP路径,直接返回:', path)
158
+ return path
159
+ }
160
+ // 如果是相对路径,添加域名前缀
161
+ if (path.startsWith('/resource/')) {
162
+ const newUrl = `${baseUrl}${path}`
163
+ console.log('相对路径转换:', newUrl)
164
+ return newUrl
165
+ }
166
+ // 如果已经是 /files/ 开头的相对路径,直接添加域名前缀
167
+ if (path.startsWith('/files/')) {
168
+ const newUrl = `${baseUrl}${path}`
169
+ console.log('files相对路径转换:', newUrl)
170
+ return newUrl
171
+ }
172
+ console.log('其他路径,直接返回:', path)
173
+ return path
174
+ }
175
+ },
176
+ mounted() {
177
+ if (this.$login.r.includes('上传附件删除')) {
178
+ this.isDelete = '1'
179
+ }
180
+ this.getFiles()
181
+ this.getfusetypes()
182
+ }
183
+ }
184
+ </script>
185
+
186
+ <style scoped>
187
+ .filter-bar {
188
+ display: flex;
189
+ gap: 10px;
190
+ margin-bottom: 15px;
191
+ }
192
+ .file-group {
193
+ margin-bottom: 15px;
194
+ }
195
+ .file-items {
196
+ display: flex;
197
+ flex-wrap: wrap;
198
+ gap: 10px;
199
+ }
200
+ .file-card {
201
+ border: 1px solid #ddd;
202
+ padding: 10px;
203
+ border-radius: 5px;
204
+ width: 200px;
205
+ }
206
+ .file-image {
207
+ width: 100%; /* 让图片填充整个容器 */
208
+ height: 150px; /* 调整高度 */
209
+ object-fit: cover; /* 保持图片比例,填充整个区域 */
210
+ border-radius: 5px; /* 圆角边框 */
211
+ }
212
+ </style>