vue2-client 1.13.5 → 1.13.6

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,107 +1,107 @@
1
- {
2
- "name": "vue2-client",
3
- "version": "1.13.5",
4
- "private": false,
5
- "scripts": {
6
- "serve": "SET NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service serve --no-eslint",
7
- "serve:gaslink": "SET NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service serve --no-eslint --mode gaslink",
8
- "serve:revenue": "SET NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service serve --no-eslint --mode revenue",
9
- "serve:liuli": "SET NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service serve --no-eslint --mode liuli",
10
- "serve:scada": "SET NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service serve --no-eslint --mode scada",
11
- "serve:iot": "SET NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service serve --no-eslint --mode iot",
12
- "serve:his": "SET NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service serve --no-eslint --mode his",
13
- "mac-serve": "vue-cli-service serve --no-eslint --mode his",
14
- "build": "SET NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service build",
15
- "test:unit": "vue-cli-service test:unit",
16
- "lint": "vue-cli-service lint",
17
- "build:preview": "vue-cli-service build --mode preview",
18
- "lint:nofix": "vue-cli-service lint --no-fix",
19
- "test": "jest"
20
- },
21
- "dependencies": {
22
- "@afwenming123/vue-easy-tree": "^1.0.1",
23
- "@afwenming123/vue-plugin-hiprint": "^0.0.70",
24
- "@amap/amap-jsapi-loader": "^1.0.1",
25
- "@antv/data-set": "^0.11.8",
26
- "@antv/g2plot": "^2.4.31",
27
- "@hufe921/canvas-editor": "^0.9.49",
28
- "@microsoft/fetch-event-source": "^2.0.1",
29
- "@vue/babel-preset-jsx": "^1.4.0",
30
- "animate.css": "^4.1.1",
31
- "ant-design-vue": "^1.7.8",
32
- "axios": "^0.27.2",
33
- "clipboard": "^2.0.11",
34
- "core-js": "^3.33.0",
35
- "crypto-js": "^4.1.1",
36
- "date-fns": "^2.29.3",
37
- "default-passive-events": "^2.0.0",
38
- "dotenv": "^16.3.1",
39
- "echarts": "^5.5.0",
40
- "enquire.js": "^2.1.6",
41
- "file-saver": "^2.0.5",
42
- "highlight.js": "^11.7.0",
43
- "html2canvas": "^1.4.1",
44
- "js-base64": "^3.7.5",
45
- "js-cookie": "^2.2.1",
46
- "jsencrypt": "^3.3.2",
47
- "jspdf": "^2.5.1",
48
- "lodash.clonedeep": "^4.5.0",
49
- "lodash.debounce": "^4",
50
- "lodash.get": "^4.4.2",
51
- "marked": "^4",
52
- "mockjs": "^1.1.0",
53
- "nprogress": "^0.2.0",
54
- "qs": "^6.11.2",
55
- "regenerator-runtime": "^0.14.0",
56
- "videojs-contrib-hls": "^5.15.0",
57
- "viser-vue": "^2.4.8",
58
- "vue": "^2.7.14",
59
- "vue-codemirror": "4.0.6",
60
- "vue-draggable-resizable": "^2",
61
- "vue-i18n": "^8.28.2",
62
- "vue-json-viewer": "^2.2.22",
63
- "vue-router": "^3.6.5",
64
- "vue-video-player": "^5.0.2",
65
- "vue-virtual-scroller": "^1.1.2",
66
- "vuedraggable": "^2.24.3",
67
- "vuex": "^3.6.2",
68
- "xlsx": "0.18.5"
69
- },
70
- "devDependencies": {
71
- "@ant-design/colors": "^7.0.0",
72
- "@babel/core": "^7.22.20",
73
- "@babel/eslint-parser": "^7.22.15",
74
- "@babel/preset-env": "^7.22.20",
75
- "@vue/cli-plugin-babel": "^5.0.8",
76
- "@vue/cli-plugin-eslint": "^5.0.8",
77
- "@vue/cli-service": "^5.0.8",
78
- "@vue/eslint-config-standard": "^8.0.1",
79
- "@vue/test-utils": "^1.3.6",
80
- "babel-plugin-transform-remove-console": "^6.9.4",
81
- "compression-webpack-plugin": "^10.0.0",
82
- "css-minimizer-webpack-plugin": "^5.0.1",
83
- "deepmerge": "^4.3.1",
84
- "eslint": "^8.51.0",
85
- "eslint-plugin-vue": "^9.17.0",
86
- "fast-deep-equal": "^3.1.3",
87
- "ignore-loader": "^0.1.2",
88
- "jest": "^29.7.0",
89
- "jest-environment-jsdom": "^29.7.0",
90
- "jest-transform-stub": "^2.0.0",
91
- "less-loader": "^6.2.0",
92
- "script-loader": "^0.7.2",
93
- "style-resources-loader": "^1.5.0",
94
- "vue-cli-plugin-style-resources-loader": "^0.1.5",
95
- "vue-jest": "^4.0.1",
96
- "vue-template-compiler": "^2.7.14",
97
- "webpack": "^5.88.2",
98
- "webpack-theme-color-replacer": "^1.4.7",
99
- "whatwg-fetch": "^3.6.19"
100
- },
101
- "browserslist": [
102
- "> 1%",
103
- "last 2 versions",
104
- "not dead",
105
- "not ie 11"
106
- ]
107
- }
1
+ {
2
+ "name": "vue2-client",
3
+ "version": "1.13.6",
4
+ "private": false,
5
+ "scripts": {
6
+ "serve": "SET NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service serve --no-eslint",
7
+ "serve:gaslink": "SET NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service serve --no-eslint --mode gaslink",
8
+ "serve:revenue": "SET NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service serve --no-eslint --mode revenue",
9
+ "serve:liuli": "SET NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service serve --no-eslint --mode liuli",
10
+ "serve:scada": "SET NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service serve --no-eslint --mode scada",
11
+ "serve:iot": "SET NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service serve --no-eslint --mode iot",
12
+ "serve:his": "SET NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service serve --no-eslint --mode his",
13
+ "mac-serve": "vue-cli-service serve --no-eslint --mode his",
14
+ "build": "SET NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service build",
15
+ "test:unit": "vue-cli-service test:unit",
16
+ "lint": "vue-cli-service lint",
17
+ "build:preview": "vue-cli-service build --mode preview",
18
+ "lint:nofix": "vue-cli-service lint --no-fix",
19
+ "test": "jest"
20
+ },
21
+ "dependencies": {
22
+ "@afwenming123/vue-easy-tree": "^1.0.1",
23
+ "@afwenming123/vue-plugin-hiprint": "^0.0.70",
24
+ "@amap/amap-jsapi-loader": "^1.0.1",
25
+ "@antv/data-set": "^0.11.8",
26
+ "@antv/g2plot": "^2.4.31",
27
+ "@hufe921/canvas-editor": "^0.9.49",
28
+ "@microsoft/fetch-event-source": "^2.0.1",
29
+ "@vue/babel-preset-jsx": "^1.4.0",
30
+ "animate.css": "^4.1.1",
31
+ "ant-design-vue": "^1.7.8",
32
+ "axios": "^0.27.2",
33
+ "clipboard": "^2.0.11",
34
+ "core-js": "^3.33.0",
35
+ "crypto-js": "^4.1.1",
36
+ "date-fns": "^2.29.3",
37
+ "default-passive-events": "^2.0.0",
38
+ "dotenv": "^16.3.1",
39
+ "echarts": "^5.5.0",
40
+ "enquire.js": "^2.1.6",
41
+ "file-saver": "^2.0.5",
42
+ "highlight.js": "^11.7.0",
43
+ "html2canvas": "^1.4.1",
44
+ "js-base64": "^3.7.5",
45
+ "js-cookie": "^2.2.1",
46
+ "jsencrypt": "^3.3.2",
47
+ "jspdf": "^2.5.1",
48
+ "lodash.clonedeep": "^4.5.0",
49
+ "lodash.debounce": "^4",
50
+ "lodash.get": "^4.4.2",
51
+ "marked": "^4",
52
+ "mockjs": "^1.1.0",
53
+ "nprogress": "^0.2.0",
54
+ "qs": "^6.11.2",
55
+ "regenerator-runtime": "^0.14.0",
56
+ "videojs-contrib-hls": "^5.15.0",
57
+ "viser-vue": "^2.4.8",
58
+ "vue": "^2.7.14",
59
+ "vue-codemirror": "4.0.6",
60
+ "vue-draggable-resizable": "^2",
61
+ "vue-i18n": "^8.28.2",
62
+ "vue-json-viewer": "^2.2.22",
63
+ "vue-router": "^3.6.5",
64
+ "vue-video-player": "^5.0.2",
65
+ "vue-virtual-scroller": "^1.1.2",
66
+ "vuedraggable": "^2.24.3",
67
+ "vuex": "^3.6.2",
68
+ "xlsx": "0.18.5"
69
+ },
70
+ "devDependencies": {
71
+ "@ant-design/colors": "^7.0.0",
72
+ "@babel/core": "^7.22.20",
73
+ "@babel/eslint-parser": "^7.22.15",
74
+ "@babel/preset-env": "^7.22.20",
75
+ "@vue/cli-plugin-babel": "^5.0.8",
76
+ "@vue/cli-plugin-eslint": "^5.0.8",
77
+ "@vue/cli-service": "^5.0.8",
78
+ "@vue/eslint-config-standard": "^8.0.1",
79
+ "@vue/test-utils": "^1.3.6",
80
+ "babel-plugin-transform-remove-console": "^6.9.4",
81
+ "compression-webpack-plugin": "^10.0.0",
82
+ "css-minimizer-webpack-plugin": "^5.0.1",
83
+ "deepmerge": "^4.3.1",
84
+ "eslint": "^8.51.0",
85
+ "eslint-plugin-vue": "^9.17.0",
86
+ "fast-deep-equal": "^3.1.3",
87
+ "ignore-loader": "^0.1.2",
88
+ "jest": "^29.7.0",
89
+ "jest-environment-jsdom": "^29.7.0",
90
+ "jest-transform-stub": "^2.0.0",
91
+ "less-loader": "^6.2.0",
92
+ "script-loader": "^0.7.2",
93
+ "style-resources-loader": "^1.5.0",
94
+ "vue-cli-plugin-style-resources-loader": "^0.1.5",
95
+ "vue-jest": "^4.0.1",
96
+ "vue-template-compiler": "^2.7.14",
97
+ "webpack": "^5.88.2",
98
+ "webpack-theme-color-replacer": "^1.4.7",
99
+ "whatwg-fetch": "^3.6.19"
100
+ },
101
+ "browserslist": [
102
+ "> 1%",
103
+ "last 2 versions",
104
+ "not dead",
105
+ "not ie 11"
106
+ ]
107
+ }
@@ -12,19 +12,74 @@
12
12
  </a-button>
