iov-pro-components 0.0.3

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 (133) hide show
  1. package/.eslintignore +5 -0
  2. package/.eslintrc.js +192 -0
  3. package/.gitignore +3 -0
  4. package/README.md +4 -0
  5. package/babel.config.js +5 -0
  6. package/docs/.vuepress/config.js +169 -0
  7. package/docs/.vuepress/styles/index.styl +62 -0
  8. package/docs/.vuepress/styles/palette.styl +20 -0
  9. package/docs/.vuepress/theme/enhanceApp.js +100 -0
  10. package/docs/.vuepress/theme/index.js +3 -0
  11. package/docs/README.md +13 -0
  12. package/docs/components/description.md +519 -0
  13. package/docs/components/dialog-select.md +91 -0
  14. package/docs/components/display.md +36 -0
  15. package/docs/components/enums.md +33 -0
  16. package/docs/components/icon.md +406 -0
  17. package/docs/components/link-group.md +39 -0
  18. package/docs/components/page-detail.md +48 -0
  19. package/docs/components/page-module.md +51 -0
  20. package/docs/components/pro-form.md +958 -0
  21. package/docs/components/pro-table.md +683 -0
  22. package/docs/components/request.md +44 -0
  23. package/docs/components/search-table.md +963 -0
  24. package/docs/components/space.md +35 -0
  25. package/docs/components/sub-title.md +24 -0
  26. package/docs/components/submit-module.md +24 -0
  27. package/docs/template/add.md +124 -0
  28. package/docs/template/confirm.md +28 -0
  29. package/docs/template/detail.md +240 -0
  30. package/docs/template/dialog.md +339 -0
  31. package/docs/template/list.md +464 -0
  32. package/docs/template/tabs-mini.md +32 -0
  33. package/docs/template/tabs.md +32 -0
  34. package/jsconfig.json +19 -0
  35. package/lib/iov-pro-components.css +1 -0
  36. package/lib/iov-pro-components.min.js +7 -0
  37. package/lib/postcss.config.js +8 -0
  38. package/package.json +75 -0
  39. package/patches/vue-server-renderer+2.7.16.patch +13 -0
  40. package/rollup.config.mjs +79 -0
  41. package/src/App.vue +103 -0
  42. package/src/main.js +33 -0
  43. package/src/packages/column-tooltip/index.js +7 -0
  44. package/src/packages/column-tooltip/src/main.vue +127 -0
  45. package/src/packages/description/index.js +7 -0
  46. package/src/packages/description/src/main.vue +375 -0
  47. package/src/packages/description/src/text.vue +103 -0
  48. package/src/packages/dialog-select/index.js +7 -0
  49. package/src/packages/dialog-select/src/main.vue +308 -0
  50. package/src/packages/display/index.js +7 -0
  51. package/src/packages/display/src/main.vue +44 -0
  52. package/src/packages/enums/index.js +7 -0
  53. package/src/packages/enums/src/main.vue +23 -0
  54. package/src/packages/export/index.js +7 -0
  55. package/src/packages/export/src/main.vue +316 -0
  56. package/src/packages/fixed-button-group/index.js +7 -0
  57. package/src/packages/fixed-button-group/src/main.vue +104 -0
  58. package/src/packages/form/index.js +7 -0
  59. package/src/packages/form/src/collapse.vue +149 -0
  60. package/src/packages/form/src/main.vue +1190 -0
  61. package/src/packages/form-collapse/index.js +7 -0
  62. package/src/packages/index.js +86 -0
  63. package/src/packages/link-group/index.js +7 -0
  64. package/src/packages/link-group/src/main.vue +52 -0
  65. package/src/packages/page-detail/index.js +7 -0
  66. package/src/packages/page-detail/src/main.vue +123 -0
  67. package/src/packages/page-module/index.js +7 -0
  68. package/src/packages/page-module/src/main.vue +56 -0
  69. package/src/packages/preview/index.js +7 -0
  70. package/src/packages/preview/src/eval-image-viewer.js +50 -0
  71. package/src/packages/preview/src/image-viewer.vue +366 -0
  72. package/src/packages/preview/src/main.vue +97 -0
  73. package/src/packages/request/index.js +7 -0
  74. package/src/packages/request/src/main.vue +125 -0
  75. package/src/packages/search-table/index.js +7 -0
  76. package/src/packages/search-table/src/inner-tabs.vue +237 -0
  77. package/src/packages/search-table/src/main.vue +472 -0
  78. package/src/packages/search-table/src/outer-tabs.vue +45 -0
  79. package/src/packages/search-table-inner-tabs/index.js +7 -0
  80. package/src/packages/search-table-outer-tabs/index.js +7 -0
  81. package/src/packages/space/index.js +7 -0
  82. package/src/packages/space/src/main.vue +74 -0
  83. package/src/packages/sub-title/index.js +7 -0
  84. package/src/packages/sub-title/src/main.vue +70 -0
  85. package/src/packages/submit-module/index.js +7 -0
  86. package/src/packages/submit-module/src/main.vue +67 -0
  87. package/src/packages/table/index.js +7 -0
  88. package/src/packages/table/src/filter.vue +89 -0
  89. package/src/packages/table/src/main.vue +668 -0
  90. package/src/packages/table/src/search.vue +90 -0
  91. package/src/packages/table/src/sort.vue +118 -0
  92. package/src/packages/theme/index.scss +15 -0
  93. package/src/packages/theme/src/column-tooltip.scss +23 -0
  94. package/src/packages/theme/src/common/color.scss +134 -0
  95. package/src/packages/theme/src/description.scss +56 -0
  96. package/src/packages/theme/src/dialog-select.scss +32 -0
  97. package/src/packages/theme/src/fixed-button-group.scss +25 -0
  98. package/src/packages/theme/src/form.scss +11 -0
  99. package/src/packages/theme/src/link-group.scss +43 -0
  100. package/src/packages/theme/src/page-detail.scss +61 -0
  101. package/src/packages/theme/src/page-module.scss +46 -0
  102. package/src/packages/theme/src/preview.scss +67 -0
  103. package/src/packages/theme/src/search-table.scss +185 -0
  104. package/src/packages/theme/src/space.scss +12 -0
  105. package/src/packages/theme/src/sub-title.scss +47 -0
  106. package/src/packages/theme/src/submit-module.scss +13 -0
  107. package/src/packages/theme/src/table.scss +129 -0
  108. package/src/packages/theme/src/toolbar.scss +109 -0
  109. package/src/packages/toolbar/index.js +7 -0
  110. package/src/packages/toolbar/src/main.vue +126 -0
  111. package/src/packages/toolbar/src/setting.vue +217 -0
  112. package/src/packages/toolbar/src/style.vue +68 -0
  113. package/src/packages/toolbar/src/zoom.vue +65 -0
  114. package/src/router.js +83 -0
  115. package/src/utils/config-center.js +218 -0
  116. package/src/utils/function-eval.js +84 -0
  117. package/src/utils/index.js +104 -0
  118. package/src/views/column-tooltip.vue +37 -0
  119. package/src/views/components/OtherSelect.vue +18 -0
  120. package/src/views/description.vue +60 -0
  121. package/src/views/detail.vue +146 -0
  122. package/src/views/directive/number.js +82 -0
  123. package/src/views/enums.vue +22 -0
  124. package/src/views/export.vue +9 -0
  125. package/src/views/form-collapse.vue +185 -0
  126. package/src/views/form.vue +402 -0
  127. package/src/views/link-group.vue +16 -0
  128. package/src/views/preview.vue +33 -0
  129. package/src/views/request.vue +56 -0
  130. package/src/views/search-table.vue +297 -0
  131. package/src/views/table.vue +145 -0
  132. package/src/views/toolbar.vue +30 -0
  133. package/vue.config.js +22 -0
