vue2-client 1.12.56 → 1.12.58-chengran

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.
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <div>
2
+ <div class="reportGridMain" ref="reportGridMain">
3
3
  <template v-if="isWidget">
4
4
  <!-- 插槽展示 -->
5
5
  <x-report-tr-group
@@ -194,6 +194,222 @@ export default {
194
194
 
195
195
  forceUpdate()
196
196
  },
197
+ applyAllStyles () {
198
+ // 应用组件样式
199
+ const component = this.$refs.reportGridMain
200
+ // 确保组件已经完全挂载
201
+ this.$nextTick(() => {
202
+ this.applyComponentStyles(component)
203
+ })
204
+ },
205
+ // 获取组件样式配置
206
+ async getComponentStyleConfig (componentType) {
207
+ try {
208
+ // 从配置中获取样式定义
209
+ const styleConfig = this.$appdata.getStylesByKey(componentType)
210
+ return styleConfig || {}
211
+ } catch (error) {
212
+ console.error('获取组件样式配置失败:', error)
213
+ return {}
214
+ }
215
+ },
216
+
217
+ // 解析组件样式配置
218
+ async parseComponentStyles (cell) {
219
+ if (!cell.class) return { rootStyles: {}, childStyles: {} }
220
+
221
+ const styleConfig = await this.getComponentStyleConfig('reportGridMain')
222
+ if (!styleConfig) return { rootStyles: {}, childStyles: {} }
223
+
224
+ const rootStyles = {}
225
+ const childStyles = new Map()
226
+
227
+ // 处理每个class配置
228
+ cell.class.split(' ').forEach(className => {
229
+ const classConfig = styleConfig[className]
230
+ if (!classConfig) return
231
+
232
+ // 处理根节点样式
233
+ Object.entries(classConfig).forEach(([key, value]) => {
234
+ if (!key.startsWith('*') && typeof key !== 'object') {
235
+ rootStyles[key] = value
236
+ }
237
+ })
238
+
239
+ // 处理子节点样式
240
+ this.parseNestedStyles(classConfig, childStyles)
241
+ })
242
+
243
+ console.warn('样式配置', rootStyles, childStyles)
244
+ return {
245
+ rootStyles,
246
+ childStyles
247
+ }
248
+ },
249
+
250
+ // 递归解析嵌套的样式配置
251
+ parseNestedStyles (config, styleMap, parentKey = '') {
252
+ Object.entries(config).forEach(([key, value]) => {
253
+ if (!key.startsWith('*')) return
254
+
255
+ const className = key.replace('*', '.')
256
+
257
+ // 如果值是对象,检查是否包含样式和子节点
258
+ if (typeof value === 'object') {
259
+ const { style = {}, children = {} } = this.separateStyleAndChildren(value)
260
+
261
+ // 创建或获取当前节点的样式配置
262
+ if (!styleMap.has(className)) {
263
+ styleMap.set(className, {
264
+ styles: {},
265
+ children: new Map()
266
+ })
267
+ }
268
+
269
+ const nodeData = styleMap.get(className)
270
+
271
+ // 合并样式
272
+ Object.assign(nodeData.styles, style)
273
+
274
+ // 递归处理子节点
275
+ this.parseNestedStyles(children, nodeData.children, className)
276
+ }
277
+ })
278
+ },
279
+
280
+ // 分离样式属性和子节点配置
281
+ separateStyleAndChildren (obj) {
282
+ const style = {}
283
+ const children = {}
284
+
285
+ Object.entries(obj).forEach(([key, value]) => {
286
+ if (key.startsWith('*')) {
287
+ // 子节点配置
288
+ children[key] = value
289
+ } else {
290
+ // 样式属性
291
+ style[key] = value
292
+ }
293
+ })
294
+
295
+ return { style, children }
296
+ },
297
+
298
+ // 应用组件样式
299
+ async applyComponentStyles (component) {
300
+ if (!component) return
301
+
302
+ const { rootStyles, childStyles } = await this.parseComponentStyles(this.activatedConfig)
303
+
304
+ // 应用根节点样式
305
+ if (Object.keys(rootStyles).length > 0) {
306
+ Object.entries(rootStyles).forEach(([property, value]) => {
307
+ component.style.setProperty(property, value, 'important')
308
+ })
309
+ }
310
+
311
+ // 如果没有子节点样式,直接返回
312
+ if (childStyles.size === 0) return
313
+
314
+ let retryCount = 0
315
+ const maxRetries = 5
316
+ const retryInterval = 100 // 100ms
317
+
318
+ const applyStyles = () => {
319
+ this.applyChildStylesOptimized(component, childStyles)
320
+ }
321
+
322
+ // 首次应用样式
323
+ applyStyles()
324
+
325
+ // 创建重试机制
326
+ const retryApplyStyles = () => {
327
+ if (retryCount >= maxRetries) return
328
+
329
+ setTimeout(() => {
330
+ applyStyles()
331
+ retryCount++
332
+ retryApplyStyles()
333
+ }, retryInterval)
334
+ }
335
+
336
+ // 开始重试
337
+ retryApplyStyles()
338
+
339
+ // 创建 MutationObserver 用于动态内容
340
+ const observer = new MutationObserver((mutations) => {
341
+ // 检查是否有新增节点
342
+ const hasNewNodes = mutations.some(mutation =>
343
+ mutation.type === 'childList' && mutation.addedNodes.length > 0
344
+ )
345
+
346
+ if (hasNewNodes) {
347
+ applyStyles()
348
+ }
349
+ })
350
+
351
+ // 配置 observer
352
+ observer.observe(component, {
353
+ childList: true,
354
+ subtree: true,
355
+ attributes: false
356
+ })
357
+
358
+ // 3秒后停止观察
359
+ setTimeout(() => {
360
+ observer.disconnect()
361
+ }, 3000)
362
+
363
+ // 组件销毁时清理
364
+ this.$once('hook:beforeDestroy', () => {
365
+ observer.disconnect()
366
+ })
367
+ },
368
+
369
+ // 优化后的子节点样式应用方法
370
+ applyChildStylesOptimized (rootElement, styleMap, parentSelector = '') {
371
+ if (!rootElement) return
372
+
373
+ // 处理样式映射
374
+ for (const [selector, data] of styleMap.entries()) {
375
+ const currentSelector = parentSelector ? `${parentSelector} ${selector}` : selector
376
+
377
+ try {
378
+ // 查找匹配的元素
379
+ const elements = Array.from(rootElement.querySelectorAll(currentSelector))
380
+
381
+ if (!elements.length) continue
382
+
383
+ // 应用当前层级样式
384
+ if (data.styles) {
385
+ elements.forEach(element => {
386
+ if (!element) return
387
+
388
+ // 应用每个样式属性
389
+ Object.entries(data.styles).forEach(([property, value]) => {
390
+ try {
391
+ element.style.setProperty(property, value, 'important')
392
+ } catch (err) {
393
+ console.warn(`设置样式失败: ${property}=${value}`, err)
394
+ }
395
+ })
396
+ })
397
+ }
398
+
399
+ // 处理子层级
400
+ if (data.children && data.children.size > 0) {
401
+ elements.forEach(element => {
402
+ if (element) {
403
+ this.applyChildStylesOptimized(element, data.children, currentSelector)
404
+ }
405
+ })
406
+ }
407
+ } catch (err) {
408
+ console.warn(`处理选择器失败: ${currentSelector}`, err)
409
+ continue
410
+ }
411
+ }
412
+ },
197
413
  },
