ylwl-cpscoms 1.1.0 → 1.3.0

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 (40) hide show
  1. package/es/SlForm/index.vue.js +1 -1
  2. package/es/SlForm/index.vue3.js +1 -1
  3. package/package.json +7 -4
  4. package/src/DtTable/DtTable/347/273/204/344/273/266/344/275/277/347/224/250/346/226/207/346/241/243.md +0 -819
  5. package/src/DtTable/index.vue +0 -779
  6. package/src/SlAlert/SlAlert.stories.js +0 -108
  7. package/src/SlAlert/index.vue +0 -55
  8. package/src/SlAlert/remark.md +0 -16
  9. package/src/SlDescriptions/SlDescriptions.stories.js +0 -119
  10. package/src/SlDescriptions/index.vue +0 -60
  11. package/src/SlDescriptions/renderOptions.vue +0 -27
  12. package/src/SlDialog/README-PLUS.md +0 -74
  13. package/src/SlDialog/README.md +0 -114
  14. package/src/SlDialog/dialogPlus.js +0 -160
  15. package/src/SlDialog/index.js +0 -170
  16. package/src/SlDrawer/SlDrawer.stories.js +0 -154
  17. package/src/SlDrawer/index.js +0 -62
  18. package/src/SlForm/SlForm.stories.js +0 -120
  19. package/src/SlForm/index.vue +0 -506
  20. package/src/SlForm/mixinRender.js +0 -228
  21. package/src/SlForm/otherItem/titleItem.vue +0 -31
  22. package/src/SlForm/remark.md +0 -607
  23. package/src/SlGuide/SlGuide.stories.js +0 -100
  24. package/src/SlGuide/index.vue +0 -166
  25. package/src/SlGuide/remark.md +0 -90
  26. package/src/SlMessageBox/index.js +0 -35
  27. package/src/SlPage/README.md +0 -515
  28. package/src/SlPage/SlPage.stories.js +0 -125
  29. package/src/SlPage/index.vue +0 -303
  30. package/src/SlPage/remark.md +0 -283
  31. package/src/SlTable/SlTable.stories.js +0 -118
  32. package/src/SlTable/components/colSetting.vue +0 -86
  33. package/src/SlTable/index.vue +0 -541
  34. package/src/SlTitle/SlTitle.stories.js +0 -98
  35. package/src/SlTitle/index.vue +0 -49
  36. package/src/global.css +0 -5
  37. package/src/index.js +0 -49
  38. package/src/store/index.js +0 -20
  39. package/src/utils/index.js +0 -47
  40. package/src/utils/tableConfig.js +0 -33
