vue2-client 1.16.54 → 1.16.55
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 +112 -112
- package/src/assets/img/paymentMethod/icon1.png +0 -0
- package/src/assets/img/paymentMethod/icon2.png +0 -0
- package/src/assets/img/paymentMethod/icon3.png +0 -0
- package/src/assets/img/paymentMethod/icon4.png +0 -0
- package/src/assets/img/paymentMethod/icon5.png +0 -0
- package/src/assets/img/paymentMethod/icon6.png +0 -0
- package/src/assets/svg/female.svg +1 -1
- package/src/assets/svg/male.svg +1 -1
- package/src/base-client/components/common/HIS/HButtons/HButtons.vue +1 -1
- package/src/base-client/components/common/HIS/HFormGroup/HFormGroup.vue +120 -120
- package/src/base-client/components/common/HIS/HFormGroup/index.js +3 -3
- package/src/base-client/components/common/HIS/HFormTable/HFormTable.vue +379 -379
- package/src/base-client/components/common/HIS/HTab/HTab.vue +29 -2
- package/src/base-client/components/common/HIS/demo.vue +61 -61
- package/src/base-client/components/common/XCollapse/XCollapse.vue +461 -461
- package/src/base-client/components/common/XInput/XInput.vue +147 -147
- package/src/base-client/components/common/XReport/XReportHospitalizationDemo.vue +45 -0
- package/src/base-client/components/common/XReportGrid/XReportTrGroup.vue +824 -824
- package/src/base-client/components/common/XTable/XTable.vue +1610 -1610
- package/src/base-client/components/common/XTimeline/XTimeline.vue +454 -454
- package/src/base-client/components/his/XCharge/XCharge.vue +244 -86
- package/src/base-client/components/his/XCharge/XChargeDemo.vue +99 -3
- package/src/base-client/components/his/XCharge/testConfig.js +439 -0
- package/src/base-client/components/his/XHisEditor/XHisEditor.vue +705 -705
- package/src/base-client/components/his/XList/XList.vue +829 -829
- package/src/base-client/components/his/XTitle/XTitle.vue +16 -0
- package/src/base-client/components/his/threeTestOrders/editor.vue +113 -113
- package/src/pages/userInfoDetailManage/ExceptionRecordQuery/index.vue +45 -45
- package/src/router/async/router.map.js +132 -129
- package/src-base-client/components/his/XCharge/README.md +0 -0
- package/src-base-client/components/his/XCharge/XCharge.vue +0 -0
@@ -1,379 +1,379 @@
|
|
1
|
-
<script setup>
|
2
|
-
import XFormTable from '@vue2-client/base-client/components/common/XFormTable/XFormTable.vue'
|
3
|
-
import { ref, computed, useAttrs, nextTick } from 'vue'
|
4
|
-
|
5
|
-
const props = defineProps({
|
6
|
-
// HFormTable特有的属性
|
7
|
-
tableStyle: {
|
8
|
-
type: String,
|
9
|
-
default: 'formtable-col1'
|
10
|
-
}
|
11
|
-
})
|
12
|
-
|
13
|
-
// 兼容多种样式配置
|
14
|
-
const attrs = useAttrs()
|
15
|
-
const wrapperClassObject = computed(() => {
|
16
|
-
const a = attrs
|
17
|
-
const classes = {}
|
18
|
-
|
19
|
-
// 通用布尔样式开关(以存在/空字符串/'true' 为真)
|
20
|
-
const booleanStyleKeys = [
|
21
|
-
'button-row-0margin',
|
22
|
-
'top-hidden',
|
23
|
-
'dialog-style'
|
24
|
-
]
|
25
|
-
for (const key of booleanStyleKeys) {
|
26
|
-
const val = a[key]
|
27
|
-
const truthy = val === true || val === '' || val === 'true'
|
28
|
-
if (truthy) classes[`h-form-table-${key}`] = true
|
29
|
-
}
|
30
|
-
|
31
|
-
// 兼容通过 attrs 透传的分页样式:将值映射为当前样式中存在的类名
|
32
|
-
const paginationAttr = a && a.paginationStyle
|
33
|
-
if (paginationAttr && ['pagination-center', 'custom-pagination'].includes(paginationAttr)) {
|
34
|
-
classes[`h-form-table-${paginationAttr}`] = true
|
35
|
-
}
|
36
|
-
return classes
|
37
|
-
})
|
38
|
-
|
39
|
-
// 通过暴露的实例访问 $slots,避免直接依赖 Composition API 的 useSlots
|
40
|
-
// 在模板中使用 `$slots` 遍历以保持与 Vue2 兼容
|
41
|
-
// 创建对XFormTable组件的引用
|
42
|
-
const xFormTableRef = ref()
|
43
|
-
|
44
|
-
// 使用 MutationObserver 监听展开行高度变化,实时同步固定列
|
45
|
-
let observer = null
|
46
|
-
const setupHeightSync = () => {
|
47
|
-
try {
|
48
|
-
const wrapper = document.querySelector('.h-form-table-wrapper')
|
49
|
-
if (!wrapper || observer) return
|
50
|
-
|
51
|
-
observer = new MutationObserver((mutations) => {
|
52
|
-
// 只在展开行相关变化时同步,避免不必要的计算
|
53
|
-
const hasRelevantChange = mutations.some(mutation =>
|
54
|
-
mutation.type === 'attributes' &&
|
55
|
-
(mutation.attributeName === 'style' || mutation.attributeName === 'class') ||
|
56
|
-
mutation.type === 'childList'
|
57
|
-
)
|
58
|
-
if (hasRelevantChange) {
|
59
|
-
syncFixedExpandedHeights()
|
60
|
-
}
|
61
|
-
})
|
62
|
-
|
63
|
-
// 监听主表展开行的属性变化
|
64
|
-
const mainTable = wrapper.querySelector('.ant-table-body > table > tbody')
|
65
|
-
if (mainTable) {
|
66
|
-
observer.observe(mainTable, {
|
67
|
-
childList: true,
|
68
|
-
subtree: true,
|
69
|
-
attributes: true,
|
70
|
-
attributeFilter: ['style', 'class']
|
71
|
-
})
|
72
|
-
}
|
73
|
-
} catch (e) {
|
74
|
-
console.warn('[HFormTable] setupHeightSync error:', e)
|
75
|
-
}
|
76
|
-
}
|
77
|
-
|
78
|
-
// 同步固定列中的"展开行"高度到主表展开行高度,避免错位
|
79
|
-
const syncFixedExpandedHeights = () => {
|
80
|
-
try {
|
81
|
-
const wrapper = document.querySelector('.h-form-table-wrapper')
|
82
|
-
if (!wrapper) return
|
83
|
-
const mainRows = Array.from(wrapper.querySelectorAll('.ant-table-body > table > tbody > tr'))
|
84
|
-
const fixedRows = Array.from(wrapper.querySelectorAll('.ant-table-fixed-right .ant-table-body-inner > table > tbody > tr'))
|
85
|
-
const len = Math.min(mainRows.length, fixedRows.length)
|
86
|
-
|
87
|
-
for (let i = 0; i < len; i++) {
|
88
|
-
const m = mainRows[i]
|
89
|
-
const f = fixedRows[i]
|
90
|
-
if (!f) continue
|
91
|
-
|
92
|
-
if (m.classList.contains('ant-table-expanded-row')) {
|
93
|
-
const h = m.clientHeight
|
94
|
-
// 缓存高度,避免重复设置
|
95
|
-
if (f.dataset.syncedHeight === h.toString()) continue
|
96
|
-
f.dataset.syncedHeight = h.toString()
|
97
|
-
|
98
|
-
// 强制同步高度,使用 !important 覆盖其他样式
|
99
|
-
f.style.setProperty('height', h + 'px', 'important')
|
100
|
-
f.style.setProperty('min-height', h + 'px', 'important')
|
101
|
-
f.style.setProperty('max-height', h + 'px', 'important')
|
102
|
-
|
103
|
-
// 同步单元格高度,确保完全一致
|
104
|
-
const tds = f.querySelectorAll('td')
|
105
|
-
tds.forEach(td => {
|
106
|
-
td.style.setProperty('height', h + 'px', 'important')
|
107
|
-
td.style.setProperty('min-height', h + 'px', 'important')
|
108
|
-
td.style.setProperty('max-height', h + 'px', 'important')
|
109
|
-
td.style.setProperty('padding', '0', 'important')
|
110
|
-
td.style.setProperty('border', 'none', 'important')
|
111
|
-
})
|
112
|
-
} else {
|
113
|
-
// 清理非展开行的内联样式和缓存
|
114
|
-
if (f.dataset.syncedHeight) {
|
115
|
-
f.removeAttribute('data-synced-height')
|
116
|
-
f.style.removeProperty('height')
|
117
|
-
f.style.removeProperty('min-height')
|
118
|
-
f.style.removeProperty('max-height')
|
119
|
-
const tds = f.querySelectorAll('td')
|
120
|
-
tds.forEach(td => {
|
121
|
-
td.style.removeProperty('height')
|
122
|
-
td.style.removeProperty('min-height')
|
123
|
-
td.style.removeProperty('max-height')
|
124
|
-
td.style.removeProperty('padding')
|
125
|
-
td.style.removeProperty('border')
|
126
|
-
})
|
127
|
-
}
|
128
|
-
}
|
129
|
-
}
|
130
|
-
} catch (e) {
|
131
|
-
console.warn('[HFormTable] syncFixedExpandedHeights error:', e)
|
132
|
-
}
|
133
|
-
}
|
134
|
-
|
135
|
-
const onExpandLog = (expanded, record) => {
|
136
|
-
// 等DOM完成再测量
|
137
|
-
nextTick(() => {
|
138
|
-
// 设置实时监听(如果还没设置)
|
139
|
-
if (!observer) {
|
140
|
-
setupHeightSync()
|
141
|
-
}
|
142
|
-
|
143
|
-
// 立即同步一次(避免第一次展开时错位)
|
144
|
-
syncFixedExpandedHeights()
|
145
|
-
|
146
|
-
// 短延迟再同步一次(应对异步渲染)
|
147
|
-
setTimeout(() => {
|
148
|
-
syncFixedExpandedHeights()
|
149
|
-
}, 20)
|
150
|
-
})
|
151
|
-
}
|
152
|
-
|
153
|
-
// 暴露方法给父组件使用
|
154
|
-
defineExpose({
|
155
|
-
// 为了兼容性,保留getXFormTableInstance方法
|
156
|
-
getXFormTableInstance: () => xFormTableRef.value
|
157
|
-
})
|
158
|
-
|
159
|
-
// 计算是否使用自定义分页(兼容 attrs 透传与 tableStyle 配置)
|
160
|
-
const isCustomPagination = computed(() => {
|
161
|
-
const a = attrs
|
162
|
-
const paginationAttr = (a && a.paginationStyle) || ''
|
163
|
-
return props.tableStyle === 'custom-pagination' || paginationAttr === 'custom-pagination'
|
164
|
-
})
|
165
|
-
</script>
|
166
|
-
|
167
|
-
<template>
|
168
|
-
<div
|
169
|
-
class="h-form-table-wrapper"
|
170
|
-
:class="[
|
171
|
-
`h-form-table-${tableStyle}`,
|
172
|
-
wrapperClassObject
|
173
|
-
]"
|
174
|
-
>
|
175
|
-
<x-form-table
|
176
|
-
ref="xFormTableRef"
|
177
|
-
v-bind="$attrs"
|
178
|
-
:customPagination="isCustomPagination"
|
179
|
-
@expand="onExpandLog"
|
180
|
-
v-on="$listeners"
|
181
|
-
>
|
182
|
-
<template v-for="(_, name) in $slots" #[name]="slotData">
|
183
|
-
<slot :name="name" v-bind="slotData" />
|
184
|
-
</template>
|
185
|
-
</x-form-table>
|
186
|
-
</div>
|
187
|
-
</template>
|
188
|
-
|
189
|
-
<style scoped lang="less">
|
190
|
-
.h-form-table-wrapper {
|
191
|
-
// 基础样式
|
192
|
-
:deep(.table-wrapper) {
|
193
|
-
.ant-table {
|
194
|
-
.ant-table-row {
|
195
|
-
margin: 0px;
|
196
|
-
|
197
|
-
.ant-form-item {
|
198
|
-
margin: 0px;
|
199
|
-
|
200
|
-
.ant-form-item-control-wrapper {
|
201
|
-
.ant-form-item-control {
|
202
|
-
line-height: 0px;
|
203
|
-
|
204
|
-
.ant-select-selection--multiple {
|
205
|
-
padding-bottom: 2px;
|
206
|
-
}
|
207
|
-
}
|
208
|
-
width: 100%;
|
209
|
-
}
|
210
|
-
}
|
211
|
-
}
|
212
|
-
font-size: 16px;
|
213
|
-
}
|
214
|
-
|
215
|
-
.ant-alert-info {
|
216
|
-
display: none;
|
217
|
-
}
|
218
|
-
}
|
219
|
-
|
220
|
-
:deep(.ant-card) {
|
221
|
-
margin: -10px 0px 29px 0px;
|
222
|
-
}
|
223
|
-
|
224
|
-
:deep(.ant-btn) {
|
225
|
-
border: 0px;
|
226
|
-
box-shadow: none;
|
227
|
-
padding: 0px;
|
228
|
-
color: #5D5C5C;
|
229
|
-
font-weight: bold;
|
230
|
-
letter-spacing: 0em;
|
231
|
-
font-size: 18px;
|
232
|
-
line-height: normal;
|
233
|
-
font-family: "Source Han Sans";
|
234
|
-
}
|
235
|
-
|
236
|
-
:deep(.ant-card-body) {
|
237
|
-
padding: 0 6px;
|
238
|
-
}
|
239
|
-
|
240
|
-
:deep(.ant-table-small) {
|
241
|
-
border-width: 0;
|
242
|
-
|
243
|
-
.ant-table-fixed {
|
244
|
-
border-radius: 0;
|
245
|
-
border-bottom: 1px solid #f0f0f0;
|
246
|
-
}
|
247
|
-
}
|
248
|
-
|
249
|
-
// 表格高度样式
|
250
|
-
&.h-form-table-height {
|
251
|
-
:deep(.table-wrapper) {
|
252
|
-
.ant-select-open ~ .ant-table-content {
|
253
|
-
height: 500px !important;
|
254
|
-
}
|
255
|
-
}
|
256
|
-
}
|
257
|
-
|
258
|
-
// 表格样式
|
259
|
-
&.h-form-table-table {
|
260
|
-
:deep(.ant-table-small .ant-table-fixed-header) {
|
261
|
-
.ant-table-content {
|
262
|
-
.ant-table-content {
|
263
|
-
.ant-table-body {
|
264
|
-
border-radius: 0 0 4px 4px;
|
265
|
-
// 修复展开行后固定列与主体错位:保持表体滚动容器为自动滚动
|
266
|
-
overflow: auto !important;
|
267
|
-
}
|
268
|
-
}
|
269
|
-
}
|
270
|
-
}
|
271
|
-
}
|
272
|
-
// 移除之前隐藏固定列占位行的样式,保持与主体行数一致
|
273
|
-
// 展开行单元格去除额外内边距,避免高度不一致
|
274
|
-
:deep(.ant-table-expanded-row > td) {
|
275
|
-
padding: 0 !important;
|
276
|
-
}
|
277
|
-
// 展开内容中的表单/控件去掉外边距,避免撑高
|
278
|
-
:deep(.ant-table-expanded-row .ant-form-item) {
|
279
|
-
margin-bottom: 0 !important;
|
280
|
-
}
|
281
|
-
|
282
|
-
// 移除之前的隐藏固定列样式,避免展开/合并后操作列消失
|
283
|
-
&.h-form-table-dialog-style {
|
284
|
-
/* 选择前面的兄弟元素 */
|
285
|
-
:global(.ant-col.ant-col-24[name="trGroup"]:has(+ .ant-card .ant-card-body .h-form-table-wrapper.h-form-table-dialog-style)) {
|
286
|
-
padding-top: 0px !important;
|
287
|
-
padding-left: 0px !important;
|
288
|
-
}
|
289
|
-
|
290
|
-
:global(.ant-card-body:has(.h-form-table-wrapper.h-form-table-dialog-style)) {
|
291
|
-
padding-top: 0px !important;
|
292
|
-
padding-left: 0px !important;
|
293
|
-
}
|
294
|
-
}
|
295
|
-
// 隐藏按钮区域
|
296
|
-
&.h-form-table-button-area-hide {
|
297
|
-
:deep(.ant-btn) {
|
298
|
-
display: none;
|
299
|
-
}
|
300
|
-
|
301
|
-
:deep(.table-wrapper) {
|
302
|
-
margin-top: -39px;
|
303
|
-
}
|
304
|
-
}
|
305
|
-
|
306
|
-
// 顶部区域隐藏(与按钮隐藏一致的视觉需求)
|
307
|
-
&.h-form-table-top-hidden {
|
308
|
-
:deep(.ant-btn) {
|
309
|
-
display: none;
|
310
|
-
}
|
311
|
-
|
312
|
-
:deep(.table-wrapper) {
|
313
|
-
margin-top: -39px;
|
314
|
-
}
|
315
|
-
}
|
316
|
-
|
317
|
-
// 列样式1
|
318
|
-
&.h-form-table-formtable-col1 {
|
319
|
-
:deep(.table-wrapper) {
|
320
|
-
.ant-row {
|
321
|
-
.ant-col span {
|
322
|
-
border: none;
|
323
|
-
width: auto;
|
324
|
-
margin-bottom: auto;
|
325
|
-
}
|
326
|
-
}
|
327
|
-
|
328
|
-
.ant-table {
|
329
|
-
.ant-table-body {
|
330
|
-
.ant-table-fixed colgroup col:nth-child(2) {
|
331
|
-
width: 50px;
|
332
|
-
min-width: 50px;
|
333
|
-
}
|
334
|
-
}
|
335
|
-
|
336
|
-
.ant-table-header {
|
337
|
-
.ant-table-fixed colgroup col:nth-child(2) {
|
338
|
-
width: 50px;
|
339
|
-
min-width: 50px;
|
340
|
-
}
|
341
|
-
}
|
342
|
-
}
|
343
|
-
}
|
344
|
-
}
|
345
|
-
|
346
|
-
// 底部分页居中 & 自定义分页样式(共用样式)
|
347
|
-
&.h-form-table-bottom-center,
|
348
|
-
&.h-form-table-custom-pagination {
|
349
|
-
:deep(.table-wrapper) {
|
350
|
-
.ant-row-flex-start {
|
351
|
-
position: relative;
|
352
|
-
display: flex;
|
353
|
-
align-items: center;
|
354
|
-
margin-top: 12px !important;
|
355
|
-
height: 32px;
|
356
|
-
|
357
|
-
// 防止第一个子元素无限拉伸,影响分页居中
|
358
|
-
> :first-child {
|
359
|
-
flex: 0 0 auto;
|
360
|
-
}
|
361
|
-
|
362
|
-
// 将第二个子元素(分页)绝对居中
|
363
|
-
> :nth-child(2) {
|
364
|
-
position: absolute;
|
365
|
-
left: 50%;
|
366
|
-
transform: translateX(-50%);
|
367
|
-
}
|
368
|
-
}
|
369
|
-
}
|
370
|
-
}
|
371
|
-
|
372
|
-
// 按钮行0margin
|
373
|
-
&.h-form-table-button-row-0margin {
|
374
|
-
:deep(.ant-row) {
|
375
|
-
margin: 0px;
|
376
|
-
}
|
377
|
-
}
|
378
|
-
}
|
379
|
-
</style>
|
1
|
+
<script setup>
|
2
|
+
import XFormTable from '@vue2-client/base-client/components/common/XFormTable/XFormTable.vue'
|
3
|
+
import { ref, computed, useAttrs, nextTick } from 'vue'
|
4
|
+
|
5
|
+
const props = defineProps({
|
6
|
+
// HFormTable特有的属性
|
7
|
+
tableStyle: {
|
8
|
+
type: String,
|
9
|
+
default: 'formtable-col1'
|
10
|
+
}
|
11
|
+
})
|
12
|
+
|
13
|
+
// 兼容多种样式配置
|
14
|
+
const attrs = useAttrs()
|
15
|
+
const wrapperClassObject = computed(() => {
|
16
|
+
const a = attrs
|
17
|
+
const classes = {}
|
18
|
+
|
19
|
+
// 通用布尔样式开关(以存在/空字符串/'true' 为真)
|
20
|
+
const booleanStyleKeys = [
|
21
|
+
'button-row-0margin',
|
22
|
+
'top-hidden',
|
23
|
+
'dialog-style'
|
24
|
+
]
|
25
|
+
for (const key of booleanStyleKeys) {
|
26
|
+
const val = a[key]
|
27
|
+
const truthy = val === true || val === '' || val === 'true'
|
28
|
+
if (truthy) classes[`h-form-table-${key}`] = true
|
29
|
+
}
|
30
|
+
|
31
|
+
// 兼容通过 attrs 透传的分页样式:将值映射为当前样式中存在的类名
|
32
|
+
const paginationAttr = a && a.paginationStyle
|
33
|
+
if (paginationAttr && ['pagination-center', 'custom-pagination'].includes(paginationAttr)) {
|
34
|
+
classes[`h-form-table-${paginationAttr}`] = true
|
35
|
+
}
|
36
|
+
return classes
|
37
|
+
})
|
38
|
+
|
39
|
+
// 通过暴露的实例访问 $slots,避免直接依赖 Composition API 的 useSlots
|
40
|
+
// 在模板中使用 `$slots` 遍历以保持与 Vue2 兼容
|
41
|
+
// 创建对XFormTable组件的引用
|
42
|
+
const xFormTableRef = ref()
|
43
|
+
|
44
|
+
// 使用 MutationObserver 监听展开行高度变化,实时同步固定列
|
45
|
+
let observer = null
|
46
|
+
const setupHeightSync = () => {
|
47
|
+
try {
|
48
|
+
const wrapper = document.querySelector('.h-form-table-wrapper')
|
49
|
+
if (!wrapper || observer) return
|
50
|
+
|
51
|
+
observer = new MutationObserver((mutations) => {
|
52
|
+
// 只在展开行相关变化时同步,避免不必要的计算
|
53
|
+
const hasRelevantChange = mutations.some(mutation =>
|
54
|
+
mutation.type === 'attributes' &&
|
55
|
+
(mutation.attributeName === 'style' || mutation.attributeName === 'class') ||
|
56
|
+
mutation.type === 'childList'
|
57
|
+
)
|
58
|
+
if (hasRelevantChange) {
|
59
|
+
syncFixedExpandedHeights()
|
60
|
+
}
|
61
|
+
})
|
62
|
+
|
63
|
+
// 监听主表展开行的属性变化
|
64
|
+
const mainTable = wrapper.querySelector('.ant-table-body > table > tbody')
|
65
|
+
if (mainTable) {
|
66
|
+
observer.observe(mainTable, {
|
67
|
+
childList: true,
|
68
|
+
subtree: true,
|
69
|
+
attributes: true,
|
70
|
+
attributeFilter: ['style', 'class']
|
71
|
+
})
|
72
|
+
}
|
73
|
+
} catch (e) {
|
74
|
+
console.warn('[HFormTable] setupHeightSync error:', e)
|
75
|
+
}
|
76
|
+
}
|
77
|
+
|
78
|
+
// 同步固定列中的"展开行"高度到主表展开行高度,避免错位
|
79
|
+
const syncFixedExpandedHeights = () => {
|
80
|
+
try {
|
81
|
+
const wrapper = document.querySelector('.h-form-table-wrapper')
|
82
|
+
if (!wrapper) return
|
83
|
+
const mainRows = Array.from(wrapper.querySelectorAll('.ant-table-body > table > tbody > tr'))
|
84
|
+
const fixedRows = Array.from(wrapper.querySelectorAll('.ant-table-fixed-right .ant-table-body-inner > table > tbody > tr'))
|
85
|
+
const len = Math.min(mainRows.length, fixedRows.length)
|
86
|
+
|
87
|
+
for (let i = 0; i < len; i++) {
|
88
|
+
const m = mainRows[i]
|
89
|
+
const f = fixedRows[i]
|
90
|
+
if (!f) continue
|
91
|
+
|
92
|
+
if (m.classList.contains('ant-table-expanded-row')) {
|
93
|
+
const h = m.clientHeight
|
94
|
+
// 缓存高度,避免重复设置
|
95
|
+
if (f.dataset.syncedHeight === h.toString()) continue
|
96
|
+
f.dataset.syncedHeight = h.toString()
|
97
|
+
|
98
|
+
// 强制同步高度,使用 !important 覆盖其他样式
|
99
|
+
f.style.setProperty('height', h + 'px', 'important')
|
100
|
+
f.style.setProperty('min-height', h + 'px', 'important')
|
101
|
+
f.style.setProperty('max-height', h + 'px', 'important')
|
102
|
+
|
103
|
+
// 同步单元格高度,确保完全一致
|
104
|
+
const tds = f.querySelectorAll('td')
|
105
|
+
tds.forEach(td => {
|
106
|
+
td.style.setProperty('height', h + 'px', 'important')
|
107
|
+
td.style.setProperty('min-height', h + 'px', 'important')
|
108
|
+
td.style.setProperty('max-height', h + 'px', 'important')
|
109
|
+
td.style.setProperty('padding', '0', 'important')
|
110
|
+
td.style.setProperty('border', 'none', 'important')
|
111
|
+
})
|
112
|
+
} else {
|
113
|
+
// 清理非展开行的内联样式和缓存
|
114
|
+
if (f.dataset.syncedHeight) {
|
115
|
+
f.removeAttribute('data-synced-height')
|
116
|
+
f.style.removeProperty('height')
|
117
|
+
f.style.removeProperty('min-height')
|
118
|
+
f.style.removeProperty('max-height')
|
119
|
+
const tds = f.querySelectorAll('td')
|
120
|
+
tds.forEach(td => {
|
121
|
+
td.style.removeProperty('height')
|
122
|
+
td.style.removeProperty('min-height')
|
123
|
+
td.style.removeProperty('max-height')
|
124
|
+
td.style.removeProperty('padding')
|
125
|
+
td.style.removeProperty('border')
|
126
|
+
})
|
127
|
+
}
|
128
|
+
}
|
129
|
+
}
|
130
|
+
} catch (e) {
|
131
|
+
console.warn('[HFormTable] syncFixedExpandedHeights error:', e)
|
132
|
+
}
|
133
|
+
}
|
134
|
+
|
135
|
+
const onExpandLog = (expanded, record) => {
|
136
|
+
// 等DOM完成再测量
|
137
|
+
nextTick(() => {
|
138
|
+
// 设置实时监听(如果还没设置)
|
139
|
+
if (!observer) {
|
140
|
+
setupHeightSync()
|
141
|
+
}
|
142
|
+
|
143
|
+
// 立即同步一次(避免第一次展开时错位)
|
144
|
+
syncFixedExpandedHeights()
|
145
|
+
|
146
|
+
// 短延迟再同步一次(应对异步渲染)
|
147
|
+
setTimeout(() => {
|
148
|
+
syncFixedExpandedHeights()
|
149
|
+
}, 20)
|
150
|
+
})
|
151
|
+
}
|
152
|
+
|
153
|
+
// 暴露方法给父组件使用
|
154
|
+
defineExpose({
|
155
|
+
// 为了兼容性,保留getXFormTableInstance方法
|
156
|
+
getXFormTableInstance: () => xFormTableRef.value
|
157
|
+
})
|
158
|
+
|
159
|
+
// 计算是否使用自定义分页(兼容 attrs 透传与 tableStyle 配置)
|
160
|
+
const isCustomPagination = computed(() => {
|
161
|
+
const a = attrs
|
162
|
+
const paginationAttr = (a && a.paginationStyle) || ''
|
163
|
+
return props.tableStyle === 'custom-pagination' || paginationAttr === 'custom-pagination'
|
164
|
+
})
|
165
|
+
</script>
|
166
|
+
|
167
|
+
<template>
|
168
|
+
<div
|
169
|
+
class="h-form-table-wrapper"
|
170
|
+
:class="[
|
171
|
+
`h-form-table-${tableStyle}`,
|
172
|
+
wrapperClassObject
|
173
|
+
]"
|
174
|
+
>
|
175
|
+
<x-form-table
|
176
|
+
ref="xFormTableRef"
|
177
|
+
v-bind="$attrs"
|
178
|
+
:customPagination="isCustomPagination"
|
179
|
+
@expand="onExpandLog"
|
180
|
+
v-on="$listeners"
|
181
|
+
>
|
182
|
+
<template v-for="(_, name) in $slots" #[name]="slotData">
|
183
|
+
<slot :name="name" v-bind="slotData" />
|
184
|
+
</template>
|
185
|
+
</x-form-table>
|
186
|
+
</div>
|
187
|
+
</template>
|
188
|
+
|
189
|
+
<style scoped lang="less">
|
190
|
+
.h-form-table-wrapper {
|
191
|
+
// 基础样式
|
192
|
+
:deep(.table-wrapper) {
|
193
|
+
.ant-table {
|
194
|
+
.ant-table-row {
|
195
|
+
margin: 0px;
|
196
|
+
|
197
|
+
.ant-form-item {
|
198
|
+
margin: 0px;
|
199
|
+
|
200
|
+
.ant-form-item-control-wrapper {
|
201
|
+
.ant-form-item-control {
|
202
|
+
line-height: 0px;
|
203
|
+
|
204
|
+
.ant-select-selection--multiple {
|
205
|
+
padding-bottom: 2px;
|
206
|
+
}
|
207
|
+
}
|
208
|
+
width: 100%;
|
209
|
+
}
|
210
|
+
}
|
211
|
+
}
|
212
|
+
font-size: 16px;
|
213
|
+
}
|
214
|
+
|
215
|
+
.ant-alert-info {
|
216
|
+
display: none;
|
217
|
+
}
|
218
|
+
}
|
219
|
+
|
220
|
+
:deep(.ant-card) {
|
221
|
+
margin: -10px 0px 29px 0px;
|
222
|
+
}
|
223
|
+
|
224
|
+
:deep(.ant-btn) {
|
225
|
+
border: 0px;
|
226
|
+
box-shadow: none;
|
227
|
+
padding: 0px;
|
228
|
+
color: #5D5C5C;
|
229
|
+
font-weight: bold;
|
230
|
+
letter-spacing: 0em;
|
231
|
+
font-size: 18px;
|
232
|
+
line-height: normal;
|
233
|
+
font-family: "Source Han Sans";
|
234
|
+
}
|
235
|
+
|
236
|
+
:deep(.ant-card-body) {
|
237
|
+
padding: 0 6px;
|
238
|
+
}
|
239
|
+
|
240
|
+
:deep(.ant-table-small) {
|
241
|
+
border-width: 0;
|
242
|
+
|
243
|
+
.ant-table-fixed {
|
244
|
+
border-radius: 0;
|
245
|
+
border-bottom: 1px solid #f0f0f0;
|
246
|
+
}
|
247
|
+
}
|
248
|
+
|
249
|
+
// 表格高度样式
|
250
|
+
&.h-form-table-height {
|
251
|
+
:deep(.table-wrapper) {
|
252
|
+
.ant-select-open ~ .ant-table-content {
|
253
|
+
height: 500px !important;
|
254
|
+
}
|
255
|
+
}
|
256
|
+
}
|
257
|
+
|
258
|
+
// 表格样式
|
259
|
+
&.h-form-table-table {
|
260
|
+
:deep(.ant-table-small .ant-table-fixed-header) {
|
261
|
+
.ant-table-content {
|
262
|
+
.ant-table-content {
|
263
|
+
.ant-table-body {
|
264
|
+
border-radius: 0 0 4px 4px;
|
265
|
+
// 修复展开行后固定列与主体错位:保持表体滚动容器为自动滚动
|
266
|
+
overflow: auto !important;
|
267
|
+
}
|
268
|
+
}
|
269
|
+
}
|
270
|
+
}
|
271
|
+
}
|
272
|
+
// 移除之前隐藏固定列占位行的样式,保持与主体行数一致
|
273
|
+
// 展开行单元格去除额外内边距,避免高度不一致
|
274
|
+
:deep(.ant-table-expanded-row > td) {
|
275
|
+
padding: 0 !important;
|
276
|
+
}
|
277
|
+
// 展开内容中的表单/控件去掉外边距,避免撑高
|
278
|
+
:deep(.ant-table-expanded-row .ant-form-item) {
|
279
|
+
margin-bottom: 0 !important;
|
280
|
+
}
|
281
|
+
|
282
|
+
// 移除之前的隐藏固定列样式,避免展开/合并后操作列消失
|
283
|
+
&.h-form-table-dialog-style {
|
284
|
+
/* 选择前面的兄弟元素 */
|
285
|
+
:global(.ant-col.ant-col-24[name="trGroup"]:has(+ .ant-card .ant-card-body .h-form-table-wrapper.h-form-table-dialog-style)) {
|
286
|
+
padding-top: 0px !important;
|
287
|
+
padding-left: 0px !important;
|
288
|
+
}
|
289
|
+
|
290
|
+
:global(.ant-card-body:has(.h-form-table-wrapper.h-form-table-dialog-style)) {
|
291
|
+
padding-top: 0px !important;
|
292
|
+
padding-left: 0px !important;
|
293
|
+
}
|
294
|
+
}
|
295
|
+
// 隐藏按钮区域
|
296
|
+
&.h-form-table-button-area-hide {
|
297
|
+
:deep(.ant-btn) {
|
298
|
+
display: none;
|
299
|
+
}
|
300
|
+
|
301
|
+
:deep(.table-wrapper) {
|
302
|
+
margin-top: -39px;
|
303
|
+
}
|
304
|
+
}
|
305
|
+
|
306
|
+
// 顶部区域隐藏(与按钮隐藏一致的视觉需求)
|
307
|
+
&.h-form-table-top-hidden {
|
308
|
+
:deep(.ant-btn) {
|
309
|
+
display: none;
|
310
|
+
}
|
311
|
+
|
312
|
+
:deep(.table-wrapper) {
|
313
|
+
margin-top: -39px;
|
314
|
+
}
|
315
|
+
}
|
316
|
+
|
317
|
+
// 列样式1
|
318
|
+
&.h-form-table-formtable-col1 {
|
319
|
+
:deep(.table-wrapper) {
|
320
|
+
.ant-row {
|
321
|
+
.ant-col span {
|
322
|
+
border: none;
|
323
|
+
width: auto;
|
324
|
+
margin-bottom: auto;
|
325
|
+
}
|
326
|
+
}
|
327
|
+
|
328
|
+
.ant-table {
|
329
|
+
.ant-table-body {
|
330
|
+
.ant-table-fixed colgroup col:nth-child(2) {
|
331
|
+
width: 50px;
|
332
|
+
min-width: 50px;
|
333
|
+
}
|
334
|
+
}
|
335
|
+
|
336
|
+
.ant-table-header {
|
337
|
+
.ant-table-fixed colgroup col:nth-child(2) {
|
338
|
+
width: 50px;
|
339
|
+
min-width: 50px;
|
340
|
+
}
|
341
|
+
}
|
342
|
+
}
|
343
|
+
}
|
344
|
+
}
|
345
|
+
|
346
|
+
// 底部分页居中 & 自定义分页样式(共用样式)
|
347
|
+
&.h-form-table-bottom-center,
|
348
|
+
&.h-form-table-custom-pagination {
|
349
|
+
:deep(.table-wrapper) {
|
350
|
+
.ant-row-flex-start {
|
351
|
+
position: relative;
|
352
|
+
display: flex;
|
353
|
+
align-items: center;
|
354
|
+
margin-top: 12px !important;
|
355
|
+
height: 32px;
|
356
|
+
|
357
|
+
// 防止第一个子元素无限拉伸,影响分页居中
|
358
|
+
> :first-child {
|
359
|
+
flex: 0 0 auto;
|
360
|
+
}
|
361
|
+
|
362
|
+
// 将第二个子元素(分页)绝对居中
|
363
|
+
> :nth-child(2) {
|
364
|
+
position: absolute;
|
365
|
+
left: 50%;
|
366
|
+
transform: translateX(-50%);
|
367
|
+
}
|
368
|
+
}
|
369
|
+
}
|
370
|
+
}
|
371
|
+
|
372
|
+
// 按钮行0margin
|
373
|
+
&.h-form-table-button-row-0margin {
|
374
|
+
:deep(.ant-row) {
|
375
|
+
margin: 0px;
|
376
|
+
}
|
377
|
+
}
|
378
|
+
}
|
379
|
+
</style>
|