vue2-client 1.22.21 → 1.22.22

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 (84) hide show
  1. package/.env.his +19 -19
  2. package/.idea/deployment.xml +14 -0
  3. package/.idea/inspectionProfiles/Project_Default.xml +11 -0
  4. package/.idea/misc.xml +5 -5
  5. package/package.json +1 -1
  6. package/src/base-client/components/common/HIS/HForm/HForm.vue +1186 -1186
  7. package/src/base-client/components/common/HIS/HTab/HTab.vue +790 -790
  8. package/src/base-client/components/common/XInspectionDetailDrawer/components/AiDeviceStatus.vue +25 -4
  9. package/src/base-client/components/common/XInspectionDetailDrawer/components/ImageAnnotationShow.vue +1371 -0
  10. package/src/base-client/components/common/XMarkdownViewer/demo.vue +102 -102
  11. package/src/base-client/components/his/XTransfer/index.md +327 -327
  12. package/src/utils/module-loader/VueSfcModuleCache.js +99 -99
  13. package/src/utils/module-loader/index.js +5 -5
  14. package/.history/.eslintrc_20260521171150.js +0 -74
  15. package/.history/.eslintrc_20260521171213.js +0 -74
  16. package/.history/src/base-client/components/common/HIS/HAddNativeForm/HAddNativeForm_20260601154443.vue +0 -726
  17. package/.history/src/base-client/components/common/HIS/HAddNativeForm/HAddNativeForm_20260601154700.vue +0 -478
  18. package/.history/src/base-client/components/common/HIS/HButtons/HButtons_20260512175435.vue +0 -706
  19. package/.history/src/base-client/components/common/HIS/HButtons/HButtons_20260512175450.vue +0 -694
  20. package/.history/src/base-client/components/common/HIS/HButtons/HButtons_20260611152602.vue +0 -755
  21. package/.history/src/base-client/components/common/HIS/HForm/HForm_20260513145941.vue +0 -524
  22. package/.history/src/base-client/components/common/HIS/HForm/HForm_20260513153133.vue +0 -731
  23. package/.history/src/base-client/components/common/HIS/HForm/HForm_20260513160316.vue +0 -525
  24. package/.history/src/base-client/components/common/HIS/HForm/HForm_20260601144150.vue +0 -1046
  25. package/.history/src/base-client/components/common/HIS/HFormTable/HFormTable_20260310142713.vue +0 -512
  26. package/.history/src/base-client/components/common/HIS/HFormTable/HFormTable_20260310145118.vue +0 -511
  27. package/.history/src/base-client/components/common/HIS/HFormTable/HFormTable_20260311094834.vue +0 -696
  28. package/.history/src/base-client/components/common/HIS/HFormTable/HFormTable_20260320143028.vue +0 -693
  29. package/.history/src/base-client/components/common/HIS/HFormTable/HFormTable_20260409101450.vue +0 -677
  30. package/.history/src/base-client/components/common/HIS/HTab/HTab_20260625173703.vue +0 -767
  31. package/.history/src/base-client/components/common/HIS/HTab/HTab_20260626112425.vue +0 -803
  32. package/.history/src/base-client/components/common/XAddNativeForm/XAddNativeForm_20260513140637.vue +0 -1455
  33. package/.history/src/base-client/components/common/XAddNativeForm/XAddNativeForm_20260513140935.vue +0 -1441
  34. package/.history/src/base-client/components/common/XAddNativeForm/XAddNativeForm_20260513150818.vue +0 -1441
  35. package/.history/src/base-client/components/common/XAddNativeForm/XAddNativeForm_20260513153119.vue +0 -1442
  36. package/.history/src/base-client/components/common/XAddNativeForm/XAddNativeForm_20260513153126.vue +0 -1486
  37. package/.history/src/base-client/components/common/XForm/XFormItem_20260513140854.vue +0 -1607
  38. package/.history/src/base-client/components/common/XMarkdownViewer/XMarkdownViewer_20260519140403.vue +0 -643
  39. package/.history/src/base-client/components/common/XMarkdownViewer/XMarkdownViewer_20260519140829.vue +0 -628
  40. package/.history/src/base-client/components/common/XMarkdownViewer/demo_20260519142824.vue +0 -104
  41. package/.history/src/base-client/components/common/XMarkdownViewer/demo_20260519143155.vue +0 -102
  42. package/.history/src/base-client/components/common/XReportGrid/XReport_20260309171231.vue +0 -1241
  43. package/.history/src/base-client/components/common/XReportGrid/XReport_20260309171441.vue +0 -1223
  44. package/.history/src/base-client/components/his/HAi/HAi_20260612174826.vue +0 -472
  45. package/.history/src/base-client/components/his/HAi/HAi_20260612175839.vue +0 -538
  46. package/.history/src/base-client/components/his/HAi/HAi_20260615103331.vue +0 -650
  47. package/.history/src/base-client/components/his/HAi/HAi_20260618140214.vue +0 -1396
  48. package/.history/src/base-client/components/his/HAi/HAi_20260618140556.vue +0 -1396
  49. package/.history/src/base-client/components/his/XHDescriptions/XHDescriptions_20260424134504.vue +0 -1469
  50. package/.history/src/base-client/components/his/XSidebar/XSidebar_20260610171133.vue +0 -788
  51. package/.history/src/base-client/components/his/XSidebar/XSidebar_20260610171151.vue +0 -780
  52. package/.history/src/base-client/components/his/XTransfer/XTransfer_20260511170841.vue +0 -585
  53. package/.history/src/base-client/components/his/XTransfer/XTransfer_20260511171138.vue +0 -787
  54. package/.history/src/base-client/components/his/XTransfer/XTransfer_20260512141830.vue +0 -739
  55. package/.history/src/components/STable/index_20260409155138.js +0 -806
  56. package/.history/src/components/STable/index_20260409155218.js +0 -814
  57. package/.history/src/expression/core/Expression_20260305164427.js +0 -1371
  58. package/.history/src/expression/core/Expression_20260305170258.js +0 -1358
  59. package/.history/src/expression/core/Program_20260305111830.js +0 -944
  60. package/.history/src/expression/core/Program_20260305112041.js +0 -931
  61. package/.history/src/logic/LogicRunner_20260304154306.js +0 -170
  62. package/.history/src/logic/LogicRunner_20260304155553.js +0 -112
  63. package/.history/src/logic/LogicRunner_20260305105834.js +0 -112
  64. package/.history/src/logic/LogicRunner_20260305112718.js +0 -129
  65. package/.history/src/logic/LogicRunner_20260305182436.js +0 -133
  66. package/.history/src/logic/LogicRunner_20260306151301.js +0 -213
  67. package/.history/src/logic/LogicRunner_20260306152419.js +0 -213
  68. package/.history/src/logic/plugins/common/DateTools_20260305154159.js +0 -61
  69. package/.history/src/logic/plugins/common/DateTools_20260305154217.js +0 -44
  70. package/.history/src/logic/plugins/common/DateTools_20260305161014.js +0 -44
  71. package/.history/src/logic/plugins/common/HttpTools_20260305164352.js +0 -80
  72. package/.history/src/logic/plugins/common/HttpTools_20260305170258.js +0 -75
  73. package/.history/src/logic/plugins/common/HttpTools_20260305171634.js +0 -75
  74. package/.history/src/logic/plugins/common/HttpTools_20260306152419.js +0 -72
  75. package/.history/src/services/api/restTools_20260427142149.js +0 -245
  76. package/.history/src/services/api/restTools_20260427142853.js +0 -230
  77. package/.history/src/services/api/restTools_20260519135558.js +0 -230
  78. package/.history/src/services/api/restTools_20260519140825.js +0 -230
  79. package/.history/src/services/api/restTools_20260519151223.js +0 -230
  80. package/.history/src/utils/indexedDB_20260306150918.js +0 -593
  81. package/.history/src/utils/indexedDB_20260306151301.js +0 -586
  82. package/.idea/codeStyles/Project.xml +0 -62
  83. package/.idea/codeStyles/codeStyleConfig.xml +0 -5
  84. package/preview-input-box.html +0 -180