@@ -1,779 +0,0 @@
1
- <!-- eslint-disable vue/no-use-v-if-with-v-for -->
2
- <template>
3
- <div class="dt_table">
4
- <!-- 表格 -->
5
- <el-form ref="formRef" :model="formModel" :rules="formRules" :validate-on-rule-change="false" size="small">
6
- <el-table
7
- ref="tableRef"
8
- :data="formModel.tableData"
9
- :style="{
10
- width: gridOptions.scroll && gridOptions.scroll.x ? `${gridOptions.scroll.x}` : '100%',
11
- minWidth: '100%'
12
- }"
13
- size="small"
14
- border
15
- :max-height="(gridOptions.scroll && gridOptions.scroll.y) || 400"
16
- :min-height="(gridOptions.scroll && gridOptions.scroll.y) || 400"
17
- v-bind="$attrs"
18
- @selection-change="handleSelectionChange"
19
- >
20
- <!-- 空状态 -->
21
- <template slot="empty">
22
- <el-empty description="暂无数据" />
23
- </template>
24
-
25
- <!-- 多选列 -->
26
- <el-table-column
27
- v-if="hasSelectionColumn"
28
- type="selection"
29
- width="55"
30
- align="center"
31
- />
32
-
33
- <!-- 数据列 -->
34
- <el-table-column v-for="column in gridOptions.columns" v-if="!column.hidden && column.field !== 'selection'" :key="column.field" :label="column.title" :prop="column.field" v-bind="column.attrs || {}">
35
- <!-- 自定义表头 -->
36
- <template slot="header">
37
- <span class="dt_table_header">
38
- <span v-if="column.rules" class="dt_required_dot">*</span>
39
- {{ column.title }}
40
- </span>
41
- </template>
42
-
43
- <!-- 单元格内容 -->
44
- <template slot-scope="scope">
45
- <!-- 自定义渲染 -->
46
- <template v-if="column.editor === 'custom' && column.render">
47
- <template v-if="isVNode(callRender(column, scope))">
48
- <vnode-component :vnode="callRender(column, scope)" />
49
- </template>
50
- <template v-else>
51
- {{ callRender(column, scope) }}
52
- </template>
53
- </template>
54
-
55
- <!-- 表单编辑器 -->
56
- <template v-else>
57
- <el-form-item :prop="`tableData.${scope.$index}.${column.field}`" :rules="column.rules">
58
- <!-- 选择器 -->
59
- <el-select v-if="column.editor === 'select'" v-model="scope.row[column.field]" :placeholder="column.placeholder || '请选择'" :disabled="getFieldDisabled(column, scope.row, scope.$index)" :remote="column.remote" :loading="scope.row[`${column.field}Loading`]" :filterable="true" v-bind="column.attrs || {}" @change="(value) => handleSelectChange(column, value, scope.row, scope.$index)" @focus="(event) => handleFocus(column, event, scope.row)" @blur="(event) => handleBlur(column, event, scope.row, scope.$index)" @clear="handleClear(column, scope.row, scope.$index)">
60
- <el-option v-for="option in getOptions(column, scope.row)" :key="option.value" :label="column.labelKey ? option[column.labelKey] : option.label" :value="column.valueKey ? option[column.valueKey] : option.value" />
61
- </el-select>
62
-
63
- <!-- 输入框 -->
64
- <el-input v-else-if="column.editor === 'input'" v-model="scope.row[column.field]" :placeholder="column.placeholder || '请输入'" :disabled="getFieldDisabled(column, scope.row, scope.$index)" v-bind="column.attrs || {}" @change="(value) => handleInputChange(column, value, scope.row, scope.$index)" @focus="(event) => handleFocus(column, event, scope.row)" @blur="(event) => handleBlur(column, event, scope.row, scope.$index)" />
65
-
66
- <!-- 数字输入框 -->
67
- <div v-else-if="column.editor === 'input-number'" style="display: flex; justify-content: space-between; align-items: center">
68
- <el-input-number v-model="scope.row[column.field]" :placeholder="column.placeholder || '请输入数字'" :disabled="getFieldDisabled(column, scope.row, scope.$index)" :min="getMinValue(column, scope.row, scope.$index)" :max="getMaxValue(column, scope.row, scope.$index)" :step="column.step || 1" :precision="column.precision" :controls-position="column.controlsPosition || ''" style="width: 100%" v-bind="column.attrs || {}" @change="(value) => handleInputNumberChange(column, value, scope.row, scope.$index)" @focus="(event) => handleFocus(column, event, scope.row)" @blur="(event) => handleBlur(column, event, scope.row, scope.$index)" />
69
- <component :is="getAppendComponent(column, scope)" />
70
- </div>
71
-
72
- <!-- 开关 -->
73
- <el-switch v-else-if="column.editor === 'switch'" v-model="scope.row[column.field]" :disabled="getFieldDisabled(column, scope.row, scope.$index)" @change="(value) => handleSwitchChange(column, value, scope.row, scope.$index)" />
74
-
75
- <!-- 时间选择器 -->
76
- <el-time-picker v-else-if="column.editor === 'time'" v-model="scope.row[column.field]" :placeholder="column.placeholder || '选择时间'" :disabled="getFieldDisabled(column, scope.row, scope.$index)" v-bind="column.attrs || {}" @change="(value) => handleTimeChange(column, value, scope.row, scope.$index)" @focus="(event) => handleFocus(column, event, scope.row)" @blur="(event) => handleBlur(column, event, scope.row, scope.$index)" @clear="handleClear(column, scope.row, scope.$index)" />
77
-
78
- <!-- 日期选择器 -->
79
- <el-date-picker v-else-if="column.editor === 'date'" v-model="scope.row[column.field]" :placeholder="column.placeholder || '选择日期'" :disabled="getFieldDisabled(column, scope.row, scope.$index)" v-bind="column.attrs || {}" @change="(value) => handleDateChange(column, value, scope.row, scope.$index)" @focus="(event) => handleFocus(column, event, scope.row)" @blur="(event) => handleBlur(column, event, scope.row, scope.$index)" @clear="handleClear(column, scope.row, scope.$index)" />
80
-
81
- <!-- 日期时间选择器 -->
82
- <el-date-picker v-else-if="column.editor === 'datetime'" v-model="scope.row[column.field]" type="datetime" :placeholder="column.placeholder || '选择日期时间'" :disabled="getFieldDisabled(column, scope.row, scope.$index)" v-bind="column.attrs || {}" @change="(value) => handleDateTimeChange(column, value, scope.row, scope.$index)" @focus="(event) => handleFocus(column, event, scope.row)" @blur="(event) => handleBlur(column, event, scope.row, scope.$index)" @clear="handleClear(column, scope.row, scope.$index)" />
83
-
84
- <!-- 日期范围选择器 -->
85
- <el-date-picker v-else-if="column.editor === 'daterange'" v-model="scope.row[column.field]" type="daterange" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期" :placeholder="column.placeholder || '选择日期范围'" :disabled="getFieldDisabled(column, scope.row, scope.$index)" value-format="yyyy-MM-dd" v-bind="column.attrs || {}" @change="(value) => handleDateRangeChange(column, value, scope.row, scope.$index)" @focus="(event) => handleFocus(column, event, scope.row)" @blur="(event) => handleBlur(column, event, scope.row, scope.$index)" @clear="handleClear(column, scope.row, scope.$index)" />
86
-
87
- <!-- 默认显示 -->
88
- <span v-else>
89
- {{ scope.row[column.field] ? scope.row[column.field] : '-' }}
90
- </span>
91
- </el-form-item>
92
- </template>
93
- </template>
94
- </el-table-column>
95
-
96
- <!-- 操作列 -->
97
- <el-table-column v-if="gridOptions.actions && gridOptions.actions.length > 0" label="操作" :width="gridOptions.actionWidth || '100px'" :align="gridOptions.actionAlign || 'left'" :fixed="gridOptions.actionFixed">
98
- <template slot-scope="scope">
99
- <div class="action-buttons">
100
- <el-button v-for="button in gridOptions.actions" v-if="getButtonShow(button, scope.row, scope.$index)" :key="button.text" :type="button.type || 'primary'" size="small" :disabled="getButtonDisabled(button, scope.row)" :icon="button.icon" style="margin: 0 5px" :style="button.style" @click="(e) => handleActionClick(button, scope.row, scope.$index, e)">
101
- {{ button.text }}
102
- </el-button>
103
- <span v-else>-</span>
104
- </div>
105
- </template>
106
- </el-table-column>
107
- </el-table>
108
- </el-form>
109
-
110
- <!-- 分页 -->
111
- <el-pagination v-if="apiFunction" :current-page="localPagination.currentPage" :page-size="localPagination.pageSize" :total="localPagination.total" :page-sizes="localPagination.pageSizes" :layout="localPagination.layout" :background="localPagination.background" :small="localPagination.small" :disabled="localPagination.disabled" :hide-on-single-page="localPagination.hideOnSinglePage" @current-change="handleCurrentChange" @size-change="handleSizeChange" />
112
- </div>
113
- </template>
114
-
115
- <script>
116
- import { Message, Loading } from 'element-ui'
117
-
118
- // VNode 渲染组件
119
- const VnodeComponent = {
120
- functional: true,
121
- props: {
122
- vnode: {
123
- type: Object,
124
- default: null
125
- }
126
- },
127
- render(h, context) {
128
- return context.props.vnode || h('span')
129
- }
130
- }
131
-
132
- export default {
133
- name: 'DtTable',
134
- components: {
135
- VnodeComponent
136
- },
137
- props: {
138
- gridOptions: {
139
- type: Object,
140
- required: true
141
- },
142
- isDisabled: {
143
- type: Boolean,
144
- default: false
145
- },
146
- pagination: {
147
- type: Object,
148
- default: () => ({
149
- currentPage: 1,
150
- pageSize: 10,
151
- total: 0,
152
- pageSizes: [10, 20, 50, 100],
153
- layout: 'total, sizes, prev, pager, next, jumper',
154
- background: true,
155
- small: false,
156
- disabled: false,
157
- hideOnSinglePage: false
158
- })
159
- },
160
- apiFunction: {
161
- type: Function
162
- },
163
- apiParams: {
164
- type: Object
165
- },
166
- immediate: {
167
- type: Boolean,
168
- default: false
169
- }
170
- },
171
- emits: ['page-change', 'size-change', 'update:pagination', 'action-click', 'validate-error', 'remote-search', 'search', 'linkage-change', 'async-load', 'selection-change'],
172
- data() {
173
- return {
174
- formRef: null,
175
- tableRef: null,
176
- loading: false,
177
- localPagination: { ...this.pagination },
178
- tableData: this.gridOptions.data || [],
179
- searchParams: {},
180
- loadingInstance: null,
181
- loadingFields: new Set(),
182
- formModel: {
183
- tableData: this.gridOptions.data || []
184
- }
185
- }
186
- },
187
- computed: {
188
- hasSelectionColumn() {
189
- return this.gridOptions.columns.some(col => col.field === 'selection')
190
- },
191
- formRules() {
192
- const rules = {}
193
- this.gridOptions.columns.forEach((column) => {
194
- if (column.field && column.rules) {
195
- rules[column.field] = column.rules
196
- }
197
- })
198
- return rules
199
- }
200
- },
201
- watch: {
202
- 'gridOptions.data': {
203
- handler(newVal) {
204
- this.tableData = newVal || []
205
- this.formModel.tableData = newVal || []
206
- },
207
- immediate: true,
208
- deep: true
209
- },
210
- pagination: {
211
- handler(newVal) {
212
- this.localPagination = { ...newVal }
213
- },
214
- deep: true
215
- },
216
- localPagination: {
217
- handler(newVal) {
218
- this.$emit('update:pagination', newVal)
219
- },
220
- deep: true
221
- },
222
- tableData: {
223
- handler(newData, oldData) {
224
- if (newData.length > 0 && newData !== oldData) {
225
- this.$nextTick(() => {
226
- this.initAsyncData()
227
- })
228
- }
229
- },
230
- deep: true
231
- }
232
- },
233
- mounted() {
234
- this.initRefs()
235
- if (this.immediate) {
236
- this.getTableDatas()
237
- }
238
- this.initAsyncData()
239
- },
240
- methods: {
241
- // 判断是否为 VNode
242
- isVNode(vnode) {
243
- return vnode && typeof vnode === 'object' && vnode.tag && vnode.children !== undefined
244
- },
245
- // 调用 render 函数并传入 h
246
- callRender(column, scope) {
247
- return column.render({ ...scope, h: this.$createElement })
248
- },
249
- // 初始化引用
250
- initRefs() {
251
- this.formRef = this.$refs.formRef
252
- this.tableRef = this.$refs.tableRef
253
- },
254
- // 滚动到底部
255
- async scrollToBottom() {
256
- await this.$nextTick()
257
-
258
- if (!this.tableRef) return
259
-
260
- try {
261
- const tableWrapper = this.tableRef.$el.querySelector('.el-table__body-wrapper')
262
- if (tableWrapper) {
263
- tableWrapper.scrollTo({
264
- top: tableWrapper.scrollHeight,
265
- behavior: 'smooth'
266
- })
267
- }
268
- } catch (error) {
269
- console.warn('滚动到底部失败:', error)
270
- }
271
- },
272
-
273
- // 异步加载选项数据
274
- async loadAsyncOptions(column, row, index) {
275
- if (column.asyncOptions && !column.asyncOptions.loadData) return
276
-
277
- const fieldKey = row ? `${column.field}_${row.id || index}` : column.field
278
-
279
- try {
280
- this.loadingFields.add(fieldKey)
281
-
282
- if (row) {
283
- this.$set(row, `${column.field}Loading`, true)
284
- } else {
285
- this.$set(this.searchParams, `${column.field}Loading`, true)
286
- }
287
-
288
- const options = await column.asyncOptions.loadData(row)
289
-
290
- if (row) {
291
- if (!row._asyncOptions) {
292
- this.$set(row, '_asyncOptions', {})
293
- }
294
- this.$set(row._asyncOptions, column.field, options)
295
- } else {
296
- if (!this.searchParams._asyncOptions) {
297
- this.$set(this.searchParams, '_asyncOptions', {})
298
- }
299
- this.$set(this.searchParams._asyncOptions, column.field, options)
300
- }
301
-
302
- this.$emit('async-load', {
303
- field: column.field,
304
- row,
305
- index,
306
- options
307
- })
308
- } catch (error) {
309
- console.error(`异步加载选项失败 [${column.field}]:`, error)
310
- } finally {
311
- if (row) {
312
- this.$set(row, `${column.field}Loading`, false)
313
- }
314
- }
315
- },
316
-
317
- // 初始化异步数据
318
- initAsyncData() {
319
- // 初始化表格中的异步 Select
320
- this.gridOptions.columns.forEach((column) => {
321
- if (column.asyncOptions && column.asyncOptions.immediate) {
322
- this.tableData.forEach((row, index) => {
323
- if (row._asyncOptions && !row._asyncOptions[column.field]) {
324
- this.loadAsyncOptions(column, row, index)
325
- }
326
- })
327
- }
328
- })
329
- },
330
-
331
- // 获取表格数据
332
- async getTableDatas(params) {
333
- if (!this.apiFunction) {
334
- console.warn('apiFunction is not provided')
335
- return
336
- }
337
-
338
- this.startLoading()
339
- this.loading = true
340
-
341
- try {
342
- const requestParams = {
343
- ...this.apiParams,
344
- ...this.searchParams,
345
- ...params,
346
- currentPage: this.localPagination.currentPage,
347
- pageSize: this.localPagination.pageSize
348
- }
349
-
350
- const { data } = await this.apiFunction(requestParams)
351
- this.tableData = data.list || []
352
- this.localPagination.total = data.count
353
- } catch (err) {
354
- console.error('Error fetching table data:', err)
355
- } finally {
356
- this.loading = false
357
- this.endLoading()
358
- }
359
- },
360
-
361
- // 开始加载
362
- startLoading() {
363
- this.loading = true
364
- if (this.loadingInstance) {
365
- this.loadingInstance.close()
366
- }
367
- this.loadingInstance = Loading.service({
368
- target: '.dt_table',
369
- lock: true,
370
- text: '加载中...',
371
- background: 'rgba(255, 255, 255, 0.5)'
372
- })
373
- },
374
-
375
- // 结束加载
376
- endLoading() {
377
- this.loading = false
378
- if (this.loadingInstance) {
379
- this.loadingInstance.close()
380
- this.loadingInstance = null
381
- }
382
- },
383
-
384
- // 处理分页变化
385
- handleCurrentChange(page) {
386
- this.localPagination.currentPage = page
387
- this.$emit('page-change', page)
388
- this.getTableDatas()
389
- },
390
-
391
- // 处理每页条数变化
392
- handleSizeChange(size) {
393
- this.localPagination.pageSize = size
394
- this.localPagination.currentPage = 1
395
- this.$emit('size-change', size)
396
- this.getTableDatas()
397
- },
398
- // 处理选择变化
399
- handleSelectionChange(selection) {
400
- this.$emit('selection-change', selection)
401
- },
402
-
403
- // 获取选中数据
404
- getSelection() {
405
- return this.$refs.tableRef ? this.$refs.tableRef.selection : []
406
- },
407
-
408
- // 清空选择
409
- clearSelection() {
410
- this.$refs.tableRef && this.$refs.tableRef.clearSelection()
411
- },
412
-
413
- // 切换行选中状态
414
- toggleRowSelection(row, selected) {
415
- this.$refs.tableRef && this.$refs.tableRef.toggleRowSelection(row, selected)
416
- },
417
-
418
- // 处理操作按钮点击
419
- handleActionClick(button, row, index, event) {
420
- event.stopPropagation()
421
- if (button.click) {
422
- button.click(row, index)
423
- }
424
- this.$emit('action-click', button, row, index)
425
- },
426
- // 确保表单就绪
427
- async ensureFormReady() {
428
- if (this.formRef) return true
429
-
430
- await this.$nextTick()
431
- this.initRefs()
432
-
433
- if (!this.formRef) {
434
- console.warn('表单引用初始化失败,尝试重新渲染')
435
- await this.$nextTick()
436
- this.initRefs()
437
- }
438
-
439
- return !!this.formRef
440
- },
441
- // 验证表单
442
- async validate() {
443
- await this.ensureFormReady()
444
-
445
- if (!this.formRef) {
446
- return Promise.reject(new Error('表单未初始化,请检查组件状态'))
447
- }
448
-
449
- const rowErrors = new Map()
450
-
451
- try {
452
- const promises = []
453
-
454
- // 修复:使用正确的 prop 路径 tableData.${rowIndex}.${column.field}
455
- this.formModel.tableData.forEach((_, rowIndex) => {
456
- this.gridOptions.columns.forEach((column) => {
457
- if (column.field && column.rules) {
458
- promises.push(
459
- new Promise((resolve, reject) => {
460
- // 修复:添加 tableData 前缀
461
- const propPath = `tableData.${rowIndex}.${column.field}`
462
- this.formRef.validateField(propPath, (error) => {
463
- if (error) {
464
- if (!rowErrors.has(rowIndex)) {
465
- rowErrors.set(rowIndex, [])
466
- }
467
- const fieldName = column.title || column.field
468
- rowErrors.get(rowIndex).push(fieldName)
469
- reject(error)
470
- } else {
471
- resolve(true)
472
- }
473
- })
474
- }).catch(() => false)
475
- )
476
- }
477
- })
478
- })
479
-
480
- const results = await Promise.all(promises)
481
- const isValid = results.every((result) => result !== false)
482
-
483
- if (!isValid) {
484
- const errorParts = []
485
- rowErrors.forEach((fields, rowIndex) => {
486
- if (fields.length > 0) {
487
- const uniqueFields = Array.from(new Set(fields))
488
- errorParts.push(`第${rowIndex + 1}行:${uniqueFields.join(',')}`)
489
- }
490
- })
491
-
492
- if (errorParts.length > 0) {
493
- const errorMessage = errorParts.join(';')
494
- Message({
495
- message: `请完善以下信息:\n${errorMessage}`,
496
- type: 'error',
497
- duration: 10000,
498
- showClose: true,
499
- dangerouslyUseHTMLString: true
500
- })
501
- }
502
-
503
- this.$emit('validate-error', '表单验证失败')
504
- return Promise.reject(new Error('表单验证失败'))
505
- }
506
-
507
- return Promise.resolve(true)
508
- } catch (error) {
509
- console.error('表单验证异常:', error)
510
- Message.error('表单验证过程中发生异常')
511
- this.$emit('validate-error', error)
512
- return Promise.reject(error)
513
- }
514
- },
515
-
516
- // 重置表单
517
- resetFields() {
518
- if (!this.formRef) return
519
- this.formModel.tableData.forEach((_, index) => {
520
- this.gridOptions.columns.forEach((column) => {
521
- if (column.field) {
522
- const propPath = `tableData.${index}.${column.field}`
523
- this.formRef.resetFields(propPath)
524
- }
525
- })
526
- })
527
- },
528
-
529
- // 清除验证
530
- clearValidate() {
531
- if (!this.formRef) return
532
- this.formModel.tableData.forEach((_, index) => {
533
- this.gridOptions.columns.forEach((column) => {
534
- if (column.field) {
535
- const propPath = `tableData.${index}.${column.field}`
536
- this.formRef.clearValidate(propPath)
537
- }
538
- })
539
- })
540
- },
541
- // 处理联动变化
542
- async handleLinkageChange(column, value, row, index, type) {
543
- if (!column.linkage) return
544
-
545
- const { targetField, method, clearTarget = true } = column.linkage
546
-
547
- if (!row._linkageOptions) {
548
- this.$set(row, '_linkageOptions', {})
549
- }
550
- this.$set(row._linkageOptions, targetField, [])
551
-
552
- if (!value && value !== 0) {
553
- this.tableData = [...this.tableData]
554
- return
555
- }
556
-
557
- try {
558
- this.$set(row, `${targetField}Loading`, true)
559
- const options = await method(value, row, type)
560
- this.$set(row._linkageOptions, targetField, options)
561
- this.tableData = [...this.tableData]
562
-
563
- this.$emit('linkage-change', {
564
- sourceField: column.field,
565
- targetField,
566
- value,
567
- row,
568
- index,
569
- options
570
- })
571
- } catch (error) {
572
- console.error('联动数据获取失败:', error)
573
- } finally {
574
- this.$set(row, `${targetField}Loading`, false)
575
- }
576
- },
577
-
578
- // 获取选项数据
579
- getOptions(column, row) {
580
- if (row._asyncOptions && row._asyncOptions[column.field]) {
581
- return row._asyncOptions[column.field]
582
- }
583
- if (row._linkageOptions && row._linkageOptions[column.field]) {
584
- return row._linkageOptions[column.field]
585
- }
586
- return column.options || []
587
- },
588
-
589
- // 计算字段是否禁用
590
- getFieldDisabled(column, row, index) {
591
- if (this.isDisabled) return true
592
-
593
- if (typeof column.disabled === 'function') {
594
- return column.disabled(row, index)
595
- }
596
-
597
- return column.disabled || false
598
- },
599
-
600
- // 计算按钮是否显示
601
- getButtonShow(button, row, index) {
602
- if (typeof button.show === 'function') {
603
- return button.show(row, index)
604
- }
605
- return button.show !== undefined ? button.show : true
606
- },
607
-
608
- // 计算按钮是否禁用
609
- getButtonDisabled(button, row) {
610
- if (typeof button.disabled === 'function') {
611
- return button.disabled(row)
612
- }
613
- return button.disabled || false
614
- },
615
-
616
- // 计算最小值
617
- getMinValue(column, row, index) {
618
- if (typeof column.min === 'function') {
619
- return column.min(row, index)
620
- }
621
- return column.min
622
- },
623
-
624
- // 计算最大值
625
- getMaxValue(column, row, index) {
626
- if (typeof column.max === 'function') {
627
- return column.max(row, index)
628
- }
629
- return column.max
630
- },
631
-
632
- // 手动触发联动
633
- triggerLinkage(field, type) {
634
- const column = this.gridOptions.columns.find((col) => col.field === field)
635
- if (!column || !column.linkage) {
636
- console.warn(`字段 ${field} 没有配置联动或不存在`)
637
- return
638
- }
639
-
640
- this.tableData.forEach((row, index) => {
641
- const sourceValue = row[field]
642
- if (sourceValue !== undefined && sourceValue !== null && sourceValue !== '') {
643
- this.handleLinkageChange(column, sourceValue, row, index, type)
644
- }
645
- })
646
- },
647
-
648
- // 各种事件处理函数
649
- handleSelectChange(column, value, row, index) {
650
- column.events && column.events.change && column.events.change(value, row, index)
651
- if (column.linkage) {
652
- this.handleLinkageChange(column, value, row, index)
653
- }
654
- const propPath = `tableData.${index}.${column.field}`
655
- this.formRef && this.formRef.validateField(propPath)
656
- },
657
-
658
- handleInputChange(column, value, row, index) {
659
- column.events && column.events.change && column.events.change(value, row, index)
660
- const propPath = `tableData.${index}.${column.field}`
661
- this.formRef && this.formRef.validateField(propPath)
662
- },
663
-
664
- handleInputNumberChange(column, value, row, index) {
665
- column.events && column.events.change && column.events.change(value, row, index)
666
- const propPath = `tableData.${index}.${column.field}`
667
- this.formRef && this.formRef.validateField(propPath)
668
- },
669
- handleSwitchChange(column, value, row, index) {
670
- column.events && column.events.change && column.events.change(value, row, index)
671
- const propPath = `tableData.${index}.${column.field}`
672
- this.formRef && this.formRef.validateField(propPath)
673
- },
674
-
675
- handleTimeChange(column, value, row, index) {
676
- column.events && column.events.change && column.events.change(value, row, index)
677
- const propPath = `tableData.${index}.${column.field}`
678
- this.formRef && this.formRef.validateField(propPath)
679
- },
680
-
681
- handleDateChange(column, value, row, index) {
682
- column.events && column.events.change && column.events.change(value, row, index)
683
- const propPath = `tableData.${index}.${column.field}`
684
- this.formRef && this.formRef.validateField(propPath)
685
- },
686
-
687
- handleDateTimeChange(column, value, row, index) {
688
- column.events && column.events.change && column.events.change(value, row, index)
689
- const propPath = `tableData.${index}.${column.field}`
690
- this.formRef && this.formRef.validateField(propPath)
691
- },
692
-
693
- handleDateRangeChange(column, value, row, index) {
694
- column.events && column.events.change && column.events.change(value, row, index)
695
- const propPath = `tableData.${index}.${column.field}`
696
- this.formRef && this.formRef.validateField(propPath)
697
- },
698
-
699
- handleFocus(column, event, row) {
700
- column.events && column.events.focus && column.events.focus(event, row)
701
- if (column.asyncOptions && !(row._asyncOptions && row._asyncOptions[column.field])) {
702
- this.loadAsyncOptions(column, row)
703
- }
704
- },
705
-
706
- handleBlur(column, event, row, index) {
707
- column.events && column.events.blur && column.events.blur(event, row)
708
- const propPath = `tableData.${index}.${column.field}`
709
- this.formRef && this.formRef.validateField(propPath)
710
- },
711
-
712
- handleClear(column, row, index) {
713
- column.events && column.events.clear && column.events.clear()
714
- if (column.linkage) {
715
- const { targetField } = column.linkage
716
- if (targetField) {
717
- this.$set(row, targetField, undefined)
718
- if (row._linkageOptions) {
719
- this.$set(row._linkageOptions, targetField, [])
720
- }
721
- }
722
- }
723
- },
724
-
725
- // 刷新方法
726
- refresh(params) {
727
- return this.getTableDatas(params)
728
- },
729
-
730
- getAppendComponent(column, scope) {
731
- if (typeof column.unit === 'function') {
732
- return {
733
- functional: true,
734
- render: (h) => column.unit(h, scope)
735
- }
736
- } else {
737
- return {
738
- render: (h) => h('span', { style: { paddingLeft: '5px' } }, column.unit)
739
- }
740
- }
741
- }
742
- }
743
- }
744
- </script>
745
-
746
- <style lang="scss" scoped>
747
- .dt_table_header {
748
- display: inline-flex;
749
- align-items: center;
750
- }
751
-
752
- .dt_required_dot {
753
- color: #f56c6c;
754
- margin-right: 4px;
755
- }
756
-
757
- .action-buttons {
758
- display: flex;
759
- align-items: center;
760
- }
761
-
762
- .dt_table .el-form-item {
763
- margin-bottom: 0px !important;
764
- }
765
-
766
- .dt_table {
767
- ::v-deep {
768
- .el-form-item__content {
769
- margin-bottom: 0px !important;
770
- }
771
- .el-input__inner {
772
- text-align: center !important;
773
- }
774
- .el-table__cell {
775
- padding: 5px 0;
776
- }
777
- }
778
- }
779
- </style>