198
414
  created () {
199
415
  console.log('>>>> xreportdesign 渲染', JSON.stringify(this.config, null, 2))
@@ -209,6 +425,7 @@ export default {
209
425
  this.activatedConfig = this.config
210
426
  this.render = true
211
427
  }
428
+
212
429
  this.activatedConfig.columns.forEach(row => {
213
430
  if (row[0] && row[0].type && row[0].type === 'list' && row[0].listLength === 1) {
214
431
  row.forEach(cell => {
@@ -218,6 +435,7 @@ export default {
218
435
  })
219
436
  },
220
437
  mounted () {
438
+ this.applyAllStyles()
221
439
  },
222
440
  watch: {
223
441
  config: {
@@ -25,7 +25,7 @@
25
25
  </template>
26
26
  <template v-else-if="cell.type === 'slot'">
27
27
  <template
28
- v-if="['x-form-table','x-add-native-form','x-tree-pro', 'x-his-editor', 'x-tab', 'x-form-group', 'x-report', 'x-buttons', 'x-label-select', 'x-conversation', 'x-check-list', 'x-cardSet', 'x-collapse','x-h-descriptions', 'x-sidebar'].includes(cell.slotType)">
28
+ v-if="['x-form-table','x-add-native-form','x-tree-pro', 'x-his-editor', 'x-tab', 'x-form-group', 'x-report', 'x-buttons', 'x-label-select', 'x-conversation', 'x-check-list', 'x-cardSet', 'x-collapse','x-h-descriptions', 'x-sidebar', 'x-list'].includes(cell.slotType)">
29
29
  <component
30
30
  :is="getComponentName(cell.slotConfig, cell.serviceName, cell.slotType)"
31
31
  :key="cellIndex"
@@ -60,7 +60,7 @@
60
60
  </template>
61
61
  <template v-else-if="cell.type === 'slot'">
62
62
  <template
63
- v-if="['x-form-table','x-add-native-form','x-tree-pro', 'x-his-editor', 'x-tab', 'x-form-group', 'x-report', 'x-buttons', 'x-label-select', 'x-conversation', 'x-check-list', 'x-cardSet', 'x-collapse', 'x-h-descriptions', 'x-sidebar'].includes(cell.slotType)">
63
+ v-if="['x-form-table','x-add-native-form','x-tree-pro', 'x-his-editor', 'x-tab', 'x-form-group', 'x-report', 'x-buttons', 'x-label-select', 'x-conversation', 'x-check-list', 'x-cardSet', 'x-collapse', 'x-h-descriptions', 'x-sidebar', 'x-list'].includes(cell.slotType)">
64
64
  <component
65
65
  :is="getComponentName(cell.slotConfig, cell.serviceName, cell.slotType)"
66
66
  :key="cellIndex"
@@ -108,6 +108,7 @@ export default {
108
108
  XCollapse: () => import('@vue2-client/base-client/components/common/XCollapse/XCollapse.vue'),
109
109
  XHDescriptions: () => import('@vue2-client/base-client/components/his/XHDescriptions/XHDescriptions.vue'),
110
110
  XSidebar: () => import('@vue2-client/base-client/components/his/XSidebar/XSidebar.vue'),
111
+ XList: () => import('@vue2-client/base-client/components/his/XList/XList.vue'),
111
112
  },
112
113
  props: {
113
114
  // 每一行的配置
@@ -149,7 +149,14 @@
149
149
  </a-row>
150
150
  <!-- 如果当前是表格模式 -->
151
151
  <template v-if="isTableMode">
152
- <x-table-wrapper ref="table"></x-table-wrapper>
152
+ <x-table-wrapper ref="table">
153
+ <template slot="footer">
154
+ <slot
155
+ name="footer"
156
+ :selectedRowKeys="selectedRowKeys"
157
+ :selectedRows="selectedRows"></slot>
158
+ </template>
159
+ </x-table-wrapper>
153
160
  </template>
154
161
  <!-- 如果当前是看板模式 -->
155
162
  <template v-else>
@@ -0,0 +1,80 @@
1
+ <template>
2
+ <div class="list-wrapper" @click="handleClick">
3
+ <a-list size="large" :data-source="data" itemLayout="horizontal" class="list-container">
4
+ <a-list-item slot="renderItem" slot-scope="item" class="list-item">
5
+ {{ item.number }} {{ item.name }}
6
+ </a-list-item>
7
+ </a-list>
8
+ </div>
9
+ </template>
10
+
11
+ <script>
12
+
13
+ export default {
14
+ name: 'XList',
15
+ data () {
16
+ return {
17
+ data: []
18
+ }
19
+ },
20
+ props: {
21
+ listData: {
22
+ type: Array,
23
+ default: []
24
+ }
25
+ },
26
+ methods: {
27
+ handleClick () {
28
+ this.$emit('listClick', {})
29
+ }
30
+ },
31
+ watch: {
32
+ listData: {
33
+ handler () {
34
+ this.$forceUpdate()
35
+ },
36
+ deep: true
37
+ }
38
+ }
39
+ }
40
+ </script>
41
+
42
+ <style scoped>
43
+ .list-wrapper {
44
+ max-height: 240px;
45
+ overflow-y: auto;
46
+ cursor: pointer;
47
+ }
48
+
49
+ .list-container {
50
+ width: 100%;
51
+ }
52
+
53
+ .list-item {
54
+ height: 35px;
55
+ border-radius: 6px;
56
+ background-color: #F4F4F4;
57
+ padding: 8px 15px 7px 15px;
58
+ font-size: 16px;
59
+ display: flex;
60
+ align-items: center;
61
+ width: 100%;
62
+ border: 1px solid #D9D9D9;
63
+ box-sizing: border-box;
64
+ margin-bottom: 16px;
65
+ }
66
+
67
+ /* 自定义滚动条样式 */
68
+ .list-wrapper::-webkit-scrollbar {
69
+ width: 6px;
70
+ }
71
+
72
+ .list-wrapper::-webkit-scrollbar-thumb {
73
+ background-color: #d9d9d9;
74
+ border-radius: 3px;
75
+ }
76
+
77
+ .list-wrapper::-webkit-scrollbar-track {
78
+ background-color: #f0f0f0;
79
+ }
80
+ </style>
@@ -167,8 +167,8 @@ export default {
167
167
  transform: translateY(-50%);
168
168
  width: 24px;
169
169
  height: 48px;
170
- background-color: #fff;
171
170
  cursor: pointer;
171
+ background-color: rgba(255, 255, 255, 0) !important;
172
172
  display: flex;
173
173
  align-items: center;
174
174
  justify-content: center;
@@ -194,6 +194,5 @@ export default {
194
194
  }
195
195
  .drawer-content {
196
196
  height: 100%;
197
- overflow-y: auto;
198
197
  }
199
198
  </style>
@@ -118,7 +118,7 @@ const GetAppDataService = {
118
118
  return object[key]
119
119
  },
120
120
  getStylesByKey (key) {
121
- const str = localStorage.getItem(process.env.VUE_APP_STYLES_KEY)
121
+ const str = localStorage.getItem(process.env.VUE_APP_WEB_STYLES_KEY)
122
122
  const object = JSON.parse(str)
123
123
  return object[key]
124
124
  },
@@ -144,7 +144,7 @@ const loginGen = async function (response) {
144
144
 
145
145
  Vue.$store.commit('account/setLogin', login)
146
146
  }
147
- const GetLoginInfoService = {
147
+ const GetLoginInfoService = {
148
148
  install (Vue) {
149
149
  // 给vue增添对话框显示方法
150
150
  Vue.$login = Vue.prototype.$login = GetLoginInfoService
@@ -100,8 +100,8 @@ export default {
100
100
  methods: {
101
101
  preview () {
102
102
  if (this.compatible === 'OA') {
103
- this.previewDocService = 'http://aote-office.8866.org:8406'
104
- this.fileServer = 'http://aote-office.8866.org:32510/onlinePreview?url='
103
+ this.fileServer = 'http://aote-office.8866.org:8406'
104
+ this.previewDocService = 'http://aote-office.8866.org:32510/onlinePreview?url='
105
105
  this.previewGen()
106
106
  return
107
107
  }
@@ -130,11 +130,6 @@ export default {
130
130
  this.playerOptions.sources[0].src = this.path
131
131
  this.showImagePreview = 3
132
132
  } else {
133
- if (this.path.startsWith('http')) {
134
- this.previewDocUrl = this.path
135
- this.showImagePreview = 1
136
- return
137
- }
138
133
  const previewDocUrl = this.previewDocService + encodeURIComponent(Base64.encode(this.fileServer + this.path))
139
134
  if (this.previewDocUrl !== previewDocUrl) {
140
135
  this.previewDocLoading = true
@@ -368,7 +368,6 @@ export default {
368
368
  const isCurrentRow = isRowKeySequence
369
369
  ? this.clickedRowKey === index
370
370
  : this.clickedRowKey === record[this.rowKey]
371
- console.log(record, index, this.rowKey, isCurrentRow)
372
371
  return {
373
372
  on: {
374
373
  click: () => this.handleRowClick(record, index)