13
13
  </div>
14
14
 
15
- <a-descriptions
16
- :column="config?.layout"
17
- :size="config?.style?.size"
18
- :bordered="config?.style?.bordered"
19
- layout="horizontal">
20
- <template v-if="data">
21
- <!-- 显示前N个标签 -->
22
- <a-descriptions-item
23
- v-for="(item) in visibleItems"
24
- :key="item.field"
25
- :colon="item.colon !== false"
26
- v-if="data[item.field] !== null && data[item.field] !== undefined && (!showAllItems || showAllItems && !hiddenItems.some(i => i.field === item.field))">
27
- <template #label>
15
+ <!-- 当有 layout 配置时使用 a-descriptions -->
16
+ <template v-if="config?.layout">
17
+ <a-descriptions
18
+ :column="config.layout"
19
+ :size="config?.style?.size"
20
+ :bordered="config?.style?.bordered"
21
+ layout="horizontal">
22
+ <template v-if="data">
23
+ <!-- 显示前N个标签 -->
24
+ <a-descriptions-item
25
+ v-for="(item) in visibleItems"
26
+ :key="item.field"
27
+ :colon="item.colon !== false"
28
+ v-if="data[item.field] !== null && data[item.field] !== undefined && (!showAllItems || showAllItems && !hiddenItems.some(i => i.field === item.field))">
29
+ <template #label>
30
+ <div :class="['label-wrapper', { 'with-avatar': item.showAvatar }]">
31
+ <a-avatar
32
+ v-if="item.showAvatar"
33
+ :size="item.avatar.size"
34
+ :icon="item.avatar.icon"
35
+ :style="{ background: item.avatar.background }"
36
+ />
37
+ <span class="label-text">{{ item.label }}</span>
38
+ </div>
39
+ </template>
40
+ <div class="content-wrapper">
41
+ {{ data[item.field] }}
42
+ </div>
43
+ </a-descriptions-item>
44
+
45
+ <!-- 展开后显示剩余标签 -->
46
+ <template v-if="showAllItems">
47
+ <a-descriptions-item
48
+ v-for="item in hiddenItems"
49
+ :key="item.field"
50
+ :colon="item.colon !== false"
51
+ v-if="data[item.field] !== null && data[item.field] !== undefined">
52
+ <template #label>
53
+ <div :class="['label-wrapper', { 'with-avatar': item.showAvatar }]">
54
+ <a-avatar
55
+ v-if="item.showAvatar"
56
+ :size="item.avatar.size"
57
+ :icon="item.avatar.icon"
58
+ :style="{ background: item.avatar.background }"
59
+ />
60
+ <span class="label-text">{{ item.label }}</span>
61
+ </div>
62
+ </template>
63
+ <div class="content-wrapper">
64
+ {{ data[item.field] }}
65
+ </div>
66
+ </a-descriptions-item>
67
+ </template>
68
+ </template>
69
+ </a-descriptions>
70
+ </template>
71
+
72
+ <!-- 当没有 layout 配置时使用自适应布局 -->
73
+ <template v-else>
74
+ <div class="flex-descriptions">
75
+ <template v-if="data">
76
+ <!-- 显示可见的标签 -->
77
+ <div
78
+ v-for="(item) in visibleItems"
79
+ :key="item.field"
80
+ class="description-item"
81
+ v-if="data[item.field] !== null && data[item.field] !== undefined"
82
+ >
28
83
  <div :class="['label-wrapper', { 'with-avatar': item.showAvatar }]">
