vue2-client 1.22.3 → 1.22.4

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 (88) hide show
  1. package/.env.his +19 -19
  2. package/.idea/.name +1 -0
  3. package/.idea/MarsCodeWorkspaceAppSettings.xml +8 -0
  4. package/.idea/deployment.xml +14 -0
  5. package/.idea/gradle.xml +7 -0
  6. package/.idea/inspectionProfiles/Project_Default.xml +6 -0
  7. package/.idea/libraries/contour_plot.xml +9 -0
  8. package/.idea/material_theme_project_new.xml +18 -0
  9. package/.idea/misc.xml +87 -5
  10. package/package.json +1 -1
  11. package/src/base-client/components/common/HIS/HForm/HForm.vue +1186 -1186
  12. package/src/base-client/components/common/XMarkdownViewer/demo.vue +102 -102
  13. package/src/base-client/components/his/HAi/HAi.vue +1177 -1177
  14. package/src/base-client/components/his/XTransfer/index.md +327 -327
  15. package/src/base-client/plugins/GetLoginInfoService.js +4 -4
  16. package/src/utils/login.js +11 -11
  17. package/.history/.eslintrc_20260521171150.js +0 -74
  18. package/.history/.eslintrc_20260521171213.js +0 -74
  19. package/.history/src/base-client/components/common/HIS/HAddNativeForm/HAddNativeForm_20260601154443.vue +0 -726
  20. package/.history/src/base-client/components/common/HIS/HAddNativeForm/HAddNativeForm_20260601154700.vue +0 -478
  21. package/.history/src/base-client/components/common/HIS/HButtons/HButtons_20260512175435.vue +0 -706
  22. package/.history/src/base-client/components/common/HIS/HButtons/HButtons_20260512175450.vue +0 -694
  23. package/.history/src/base-client/components/common/HIS/HButtons/HButtons_20260611152602.vue +0 -755
  24. package/.history/src/base-client/components/common/HIS/HForm/HForm_20260513145941.vue +0 -524
  25. package/.history/src/base-client/components/common/HIS/HForm/HForm_20260513153133.vue +0 -731
  26. package/.history/src/base-client/components/common/HIS/HForm/HForm_20260513160316.vue +0 -525
  27. package/.history/src/base-client/components/common/HIS/HForm/HForm_20260601144150.vue +0 -1046
  28. package/.history/src/base-client/components/common/HIS/HFormTable/HFormTable_20260310142713.vue +0 -512
  29. package/.history/src/base-client/components/common/HIS/HFormTable/HFormTable_20260310145118.vue +0 -511
  30. package/.history/src/base-client/components/common/HIS/HFormTable/HFormTable_20260311094834.vue +0 -696
  31. package/.history/src/base-client/components/common/HIS/HFormTable/HFormTable_20260320143028.vue +0 -693
  32. package/.history/src/base-client/components/common/HIS/HFormTable/HFormTable_20260409101450.vue +0 -677
  33. package/.history/src/base-client/components/common/HIS/HTab/HTab_20260508164645.vue +0 -758
  34. package/.history/src/base-client/components/common/HIS/HTab/HTab_20260508164714.vue +0 -693
  35. package/.history/src/base-client/components/common/HIS/HTab/HTab_20260508171651.vue +0 -716
  36. package/.history/src/base-client/components/common/HIS/HTab/HTab_20260509133717.vue +0 -695
  37. package/.history/src/base-client/components/common/HIS/HTab/HTab_20260509171115.vue +0 -664
  38. package/.history/src/base-client/components/common/XAddNativeForm/XAddNativeForm_20260513140637.vue +0 -1455
  39. package/.history/src/base-client/components/common/XAddNativeForm/XAddNativeForm_20260513140935.vue +0 -1441
  40. package/.history/src/base-client/components/common/XAddNativeForm/XAddNativeForm_20260513150818.vue +0 -1441
  41. package/.history/src/base-client/components/common/XAddNativeForm/XAddNativeForm_20260513153119.vue +0 -1442
  42. package/.history/src/base-client/components/common/XAddNativeForm/XAddNativeForm_20260513153126.vue +0 -1486
  43. package/.history/src/base-client/components/common/XForm/XFormItem_20260513140854.vue +0 -1607
  44. package/.history/src/base-client/components/common/XMarkdownViewer/XMarkdownViewer_20260519140403.vue +0 -643
  45. package/.history/src/base-client/components/common/XMarkdownViewer/XMarkdownViewer_20260519140829.vue +0 -628
  46. package/.history/src/base-client/components/common/XMarkdownViewer/demo_20260519142824.vue +0 -104
  47. package/.history/src/base-client/components/common/XMarkdownViewer/demo_20260519143155.vue +0 -102
  48. package/.history/src/base-client/components/common/XReportGrid/XReport_20260309171231.vue +0 -1241
  49. package/.history/src/base-client/components/common/XReportGrid/XReport_20260309171441.vue +0 -1223
  50. package/.history/src/base-client/components/his/HAi/HAi_20260612174826.vue +0 -472
  51. package/.history/src/base-client/components/his/HAi/HAi_20260612175839.vue +0 -538
  52. package/.history/src/base-client/components/his/HAi/HAi_20260615103331.vue +0 -650
  53. package/.history/src/base-client/components/his/XHDescriptions/XHDescriptions_20260424134504.vue +0 -1469
  54. package/.history/src/base-client/components/his/XSidebar/XSidebar_20260610171133.vue +0 -788
  55. package/.history/src/base-client/components/his/XSidebar/XSidebar_20260610171151.vue +0 -780
  56. package/.history/src/base-client/components/his/XTransfer/XTransfer_20260511170841.vue +0 -585
  57. package/.history/src/base-client/components/his/XTransfer/XTransfer_20260511171138.vue +0 -787
  58. package/.history/src/base-client/components/his/XTransfer/XTransfer_20260512141830.vue +0 -739
  59. package/.history/src/components/STable/index_20260409155138.js +0 -806
  60. package/.history/src/components/STable/index_20260409155218.js +0 -814
  61. package/.history/src/expression/core/Expression_20260305164427.js +0 -1371
  62. package/.history/src/expression/core/Expression_20260305170258.js +0 -1358
  63. package/.history/src/expression/core/Program_20260305111830.js +0 -944
  64. package/.history/src/expression/core/Program_20260305112041.js +0 -931
  65. package/.history/src/logic/LogicRunner_20260304154306.js +0 -170
  66. package/.history/src/logic/LogicRunner_20260304155553.js +0 -112
  67. package/.history/src/logic/LogicRunner_20260305105834.js +0 -112
  68. package/.history/src/logic/LogicRunner_20260305112718.js +0 -129
  69. package/.history/src/logic/LogicRunner_20260305182436.js +0 -133
  70. package/.history/src/logic/LogicRunner_20260306151301.js +0 -213
  71. package/.history/src/logic/LogicRunner_20260306152419.js +0 -213
  72. package/.history/src/logic/plugins/common/DateTools_20260305154159.js +0 -61
  73. package/.history/src/logic/plugins/common/DateTools_20260305154217.js +0 -44
  74. package/.history/src/logic/plugins/common/DateTools_20260305161014.js +0 -44
  75. package/.history/src/logic/plugins/common/HttpTools_20260305164352.js +0 -80
  76. package/.history/src/logic/plugins/common/HttpTools_20260305170258.js +0 -75
  77. package/.history/src/logic/plugins/common/HttpTools_20260305171634.js +0 -75
  78. package/.history/src/logic/plugins/common/HttpTools_20260306152419.js +0 -72
  79. package/.history/src/services/api/restTools_20260427142149.js +0 -245
  80. package/.history/src/services/api/restTools_20260427142853.js +0 -230
  81. package/.history/src/services/api/restTools_20260519135558.js +0 -230
  82. package/.history/src/services/api/restTools_20260519140825.js +0 -230
  83. package/.history/src/services/api/restTools_20260519151223.js +0 -230
  84. package/.history/src/utils/indexedDB_20260306150918.js +0 -593
  85. package/.history/src/utils/indexedDB_20260306151301.js +0 -586
  86. package/.idea/codeStyles/Project.xml +0 -62
  87. package/.idea/codeStyles/codeStyleConfig.xml +0 -5
  88. 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>