@@ -0,0 +1,237 @@
1
+ <script>
2
+ import cloneDeep from 'lodash/cloneDeep'
3
+ import ProForm from '@/packages/form'
4
+ import Space from '@/packages/space'
5
+ import ProFormCollapse from '@/packages/form-collapse'
6
+ import { toUpperCamelCase } from '@/utils'
7
+ import { getComponentNames } from '@/utils/config-center'
8
+
9
+ export default {
10
+ name: 'IovProSearchTableInnerTabs',
11
+ provide() {
12
+ return {
13
+ isInnerTable: true,
14
+ innerTableConfig: {
15
+ table: this.config.table,
16
+ pagination: this.config.pagination
17
+ }
18
+ }
19
+ },
20
+ props: {
21
+ title: {
22
+ type: String,
23
+ default: '请输入标题'
24
+ },
25
+ subTitle: {
26
+ type: String,
27
+ default: ''
28
+ },
29
+ formItems: {
30
+ type: Array,
31
+ default: () => []
32
+ },
33
+ dataSource: {
34
+ type: Object,
35
+ default: () => ({})
36
+ },
37
+ config: {
38
+ type: Object,
39
+ default: () => ({})
40
+ }
41
+ },
42
+ data() {
43
+ return {
44
+ formData: {},
45
+ tabName: 'tab-0'
46
+ }
47
+ },
48
+ computed: {
49
+ /**
50
+ * 表单配置
51
+ * @time 2024-11-18 09:18:54
52
+ */
53
+ formConfig() {
54
+ return {
55
+ grid: true,
56
+ span: 6,
57
+ gutter: 16,
58
+ collapse: true,
59
+ maxLine: 2,
60
+ ...this.config.form
61
+ }
62
+ },
63
+
64
+ /**
65
+ * 给表单组件增加slots以及label-width
66
+ * @time 2024-11-26 20:10:08
67
+ */
68
+ normalizedFormItems() {
69
+ return this.formItems.map(item => {
70
+ // 浅拷贝一下对象
71
+ const itemCopy = { ...item }
72
+ // 如果当前是如下组件,则默认需要插槽
73
+ if (![
74
+ 'Radio',
75
+ 'Checkbox',
76
+ 'RadioGroup',
77
+ 'CheckboxGroup'
78
+ ].includes(toUpperCamelCase(item.type))) {
79
+ // label宽度
80
+ itemCopy['labelWidth'] = '0px'
81
+ // 设置文字插槽
82
+ itemCopy['slots'] = {
83
+ component: {
84
+ prefixLabel: `${item.name}-prefix-label`
85
+ }
86
+ }
87
+ }
88
+ // 删除reloadRequest属性
89
+ delete itemCopy['reloadRequest']
90
+ return itemCopy
91
+ })
92
+ }
93
+ },
94
+ mounted() {
95
+ this.$nextTick(() => this.onSearch())
96
+ },
97
+ methods: {
98
+ /**
99
+ * 搜索表单
100
+ * @time 2024-11-18 09:43:49
101
+ */
102
+ onSearch() {
103
+ // 遍历子组件
104
+ this.$slots.default.forEach(({ componentInstance }) => {
105
+ // 如果组件实例存在
106
+ if (componentInstance) {
107
+ // 赋值
108
+ componentInstance.formData = this.formData
109
+ // 重新赋值表单数据
110
+ componentInstance.queryData = cloneDeep(this.formData)
111
+ // 重置表单分页数据
112
+ componentInstance.$refs.table.reset()
113
+ }
114
+ })
115
+ },
116
+
117
+ /**
118
+ * 重置表单数据
119
+ * @time 2024-11-18 09:49:31
120
+ */
121
+ onReset() {
122
+ // 重置表单数据
123
+ this.$refs.form.resetFields()
124
+ // 接口重新加载数据
125
+ this.$nextTick(() => this.onSearch())
126
+ },
127
+
128
+ /**
129
+ * 当表单字段发生改变
130
+ * @param {Object} newValue 新值
131
+ * @param {Object} oldValue 旧值
132
+ * @time 2024-12-16 16:06:23
133
+ */
134
+ onFormChange(newValue, oldValue) {
135
+ // 重新加载接口的字段
136
+ const reloadFields = this.formItems.filter(item => item.reloadRequest).map(item => item.name)
137
+ // 是否需要重新加载
138
+ const needReloadRequest = reloadFields.some(field => {
139
+ return Array.isArray(field)
140
+ ? field.some(item => newValue[item] !== oldValue[item])
141
+ : newValue[field] !== oldValue[field]
142
+ })
143
+ // 只要任意一个字段发生改变
144
+ if (needReloadRequest) {
145
+ // 接口重新加载数据
146
+ this.onSearch()
147
+ }
148
+ }
149
+ },
150
+ render() {
151
+ const [
152
+ Tabs,
153
+ TabPane,
154
+ Col,
155
+ Button
156
+ ] = getComponentNames(['tabs', 'tab-pane', 'col', 'button'])
157
+
158
+ // 生成pro表单
159
+ const renderProForm = ({ status, toggleStatus, needCollapse }) => {
160
+ // 插槽
161
+ const scopedSlots = this.config.simple ? {} : {
162
+ append: () => (
163
+ <Col span={this.formConfig.span}>
164
+ <Space class='search-table__append' direction='horizontal' space={8}>
165
+ <Button type='info' size='small' round onClick={this.onSearch}>查询</Button>
166
+ <Button size='small' round onClick={this.onReset}>重置</Button>
167
+ { status && needCollapse && <span class={['search-table__toggle-status', status].join(' ')} onClick={toggleStatus}>{status === 'expand' ? '收起' : '展开'}筛选项 <i class={ status === 'expand' ? 'iov-icon-arrow-up' : 'iov-icon-arrow-down'} /></span> }
168
+ </Space>
169
+ </Col>
170
+ )
171
+ }
172
+ // 遍历所有的prefixLabel
173
+ this.normalizedFormItems
174
+ .filter(item => item.slots && item.slots.component && item.slots.component.prefixLabel)
175
+ .forEach(item => {
176
+ // 塞入插槽
177
+ scopedSlots[item.slots.component.prefixLabel] = () => item.label
178
+ })
179
+ return (
180
+ <ProForm
181
+ ref='form'
182
+ data-source={this.dataSource}
183
+ value={this.formData}
184
+ items={this.normalizedFormItems}
185
+ config={this.formConfig}
186
+ onInput={val => (this.formData = val)}
187
+ onChange={this.onFormChange}
188
+ scopedSlots={scopedSlots}
189
+ />
190
+ )
191
+ }
192
+ return (
193
+ <div class='inner-tabs'>
194
+ <div class='inner-tabs__module'>
195
+ <div class='inner-tabs__title-main'>
196
+ { this.$slots.title ? this.$slots.title : <span class='inner-tabs__title'>{this.title}</span> }
197
+ { this.$slots.subTitle ? this.$slots.subTitle : this.subTitle ? <span class='inner-tabs__sub-title'>{this.subTitle}</span> : null }
198
+ </div>
199
+ { // 如果需要折叠,则展示需要折叠的组件
200
+ this.formConfig.collapse
201
+ ? (
202
+ <ProFormCollapse
203
+ buttonSpan={this.formConfig.span}
204
+ maxLine={this.formConfig.maxLine}
205
+ scopedSlots={{
206
+ default: renderProForm
207
+ }}
208
+ />
209
+ )
210
+ : renderProForm({})
211
+ }
212
+ </div>
213
+ <div class='inner-tabs__module'>
214
+ <Tabs
215
+ value={this.tabName}
216
+ onInput={val => (this.tabName = val)}
217
+ >
218
+ { // 遍历插槽的值
219
+ this.$slots.default
220
+ .filter(comp => !!comp.tag)
221
+ .map((comp, index) => {
222
+ const label = comp.componentOptions.propsData.title
223
+ return (
224
+ <TabPane
225
+ label={label}
226
+ name={`tab-${index}`}
227
+ >{comp}</TabPane>
228
+ )
229
+ })
230
+ }
231
+ </Tabs>
232
+ </div>
233
+ </div>
234
+ )
235
+ }
236
+ }
237
+ </script>
@@ -0,0 +1,472 @@
1
+ <script>
2
+ import cloneDeep from 'lodash/cloneDeep'
3
+ import lodashGet from 'lodash/get'
4
+ import ProForm from '@/packages/form'
5
+ import ProTable from '@/packages/table'
6
+ import { PAGINATION_EVENTS, TABLE_EVENTS } from '@/packages/table/src/main.vue'
7
+ import Toolbar from '@/packages/toolbar'
8
+ import Space from '@/packages/space'
9
+ import ProFormCollapse from '@/packages/form-collapse'
10
+ import { toUpperCamelCase } from '@/utils'
11
+ import { getComponentNames } from '@/utils/config-center'
12
+ import isEqual from 'lodash/isEqual'
13
+
14
+ export default {
15
+ name: 'IovProSearchTable',
16
+ inject: {
17
+ isInnerTable: { value: 'isInnerTable', default: false },
18
+ innerTableConfig: { value: 'innerTableConfig', default: {}}
19
+ },
20
+ props: {
21
+ title: {
22
+ type: String,
23
+ default: '请输入标题'
24
+ },
25
+ subTitle: {
26
+ type: String,
27
+ default: ''
28
+ },
29
+ formItems: {
30
+ type: Array,
31
+ default: () => []
32
+ },
33
+ tableColumns: {
34
+ type: Array,
35
+ default: () => []
36
+ },
37
+ dataSource: {
38
+ type: Object,
39
+ default: () => ({})
40
+ },
41
+ config: {
42
+ type: Object,
43
+ default: () => ({})
44
+ },
45
+ // 接口请求方法
46
+ request: {
47
+ type: Object,
48
+ default: () => ({})
49
+ }
50
+ },
51
+ data() {
52
+ return {
53
+ formData: {},
54
+ queryData: {},
55
+ tableAdvanceData: {}
56
+ }
57
+ },
58
+ computed: {
59
+ /**
60
+ * 表单配置
61
+ * @time 2024-11-18 09:18:54
62
+ */
63
+ formConfig() {
64
+ return {
65
+ grid: true,
66
+ span: 6,
67
+ gutter: 16,
68
+ collapse: true,
69
+ maxLine: 2,
70
+ space: 16,
71
+ ...this.config.form
72
+ }
73
+ },
74
+
75
+ /**
76
+ * 给表单组件增加slots以及label-width
77
+ * @time 2024-11-26 20:10:08
78
+ */
79
+ normalizedFormItems() {
80
+ return this.formItems.map(item => {
81
+ // 浅拷贝一下对象
82
+ const itemCopy = { ...item }
83
+ // 如果当前是如下组件,则默认需要插槽
84
+ if (![
85
+ 'Radio',
86
+ 'Checkbox',
87
+ 'RadioGroup',
88
+ 'CheckboxGroup'
89
+ ].includes(toUpperCamelCase(item.type))) {
90
+ // label宽度
91
+ itemCopy['labelWidth'] = '0px'
92
+ // 设置文字插槽
93
+ itemCopy['slots'] = {
94
+ component: {
95
+ prefixLabel: `${item.name}-prefix-label`
96
+ }
97
+ }
98
+ }
99
+ // 如果当前是简易模式
100
+ if (this.config.simple) {
101
+ // 如果无监听的事件
102
+ if (!itemCopy.on) {
103
+ itemCopy.on = {}
104
+ }
105
+ // 当值发生改变时触发校验
106
+ const onSearchByValueChange = () => {
107
+ // 等数据更新后再判断
108
+ this.$nextTick(() => {
109
+ // 如果前后值相等,则不处理
110
+ if (isEqual(this.formData, this.queryData)) {
111
+ return
112
+ }
113
+ // 如果值不相等
114
+ this.onSearch()
115
+ })
116
+ }
117
+ // 如果是输入框,则绑定blur方法
118
+ if (toUpperCamelCase(item.type) === 'Input') {
119
+ itemCopy.on['blur'] = onSearchByValueChange
120
+ }
121
+ // 绑定change方法
122
+ itemCopy.on['change'] = onSearchByValueChange
123
+ }
124
+ // 删除reloadRequest属性
125
+ delete itemCopy['reloadRequest']
126
+ return itemCopy
127
+ })
128
+ },
129
+
130
+ /**
131
+ * 表格配置如果是tag则需要按照不同tag类型进行大小设定
132
+ * @time 2024-12-10 10:10:39
133
+ */
134
+ normalizedTableColumns() {
135
+ return this.tableColumns.map(item => {
136
+ // 浅拷贝一下对象
137
+ const itemCopy = { ...item }
138
+ // 如果当前类型是tag
139
+ if (itemCopy.type === 'tag') {
140
+ // 如果没有config配置,则初始化
141
+ if (!itemCopy.config) {
142
+ itemCopy.config = {}
143
+ }
144
+ // 设置hit属性
145
+ itemCopy.config['hit'] = true
146
+ // 如果当前是dot模式,并且未设置
147
+ if ([undefined, null].includes(itemCopy.config.size)) {
148
+ // 如果当前是dot模式,则默认是medium,否则是small
149
+ itemCopy.config.size = [undefined, null].includes(itemCopy.config.dot) ? 'mini' : 'medium'
150
+ }
151
+ }
152
+ return itemCopy
153
+ })
154
+ },
155
+
156
+ /**
157
+ * 表格配置
158
+ * @time 2024-11-18 09:26:23
159
+ */
160
+ tableConfig() {
161
+ return {
162
+ pagination: {
163
+ ...(this.innerTableConfig.pagination || {}),
164
+ ...(this.config.pagination || {})
165
+ },
166
+ table: {
167
+ outerBorder: true,
168
+ ...(this.innerTableConfig.table || {}),
169
+ ...(this.config.table || {})
170
+ }
171
+ }
172
+ },
173
+
174
+ /**
175
+ * 表格请求配置
176
+ * @time 2024-11-18 09:54:07
177
+ */
178
+ tableRequest() {
179
+ return {
180
+ reloadOnParamsChange: true,
181
+ ...this.request,
182
+ api: async params => {
183
+ // 触发请求前事件
184
+ this.$emit('before-request', params)
185
+ // 获取接口请求接口
186
+ const respData = await this.request.api(params)
187
+ // 触发请求后事件
188
+ this.$emit('after-request', respData)
189
+ return respData
190
+ },
191
+ params: {
192
+ ...this.queryData,
193
+ ...(this.request.params || {})
194
+ }
195
+ }
196
+ },
197
+
198
+ /**
199
+ * 绑定表格的事件
200
+ * @time 2025-01-09 17:41:50
201
+ */
202
+ bindTableEvent() {
203
+ // 当前事件
204
+ const EVENTS = [
205
+ ...PAGINATION_EVENTS,
206
+ ...TABLE_EVENTS
207
+ ]
208
+ return EVENTS.reduce(
209
+ (memo, eventKey) => {
210
+ // 开始透传事件
211
+ memo[eventKey] = (...args) => {
212
+ // 如果当前是过滤数据
213
+ if (eventKey === 'filter-change') {
214
+ this.onFilterChange(...args)
215
+ }
216
+ // 抛出事件
217
+ this.$emit(eventKey, ...args)
218
+ }
219
+ // 返回事件
220
+ return memo
221
+ }, []
222
+ )
223
+ }
224
+ },
225
+ mounted() {
226
+ this.$nextTick(() => {
227
+ this.queryData = cloneDeep(this.formData)
228
+ })
229
+ },
230
+ methods: {
231
+ /**
232
+ * 搜索表单
233
+ * @time 2024-11-18 09:43:49
234
+ */
235
+ onSearch() {
236
+ // 深拷贝一份对象
237
+ this.queryData = cloneDeep(this.formData)
238
+ // 重置表格分页数据
239
+ this.$refs.table.reset()
240
+ },
241
+
242
+ /**
243
+ * 刷新表格数据
244
+ * @time 2024-11-21 15:52:13
245
+ */
246
+ refresh() {
247
+ // 如果数据相同,则需要手动刷新
248
+ if (isEqual(this.queryData, this.formData)) {
249
+ this.$refs.table.refresh()
250
+ } else {
251
+ // 深拷贝一份对象
252
+ this.queryData = cloneDeep(this.formData)
253
+ }
254
+ },
255
+
256
+ /**
257
+ * 重置表单数据
258
+ * @time 2024-11-18 09:49:31
259
+ */
260
+ onReset() {
261
+ // 重置表单数据
262
+ this.$refs.form.resetFields()
263
+ // 接口重新加载数据
264
+ this.$nextTick(() => {
265
+ this.queryData = cloneDeep(this.formData)
266
+ // 重置表格分页数据
267
+ this.$refs.table.reset()
268
+ })
269
+ },
270
+
271
+ /**
272
+ * 当表单字段发生改变
273
+ * @param {Object} newValue 新值
274
+ * @param {Object} oldValue 旧值
275
+ * @time 2024-12-16 16:06:23
276
+ */
277
+ onFormChange(newValue, oldValue) {
278
+ // 重新加载接口的字段
279
+ const reloadFields = this.formItems.filter(item => item.reloadRequest).map(item => item.name)
280
+ // 是否需要重新加载
281
+ const needReloadRequest = reloadFields.some(field => {
282
+ return Array.isArray(field)
283
+ ? field.some(item => newValue[item] !== oldValue[item])
284
+ : newValue[field] !== oldValue[field]
285
+ })
286
+ // 只要任意一个字段发生改变
287
+ if (needReloadRequest) {
288
+ // 接口重新加载数据
289
+ this.queryData = cloneDeep(this.formData)
290
+ }
291
+ },
292
+
293
+ /**
294
+ * 当筛选字段发生变化
295
+ * @param {Object} column 表格字段
296
+ * @param {String} value 当前选中的值
297
+ * @time 2025-02-18 13:49:55
298
+ */
299
+ onFilterChange(column, value) {
300
+ this.$set(this.tableAdvanceData, column.prop, value)
301
+ }
302
+ },
303
+ render() {
304
+ const [
305
+ Col,
306
+ Button
307
+ ] = getComponentNames(['col', 'button'])
308
+
309
+ // 生成pro表单
310
+ const renderProForm = ({ status, toggleStatus, needCollapse }) => {
311
+ // 插槽
312
+ const scopedSlots = this.config.simple ? {} : {
313
+ append: () => (
314
+ <Col span={this.formConfig.span}>
315
+ <Space class='search-table__append' direction='horizontal' space={8}>
316
+ <Button type='info' size='small' round onClick={this.onSearch}>查询</Button>
317
+ <Button size='small' round onClick={this.onReset}>重置</Button>
318
+ { status && needCollapse && <span class={['search-table__toggle-status', status].join(' ')} onClick={toggleStatus}>{status === 'expand' ? '收起' : '展开'}筛选项 <i class={ status === 'expand' ? 'iov-icon-arrow-up' : 'iov-icon-arrow-down'} /></span> }
319
+ </Space>
320
+ </Col>
321
+ )
322
+ }
323
+ // 遍历所有的prefixLabel
324
+ this.normalizedFormItems
325
+ .filter(item => item.slots && item.slots.component && item.slots.component.prefixLabel)
326
+ .forEach(item => {
327
+ // 塞入插槽
328
+ scopedSlots[item.slots.component.prefixLabel] = () => item.label
329
+ })
330
+ return (
331
+ <ProForm
332
+ ref='form'
333
+ data-source={this.dataSource}
334
+ value={this.formData}
335
+ items={this.normalizedFormItems}
336
+ config={this.formConfig}
337
+ onInput={val => (this.formData = val)}
338
+ onChange={this.onFormChange}
339
+ scopedSlots={scopedSlots}
340
+ />
341
+ )
342
+ }
343
+
344
+ // 生成pro表格
345
+ const renderProTable = () => (
346
+ <ProTable
347
+ ref='table'
348
+ columns={this.normalizedTableColumns}
349
+ request={this.tableRequest}
350
+ config={this.tableConfig}
351
+ scopedSlots={this.$scopedSlots}
352
+ on={this.bindTableEvent}
353
+ />
354
+ )
355
+
356
+ // 生成actionbar
357
+ const renderActionBar = () => (
358
+ this.$scopedSlots['action-bar']
359
+ ? this.$scopedSlots['action-bar']({
360
+ data: cloneDeep({
361
+ ...this.queryData,
362
+ ...this.tableAdvanceData
363
+ }),
364
+ ref: {
365
+ form: () => lodashGet(this.$refs.form, '$refs.form'),
366
+ table: () => lodashGet(this.$refs.table, '$refs.table')
367
+ }
368
+ }) : this.$slots['action-bar']
369
+ )
370
+
371
+ // 如果内嵌到inner-tabs组件中
372
+ if (this.isInnerTable) {
373
+ return (
374
+ <div class='search-table'>
375
+ <div class='search-table__module'>
376
+ <div class='search-table__row'>
377
+ <div class='search-table__action-bar'>
378
+ {renderActionBar()}
379
+ </div>
380
+ </div>
381
+ {renderProTable()}
382
+ </div>
383
+ </div>
384
+ )
385
+ }
386
+
387
+ // 如果是简单模式
388
+ if (this.config.simple) {
389
+ return (
390
+ <div class='search-table'>
391
+ <div class='search-table__module'>
392
+ <iov-pro-space space='12'>
393
+ <div class='search-table__row'>
394
+ {renderProForm({})}
395
+ <div class='search-table__action-bar'>
396
+ {renderActionBar()}
397
+ </div>
398
+ </div>
399
+ {renderProTable()}
400
+ </iov-pro-space>
401
+ </div>
402
+ </div>
403
+ )
404
+ }
405
+
406
+ // 如果没有插槽
407
+ if (!this.$slots['action-bar'] && !this.$scopedSlots['action-bar']) {
408
+ return (
409
+ <div class='search-table'>
410
+ <div class='search-table__module'>
411
+ <div class='search-table__title-main'>
412
+ <span class='search-table__title'>{this.$slots.title || this.title}</span>
413
+ <span class='search-table__sub-title'>{this.$slots.subTitle || this.subTitle}</span>
414
+ </div>
415
+ <iov-pro-space space='16'>
416
+ { // 如果需要折叠,则展示需要折叠的组件
417
+ this.formConfig.collapse
418
+ ? (
419
+ <ProFormCollapse
420
+ buttonSpan={this.formConfig.span}
421
+ maxLine={this.formConfig.maxLine}
422
+ scopedSlots={{
423
+ default: renderProForm
424
+ }}
425
+ />
426
+ )
427
+ : renderProForm({})
428
+ }
429
+ {renderProTable()}
430
+ </iov-pro-space>
431
+ </div>
432
+ </div>
433
+ )
434
+ }
435
+
436
+ return (
437
+ <div class='search-table'>
438
+ <div class='search-table__module'>
439
+ <div class='search-table__title-main'>
440
+ { this.$slots.title ? this.$slots.title : <span class='search-table__title'>{this.title}</span> }
441
+ { this.$slots.subTitle ? this.$slots.subTitle : this.subTitle ? <span class='search-table__sub-title'>{this.subTitle}</span> : null }
442
+ </div>
443
+ { // 如果需要折叠,则展示需要折叠的组件
444
+ this.formConfig.collapse
445
+ ? (
446
+ <ProFormCollapse
447
+ buttonSpan={this.formConfig.span}
448
+ maxLine={this.formConfig.maxLine}
449
+ scopedSlots={{
450
+ default: renderProForm
451
+ }}
452
+ />
453
+ )
454
+ : renderProForm({})
455
+ }
456
+ </div>
457
+ <div class='search-table__module'>
458
+ <div class='search-table__bar'>
459
+ <div class='search-table__action-bar'>
460
+ {renderActionBar()}
461
+ </div>
462
+ <div class='search-table__toolbar'>
463
+ <Toolbar config={this.config.toolbar} table={() => this.$refs.table} />
464
+ </div>
465
+ </div>
466
+ {renderProTable()}
467
+ </div>
468
+ </div>
469
+ )
470
+ }
471
+ }
472
+ </script>