29
84
  <a-avatar
30
85
  v-if="item.showAvatar"
@@ -32,22 +87,21 @@
32
87
  :icon="item.avatar.icon"
33
88
  :style="{ background: item.avatar.background }"
34
89
  />
35
- <span class="label-text">{{ item.label }}</span>
90
+ <span class="label-text">{{ item.label }}:</span>
91
+ </div>
92
+ <div class="content-wrapper">
93
+ {{ data[item.field] }}
36
94
  </div>
37
- </template>
38
- <div class="content-wrapper">
39
- {{ data[item.field] }}
40
95
  </div>
41
- </a-descriptions-item>
42
96
 
43
- <!-- 展开后显示剩余标签 -->
44
- <template v-if="showAllItems">
45
- <a-descriptions-item
46
- v-for="item in hiddenItems"
47
- :key="item.field"
48
- :colon="item.colon !== false"
49
- v-if="data[item.field] !== null && data[item.field] !== undefined">
50
- <template #label>
97
+ <!-- 展开后显示的内容 -->
98
+ <template v-if="showAllItems">
99
+ <div
100
+ v-for="item in hiddenItems"
101
+ :key="item.field"
102
+ class="description-item"
103
+ v-if="data[item.field] !== null && data[item.field] !== undefined"
104
+ >
51
105
  <div :class="['label-wrapper', { 'with-avatar': item.showAvatar }]">
