vue2-client 1.18.28 → 1.18.30

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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vue2-client",
3
- "version": "1.18.28",
3
+ "version": "1.18.30",
4
4
  "private": false,
5
5
  "scripts": {
6
6
  "serve": "SET NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service serve --no-eslint",
@@ -27,6 +27,7 @@ const wrapperClassObject = computed(() => {
27
27
  'border', 'no-style',
28
28
  'fill-container',
29
29
  'no-boder-style',
30
+ 'form-inline',
30
31
  'one-button-style' // 一个按钮样式,占满整个宽度
31
32
  ]
32
33
  for (const key of booleanStyleKeys) {
@@ -154,7 +154,8 @@ defineExpose({
154
154
  border-radius: 6px 6px 0 0;
155
155
  color: #5D5C5C;
156
156
  font-weight: bold;
157
- width: 134px;
157
+ min-width: 134px;
158
+ width: auto;
158
159
  font-size: 18px;
159
160
  line-height: 26px;
160
161
  font-family: "Source Han Sans";
@@ -162,17 +163,18 @@ defineExpose({
162
163
  height: 32px;
163
164
  text-align: center;
164
165
  margin: 0 !important;
165
- padding: 0 !important;
166
+ padding: 0 12px !important;
166
167
  }
167
168
  .ant-tabs-tab-active {
168
169
  background-color: #0057FE;
169
170
  color: #ffffff;
170
- width: 134px;
171
+ min-width: 134px;
172
+ width: auto;
171
173
  line-height: 26px;
172
174
  height: 32px;
173
175
  text-align: center;
174
176
  margin: 0 !important;
175
- padding: 0 !important;
177
+ padding: 0 12px !important;
176
178
  }
177
179
  }
178
180
 
@@ -274,12 +274,24 @@ const resolveStaticDataset = (config) => {
274
274
  return scoped
275
275
  }
276
276
  let scopedDataset = dataset
277
+ // 先处理时间粒度筛选(radioFilter),因为 dataset 的第一层可能是时间粒度
278
+ const filterKeys = [
279
+ selectedFilterValue.value,
280
+ radioFilterConfig.value?.defaultValue
281
+ ].filter(Boolean)
282
+ if (filterKeys.length) {
283
+ const filterScoped = pickByKeys(dataset, filterKeys, true)
284
+ if (Array.isArray(filterScoped)) return filterScoped
285
+ if (filterScoped && typeof filterScoped === 'object') scopedDataset = filterScoped
286
+ }
287
+ if (Array.isArray(scopedDataset)) return scopedDataset
288
+ // 再处理级联筛选或侧边列表筛选
277
289
  if (isCascadeMode.value) {
278
290
  const cascadeKeys = cascadeColumns.value
279
291
  .map(column => column.field && selectedCascadeValues.value[column.field])
280
292
  .filter(value => value !== undefined && value !== null && value !== '')
281
293
  if (cascadeKeys.length) {
282
- const cascadeScoped = pickNestedByKeys(dataset, cascadeKeys)
294
+ const cascadeScoped = pickNestedByKeys(scopedDataset, cascadeKeys)
283
295
  if (Array.isArray(cascadeScoped)) return cascadeScoped
284
296
  if (cascadeScoped && typeof cascadeScoped === 'object') scopedDataset = cascadeScoped
285
297
  }
@@ -289,18 +301,32 @@ const resolveStaticDataset = (config) => {
289
301
  sideListConfig.value?.defaultValue
290
302
  ].filter(Boolean)
291
303
  if (listKeys.length) {
292
- const listScoped = pickByKeys(dataset, listKeys, true)
304
+ // 优先在已按时间粒度过滤后的 scopedDataset 中取
305
+ const listScoped = pickByKeys(scopedDataset, listKeys, true)
293
306
  if (Array.isArray(listScoped)) return listScoped
294
- if (listScoped && typeof listScoped === 'object') scopedDataset = listScoped
307
+ if (listScoped && typeof listScoped === 'object') {
308
+ // 在侧边列表命中的作用域内,再次按时间粒度过滤(处理 { dept: { week: [...] } } 场景)
309
+ let scopedAfterList = listScoped
310
+ if (filterKeys.length) {
311
+ const filterScopedInner = pickByKeys(scopedAfterList, filterKeys, true)
312
+ if (Array.isArray(filterScopedInner)) return filterScopedInner
313
+ if (filterScopedInner && typeof filterScopedInner === 'object') scopedAfterList = filterScopedInner
314
+ }
315
+ scopedDataset = scopedAfterList
316
+ } else {
317
+ // 如果时间粒度在第二层(如 { dept: { week: [...] } }),尝试反向嵌套取值
318
+ const nestedOrder = pickNestedByKeys(dataset, [...listKeys, ...filterKeys])
319
+ if (Array.isArray(nestedOrder)) return nestedOrder
320
+ if (nestedOrder && typeof nestedOrder === 'object') scopedDataset = nestedOrder
321
+ else {
322
+ const reverseNested = pickNestedByKeys(dataset, [...filterKeys, ...listKeys])
323
+ if (Array.isArray(reverseNested)) return reverseNested
324
+ if (reverseNested && typeof reverseNested === 'object') scopedDataset = reverseNested
325
+ }
326
+ }
295
327
  }
296
328
  }
297
329
  if (Array.isArray(scopedDataset)) return scopedDataset
298
- const filterKeys = [
299
- selectedFilterValue.value,
300
- radioFilterConfig.value?.defaultValue
301
- ].filter(Boolean)
302
- const filterScoped = pickByKeys(scopedDataset, filterKeys, false)
303
- if (Array.isArray(filterScoped)) return filterScoped
304
330
  const firstArray = pickFirstArray(scopedDataset)
305
331
  if (Array.isArray(firstArray)) return firstArray
306
332
  }
@@ -1,159 +1,159 @@
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
- <a-button type="primary" @click="selfSearch">查询</a-button>
13
- </div>
14
- <a-list bordered>
15
- <a-list-item v-for="item in files" :key="item.days">
16
- <div class="file-group">
17
- <h4>{{ item.days }}</h4>
18
- <div class="file-items">
19
- <div v-for="file in item.arrays" :key="file.id" class="file-card">
20
- <img :src="getFileUrl(file.f_downloadpath)" class="file-image" v-if="file.f_filetype.includes('jpg') || file.f_filetype.includes('png')" @click="openPreview(file.f_downloadpath)" style="cursor:pointer" />
21
- <p>上传时间: {{ file.f_uploaddate }}</p>
22
- <p>操作员: {{ file.f_username }}</p>
23
- <p>分类: {{ file.fusetype }}</p>
24
- <p>说明: {{ file.fremarks }}</p>
25
- <a :href="getFileUrl(file.f_downloadpath)" target="_blank">预览</a>
26
- <a-button v-if="isDelete === '1'" @click="delet(file.id)">删除</a-button>
27
- </div>
28
- </div>
29
- </div>
30
- </a-list-item>
31
- </a-list>
32
- <ImagePreview :src="previewImg" :visible="previewVisible" @close="previewVisible = false" />
33
- </div>
34
- </template>
35
-
36
- <script>
37
- import { post } from '@vue2-client/services/api'
38
- import { del } from '@vue2-client/services/api/restTools'
39
- import ImagePreview from './ImagePreview.vue'
40
- export default {
41
- props: {
42
- currUserInfo: {
43
- type: Object,
44
- default: () => undefined
45
- }
46
- },
47
- components: { ImagePreview },
48
- data () {
49
- return {
50
- upload_date: null,
51
- fusetype: null,
52
- files: [],
53
- fusetypes: [],
54
- isDelete: '0',
55
- previewVisible: false,
56
- previewImg: ''
57
- }
58
- },
59
- methods: {
60
- async getfusetypes () {
61
- this.fusetypes = [{ label: '全部', value: '' }]
62
- const res = await post('/api/af-revenue/logic/getFileUseType', {})
63
- this.fusetypes.push(...res.map(item => ({ label: item.fusetype, value: item.fusetype })))
64
- },
65
- async getFiles () {
66
- if (!this.currUserInfo) return
67
- this.files = []
68
- let condition = `f_blobid = '${this.currUserInfo.f_userinfo_id}'`
69
- if (this.upload_date) {
70
- condition += ` and CONVERT(VARCHAR(100), f_uploaddate, 23) = '${this.upload_date}'`
71
- }
72
- if (this.fusetype) {
73
- condition += ` and fusetype = '${this.fusetype}'`
74
- }
75
- const res = await post('/api/af-revenue/logic/getAllFiles', { data: { condition } })
76
- this.files = res.days.map(day => ({
77
- days: day.uploadday,
78
- arrays: res.array.filter(file => file.uploadday === day.uploadday)
79
- }))
80
- },
81
- async delet (fileId) {
82
- await del('api/af-revenue/entity/save/t_files', { id: fileId }, { resolveMsg: '删除成功', rejectMsg: '删除失败' })
83
- this.getFiles()
84
- },
85
- selfSearch () {
86
- this.getFiles()
87
- },
88
- openPreview (src) {
89
- this.previewImg = this.getFileUrl(src)
90
- this.previewVisible = true
91
- },
92
- getFileUrl (path) {
93
- if (!path) return ''
94
-
95
- console.log('原始路径:', path)
96
-
97
- // 获取当前域名和端口
98
- const baseUrl = `${window.location.protocol}//${window.location.host}`
99
-
100
- // 如果是本地文件路径,转换为新的转发路径
101
- if (path.match(/^[A-Za-z]:[\/\\]/)) {
102
- // 提取文件名
103
- const fileName = path.split(/[/\\]/).pop()
104
- const newUrl = `${baseUrl}/rs/image/file/${fileName}`
105
- console.log('转换后路径:', newUrl)
106
- return newUrl
107
- }
108
- // 如果已经是HTTP路径,直接返回
109
- if (path.startsWith('http')) {
110
- console.log('HTTP路径,直接返回:', path)
111
- return path
112
- }
113
- // 如果是相对路径,添加域名前缀
114
- if (path.startsWith('/resource/')) {
115
- const newUrl = `${baseUrl}${path}`
116
- console.log('相对路径转换:', newUrl)
117
- return newUrl
118
- }
119
- console.log('其他路径,直接返回:', path)
120
- return path
121
- }
122
- },
123
- mounted () {
124
- if (this.$login.r.includes('上传附件删除')) {
125
- this.isDelete = '1'
126
- }
127
- this.getFiles()
128
- this.getfusetypes()
129
- }
130
- }
131
- </script>
132
-
133
- <style scoped>
134
- .filter-bar {
135
- display: flex;
136
- gap: 10px;
137
- margin-bottom: 15px;
138
- }
139
- .file-group {
140
- margin-bottom: 15px;
141
- }
142
- .file-items {
143
- display: flex;
144
- flex-wrap: wrap;
145
- gap: 10px;
146
- }
147
- .file-card {
148
- border: 1px solid #ddd;
149
- padding: 10px;
150
- border-radius: 5px;
151
- width: 200px;
152
- }
153
- .file-image {
154
- width: 100%; /* 让图片填充整个容器 */
155
- height: 150px; /* 调整高度 */
156
- object-fit: cover; /* 保持图片比例,填充整个区域 */
157
- border-radius: 5px; /* 圆角边框 */
158
- }
159
- </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
+ <a-button type="primary" @click="selfSearch">查询</a-button>
13
+ </div>
14
+ <a-list bordered>
15
+ <a-list-item v-for="item in files" :key="item.days">
16
+ <div class="file-group">
17
+ <h4>{{ item.days }}</h4>
18
+ <div class="file-items">
19
+ <div v-for="file in item.arrays" :key="file.id" class="file-card">
20
+ <img :src="getFileUrl(file.f_downloadpath)" class="file-image" v-if="file.f_filetype.includes('jpg') || file.f_filetype.includes('png')" @click="openPreview(file.f_downloadpath)" style="cursor:pointer" />
21
+ <p>上传时间: {{ file.f_uploaddate }}</p>
22
+ <p>操作员: {{ file.f_username }}</p>
23
+ <p>分类: {{ file.fusetype }}</p>
24
+ <p>说明: {{ file.fremarks }}</p>
25
+ <a :href="getFileUrl(file.f_downloadpath)" target="_blank">预览</a>
26
+ <a-button v-if="isDelete === '1'" @click="delet(file.id)">删除</a-button>
27
+ </div>
28
+ </div>
29
+ </div>
30
+ </a-list-item>
31
+ </a-list>
32
+ <ImagePreview :src="previewImg" :visible="previewVisible" @close="previewVisible = false" />
33
+ </div>
34
+ </template>
35
+
36
+ <script>
37
+ import { post } from '@vue2-client/services/api'
38
+ import { del } from '@vue2-client/services/api/restTools'
39
+ import ImagePreview from './ImagePreview.vue'
40
+ export default {
41
+ props: {
42
+ currUserInfo: {
43
+ type: Object,
44
+ default: () => undefined
45
+ }
46
+ },
47
+ components: { ImagePreview },
48
+ data () {
49
+ return {
50
+ upload_date: null,
51
+ fusetype: null,
52
+ files: [],
53
+ fusetypes: [],
54
+ isDelete: '0',
55
+ previewVisible: false,
56
+ previewImg: ''
57
+ }
58
+ },
59
+ methods: {
60
+ async getfusetypes () {
61
+ this.fusetypes = [{ label: '全部', value: '' }]
62
+ const res = await post('/api/af-revenue/logic/getFileUseType', {})
63
+ this.fusetypes.push(...res.map(item => ({ label: item.fusetype, value: item.fusetype })))
64
+ },
65
+ async getFiles () {
66
+ if (!this.currUserInfo) return
67
+ this.files = []
68
+ let condition = `f_blobid = '${this.currUserInfo.f_userinfo_id}'`
69
+ if (this.upload_date) {
70
+ condition += ` and CONVERT(VARCHAR(100), f_uploaddate, 23) = '${this.upload_date}'`
71
+ }
72
+ if (this.fusetype) {
73
+ condition += ` and fusetype = '${this.fusetype}'`
74
+ }
75
+ const res = await post('/api/af-revenue/logic/getAllFiles', { data: { condition } })
76
+ this.files = res.days.map(day => ({
77
+ days: day.uploadday,
78
+ arrays: res.array.filter(file => file.uploadday === day.uploadday)
79
+ }))
80
+ },
81
+ async delet (fileId) {
82
+ await del('api/af-revenue/entity/save/t_files', { id: fileId }, { resolveMsg: '删除成功', rejectMsg: '删除失败' })
83
+ this.getFiles()
84
+ },
85
+ selfSearch () {
86
+ this.getFiles()
87
+ },
88
+ openPreview (src) {
89
+ this.previewImg = this.getFileUrl(src)
90
+ this.previewVisible = true
91
+ },
92
+ getFileUrl (path) {
93
+ if (!path) return ''
94
+
95
+ console.log('原始路径:', path)
96
+
97
+ // 获取当前域名和端口
98
+ const baseUrl = `${window.location.protocol}//${window.location.host}`
99
+
100
+ // 如果是本地文件路径,转换为新的转发路径
101
+ if (path.match(/^[A-Za-z]:[\/\\]/)) {
102
+ // 提取文件名
103
+ const fileName = path.split(/[/\\]/).pop()
104
+ const newUrl = `${baseUrl}/rs/image/file/${fileName}`
105
+ console.log('转换后路径:', newUrl)
106
+ return newUrl
107
+ }
108
+ // 如果已经是HTTP路径,直接返回
109
+ if (path.startsWith('http')) {
110
+ console.log('HTTP路径,直接返回:', path)
111
+ return path
112
+ }
113
+ // 如果是相对路径,添加域名前缀
114
+ if (path.startsWith('/resource/')) {
115
+ const newUrl = `${baseUrl}${path}`
116
+ console.log('相对路径转换:', newUrl)
117
+ return newUrl
118
+ }
119
+ console.log('其他路径,直接返回:', path)
120
+ return path
121
+ }
122
+ },
123
+ mounted () {
124
+ if (this.$login.r.includes('上传附件删除')) {
125
+ this.isDelete = '1'
126
+ }
127
+ this.getFiles()
128
+ this.getfusetypes()
129
+ }
130
+ }
131
+ </script>
132
+
133
+ <style scoped>
134
+ .filter-bar {
135
+ display: flex;
136
+ gap: 10px;
137
+ margin-bottom: 15px;
138
+ }
139
+ .file-group {
140
+ margin-bottom: 15px;
141
+ }
142
+ .file-items {
143
+ display: flex;
144
+ flex-wrap: wrap;
145
+ gap: 10px;
146
+ }
147
+ .file-card {
148
+ border: 1px solid #ddd;
149
+ padding: 10px;
150
+ border-radius: 5px;
151
+ width: 200px;
152
+ }
153
+ .file-image {
154
+ width: 100%; /* 让图片填充整个容器 */
155
+ height: 150px; /* 调整高度 */
156
+ object-fit: cover; /* 保持图片比例,填充整个区域 */
157
+ border-radius: 5px; /* 圆角边框 */
158
+ }
159
+ </style>