@@ -1,1607 +0,0 @@
1
- <template>
2
- <!-- 输入框 -->
3
- <x-form-col v-if="attr.type === 'input' && show" :occupyCol="attr.occupyCol" :labelCol="labelCol" :mode="mode" :layout="layout" :attrType="attr.type">
4
- <a-form-model-item
5
- v-bind="bindOther"
6
- :rules="effectiveRules"
7
- :ref="attr.model"
8
- :label="showLabel ? attr.name : undefined"
9
- :prop="attr.prop ? attr.prop : attr.model"
10
- >
11
- <!-- 如果配置了后置按钮插槽 -->
12
- <a-input-group
13
- v-if="
14
- ((attr.inputOnAfterName && attr.inputOnAfterFunc) || (attr.inputOnAfterIcon && attr.inputOnAfterIconFunc)) &&
15
- mode !== '查询'
16
- "
17
- style="display: flex; width: 100%; padding: 4px 0"
18
- compact
19
- >
20
- <a-input
21
- v-model="form[attr.model]"
22
- autocomplete="off"
23
- :read-only="readOnly"
24
- :disabled="disabled && !readOnly"
25
- :whitespace="true"
26
- @input="attr.dataChangeFunc && debouncedDataChangeFunc()"
27
- :suffix="attr.inputSuffix && mode !== '新增' ? attr.inputSuffix : ''"
28
- @blur="mode !== '查询' && attr.inputOnBlurFunc && emitFunc(attr.inputOnBlurFunc, attr)"
29
- @keyup.enter="mode !== '查询' && attr.inputOnEnterFunc && emitFunc(attr.inputOnEnterFunc, attr)"
30
- :placeholder="attr.placeholder ? attr.placeholder : '请输入' + attr.name.replace(/\s*/g, '')"
31
- :ref="rowIndex !== undefined ? `${rowIndex}-${attr.model}input` : `${attr.model}input`"
32
- :id="rowIndex !== undefined ? `${rowIndex}-${attr.model}input` : `${attr.model}input`"
33
- />
34
- <a-button
35
- v-if="attr.inputOnAfterName && attr.inputOnAfterFunc && !attr.inputOnAfterName.includes('|')"
36
- style="width: auto; min-width: 4rem; max-width: 6rem"
37
- type="primary"
38
- @click="emitFunc(attr.inputOnAfterFunc, attr)"
39
- >
40
- {{ attr.inputOnAfterName }}
41
- </a-button>
42
- <!-- 仅可以配置 一个按钮 以及 一个图标插槽 -->
43
- <a-button
44
- style="width: 2rem; flex-shrink: 0"
45
- v-else-if="attr.inputOnAfterIcon"
46
- :type="attr.inputOnAfterIcon && attr.inputOnAfterName ? 'primary' : ''"
47
- :icon="attr.inputOnAfterIcon || 'question'"
48
- @click="emitFunc(attr.inputOnAfterIconFunc, attr)"
49
- ></a-button>
50
- <!-- 状态按钮 -->
51
- <x-status-button
52
- v-else
53
- :states="parseStates(attr.inputOnAfterName, attr.inputOnAfterFunc)"
54
- v-on="generateDynamicEvents(attr.inputOnAfterFunc, attr)"
55
- style="width: auto; min-width: 4rem; max-width: 6rem"
56
- />
57
- </a-input-group>
58
- <a-input-number
59
- v-else-if="attr.numberInput && !readOnly"
60
- v-model="form[attr.model]"
61
- autocomplete="off"
62
- :whitespace="true"
63
- @change="attr.dataChangeFunc && debouncedDataChangeFunc()"
64
- :disabled="disabled && !readOnly"
65
- style="width: 100%"
66
- @blur="mode !== '查询' && attr.inputOnBlurFunc && emitFunc(attr.inputOnBlurFunc, attr)"
67
- @keyup.enter="mode !== '查询' && attr.inputOnEnterFunc && emitFunc(attr.inputOnEnterFunc, attr)"
68
- :suffix="attr.inputSuffix && mode !== '新增' ? attr.inputSuffix : ''"
69
- :placeholder="attr.placeholder ? attr.placeholder : '请输入' + attr.name.replace(/\s*/g, '')"
70
- :ref="rowIndex !== undefined ? `${rowIndex}-${attr.model}input` : `${attr.model}input`"
71
- :id="rowIndex !== undefined ? `${rowIndex}-${attr.model}input` : `${attr.model}input`"
72
- />
73
- <a-input
74
- v-else
75
- v-model="form[attr.model]"
76
- autocomplete="off"
77
- :whitespace="true"
78
- :read-only="readOnly"
79
- :disabled="disabled && !readOnly"
80
- @input="attr.dataChangeFunc && debouncedDataChangeFunc()"
81
- :suffix="attr.inputSuffix && mode !== '新增' ? attr.inputSuffix : ''"
82
- style="width: 100%"
83
- @blur="mode !== '查询' && attr.inputOnBlurFunc && emitFunc(attr.inputOnBlurFunc, attr)"
84
- @keyup.enter="mode !== '查询' && attr.inputOnEnterFunc && emitFunc(attr.inputOnEnterFunc, attr)"
85
- :placeholder="attr.placeholder ? attr.placeholder : '请输入' + attr.name.replace(/\s*/g, '')"
86
- :ref="rowIndex !== undefined ? `${rowIndex}-${attr.model}input` : `${attr.model}input`"
87
- :id="rowIndex !== undefined ? `${rowIndex}-${attr.model}input` : `${attr.model}input`"
88
- />
89
- </a-form-model-item>
90
- </x-form-col>
91
- <!-- 下拉框 -->
92
- <x-form-col v-else-if="attr.type === 'select' && show" :labelCol="labelCol" :mode="mode" :layout="layout" :attrType="attr.type">
93
- <a-form-model-item
94
- v-bind="bindOther"
95
- :rules="effectiveRules"
96
- v-if="!attr.showMode || mode === '查询' || attr.showMode === 'select'"
97
- :ref="attr.model"
98
- :label="showLabel ? attr.name : undefined"
99
- :prop="attr.prop ? attr.prop : attr.model"
100
- >
101
- <!-- <span slot="label" class="label-box">{{ showLabel?attr.name:undefined }}</span>-->
102
- <a-select
103
- v-if="!attr.lazyLoad || attr.lazyLoad === 'false'"
104
- v-model="form[attr.model]"
105
- :disabled="disabled || readOnly"
106
- @change="handleSelectChange"
107
- :filter-option="filterOption"
108
- :getPopupContainer="getPopupContainer"
109
- dropdownClassName="custom-dropdown"
110
- :dropdownMatchSelectWidth="false"
111
- :dropdownStyle="{ position: 'absolute' }"
112
- :placeholder="attr.placeholder ? attr.placeholder : '请选择'"
113
- show-search
114
- :allowClear="true"
115
- :getCalendarContainer="triggerNode => triggerNode.parentNode"
116
- >
117
- <a-select-option v-if="mode === '查询'" key="999999" value="">全部</a-select-option>
118
- <template v-if="attr.keys">
119
- <a-select-option v-for="(item, index) in attr.keys" :key="index.value" :value="item.value + ''">
120
- {{ item.label }}
121
- </a-select-option>
122
- </template>
123
- <template v-else-if="attr.keyName">
124
- <template v-if="attr.keyName.indexOf('async ') !== -1 || attr.keyName.indexOf('function ') !== -1">
125
- <a-select-option v-for="(item, index) in optionForFunc" :key="index.value" :value="item.value + ''">
126
- <template>
127
- {{ item.label }}
128
- </template>
129
- </a-select-option>
130
- </template>
131
- <template v-else>
132
- <a-select-option v-for="(item, index) in option" :key="index.value" :value="item.value + ''">
133
- <template
134
- v-if="
135
- attr.keyName.indexOf('logic@') !== -1 ||
136
- attr.keyName.indexOf('config@') !== -1 ||
137
- attr.keyName.indexOf('search@') !== -1
138
- "
139
- >
140
- {{ item.label }}
141
- </template>
142
- <template v-else-if="item.status">
143
- <!-- 徽标(badge) -->
144
- <a-badge v-if="item.status !== 'gary'" :color="item.status" :text="item.label" />
145
- <a-badge v-else color="#D9D9D9" :text="item.label" />
146
- </template>
147
- </a-select-option>
148
- </template>
149
- </template>
150
- </a-select>
151
- <a-select
152
- v-else
153
- v-model="form[attr.model]"
154
- :disabled="disabled || readOnly"
155
- @change="handleSelectChange"
156
- :filter-option="filterOption"
157
- :getPopupContainer="getPopupContainer"
158
- dropdownClassName="custom-dropdown"
159
- :dropdownMatchSelectWidth="false"
160
- :dropdownStyle="{ position: 'absolute' }"
161
- :placeholder="attr.placeholder ? attr.placeholder : '搜索' + attr.name"
162
- show-search
163
- @search="fetchFunction"
164
- >
165
- <template #notFoundContent>
166
- <a-spin v-if="searching" size="small" />
167
- </template>
168
- <a-select-option v-if="mode === '查询'" key="999999" value="">全部</a-select-option>
169
- <a-select-option v-for="(item, index) in option" :key="index" :value="item.value + ''">
170
- {{ item.label }}
171
- </a-select-option>
172
- </a-select>
173
- </a-form-model-item>
174
- <a-form-model-item
175
- :disabled="disabled || readOnly"
176
- v-bind="bindOther"
177
- :rules="effectiveRules"
178
- v-else-if="attr.showMode === 'radioGroup'"
179
- :ref="attr.model"
180
- :label="showLabel ? attr.name : undefined"
181
- :prop="attr.prop ? attr.prop : attr.model"
182
- >
183
- <a-radio-group v-model="form[attr.model]">
184
- <a-radio-button v-for="modeItem in option" :key="modeItem.value" :value="modeItem.value">
185
- {{ modeItem.label }}
186
- </a-radio-button>
187
- </a-radio-group>
188
- </a-form-model-item>
189
- <a-form-model-item
190
- v-bind="bindOther"
191
- v-else-if="attr.showMode === 'clickChange' && option.length > 0"
192
- :ref="attr.model"
193
- :label="showLabel ? attr.name : undefined"
194
- :prop="attr.prop ? attr.prop : attr.model"
195
- >
196
- <XClickChangeBtn></XClickChangeBtn>
197
- </a-form-model-item>
198
- </x-form-col>
199
- <!-- 多选框 -->
200
- <x-form-col v-else-if="attr.type === 'checkbox' && show" :labelCol="labelCol" :mode="mode" :layout="layout" :attrType="attr.type">
201
- <a-form-model-item
202
- v-bind="bindOther"
203
- :rules="effectiveRules"
204
- v-if="!attr.showMode || mode === '查询' || attr.showMode === 'select'"
205
- :ref="attr.model"
206
- :label="showLabel ? attr.name : undefined"
207
- :prop="attr.prop ? attr.prop : attr.model"
208
- >
209
- <a-select
210
- class="multiple_select"
211
- style="width: 100%"
212
- v-if="!attr.lazyLoad || attr.lazyLoad === 'false'"
213
- v-model="form[attr.model]"
214
- :disabled="disabled"
215
- :filter-option="filterOption"
216
- :getPopupContainer="getPopupContainer"
217
- :placeholder="attr.placeholder ? attr.placeholder : '请选择'"
218
- @change="handleCheckboxChange"
219
- :mode="mode === '新增/修改' && attr.chooseForm === 'singleChoice' ? 'default' : 'multiple'"
220
- show-search
221
- allowClear
222
- >
223
- <template v-if="attr.keys">
224
- <a-select-option v-for="(item, index) in attr.keys" :key="index" :value="item.value + ''">
225
- {{ item.label }}
226
- </a-select-option>
227
- </template>
228
- <template v-else-if="attr.keyName">
229
- <template v-if="attr.keyName.indexOf('async ') !== -1 || attr.keyName.indexOf('function ') !== -1">
230
- <a-select-option v-for="(item, index) in optionForFunc" :key="index.value" :value="item.value + ''">
231
- <template>
232
- {{ item.label }}
233
- </template>
234
- </a-select-option>
235
- </template>
236
- <template v-else>
237
- <a-select-option v-for="(item, index) in option" :key="index" :value="item.value">
238
- {{ item.label }}
239
- </a-select-option>
240
- </template>
241
- </template>
242
- </a-select>
243
- <a-select
244
- v-else
245
- class="multiple_select"
246
- v-model="form[attr.model]"
247
- :disabled="disabled"
248
- :filter-option="filterOption"
249
- :getPopupContainer="getPopupContainer"
250
- :placeholder="attr.placeholder ? attr.placeholder : '搜索' + attr.name"
251
- :mode="mode === '新增/修改' && attr.chooseForm === 'singleChoice' ? 'default' : 'multiple'"
252
- style="width: 100%"
253
- @change="handleCheckboxChange"
254
- show-search
255
- allowClear
256
- @search="fetchFunction"
257
- >
258
- <template #notFoundContent>
259
- <a-spin v-if="searching" size="small" />
260
- </template>
261
- <a-select-option v-for="(item, index) in option" :key="index" :value="item.value + ''">
262
- {{ item.label }}
263
- </a-select-option>
264
- </a-select>
265
- </a-form-model-item>
266
- <a-form-model-item
267
- v-bind="bindOther"
268
- :rules="effectiveRules"
269
- v-else
270
- :ref="attr.model"
271
- :label="showLabel ? attr.name : undefined"
272
- :prop="attr.prop ? attr.prop : attr.model"
273
- >
274
- <a-checkbox-group v-model="form[attr.model]" :options="option" @change="handleCheckboxChange" />
275
- </a-form-model-item>
276
- </x-form-col>
277
- <!-- 单选框 -->
278
- <x-form-col v-else-if="attr.type === 'radio' && show" :labelCol="labelCol" :mode="mode" :layout="layout" :attrType="attr.type">
279
- <a-form-model-item
280
- v-bind="bindOther"
281
- :rules="effectiveRules"
282
- v-if="!attr.showMode || attr.type === 'radio'"
283
- :ref="attr.model"
284
- :label="showLabel ? attr.name : undefined"
285
- :prop="attr.prop ? attr.prop : attr.model"
286
- >
287
- <a-radio-group v-model="form[attr.model]" @change="handleRadioChange">
288
- <template v-if="attr.keys">
289
- <a-radio v-for="(item, index) in attr.keys" :key="index" :value="item.value">
290
- {{ item.label }}
291
- </a-radio>
292
- </template>
293
- <template v-else-if="attr.keyName">
294
- <a-radio v-for="(item, index) in option" :key="index" :value="item.value">
295
- {{ item.label }}
296
- </a-radio>
297
- </template>
298
- </a-radio-group>
299
- </a-form-model-item>
300
- <a-form-model-item
301
- v-bind="bindOther"
302
- :rules="effectiveRules"
303
- v-else-if="attr.showMode === 'radioGroup'"
304
- :ref="attr.model"
305
- :label="showLabel ? attr.name : undefined"
306
- :prop="attr.prop ? attr.prop : attr.model"
307
- >
308
- <a-radio-group v-model="form[attr.model]">
309
- <a-radio-button v-for="modeItem in option" :key="modeItem.value" :value="modeItem.value">
310
- {{ modeItem.label }}
311
- </a-radio-button>
312
- </a-radio-group>
313
- </a-form-model-item>
314
- <a-form-model-item
315
- v-bind="bindOther"
316
- :rules="effectiveRules"
317
- v-else-if="attr.showMode === 'clickChange' && option.length > 0"
318
- :ref="attr.model"
319
- :label="showLabel ? attr.name : undefined"
320
- :prop="attr.prop ? attr.prop : attr.model"
321
- >
322
- <XClickChangeBtn></XClickChangeBtn>
323
- </a-form-model-item>
324
- </x-form-col>
325
- <!-- 时间 日期 框整合 -->
326
- <x-form-col
327
- v-else-if="
328
- [
329
- 'datePicker',
330
- 'rangePicker',
331
- 'yearPicker',
332
- 'monthPicker',
333
- 'yearRangePicker',
334
- 'monthRangePicker',
335
- 'timePicker',
336
- 'timeRangePicker'
337
- ].includes(attr.type) && show
338
- "
339
- :labelCol="labelCol"
340
- :mode="mode"
341
- :layout="layout"
342
- :attrType="attr.type"
343
- >
344
- <a-form-model-item
345
- v-bind="bindOther"
346
- :rules="effectiveRules"
347
- :ref="attr.model"
348
- :label="showLabel ? attr.name : undefined"
349
- :prop="attr.prop ? attr.prop : attr.model"
350
- >
351
- <XFormDatePicker
352
- :attr="attr"
353
- :mode="mode"
354
- :enablePopupToBody="enablePopupToBody"
355
- :getCalendarContainer="getPopupContainer"
356
- :disabled="disabled"
357
- :readOnly="readOnly"
358
- :showLabel="showLabel"
359
- @change="attr.dataChangeFunc && debouncedDataChangeFunc()"
360
- v-model="form[attr.model]"
361
- />
362
- </a-form-model-item>
363
- </x-form-col>
364
- <!-- 文本域 -->
365
- <x-form-col v-else-if="attr.type === 'textarea' && show" :labelCol="labelCol" :mode="mode" :layout="layout" :attrType="attr.type">
366
- <!-- :style="layout === 'inline'?{width:'calc(100% - 60px)'}:{}"-->
367
- <a-form-model-item
368
- v-bind="bindOther"
369
- :rules="effectiveRules"
370
- :ref="attr.model"
371
- :label="showLabel ? attr.name : undefined"
372
- :prop="attr.prop ? attr.prop : attr.model"
373
- >
374
- <a-textarea
375
- v-model="form[attr.model]"
376
- autocomplete="off"
377
- style="width: 100%"
378
- :readOnly="readOnly"
379
- :disabled="disabled"
380
- :placeholder="attr.placeholder ? attr.placeholder : '请输入' + attr.name.replace(/\s*/g, '')"
381
- :rows="4"
382
- />
383
- </a-form-model-item>
384
- </x-form-col>
385
- <!-- 文件上传 -->
386
- <x-form-col
387
- v-else-if="(attr.type === 'file' || attr.type === 'image' || attr.type === 'signature') && show"
388
- :labelCol="labelCol"
389
-
390
- :mode="mode"
391
- :layout="layout"
392
- :attrType="attr.type"
393
- >
394
- <a-form-model-item
395
- v-bind="bindOther"
396
- :rules="effectiveRules"
397
- :ref="attr.model"
398
- :label="showLabel ? attr.name : undefined"
399
- :prop="attr.prop ? attr.prop : attr.model"
400
- >
401
- <upload
402
- :files="files"
403
- :signs="signs"
404
- :read-only="readOnly"
405
- :images="images"
406
- :compatible-images="form[attr.model]"
407
- :model="attr"
408
- v-bind="attr"
409
- :service-name="serviceName"
410
- @setFiles="setFiles"
411
- ></upload>
412
- </a-form-model-item>
413
- </x-form-col>
414
- <!-- 省市区选择框 -->
415
- <x-form-col v-else-if="attr.type === 'citySelect' && show" :labelCol="labelCol" :mode="mode" :layout="layout" :attrType="attr.type">
416
- <a-form-model-item
417
- v-bind="bindOther"
418
- :rules="effectiveRules"
419
- :ref="attr.model"
420
- :label="showLabel ? attr.name : undefined"
421
- :prop="attr.prop ? attr.prop : attr.model"
422
- >
423
- <citySelect
424
- @change="attr.dataChangeFunc && debouncedDataChangeFunc()"
425
- ref="citySelect"
426
- v-model="form[attr.model]"
427
- :contexts="attr.contexts"
428
- :value-type="attr.valueType"
429
- :default-value="form[attr.model]"
430
- ></citySelect>
431
- </a-form-model-item>
432
- </x-form-col>
433
- <!-- 地点搜索框 -->
434
- <x-form-col
435
- v-else-if="(attr.type === 'addressSearch' || attr.type === 'coordinateSearch') && show"
436
- :labelCol="labelCol"
437
- :occupyCol="attr.occupyCol"
438
-
439
- :mode="mode"
440
- :layout="layout"
441
- :attrType="attr.type"
442
- >
443
- <a-form-model-item
444
- v-bind="bindOther"
445
- :rules="effectiveRules"
446
- :ref="attr.model"
447
- :label="showLabel ? attr.name : undefined"
448
- :prop="attr.prop ? attr.prop : attr.model"
449
- >
450
- <address-search-combobox
451
- :emitFunc="emitFunc"
452
- :attr="attr"
453
- :read-only="readOnly"
454
- :searchResult="form[attr.model]"
455
- :address="{ address: form[attr.model], coords: form[`${attr.model}_lng_lat`] }"
456
- :resultKeys="{ address: attr.model, coords: `${attr.model}_lng_lat` }"
457
- ref="addressSearchCombobox"
458
- searchResultType="Object"
459
- @onSelect="addressSearchComboboxSelect"
460
- @onDivisionsChange="onDivisionsChange"
461
- ></address-search-combobox>
462
- </a-form-model-item>
463
- </x-form-col>
464
- <!-- 颜色选择器 -->
465
- <x-form-col v-else-if="attr.type === 'colorPicker' && show" :labelCol="labelCol" :mode="mode" :layout="layout" :attrType="attr.type">
466
- <a-form-model-item
467
- v-bind="bindOther"
468
- :rules="effectiveRules"
469
- :ref="attr.model"
470
- :label="showLabel ? attr.name : undefined"
471
- :prop="attr.prop ? attr.prop : attr.model"
472
- >
473
- <color-picker-combobox :value="form[attr.model]" :read-only="readOnly" @onSelect="colorPickerComboboxSelect" />
474
- </a-form-model-item>
475
- </x-form-col>
476
- <!-- 人员选择框 -->
477
- <x-form-col v-else-if="attr.type === 'personSetting' && show" :labelCol="labelCol" :mode="mode" :layout="layout" :attrType="attr.type">
478
- <a-form-model-item
479
- v-bind="bindOther"
480
- :rules="effectiveRules"
481
- :ref="attr.model"
482
- :label="showLabel ? attr.name : undefined"
483
- :prop="attr.prop ? attr.prop : attr.model"
484
- >
485
- <PersonSetting v-model="form[attr.model]"></PersonSetting>
486
- </a-form-model-item>
487
- </x-form-col>
488
- <!-- 树形选择框 -->
489
- <x-form-col v-else-if="attr.type === 'treeSelect' && show" :labelCol="labelCol" :mode="mode" :layout="layout" :attrType="attr.type">
490
- <x-tree-select
491
- :rules="effectiveRules"
492
- @onChange="handleTreeSelectChange"
493
- v-model="form[attr.model]"
494
- :attr="attr"
495
- :disabled="disabled"
496
- :readOnly="readOnly"
497
- @mounted="itemMounted"
498
- ref="xTreeSelect"
499
- ></x-tree-select>
500
- </x-form-col>
501
- <!-- 列表选择框 -->
502
- <x-form-col v-else-if="attr.type === 'listSelect' && show" :labelCol="labelCol" :mode="mode" :layout="layout" :attrType="attr.type">
503
- <a-form-model-item
504
- v-bind="bindOther"
505
- :rules="effectiveRules"
506
- :ref="attr.model"
507
- :label="showLabel ? attr.name : undefined"
508
- :style="
509
- layout === 'inline' && attr.occupyCol && attr.occupyCol > 1
510
- ? { width: `calc(100% - ${attr.occupyCol * 1.533}rem)` }
511
- : {}
512
- "
513
- :prop="attr.prop ? attr.prop : attr.model"
514
- >
515
- <a-popover
516
- ref="rowChoosePopover"
517
- :visible="rowChoosePopoverVisible"
518
- title="选择数据"
519
- placement="bottom"
520
- trigger="focus"
521
- :arrowPointAtCenter="true"
522
- :overlayStyle="{ width: '1000px', height: '30vh' }"
523
- >
524
- <template #content>
525
- <x-report
526
- v-if="isCover"
527
- :use-oss-for-img="false"
528
- :config-name="queryParamsName"
529
- :service-name="serviceName"
530
- :show-img-in-cell="true"
531
- :display-only="true"
532
- :edit-mode="false"
533
- :show-save-button="true"
534
- :no-padding="true"
535
- :dont-format="true"
536
- @rowChoose="rowChoose"
537
- @cancel="closeRowChooseInput"
538
- ></x-report>
539
- <x-form-table
540
- v-else
541
- title="请选择数据"
542
- :queryParamsName="queryParamsName"
543
- :rowSelectMode="true"
544
- :allowSelectRowNum="1"
545
- :service-name="serviceName"
546
- :fixed-query-form="rowChooseFixedQueryValue"
547
- @rowChoose="rowChoose"
548
- @afterQuery="rowChooseSearchAfterQuery"
549
- ref="rowChooseTable"
550
- >
551
- <template #button>
552
- <a-button @click="closeRowChooseInput">关闭</a-button>
553
- </template>
554
- </x-form-table>
555
- </template>
556
- <a-input
557
- v-model="form[attr.model]"
558
- autocomplete="off"
559
- :placeholder="attr.placeholder ? attr.placeholder : '请输入' + attr.name.replace(/\s*/g, '')"
560
- @change="searchRowChooseData"
561
- @focus="showCloseRowChooseInput"
562
- />
563
- </a-popover>
564
- </a-form-model-item>
565
- </x-form-col>
566
- <!-- 评分框 -->
567
- <x-form-col v-else-if="attr.type === 'rate' && show" :labelCol="labelCol" :mode="mode" :layout="layout" :attrType="attr.type">
568
- <a-form-model-item
569
- v-bind="bindOther"
570
- :rules="effectiveRules"
571
- :ref="attr.model"
572
- :label="showLabel ? attr.name : undefined"
573
- :prop="attr.prop ? attr.prop : attr.model"
574
- >
575
- <x-rate
576
- v-model="form[attr.model]"
577
- :mode="mode"
578
- :disabled="disabled"
579
- :query-type="attr.queryType"
580
- :display-count="attr.displayCount"
581
- :max-count="attr.maxCount"
582
- :allow-half="attr.allowHalf"
583
- :icon="attr.rateIcon"
584
- :placeholder="attr.placeholder ? attr.placeholder : '请选择' + attr.name.replace(/\s*/g, '')"
585
- @change="attr.dataChangeFunc && debouncedDataChangeFunc()"
586
- />
587
- </a-form-model-item>
588
- </x-form-col>
589
- <!-- 区间选择器 -->
590
- <x-form-col v-else-if="attr.type === 'intervalPicker' && show" :labelCol="labelCol" :mode="mode" :layout="layout" :attrType="attr.type">
591
- <a-form-model-item
592
- v-bind="bindOther"
593
- :rules="effectiveRules"
594
- :ref="attr.model"
595
- :label="showLabel ? attr.name : undefined"
596
- :prop="attr.prop ? attr.prop : attr.model"
597
- >
598
- <x-interval-picker
599
- v-model="form[attr.model]"
600
- :mode="mode"
601
- :read-only="readOnly"
602
- :disabled="disabled && !readOnly"
603
- :placeholder="attr.placeholder ? attr.placeholder : '请输入' + attr.name.replace(/\s*/g, '')"
604
- :start-placeholder="attr.startPlaceholder || '起始值'"
605
- :end-placeholder="attr.endPlaceholder || '结束值'"
606
- @blur="attr.inputOnBlurFunc && emitFunc(attr.inputOnBlurFunc, attr)"
607
- />
608
- </a-form-model-item>
609
- </x-form-col>
610
- <!-- 车牌号选择 -->
611
- <x-form-col v-else-if="attr.type === 'licensePlate' && show" :labelCol="labelCol" :mode="mode" :layout="layout" :attrType="attr.type">
612
- <a-form-model-item
613
- v-bind="bindOther"
614
- :rules="effectiveRules"
615
- :ref="attr.model"
616
- :label="showLabel ? attr.name : undefined"
617
- :style="
618
- layout === 'inline' && attr.occupyCol && attr.occupyCol > 1
619
- ? { width: `calc(100% - ${attr.occupyCol * 1.533}rem)` }
620
- : {}
621
- "
622
- :prop="attr.prop ? attr.prop : attr.model"
623
- >
624
- <!-- 如果配置了后置按钮插槽 -->
625
- <a-input
626
- v-if="mode === '查询'"
627
- v-model="form[attr.model]"
628
- autocomplete="off"
629
- :whitespace="true"
630
- :read-only="readOnly"
631
- :disabled="disabled && !readOnly"
632
- style="width: 100%"
633
- @blur="attr.inputOnBlurFunc && emitFunc(attr.inputOnBlurFunc, attr)"
634
- :placeholder="attr.placeholder ? attr.placeholder : '请输入' + attr.name.replace(/\s*/g, '')"
635
- :ref="rowIndex !== undefined ? `${rowIndex}-${attr.model}input` : `${attr.model}input`"
636
- />
637
- <x-license-plate
638
- v-else
639
- v-model="form[attr.model]"
640
- @change="attr.dataChangeFunc && debouncedDataChangeFunc()"
641
- ></x-license-plate>
642
- </a-form-model-item>
643
- </x-form-col>
644
- <!-- 录音 -->
645
- <x-form-col v-else-if="attr.type === 'recording' && show" :labelCol="labelCol" >
646
- <recording ref="recording" @recordingData="recordingData"></recording>
647
- </x-form-col>
648
- <!-- 表格录入 -->
649
- <x-form-col v-else-if="attr.type === 'rowEdit' && show" :labelCol="labelCol" :mode="mode" :layout="layout" :attrType="attr.type">
650
- <a-form-model-item
651
- v-bind="bindOther"
652
- :rules="effectiveRules"
653
- :ref="attr.model"
654
- :label="showLabel ? attr.name : undefined"
655
- :prop="attr.prop ? attr.prop : attr.model"
656
- >
657
- <x-form-table
658
- :key="'childTable_' + attr.model"
659
- :title="attr.name"
660
- :queryParamsName="attr.crud"
661
- :localEditMode="true"
662
- :fixed-query-form="childTableFixedQueryForm(attr)"
663
- :service-name="serviceName"
664
- @hook:mounted="h => onComponentMounted(h, attr)"
665
- :ref="'childXFormTable_' + attr.model"
666
- ></x-form-table>
667
- </a-form-model-item>
668
- </x-form-col>
669
- </template>
670
- <script>
671
- import { debounce } from 'ant-design-vue/lib/vc-table/src/utils'
672
- import XFormCol from '@vue2-client/base-client/components/common/XFormCol'
673
- import XBadge from '@vue2-client/base-client/components/common/XBadge'
674
- import CitySelect from '@vue2-client/base-client/components/common/CitySelect'
675
- import PersonSetting from '@vue2-client/base-client/components/common/PersonSetting'
676
- import AddressSearchCombobox from '@vue2-client/base-client/components/common/AddressSearchCombobox'
677
- import Upload from '@vue2-client/base-client/components/common/Upload'
678
- import moment from 'moment'
679
- import { runLogic, getConfigByNameAsync } from '@vue2-client/services/api/common'
680
- import * as util from '@vue2-client/utils/util'
681
- import XTreeSelect from '@vue2-client/base-client/components/common/XForm/XTreeSelect'
682
- import { searchToListOption, searchToOption } from '@vue2-client/services/v3Api'
683
- import { mapState } from 'vuex'
684
- import { executeStrFunctionByContext } from '@vue2-client/utils/runEvalFunction'
685
- import XLicensePlate from '@vue2-client/base-client/components/common/XLicensePlate/XLicensePlate.vue'
686
- import XStatusButton from './XStatusButton.vue'
687
- import XClickChangeBtn from './itemComponent/XClickChangeBtn'
688
- import 'moment/locale/zh-cn'
689
- import XFormDatePicker from '@vue2-client/base-client/components/common/XDatePicker/index.vue'
690
- import XIntervalPicker from '@vue2-client/base-client/components/common/XIntervalPicker/XIntervalPicker.vue'
691
- import XRate from '@vue2-client/base-client/components/common/XRate/index.vue'
692
- import { post } from '@vue2-client/services/api/restTools'
693
- import ColorPickerCombobox from '@vue2-client/base-client/components/common/ColorPickerCombobox/ColorPickerCombobox.vue'
694
- import { createSelectValueTypeHandler } from '@vue2-client/base-client/plugins/selectValueTypeHelper'
695
-
696
- export default {
697
- name: 'XFormItem',
698
- components: {
699
- XFormDatePicker,
700
- XFormTable: () => import('@vue2-client/base-client/components/common/XFormTable/XFormTable.vue'),
701
- Recording: () => import('@vue2-client/base-client/components/common/Recording/Recording.vue'),
702
- XReport: () => import('@vue2-client/base-client/components/common/XReportGrid/XReport.vue'),
703
- XLicensePlate,
704
- XTreeSelect,
705
- XFormCol,
706
- XBadge,
707
- CitySelect,
708
- PersonSetting,
709
- AddressSearchCombobox,
710
- Upload,
711
- XStatusButton,
712
- XClickChangeBtn,
713
- XIntervalPicker,
714
- XRate,
715
- ColorPickerCombobox
716
- },
717
- data() {
718
- // 检索去抖
719
- this.fetchFunction = debounce(this.fetchFunction, 800)
720
- // 初始化selectValueType处理器
721
- this.selectValueTypeHandler = createSelectValueTypeHandler(this)
722
- return {
723
- option: [],
724
- // 最后检索版本
725
- lastFetchId: 0,
726
- // 检索中
727
- searching: false,
728
- searchResult: '',
729
- optionForFunc: [],
730
- // 控制当前表单项是否展示
731
- show: true,
732
- // moment
733
- moment,
734
- // 行选择器浮层是否显示
735
- rowChoosePopoverVisible: false,
736
- // 行选择器CRUD固定查询值
737
- rowChooseFixedQueryValue: undefined,
738
- bindOther: {}
739
- }
740
- },
741
- props: {
742
- attr: {
743
- type: Object,
744
- default: () => {
745
- return {}
746
- }
747
- },
748
- form: {
749
- type: Object,
750
- required: true
751
- },
752
- disabled: {
753
- type: Boolean,
754
- default: () => {
755
- return false
756
- }
757
- },
758
- readOnly: {
759
- type: Boolean,
760
- default: () => {
761
- return false
762
- }
763
- },
764
- mode: {
765
- type: String,
766
- default: () => {
767
- return '查询'
768
- }
769
- },
770
- files: {
771
- type: Array,
772
- default: () => {
773
- return []
774
- }
775
- },
776
- signs: {
777
- type: Array,
778
- default: () => {
779
- return []
780
- }
781
- },
782
- images: {
783
- type: Array,
784
- default: () => {
785
- return []
786
- }
787
- },
788
- // 是否启用时间弹出到最外层
789
- enablePopupToBody: {
790
- type: Boolean,
791
- default: false
792
- },
793
- serviceName: {
794
- type: String,
795
- default: process.env.VUE_APP_SYSTEM_NAME
796
- },
797
- // 调用logic获取数据源的追加参数
798
- getDataParams: {
799
- type: Object,
800
- default: undefined
801
- },
802
- // 布局
803
- layout: {
804
- type: String,
805
- default: 'horizontal'
806
- },
807
- // 环境
808
- env: {
809
- type: String,
810
- default: () => {
811
- return 'prod'
812
- }
813
- },
814
- // 设置表单值
815
- setForm: {
816
- type: Function,
817
- default: val => {
818
- console.log(val)
819
- }
820
- },
821
- showLabel: {
822
- type: Boolean,
823
- default: () => {
824
- return true
825
- }
826
- },
827
- labelCol: {
828
- type: Object,
829
- default: () => {
830
- return { span: 8 }
831
- }
832
- },
833
- rules: {
834
- type: Array,
835
- default: () => {
836
- return undefined
837
- }
838
- },
839
- // 行索引(行编辑模式下使用)
840
- rowIndex: {
841
- type: Number,
842
- default: undefined
843
- }
844
- },
845
- provide() {
846
- return {
847
- FormItemContext: this
848
- }
849
- },
850
- async created() {
851
- this.init()
852
- if (
853
- this.attr.keyName &&
854
- (this.attr?.keyName?.toString().indexOf('async ') !== -1 ||
855
- this.attr?.keyName?.toString()?.indexOf('function') !== -1)
856
- ) {
857
- this.debouncedUpdateOptions = debounce(this.updateOptions, 200)
858
- }
859
- if (this.attr.dataChangeFunc) {
860
- this.debouncedDataChangeFunc = debounce(this.dataChangeFunc, 200)
861
- // 执行一次
862
- this.dataChangeFunc(true)
863
- }
864
- if (this.attr.showFormItemFunc) {
865
- this.debouncedShowFormItemFunc = debounce(this.showFormItemFunc, 100)
866
- // 执行一次
867
- this.showFormItemFunc()
868
- }
869
- if (this.attr.showQueryFormItemFunc) {
870
- this.debouncedShowQueryFormItemFunc = debounce(this.showQueryFormItemFunc, 100)
871
- // 执行一次
872
- this.showQueryFormItemFunc()
873
- }
874
- // 人员联动框增加监听
875
- if (
876
- this?.attr?.keyName?.toString()?.startsWith('search@根据表单项[') &&
877
- this?.attr?.keyName?.toString().endsWith(']联动人员')
878
- ) {
879
- this.debouncedUserLinkFunc = debounce(() => this.updateResOptions('人员'), 200)
880
- }
881
- if (
882
- this?.attr?.keyName?.toString()?.startsWith('search@根据表单项[') &&
883
- this?.attr?.keyName?.toString().endsWith(']联动部门')
884
- ) {
885
- this.debouncedDepLinkFunc = debounce(() => this.updateResOptions('部门'), 200)
886
- }
887
- // xTreeSelect 自己调用 mounted
888
- if (this.attr.type !== 'treeSelect') {
889
- this.$emit('mounted', this.attr)
890
- }
891
- },
892
- computed: {
893
- ...mapState('account', { currUser: 'user', curRoles: 'roles', curPermissions: 'permissions' }),
894
- /**
895
- * 合并 attr.tempRequired 的必填规则,用于自定义校验(customJs)动态显示红星
896
- * tempRequired 由 XAddNativeForm.runCustomValidationForDisplay 根据校验结果设置
897
- * 未开 tempRequired 时直接返回 this.rules(含 undefined),以便 a-form-model-item 合并表单级 rules;勿用 || [] 挡住 FormContext.rules
898
- */
899
- effectiveRules() {
900
- if (this.attr.tempRequired) {
901
- const selectTypes = ['select', 'checkbox', 'radio', 'treeSelect', 'file', 'image', 'citySelect', 'addressSearch', 'personSetting']
902
- const msg = selectTypes.includes(this.attr.type) ? '请选择' + this.attr.name : '请输入' + this.attr.name
903
- return [...(this.rules || []), { required: true, message: msg }]
904
- }
905
- return this.rules
906
- },
907
- queryParamsName() {
908
- if (this.attr.keyName.startsWith('function')) {
909
- // 调用异步函数获取内容
910
- const obj = executeStrFunctionByContext(this, this.attr.keyName, [
911
- this.form,
912
- runLogic,
913
- this.mode,
914
- getConfigByNameAsync
915
- ])
916
- // 处理同步返回值
917
- return this.handleQueryParamsResult(obj)
918
- } else if (this.attr.keyName.startsWith('async ')) {
919
- console.warn('此处不支持异步操作')
920
- return ''
921
- } else {
922
- // 按现有方式处理
923
- return this.attr.keyName.split('@')[this.attr.keyName.split('@').length - 1]
924
- }
925
- },
926
- // 判断弹出时是否Cover,弹出只支持Cover以及CRUD
927
- isCover() {
928
- // 如果 queryParamsName 为空,返回空
929
- if (!this.queryParamsName) {
930
- return false
931
- }
932
- const result = this.queryParamsName.endsWith('Cover')
933
- return result
934
- },
935
- copyForm() {
936
- return JSON.parse(JSON.stringify(this.form))
937
- }
938
- },
939
- watch: {
940
- attr: {
941
- handler() {
942
- this.init()
943
- },
944
- deep: true
945
- },
946
- copyForm: {
947
- handler(newVal, oldVal) {
948
- if (
949
- this.attr.keyName &&
950
- (this.attr.keyName.toString().indexOf('async ') !== -1 ||
951
- this.attr.keyName.toString().indexOf('function') !== -1)
952
- ) {
953
- this.debouncedUpdateOptions()
954
- }
955
- // 如果有自定义是否展示表单项函数
956
- if (this.attr.showFormItemFunc) {
957
- this.debouncedShowFormItemFunc()
958
- }
959
- // 如果有自定义是否展示查询表单项函数
960
- if (this.attr.showQueryFormItemFunc) {
961
- this.debouncedShowQueryFormItemFunc()
962
- }
963
- // 地址搜索框赋值
964
- if (this.attr.type === 'addressSearch' || this.attr.type === 'coordinateSearch') {
965
- this.$refs.addressSearchCombobox.addressInput = this.form[this.attr.model]
966
- }
967
- // 数据源来自人员联动时更新数据
968
- if (
969
- this?.attr?.keyName?.toString()?.startsWith('search@根据表单项[') &&
970
- this?.attr?.keyName?.toString().endsWith(']联动人员')
971
- ) {
972
- const startIndex = this.attr.keyName.indexOf('[') + 1
973
- const endIndex = this.attr.keyName.indexOf(']', startIndex)
974
- const fromModel = this.attr.keyName.substring(startIndex, endIndex).replace('.', '_')
975
- if (JSON.stringify(newVal[fromModel]) !== JSON.stringify(oldVal[fromModel])) {
976
- this.debouncedUserLinkFunc()
977
- }
978
- }
979
- // 数据源来自部门联动时更新数据
980
- if (
981
- this?.attr?.keyName?.toString()?.startsWith('search@根据表单项[') &&
982
- this?.attr?.keyName?.toString().endsWith(']联动部门')
983
- ) {
984
- const startIndex = this.attr.keyName.indexOf('[') + 1
985
- const endIndex = this.attr.keyName.indexOf(']', startIndex)
986
- const fromModel = this.attr.keyName.substring(startIndex, endIndex).replace('.', '_')
987
- if (JSON.stringify(newVal[fromModel]) !== JSON.stringify(oldVal[fromModel])) {
988
- this.debouncedDepLinkFunc()
989
- }
990
- }
991
- },
992
- deep: true
993
- }
994
- },
995
- inject: {
996
- getComponentByName: {
997
- default: () => () => {
998
- console.warn('getComponentByName is not provided')
999
- return null // 或者返回一个默认的函数
1000
- }
1001
- },
1002
- registerComponent: {
1003
- default: () => () => {
1004
- console.warn('registerComponent is not provided')
1005
- return null // 或者返回一个默认的函数
1006
- }
1007
- },
1008
- getSelf: {
1009
- default: () => () => {
1010
- console.warn('getSelf is not provided')
1011
- return null // 或者返回一个默认的函数
1012
- }
1013
- },
1014
- XFormContext: {
1015
- default: () => () => {
1016
- console.warn('XFormContext is not provided')
1017
- return null // 或者返回一个默认的函数
1018
- }
1019
- },
1020
- setRequired: {
1021
- default: () => () => {
1022
- console.warn('setRequired is not provided')
1023
- return null // 或者返回一个默认的函数
1024
- }
1025
- },
1026
- removeRequired: {
1027
- default: () => () => {
1028
- console.warn('removeRequired is not provided')
1029
- return null // 或者返回一个默认的函数
1030
- }
1031
- },
1032
- // 表单组上下文(通过注入传递)
1033
- formGroupContext: {
1034
- default: null
1035
- },
1036
- // 外部数据(通过 XAddNativeForm 的 provide 传递)
1037
- _getExtData: {
1038
- default: () => ({})
1039
- }
1040
- },
1041
- methods: {
1042
- /**
1043
- * 获取外部数据
1044
- * @returns {Object} 外部扩展数据对象 比如收费表单中俄的 用户信息要参与表单判断
1045
- */
1046
- getExtData() {
1047
- return (this._getExtData && typeof this._getExtData === 'function') ? this._getExtData() : {}
1048
- },
1049
- // 处理 queryParams 结果并更新 rowChooseFixedQueryValue
1050
- handleQueryParamsResult(obj) {
1051
- let configName = ''
1052
- if (obj && typeof obj === 'object') {
1053
- // obj 是一个对象,并且不是数组
1054
- if (Object.prototype.hasOwnProperty.call(obj, 'configName')) {
1055
- configName = obj?.configName
1056
- }
1057
- if (Object.prototype.hasOwnProperty.call(obj, 'fixedQueryForm')) {
1058
- if (obj?.fixedQueryForm && typeof obj?.fixedQueryForm === 'object') {
1059
- this.rowChooseFixedQueryValue = Object.assign({}, this.rowChooseFixedQueryValue, obj.fixedQueryForm)
1060
- }
1061
- }
1062
- } else if (obj && typeof obj === 'string') {
1063
- configName = obj
1064
- }
1065
- return configName
1066
- },
1067
- // 根据selectValueType预处理options数据
1068
- processOptionsForValueType(options) {
1069
- return this.selectValueTypeHandler.processOptions(options, this.attr.selectValueType)
1070
- },
1071
-
1072
- // 处理both模式的数据,为表单添加label字段
1073
- processBothModeData() {
1074
- this.selectValueTypeHandler.processBothMode()
1075
- },
1076
- // 获取所有表单组数据(通过 formGroupContext)
1077
- getAllFormData() {
1078
- if (this.formGroupContext && this.formGroupContext.allFormData) {
1079
- return this.formGroupContext.allFormData
1080
- }
1081
- return {}
1082
- },
1083
-
1084
- // 根据value查找对应的label(支持单选和多选)
1085
- findLabelByValue(value) {
1086
- return this.selectValueTypeHandler.findLabel(value, this.option)
1087
- },
1088
-
1089
- // 统一的表单项change处理逻辑
1090
- handleFormItemChange() {
1091
- // 处理both模式
1092
- if (this.attr.selectValueType === 'both') {
1093
- this.$nextTick(() => {
1094
- this.selectValueTypeHandler.processBothMode()
1095
- })
1096
- }
1097
- // 处理label模式
1098
- if (this.attr.selectValueType === 'label') {
1099
- this.$nextTick(() => {
1100
- this.selectValueTypeHandler.processLabelMode()
1101
- })
1102
- }
1103
- // 处理扩展字段
1104
- this.selectValueTypeHandler.processExtField()
1105
- // 处理原有的dataChangeFunc
1106
- if (this.attr.dataChangeFunc) {
1107
- this.debouncedDataChangeFunc()
1108
- }
1109
- },
1110
-
1111
- // Select组件change处理
1112
- handleSelectChange(a,b,c) {
1113
- console.warn(a,b,c)
1114
- this.handleFormItemChange()
1115
- },
1116
-
1117
- // Checkbox组件change处理
1118
- handleCheckboxChange() {
1119
- this.handleFormItemChange()
1120
- },
1121
-
1122
- // Radio组件change处理
1123
- handleRadioChange() {
1124
- this.handleFormItemChange()
1125
- },
1126
-
1127
- // TreeSelect组件change处理(通过XTreeSelect组件回调)
1128
- handleTreeSelectChange() {
1129
- this.handleFormItemChange()
1130
- },
1131
-
1132
- // 把内部的crud表单录入放到表单中,以便外部可以调用
1133
- onComponentMounted(h, attr) {
1134
- console.log('crud表单', h)
1135
- if (attr.crud) {
1136
- this.registerComponent(attr.model, this.$refs['childXFormTable_' + attr.model])
1137
- }
1138
- },
1139
- childTableFixedQueryForm(item) {
1140
- console.log('传递的form', this.form)
1141
- if (this.modifyModelData?.primaryKeyData) {
1142
- const fixedForm = {}
1143
- fixedForm[item.childTableForeignKeyName] = Object.values(this.modifyModelData.primaryKeyData)[0]
1144
- return fixedForm
1145
- }
1146
- return null
1147
- },
1148
- // 动态生成事件绑定对象
1149
- generateDynamicEvents(inputOnAfterFunc, attr) {
1150
- const events = {}
1151
- const states = this.parseStates(attr.inputOnAfterName, inputOnAfterFunc)
1152
-
1153
- states.forEach(state => {
1154
- // 动态绑定事件名到 emitFunc
1155
- events[state.event] = () => {
1156
- console.info('事件名', state.event)
1157
- this.emitFunc(state.event, attr)
1158
- }
1159
- })
1160
-
1161
- return events // 返回 { state1Event: handler, state2Event: handler, ... }
1162
- },
1163
- parseStates(input, events) {
1164
- const eventNames = events.split('|')
1165
- return input.split('|').map((label, index) => ({
1166
- label,
1167
- event: eventNames[index] // 如果没有提供事件名称,则使用默认值
1168
- }))
1169
- },
1170
- focusInput() {
1171
- if (this.attr.defaultFocus) {
1172
- this.$nextTick(h => {
1173
- const el = this.$refs[`${this.attr.model}input`]?.$el
1174
- let inputEl
1175
- if (el) {
1176
- if (el.tagName.toLowerCase() === 'input') {
1177
- inputEl = el
1178
- } else {
1179
- inputEl = el.querySelector('input')
1180
- }
1181
- }
1182
- if (inputEl) {
1183
- inputEl.focus()
1184
- if (inputEl.type === 'number') {
1185
- if (inputEl.valueAsNumber) {
1186
- inputEl.setSelectionRange(0, inputEl.valueAsNumber.toString().length)
1187
- }
1188
- } else {
1189
- if (inputEl.value) {
1190
- inputEl.setSelectionRange(0, inputEl.value.length)
1191
- }
1192
- }
1193
- }
1194
- })
1195
- }
1196
- },
1197
- // 更新人员下拉框数据
1198
- async updateResOptions(type) {
1199
- if (
1200
- this?.attr?.keyName?.toString()?.startsWith('search@根据表单项[') &&
1201
- this?.attr?.keyName?.toString()?.endsWith(`]联动${type}`)
1202
- ) {
1203
- const startIndex = this.attr.keyName.indexOf('[') + 1
1204
- const endIndex = this.attr.keyName.indexOf(']', startIndex)
1205
- const fromModel = this.attr.keyName.substring(startIndex, endIndex).replace('.', '_')
1206
- // 获取表单字段的实际值(优先使用originData中的原始值)
1207
- const rawFieldValue =
1208
- this.form.originData && this.form.originData[fromModel]
1209
- ? this.form.originData[fromModel]
1210
- : this.form[fromModel]
1211
-
1212
- // 确保数据为数组格式(用于filter参数)
1213
- const filterValues = Array.isArray(rawFieldValue) ? rawFieldValue : [rawFieldValue]
1214
- if (fromModel?.length && filterValues?.length) {
1215
- const searchData = {
1216
- source: `获取${type}`,
1217
- userid: this.currUser.id,
1218
- filter: filterValues,
1219
- filterType: fromModel.indexOf('org') > -1 ? 'org' : 'dep'
1220
- }
1221
- const tempArray = []
1222
- await searchToListOption(searchData, res => {
1223
- this.getDataCallback(
1224
- res.filter(h => {
1225
- if (fromModel.indexOf('org') > -1) {
1226
- if (type === '部门') {
1227
- if (
1228
- filterValues?.includes(h.orgid || h.f_organization_id) ||
1229
- filterValues?.includes(h.parentid) ||
1230
- tempArray.includes(h.parentid)
1231
- ) {
1232
- tempArray.push(h.value)
1233
- return true
1234
- }
1235
- return false
1236
- } else {
1237
- return filterValues?.includes(h.orgid || h.f_organization_id || h.parentid)
1238
- }
1239
- } else {
1240
- return filterValues?.includes(h?.parentid)
1241
- }
1242
- })
1243
- )
1244
- })
1245
- }
1246
- }
1247
- },
1248
- // js 函数作为数据源
1249
- async updateOptions() {
1250
- if (
1251
- this.attr.keyName &&
1252
- (this.attr.keyName.indexOf('async ') !== -1 || this.attr.keyName.indexOf('function ') !== -1)
1253
- ) {
1254
- const rawOptions = await executeStrFunctionByContext(this, this.attr.keyName, [
1255
- this.form,
1256
- runLogic,
1257
- this.mode,
1258
- getConfigByNameAsync,
1259
- post
1260
- ])
1261
- // 根据selectValueType预处理options数据
1262
- this.optionForFunc = this.processOptionsForValueType(rawOptions)
1263
- const option = this.optionForFunc
1264
- this.getDataCallback(option)
1265
- }
1266
- },
1267
- // f 是否是初始化执行的
1268
- async dataChangeFunc(f = false) {
1269
- if (this.attr.dataChangeFunc) {
1270
- await executeStrFunctionByContext(this, this.attr.dataChangeFunc, [
1271
- this.form,
1272
- this.setForm,
1273
- this.attr,
1274
- util,
1275
- this.mode,
1276
- runLogic,
1277
- getConfigByNameAsync,
1278
- f
1279
- ])
1280
- }
1281
- },
1282
- async showFormItemFunc() {
1283
- if (this.attr.showFormItemFunc) {
1284
- const obj = executeStrFunctionByContext(this, this.attr.showFormItemFunc, [
1285
- this.form,
1286
- this.setForm,
1287
- this.attr,
1288
- util,
1289
- this.mode,
1290
- this.curPermissions,
1291
- this.curRoles
1292
- ])
1293
- // 判断是 bool 还是 obj 兼容
1294
- if (typeof obj === 'boolean') {
1295
- this.show = obj
1296
- } else if (obj && typeof obj === 'object') {
1297
- console.warn('showFormItemFunc obj', obj)
1298
- // obj 是一个对象,并且不是数组
1299
- if (Object.prototype.hasOwnProperty.call(obj, 'show')) {
1300
- this.show = obj?.show
1301
- }
1302
- if (Object.prototype.hasOwnProperty.call(obj, 'readOnly')) {
1303
- this.readOnly = obj?.readOnly
1304
- }
1305
- if (Object.prototype.hasOwnProperty.call(obj, 'disabled')) {
1306
- this.disabled = obj?.disabled
1307
- }
1308
- }
1309
- } else {
1310
- this.show = true
1311
- }
1312
- },
1313
- async showQueryFormItemFunc() {
1314
- if (this.attr.showQueryFormItemFunc) {
1315
- const obj = executeStrFunctionByContext(this, this.attr.showQueryFormItemFunc, [
1316
- this.form,
1317
- this.setForm,
1318
- this.attr,
1319
- util,
1320
- this.mode,
1321
- this.curPermissions,
1322
- this.curRoles
1323
- ])
1324
- // 判断是 bool 还是 obj 兼容
1325
- if (typeof obj === 'boolean') {
1326
- this.show = obj
1327
- } else if (obj && typeof obj === 'object') {
1328
- // obj 是一个对象,并且不是数组
1329
- if (Object.prototype.hasOwnProperty.call(obj, 'show')) {
1330
- this.show = obj?.show
1331
- }
1332
- if (Object.prototype.hasOwnProperty.call(obj, 'readOnly')) {
1333
- this.readOnly = obj?.readOnly
1334
- }
1335
- if (Object.prototype.hasOwnProperty.call(obj, 'disabled')) {
1336
- this.disabled = obj?.disabled
1337
- }
1338
- }
1339
- } else {
1340
- this.show = true
1341
- }
1342
- },
1343
- init() {
1344
- // flex赋值逻辑已移至XFormCol组件内部处理
1345
- // 不再在此处设置attr.flex,由XFormCol根据mode、layout、attrType自动计算
1346
- if (this.attr.keyName && typeof this.attr.keyName === 'string') {
1347
- if (this.attr.keyName.indexOf('logic@') !== -1) {
1348
- const data = Object.assign(this.getExtData(), { serviceName: process.env.VUE_APP_SYSTEM_NAME })
1349
- this.getData(data, res => this.getDataCallback(res))
1350
- } else if (this.attr.keyName.indexOf('search@') !== -1) {
1351
- // `tool.getFullTree(this.getRights().where(row.getType()==$organization$))`
1352
- // 判断是否根据角色查询
1353
- let source = this.attr.keyName.substring(7)
1354
- const userid = this.currUser.id
1355
- let roleName = 'roleName'
1356
- if (source.startsWith('根据角色[') && source.endsWith(']获取人员')) {
1357
- const startIndex = source.indexOf('[') + 1
1358
- const endIndex = source.indexOf(']', startIndex)
1359
- roleName = source.substring(startIndex, endIndex)
1360
- source = '根据角色获取人员'
1361
- }
1362
- const searchData = { source, userid, roleName }
1363
- // 判断是否根据某个表单项联动 仅返回列表结构并筛选
1364
- if (source.startsWith('根据表单项[') && source.endsWith(']联动人员')) {
1365
- this.updateResOptions('人员')
1366
- } else if (source.startsWith('根据表单项[') && source.endsWith(']联动部门')) {
1367
- this.updateResOptions('部门')
1368
- } else if (this.attr.type === 'select' || this.attr.type === 'checkbox') {
1369
- // 仅获取最内层数据
1370
- searchToListOption(searchData, res => this.getDataCallback(res))
1371
- } else {
1372
- // 其他资源通用逻辑
1373
- searchToOption(searchData, res => this.getDataCallback(res))
1374
- }
1375
- } else if (this.attr.keyName.indexOf('async ') !== -1 || this.attr.keyName.indexOf('function ') !== -1) {
1376
- this.updateOptions()
1377
- } else if (this.attr.keyName.indexOf('systemParam@') !== -1 && this.attr.keyName.length >= 12 && this.attr.keyName.substring(0, 12) === 'systemParam@') {
1378
- const configName = this.attr.keyName.substring(12)
1379
- if (configName && configName !== 'undefined' && this.currUser.appdata && this.currUser.appdata.params) {
1380
- this.getDataCallback(this.currUser.appdata.params[configName])
1381
- }
1382
- } else {
1383
- let configName
1384
- if (this.attr.keyName.indexOf('config@') !== -1) {
1385
- configName = this.attr.keyName.substring(7)
1386
- } else {
1387
- configName = this.attr.keyName
1388
- }
1389
- if (configName && configName !== 'undefined') {
1390
- this.$appdata.getDictByKey(
1391
- configName,
1392
- this.serviceName,
1393
- res => this.getDataCallback(res),
1394
- this.env === 'dev'
1395
- )
1396
- }
1397
- }
1398
- } else if (this.attr.keys) {
1399
- // 对静态配置的keys也进行预处理
1400
- this.getDataCallback(this.attr.keys)
1401
- }
1402
- this.focusInput()
1403
- },
1404
- addressSearchComboboxSelect(data) {
1405
- this.form = Object.assign(this.form, JSON.parse(data))
1406
- },
1407
- onDivisionsChange(data) {
1408
- this.emitFunc('addressSearchComboboxSelect', {
1409
- key: this.attr.model,
1410
- value: data
1411
- })
1412
- },
1413
- getDataCallback(res) {
1414
- // 根据selectValueType预处理options数据
1415
- this.option = this.processOptionsForValueType(res)
1416
-
1417
- if (this.attr.type === 'treeSelect') {
1418
- this.$nextTick(() => {
1419
- this.$refs.xTreeSelect.init({
1420
- option: this.option,
1421
- form: this.form,
1422
- queryType: this.attr.queryType,
1423
- name: this.attr.name,
1424
- model: this.attr.model,
1425
- mode: this.mode,
1426
- })
1427
- })
1428
- } else if (this.attr.type === 'radio' || ['radioGroup', 'clickChange'].includes(this.attr.showMode)) {
1429
- this.initRadioValue()
1430
- }
1431
- },
1432
- initRadioValue() {
1433
- const model = this.attr.model
1434
- if (
1435
- this.mode === '新增/修改' &&
1436
- (this.form[model] === undefined || this.form[model] === null) &&
1437
- !this.attr.prop
1438
- ) {
1439
- if (this.attr.keys && this.attr.keys.length > 1) {
1440
- this.form[model] = this.attr.keys[0].value
1441
- } else if (this.option.length > 1) {
1442
- this.form[model] = this.option[0].value
1443
- }
1444
- }
1445
- },
1446
- // 文件框时设置上传组件的值
1447
- setFiles(fileIds) {
1448
- if (!this.form[this.attr.model]) {
1449
- this.form[this.attr.model] = []
1450
- }
1451
- this.form[this.attr.model] = [...fileIds]
1452
- },
1453
- // 懒加载检索方法
1454
- fetchFunction(value) {
1455
- this.lastFetchId += 1
1456
- const fetchId = this.lastFetchId
1457
- this.option = []
1458
- this.searching = true
1459
- this.getData(
1460
- {
1461
- word: value
1462
- },
1463
- res => {
1464
- if (fetchId !== this.lastFetchId) {
1465
- return
1466
- }
1467
- this.option = res
1468
- this.searching = false
1469
- }
1470
- )
1471
- },
1472
- // 获取数据
1473
- getData(value, callbackFun) {
1474
- if (value !== '') {
1475
- const logicName = this.attr.keyName
1476
- const logic = logicName.substring(6)
1477
- // 调用logic前设置参数
1478
- if (this.getDataParams && this.getDataParams[this.attr.model]) {
1479
- Object.assign(value, this.getDataParams[this.attr.model])
1480
- }
1481
- // 获取下拉框数据,启用请求复用策略(相同请求共享结果)
1482
- runLogic(
1483
- logic,
1484
- Object.assign(value, {
1485
- orgId: this.currUser.orgid,
1486
- userId: this.currUser.id
1487
- }),
1488
- this.serviceName,
1489
- this.env === 'dev',
1490
- {
1491
- dedupe: true,
1492
- dedupeStrategy: 'reuse'
1493
- }
1494
- )
1495
- .then(res => {
1496
- callbackFun(res)
1497
- })
1498
- .catch(e => {
1499
- // 重复请求被复用时不会进入 catch,只有真正失败才会
1500
- if (e.code !== 'ERR_DUPLICATE_REQUEST') {
1501
- callbackFun([])
1502
- console.error('获取数据失败:' + e)
1503
- }
1504
- })
1505
- }
1506
- },
1507
- filterOption(input, option) {
1508
- const child = option.componentOptions.children[0]
1509
- if (child.text) {
1510
- return child.text.toLowerCase().indexOf(input.toLowerCase()) >= 0
1511
- } else if (child.elm.innerText) {
1512
- return child.elm.innerText.toLowerCase().indexOf(input.toLowerCase()) >= 0
1513
- } else {
1514
- return child.child.value.toLowerCase().indexOf(input.toLowerCase()) >= 0
1515
- }
1516
- },
1517
- // 表单项变更函数中调用 控制表单组中表单项组名为 groupName 的表单是否展示
1518
- // func:x-form-show(显示)/x-form-no-show(不显示)
1519
- emitShowFormFunc(func, groupName, data) {
1520
- this.emitFunc(func, groupName, data)
1521
- },
1522
- emitFunc(func, data) {
1523
- if(func === 'x-form-show' || func === 'x-form-no-show') {
1524
- this.$emit('x-form-item-emit-func', func, data)
1525
- } else {
1526
- this.$emit('x-form-item-emit-func', func, data, data?.model ? this.form[data.model] : this.form)
1527
- }
1528
- },
1529
- itemMounted(h) {
1530
- this.$emit('mounted', h)
1531
- },
1532
- rowChoose(rows) {
1533
- this.$emit('rowChoose', rows, this.attr, this.closeRowChooseInput)
1534
- },
1535
- searchRowChooseData() {
1536
- if (this.searching) {
1537
- return
1538
- }
1539
- this.lastFetchId += 1
1540
- const fetchId = this.lastFetchId
1541
- this.searching = true
1542
- if (fetchId !== this.lastFetchId) {
1543
- return
1544
- }
1545
- this.rowChooseFixedQueryValue = []
1546
- this.rowChooseFixedQueryValue[this.attr.model] = this.form[this.attr.model]
1547
- this.$nextTick(() => {
1548
- this.$refs.rowChooseTable.refresh(true)
1549
- })
1550
- },
1551
- showCloseRowChooseInput() {
1552
- this.rowChoosePopoverVisible = true
1553
- },
1554
- closeRowChooseInput() {
1555
- this.rowChoosePopoverVisible = false
1556
- },
1557
- rowChooseSearchAfterQuery() {
1558
- this.searching = false
1559
- },
1560
- // 获取 recording 转换后的数据
1561
- getRecodingData() {
1562
- return this.$refs.recording.getRecordingData()
1563
- },
1564
- recordingData(data) {
1565
- this.emitFunc('recordingData', data)
1566
- },
1567
- getPopupContainer(triggerNode) {
1568
- // 行编辑模式特殊处理
1569
- if (typeof this.$vnode?.key === 'string' && this.$vnode.key.startsWith('editRow')) {
1570
- // 限制最多向上查找5层
1571
- let parent = triggerNode.parentNode
1572
- let depth = 0
1573
- const maxDepth = 10
1574
-
1575
- while (parent && parent !== document.body && depth < maxDepth) {
1576
- if (parent.tagName === 'TBODY') {
1577
- return parent
1578
- }
1579
- parent = parent.parentNode
1580
- depth++
1581
- }
1582
- // 如果5层内没找到,回退到body
1583
- return document.body
1584
- }
1585
- return triggerNode.parentNode
1586
- },
1587
- colorPickerComboboxSelect(val) {
1588
- this.form[this.attr.model] = val
1589
- }
1590
- }
1591
- }
1592
- </script>
1593
-
1594
- <style lang="less" scoped>
1595
- .custom-dropdown {
1596
- position: absolute;
1597
- z-index: 1050;
1598
- }
1599
-
1600
- .multiple_select {
1601
- vertical-align: middle;
1602
- :deep(.ant-select-selection) {
1603
- max-height: 32px;
1604
- overflow-y: scroll;
1605
- }
1606
- }
1607
- </style>