52
106
  <a-avatar
53
107
  v-if="item.showAvatar"
@@ -55,19 +109,20 @@
55
109
  :icon="item.avatar.icon"
56
110
  :style="{ background: item.avatar.background }"
57
111
  />
58
- <span class="label-text">{{ item.label }}</span>
112
+ <span class="label-text">{{ item.label }}:</span>
113
+ </div>
114
+ <div class="content-wrapper">
115
+ {{ data[item.field] }}
59
116
  </div>
60
- </template>
61
- <div class="content-wrapper">
62
- {{ data[item.field] }}
63
117
  </div>
64
- </a-descriptions-item>
118
+ </template>
65
119
  </template>
66
- </template>
67
- </a-descriptions>
120
+ </div>
121
+ </template>
68
122
  </div>
69
123
  </div>
70
124
  </template>
125
+
71
126
  <script>
72
127
  import { getConfigByName, runLogic } from '@vue2-client/services/api/common'
73
128
 
@@ -95,20 +150,14 @@ export default {
95
150
  computed: {
96
151
  // 获取详情按钮应该显示在第几个标签后
97
152
  detailsAfterIndex () {
98
- // 只有明确配置了detailsConfig且设置了showAfterIndex时才使用配置值
99
- // 否则返回一个很大的值,使所有字段都显示
100
153
  return this.config?.detailsConfig?.showAfterIndex || 999
101
154
  },
102
155
  // 判断是否有更多标签需要显示
103
156
  hasMoreItems () {
104
- // 只有明确配置了detailsConfig时才显示详情按钮
105
157
  if (!this.config?.detailsConfig) return false
106
- // 如果没有数据或没有配置项,不显示详情按钮
107
158
  if (!this.data || !this.config?.items || !Array.isArray(this.config.items)) return false
108
- // 获取隐藏项索引
109
159
  const hiddenStartIndex = this.detailsAfterIndex || 0
110
160
  if (hiddenStartIndex >= this.config.items.length) return false
111
- // 检查隐藏的项中是否有非空值
112
161
  for (let i = hiddenStartIndex; i < this.config.items.length; i++) {
113
162
  const item = this.config.items[i]
114
163
  if (item && item.field && this.data[item.field] !== null && this.data[item.field] !== undefined) {
@@ -120,31 +169,15 @@ export default {
120
169
  // 获取应该显示的标签
121
170
  visibleItems () {
122
171
  if (!this.config?.items) return []
123
-
124
- if (!this.config?.detailsConfig) {
125
- // 如果没有配置detailsConfig,直接显示所有项
126
- return this.config.items
127
- }
128
-
129
- if (this.showAllItems) {
130
- // 如果已经展开,也返回前N项,后面的项目会通过hiddenItems显示
131
- return this.config.items.slice(0, this.detailsAfterIndex)
132
- }
133
-
134
- // 否则显示前N项
172
+ if (!this.config?.detailsConfig) return this.config.items
173
+ if (this.showAllItems) return this.config.items.slice(0, this.detailsAfterIndex)
135
174
  return this.config.items.slice(0, this.detailsAfterIndex)
136
175
  },
137
- // 获取隐藏的标签
176
+ // 获取隐藏的标签(保持原有逻辑)
138
177
  hiddenItems () {
139
178
  if (!this.config?.items) return []
140
- if (!this.config?.detailsConfig) return [] // 如果没有配置detailsConfig,没有隐藏的项
179
+ if (!this.config?.detailsConfig) return []
141
180
  return this.config.items.slice(this.detailsAfterIndex)
142
- },
143
- // 获取有效的visible项目数量(排除null值)
144
- validVisibleItemsCount () {
145
- if (!this.config?.items || !this.data) return 0
146
- const items = this.visibleItems
147
- return items.filter(item => this.data[item.field] !== null && this.data[item.field] !== undefined).length
148
181
  }
149
182
  },
150
183
  created () {
@@ -153,7 +186,7 @@ export default {
153
186
  methods: {
154
187
  async getData (data) {
155
188
  this.data = null
156
- this.showAllItems = false // 重置展开状态
189
+ this.showAllItems = false
157
190
  getConfigByName(data, 'af-his', res => {
158
191
  this.config = res
159
192
  console.log(this.config)
@@ -163,7 +196,6 @@ export default {
163
196
  })
164
197
  })
165
198
  },
166
- // 切换详情显示状态
167
199
  toggleDetails () {
168
200
  this.showAllItems = !this.showAllItems
169
201
  }
@@ -185,30 +217,45 @@ export default {
185
217
  background: #fff;
186
218
  padding: 12px;
187
219
  border-radius: 4px;
220
+ width: 100%;
188
221
  }
189
222
 
190
223
  .descriptions-container {
191
- position: relative; /* 为绝对定位的按钮提供参考点 */
224
+ position: relative;
225
+ width: 100%;
226
+ padding-right: 80px; /* 为按钮预留空间 */
192
227
  }
193
228
 
194
- .detail-button-wrapper {
195
- position: absolute;
196
- right: 0;
197
- top: 0;
198
- z-index: 10;
229
+ /* 自适应布局样式 */
230
+ .flex-descriptions {
231
+ display: flex;
232
+ flex-wrap: wrap;
233
+ gap: 8px 24px;
234
+ width: 100%;
235
+ }
236
+
237
+ .description-item {
238
+ display: inline-flex;
239
+ align-items: center;
199
240
  padding: 4px 8px;
200
241
  border-radius: 4px;
201
- background-color: rgba(255, 255, 255, 0.9);
242
+ transition: background-color 0.3s;
243
+ white-space: nowrap;
244
+ flex: 0 1 auto;
245
+ }
246
+
247
+ .description-item:hover {
248
+ background-color: rgba(0, 0, 0, 0.02);
202
249
  }
203
250
 
251
+ /* 共用样式 */
204
252
  .label-wrapper {
205
253
  display: flex;
206
254
  align-items: center;
255
+ gap: 8px;
256
+ color: rgba(0, 0, 0, 0.65);
257
+ font-size: v-bind('config?.style?.fontSize');
207
258
  white-space: nowrap;
208
- line-height: 24px;
209
- position: relative;
210
- padding: 0;
211
- margin: 0;
212
259
  }
213
260
 
214
261
  .label-wrapper.with-avatar {
@@ -216,15 +263,32 @@ export default {
216
263
  }
217
264
 
218
265
  .label-text {
266
+ white-space: nowrap;
267
+ }
268
+
269
+ .content-wrapper {
219
270
  display: inline-flex;
220
271
  align-items: center;
272
+ margin-left: 4px;
273
+ font-size: v-bind('config?.style?.fontSize');
274
+ color: rgba(0, 0, 0, 0.85);
275
+ max-width: 300px;
276
+ overflow: hidden;
277
+ text-overflow: ellipsis;
278
+ white-space: nowrap;
221
279
  }
222
280
 
223
- .content-wrapper {
224
- line-height: 24px;
281
+ .detail-button-wrapper {
282
+ position: absolute;
283
+ right: 0;
284
+ top: 0;
285
+ z-index: 10;
286
+ padding: 4px 8px;
225
287
  white-space: nowrap;
288
+ background-color: #fff;
226
289
  }
227
290
 
291
+ /* Ant Design 描述列表样式覆盖 */
228
292
  :deep(.ant-descriptions-row) {
229
293
  display: flex;
230
294
  flex-direction: row;
@@ -276,23 +340,11 @@ export default {
276
340
  padding: 0 !important;
277
341
  }
278
342
 
279
- /* 移除 Ant Design 的默认样式 */
280
- :deep(.ant-descriptions-item-container),
281
- :deep(.ant-descriptions-item-label),
282
- :deep(.ant-descriptions-item-content),
283
- :deep(.ant-descriptions-item-colon) {
284
- box-sizing: border-box !important;
285
- border-spacing: 0 !important;
286
- border-collapse: collapse !important;
287
- }
288
-
289
- /* 添加悬停效果 */
290
343
  :deep(.ant-descriptions-item-container:hover) {
291
344
  background-color: rgba(0, 0, 0, 0.02);
292
345
  border-radius: 4px;
293
346
  }
294
347
 
295
- /* 添加详情按钮样式 */
296
348
  :deep(.ant-btn-link) {
297
349
  padding: 0;
298
350
  height: auto;
@@ -303,4 +355,20 @@ export default {
303
355
  color: #1890ff;
304
356
  background: transparent;
305
357
  }
358
+
359
+ /* 响应式调整 */
360
+ @media screen and (max-width: 768px) {
361
+ .content-wrapper {
362
+ max-width: 200px;
363
+ }
364
+ }
365
+
366
+ @media screen and (max-width: 576px) {
367
+ .content-wrapper {
368
+ max-width: 150px;
369
+ }
370
+ .flex-descriptions {
371
+ gap: 4px 12px;
372
+ }
373
+ }
306
374
  </style>
@@ -4,21 +4,21 @@
4
4
 
5
5
  `XHDescriptions` 是一个基于 Ant Design Vue 的描述列表组件封装,专用于显示患者基本信息。该组件具有以下特点:
6
6
 
7
- - 支持响应式布局,在不同屏幕尺寸下自动调整列数
7
+ - 支持两种布局模式:响应式列数布局和自适应流式布局
8
8
  - 支持折叠/展开功能,控制信息的显示量
9
9
  - 支持自定义样式和头像
10
- - 自动隐藏值为 null、undefined的字段
10
+ - 自动隐藏值为 null、undefined 的字段
11
11
  - 右上角悬浮"详情/收起"按钮,布局更整洁
12
12
 
13
13
  ## 配置说明
14
14
 
15
15
  组件通过 JSON 配置文件进行配置,主要包含以下部分:
16
16
 
17
- ### 1. 布局配置 (layout)
17
+ ### 1. 布局配置 (layout,可选)
18
18
 
19
19
  ```json
20
20
  "layout": {
21
- "xl": 4,
21
+ "xl": 4,
22
22
  "md": 3,
23
23
  "sm": 2,
24
24
  "lg": 4,
@@ -27,24 +27,21 @@
27
27
  }
28
28
  ```
29
29
 
30
- - 用于设置在不同屏幕尺寸下的列数
30
+ - 可选配置,用于设置固定列数布局模式
31
+ - 当配置了 layout 时,使用 Ant Design 的 Descriptions 组件布局
31
32
  - 键名对应不同的屏幕尺寸(xs, sm, md, lg, xl, xxl)
32
33
  - 值为每行显示的列数
33
- - 建议根据字段宽度合理设置,避免一行过多字段导致布局问题
34
+ - 如果不配置 layout,则使用自适应流式布局
34
35
 
35
36
  ### 2. 样式配置 (style)
36
37
 
37
38
  ```json
38
39
  "style": {
39
- "size": "small",
40
- "fontSize": "14px",
41
- "bordered": false
40
+ "fontSize": "14px"
42
41
  }
43
42
  ```
44
43
 
45
- - `size`: 设置尺寸,可选值为 "default", "middle", "small"
46
44
  - `fontSize`: 控制文字大小
47
- - `bordered`: 是否显示边框
48
45
 
49
46
  ### 3. 字段配置 (items)
50
47
 
@@ -52,19 +49,13 @@
52
49
  "items": [
53
50
  {
54
51
  "field": "patientName",
55
- "style": {
56
- "minHeight": "24px",
57
- "width": "120px",
58
- "minWidth": "100px",
59
- "height": "24px"
60
- },
61
52
  "label": "患者",
53
+ "showAvatar": true,
62
54
  "avatar": {
63
55
  "size": 20,
64
56
  "background": "#5D5C5C",
65
57
  "icon": "user"
66
- },
67
- "showAvatar": true
58
+ }
68
59
  }
69
60
  ]
70
61
  ```
@@ -73,7 +64,6 @@
73
64
 
74
65
  - `field`: 字段名,用于从数据源获取值
75
66
  - `label`: 显示的标签名
76
- - `style`: 控制字段的样式(宽度、高度等)
77
67
  - `showAvatar`: 是否显示头像
78
68
  - `avatar`: 头像配置(仅当 showAvatar 为 true 时有效)
79
69
  - `size`: 头像大小
@@ -86,17 +76,18 @@
86
76
  "detailsConfig": {
87
77
  "buttonText": "详细",
88
78
  "buttonType": "link",
89
- "showAfterIndex": 5
79
+ "showAfterIndex": 6
90
80
  }
91
81
  ```
92
82
 
93
83
  - `buttonText`: 详情按钮显示的文本
94
84
  - `buttonType`: 按钮类型,可选值为 "default", "primary", "dashed", "link" 等
95
85
  - `showAfterIndex`: 控制在显示多少个字段后显示详情按钮
96
- - **重要说明**:
97
- - 只有明确配置了 `detailsConfig` 对象时,才会启用折叠功能
98
- - 如果没有配置 `detailsConfig`,将直接显示所有字段,不会出现详情按钮
99
- - 如果配置了 `detailsConfig` 但字段总数少于或等于 `showAfterIndex`,则不会显示详情按钮
86
+
87
+ **重要说明**:
88
+ - 只有明确配置了 `detailsConfig` 对象时,才会启用折叠功能
89
+ - 如果没有配置 `detailsConfig`,将直接显示所有字段,不会出现详情按钮
90
+ - 如果配置了 `detailsConfig` 但字段总数少于或等于 `showAfterIndex`,则不会显示详情按钮
100
91
 
101
92
  ### 5. 其他配置
102
93
 
@@ -132,56 +123,32 @@ export default {
132
123
 
133
124
  ```vue
134
125
  <template>
135
- <XHDescriptions
136
- queryParamsName="patientBasicInfoConfig"
137
- :parameter="{ patientId: '123456' }"
126
+ <XHDescriptions
127
+ queryParamsName="patientBasicInfoConfig"
128
+ :parameter="{ patientId: '123456' }"
138
129
  />
139
130
  </template>
140
131
  ```
141
132
 
142
133
  ## 特殊说明
143
134
 
144
- 1. **响应式布局**:
145
- - 组件会根据屏幕尺寸自动调整列数
146
- - 可在 `layout` 配置中自定义不同尺寸下的列数
147
- - 建议根据字段数量和宽度合理设置列数,例如字段较多时可减少列数
135
+ 1. **布局模式**:
136
+ - 配置了 `layout` 时:使用固定列数布局,每行显示指定数量的列
137
+ - 未配置 `layout` 时:使用自适应流式布局,根据内容自动换行
138
+ - 两种模式下详情按钮都固定在右上角
148
139
 
149
140
  2. **折叠/展开功能**:
150
141
  - 折叠功能只在明确配置了 `detailsConfig` 对象时启用
151
- - 没有配置 `detailsConfig` 时,会直接显示所有字段,不会出现详情按钮
142
+ - 没有配置 `detailsConfig` 时,会直接显示所有字段
152
143
  - 详情按钮会悬浮在组件右上角,点击可展开/收起全部字段
153
- - 按钮显示"详情"或"收起",会根据当前状态自动切换
154
144
 
155
145
  3. **空值处理**:
156
- - 当字段值为 `null`、`undefined` 或空字符串 `""` 时,该字段不会显示
146
+ - 当字段值为 `null`、`undefined` 时,该字段不会显示
157
147
  - 折叠功能会忽略空值的字段,只有有值的隐藏字段才会触发显示详情按钮
158
- - 这个特性可以用于根据数据动态控制字段的显示,无需修改配置
159
-
160
- 4. **字段重复问题处理**:
161
- - 组件已经优化处理了展开时的字段重复显示问题
162
- - 采用智能过滤机制,确保同一字段不会在多个位置显示
163
-
164
- ## 配置优化建议
165
-
166
- 1. **字段数量**:
167
- - 建议将最重要、最常用的信息放在前 `showAfterIndex` 个位置
168
- - 避免配置过多字段,通常不建议超过 20 个字段
169
- - 如有大量相关字段,考虑拆分为多个不同的描述组件
170
-
171
- 2. **布局优化**:
172
- - 根据字段的宽度调整 `layout` 配置
173
- - 较宽的字段(如地址、证件号等)可能需要更多的列宽
174
- - 建议在大屏幕下(xl, xxl)不要超过 4-5 列
175
-
176
- 3. **样式设置**:
177
- - 为了统一视觉效果,建议所有相似的描述组件使用统一的样式设置
178
- - 字段宽度设置合理的 `minWidth`,确保在各种屏幕下显示正常
179
148
 
180
149
  ## 配置示例
181
150
 
182
- ### 启用折叠功能示例
183
-
184
- 以下配置将启用折叠功能,只显示前6个字段,其余字段需点击"详细"按钮查看:
151
+ ### 固定列数布局示例
185
152
 
186
153
  ```json
187
154
  {
@@ -189,14 +156,12 @@ export default {
189
156
  "xl": 4,
190
157
  "md": 3,
191
158
  "sm": 2,
192
- "lg": 3,
159
+ "lg": 4,
193
160
  "xs": 1,
194
161
  "xxl": 5
195
162
  },
196
163
  "style": {
197
- "size": "small",
198
- "fontSize": "14px",
199
- "bordered": false
164
+ "fontSize": "14px"
200
165
  },
201
166
  "items": [
202
167
  {
@@ -216,67 +181,37 @@ export default {
216
181
  {
217
182
  "field": "diagnosisNo",
218
183
  "label": "诊号"
219
- },
220
- {
221
- "field": "gender",
222
- "label": "性别"
223
- },
224
- {
225
- "field": "age",
226
- "label": "年龄"
227
- },
228
- {
229
- "field": "diagnosis",
230
- "label": "诊断"
231
- },
232
- {
233
- "field": "phone_no",
234
- "label": "电话号码"
235
- },
236
- {
237
- "field": "identification_no",
238
- "label": "身份证号"
239
- },
240
- {
241
- "field": "allergies",
242
- "label": "过敏史"
243
184
  }
244
185
  // ... 更多字段
245
186
  ],
246
187
  "detailsConfig": {
247
188
  "buttonText": "详细",
248
189
  "buttonType": "link",
249
- "showAfterIndex": 6 // 设置为6表示只显示前6个字段,其余字段点击"详细"后显示
190
+ "showAfterIndex": 6
250
191
  },
251
192
  "logicName": "patientBasicInfoLogic",
252
193
  "serverName": "af-his"
253
194
  }
254
195
  ```
255
196
 
256
- ### 禁用折叠功能示例
257
-
258
- 如果不希望使用折叠功能,希望一次性显示所有字段,只需要移除 `detailsConfig` 对象:
197
+ ### 自适应流式布局示例
259
198
 
260
199
  ```json
261
200
  {
262
- "layout": {
263
- "xl": 4,
264
- "md": 3,
265
- "sm": 2,
266
- "lg": 3,
267
- "xs": 1,
268
- "xxl": 5
269
- },
270
201
  "style": {
271
- "size": "small",
272
- "fontSize": "14px",
273
- "bordered": false
202
+ "fontSize": "14px"
274
203
  },
275
204
  "items": [
276
- // 字段配置...
205
+ {
206
+ "field": "patientName",
207
+ "label": "患者"
208
+ },
209
+ {
210
+ "field": "patientType",
211
+ "label": "类别"
212
+ }
277
213
  ],
278
214
  "logicName": "patientBasicInfoLogic",
279
215
  "serverName": "af-his"
280
- // 没有 detailsConfig,将直接显示所有字段
281
216
  }
282
- ```
217
+ ```
@@ -14,9 +14,9 @@
14
14
  >
15
15
  <a-select-option v-for="item of resListCp" :key="item.value" :value="item.value">{{ item.label }}</a-select-option>
16
16
  </a-select>
17
- <template v-if="this.modeType !== 'readonly' && this.resId !== -1">
18
- <a-button icon="plus" @click="addRes"/>
19
- </template>
17
+ <!-- <template v-if="this.modeType !== 'readonly' && this.resId !== -1">-->
18
+ <!-- <a-button icon="plus" @click="addRes"/>-->
19
+ <!-- </template>-->
20
20
  </template>
21
21
  <a-radio-group
22
22
  v-show="showModeChoose"
@@ -6,6 +6,7 @@
6
6
  style="width: 150px"
7
7
  :allowClear="true"
8
8
  :showSearch="true"
9
+ :filter-option="filterOption"
9
10
  @change="handleChange"
10
11
  >
11
12
  <a-select-option v-for="(item, index) in data" :key="index" :value="item.value">
@@ -53,6 +54,9 @@ export default {
53
54
  this.selectedValue = value === '' ? undefined : value
54
55
  this.$emit('change', this.selectedValue)
55
56
  },
57
+ filterOption (input, option) {
58
+ return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
59
+ }
56
60
  },
57
61
  watch: {
58
62
  selectedValue (val) {