vue2-client 1.22.2 → 1.22.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (170) hide show
  1. package/.claude/settings.local.json +30 -30
  2. package/.env.his +19 -19
  3. package/.eslintrc.js +74 -74
  4. package/.history/.eslintrc_20260521171150.js +74 -0
  5. package/.history/.eslintrc_20260521171213.js +74 -0
  6. package/.history/src/base-client/components/common/HIS/HAddNativeForm/HAddNativeForm_20260601154443.vue +726 -0
  7. package/.history/src/base-client/components/common/HIS/HAddNativeForm/HAddNativeForm_20260601154700.vue +478 -0
  8. package/.history/src/base-client/components/common/HIS/HButtons/HButtons_20260512175435.vue +706 -0
  9. package/.history/src/base-client/components/common/HIS/HButtons/HButtons_20260512175450.vue +694 -0
  10. package/.history/src/base-client/components/common/HIS/HButtons/HButtons_20260611152602.vue +755 -0
  11. package/.history/src/base-client/components/common/HIS/HForm/HForm_20260513145941.vue +524 -0
  12. package/.history/src/base-client/components/common/HIS/HForm/HForm_20260513153133.vue +731 -0
  13. package/.history/src/base-client/components/common/HIS/HForm/HForm_20260513160316.vue +525 -0
  14. package/.history/src/base-client/components/common/HIS/HForm/HForm_20260601144150.vue +1046 -0
  15. package/.history/src/base-client/components/common/HIS/HFormTable/HFormTable_20260310142713.vue +512 -0
  16. package/.history/src/base-client/components/common/HIS/HFormTable/HFormTable_20260310145118.vue +511 -0
  17. package/.history/src/base-client/components/common/HIS/HFormTable/HFormTable_20260311094834.vue +696 -0
  18. package/.history/src/base-client/components/common/HIS/HFormTable/HFormTable_20260320143028.vue +693 -0
  19. package/.history/src/base-client/components/common/HIS/HFormTable/HFormTable_20260409101450.vue +677 -0
  20. package/.history/src/base-client/components/common/HIS/HTab/HTab_20260508164645.vue +758 -0
  21. package/.history/src/base-client/components/common/HIS/HTab/HTab_20260508164714.vue +693 -0
  22. package/.history/src/base-client/components/common/HIS/HTab/HTab_20260508171651.vue +716 -0
  23. package/.history/src/base-client/components/common/HIS/HTab/HTab_20260509133717.vue +695 -0
  24. package/.history/src/base-client/components/common/HIS/HTab/HTab_20260509171115.vue +664 -0
  25. package/.history/src/base-client/components/common/XAddNativeForm/XAddNativeForm_20260513140637.vue +1455 -0
  26. package/.history/src/base-client/components/common/XAddNativeForm/XAddNativeForm_20260513140935.vue +1441 -0
  27. package/.history/src/base-client/components/common/XAddNativeForm/XAddNativeForm_20260513150818.vue +1441 -0
  28. package/.history/src/base-client/components/common/XAddNativeForm/XAddNativeForm_20260513153119.vue +1442 -0
  29. package/.history/src/base-client/components/common/XAddNativeForm/XAddNativeForm_20260513153126.vue +1486 -0
  30. package/.history/src/base-client/components/common/XForm/XFormItem_20260513140854.vue +1607 -0
  31. package/.history/src/base-client/components/common/XMarkdownViewer/XMarkdownViewer_20260519140403.vue +643 -0
  32. package/.history/src/base-client/components/common/XMarkdownViewer/XMarkdownViewer_20260519140829.vue +628 -0
  33. package/.history/src/base-client/components/common/XMarkdownViewer/demo_20260519142824.vue +104 -0
  34. package/.history/src/base-client/components/common/XMarkdownViewer/demo_20260519143155.vue +102 -0
  35. package/.history/src/base-client/components/common/XReportGrid/XReport_20260309171231.vue +1241 -0
  36. package/.history/src/base-client/components/common/XReportGrid/XReport_20260309171441.vue +1223 -0
  37. package/.history/src/base-client/components/his/HAi/HAi_20260612174826.vue +472 -0
  38. package/.history/src/base-client/components/his/HAi/HAi_20260612175839.vue +538 -0
  39. package/.history/src/base-client/components/his/HAi/HAi_20260615103331.vue +650 -0
  40. package/.history/src/base-client/components/his/XHDescriptions/XHDescriptions_20260424134504.vue +1469 -0
  41. package/.history/src/base-client/components/his/XSidebar/XSidebar_20260610171133.vue +788 -0
  42. package/.history/src/base-client/components/his/XSidebar/XSidebar_20260610171151.vue +780 -0
  43. package/.history/src/base-client/components/his/XTransfer/XTransfer_20260511170841.vue +585 -0
  44. package/.history/src/base-client/components/his/XTransfer/XTransfer_20260511171138.vue +787 -0
  45. package/.history/src/base-client/components/his/XTransfer/XTransfer_20260512141830.vue +739 -0
  46. package/.history/src/components/STable/index_20260409155138.js +806 -0
  47. package/.history/src/components/STable/index_20260409155218.js +814 -0
  48. package/.history/src/expression/core/Expression_20260305164427.js +1371 -0
  49. package/.history/src/expression/core/Expression_20260305170258.js +1358 -0
  50. package/.history/src/expression/core/Program_20260305111830.js +944 -0
  51. package/.history/src/expression/core/Program_20260305112041.js +931 -0
  52. package/.history/src/logic/LogicRunner_20260304154306.js +170 -0
  53. package/.history/src/logic/LogicRunner_20260304155553.js +112 -0
  54. package/.history/src/logic/LogicRunner_20260305105834.js +112 -0
  55. package/.history/src/logic/LogicRunner_20260305112718.js +129 -0
  56. package/.history/src/logic/LogicRunner_20260305182436.js +133 -0
  57. package/.history/src/logic/LogicRunner_20260306151301.js +213 -0
  58. package/.history/src/logic/LogicRunner_20260306152419.js +213 -0
  59. package/.history/src/logic/plugins/common/DateTools_20260305154159.js +61 -0
  60. package/.history/src/logic/plugins/common/DateTools_20260305154217.js +44 -0
  61. package/.history/src/logic/plugins/common/DateTools_20260305161014.js +44 -0
  62. package/.history/src/logic/plugins/common/HttpTools_20260305164352.js +80 -0
  63. package/.history/src/logic/plugins/common/HttpTools_20260305170258.js +75 -0
  64. package/.history/src/logic/plugins/common/HttpTools_20260305171634.js +75 -0
  65. package/.history/src/logic/plugins/common/HttpTools_20260306152419.js +72 -0
  66. package/.history/src/services/api/restTools_20260427142149.js +245 -0
  67. package/.history/src/services/api/restTools_20260427142853.js +230 -0
  68. package/.history/src/services/api/restTools_20260519135558.js +230 -0
  69. package/.history/src/services/api/restTools_20260519140825.js +230 -0
  70. package/.history/src/services/api/restTools_20260519151223.js +230 -0
  71. package/.history/src/utils/indexedDB_20260306150918.js +593 -0
  72. package/.history/src/utils/indexedDB_20260306151301.js +586 -0
  73. package/.idea/af-vue2-client.iml +9 -0
  74. package/.idea/codeStyles/Project.xml +62 -0
  75. package/.idea/codeStyles/codeStyleConfig.xml +5 -0
  76. package/.idea/misc.xml +6 -0
  77. package/.idea/modules.xml +1 -1
  78. package/Components.md +60 -60
  79. package/index.js +31 -31
  80. package/jest-transform-stub.js +8 -8
  81. package/jest.setup.js +7 -7
  82. package/package.json +1 -1
  83. package/preview-input-box.html +180 -0
  84. package/src/assets/img/querySlotDemo.svg +15 -15
  85. package/src/base-client/components/common/AmapMarker/AmapPointRendering.vue +120 -120
  86. package/src/base-client/components/common/CitySelect/index.js +3 -3
  87. package/src/base-client/components/common/CitySelect/index.md +109 -109
  88. package/src/base-client/components/common/FormGroupEdit/index.js +3 -3
  89. package/src/base-client/components/common/FormGroupEdit/index.md +43 -43
  90. package/src/base-client/components/common/HIS/HButtons/HButtons.vue +55 -1
  91. package/src/base-client/components/common/HIS/HForm/HForm.vue +1186 -1186
  92. package/src/base-client/components/common/HIS/HTab/HTab.vue +88 -1
  93. package/src/base-client/components/common/JSONToTree/jsontotree.vue +271 -271
  94. package/src/base-client/components/common/PersonSetting/index.js +3 -3
  95. package/src/base-client/components/common/Tree/index.js +2 -2
  96. package/src/base-client/components/common/Upload/index.js +3 -3
  97. package/src/base-client/components/common/XAddNativeForm/index.md +146 -146
  98. package/src/base-client/components/common/XAddReport/XAddReport.vue +16 -1
  99. package/src/base-client/components/common/XCard/XCard.vue +64 -64
  100. package/src/base-client/components/common/XDataDrawer/XDataDrawer.vue +180 -180
  101. package/src/base-client/components/common/XDataDrawer/index.js +3 -3
  102. package/src/base-client/components/common/XDataDrawer/index.md +41 -41
  103. package/src/base-client/components/common/XDescriptions/index.js +3 -3
  104. package/src/base-client/components/common/XDescriptions/index.md +382 -382
  105. package/src/base-client/components/common/XForm/index.md +178 -178
  106. package/src/base-client/components/common/XInput/XInput.vue +32 -1
  107. package/src/base-client/components/common/XInspectionDetailDrawer/index.vue +1 -1
  108. package/src/base-client/components/common/XMarkdownViewer/demo.vue +102 -102
  109. package/src/base-client/components/common/XStepView/XStepView.vue +252 -252
  110. package/src/base-client/components/common/XStepView/index.js +3 -3
  111. package/src/base-client/components/common/XStepView/index.md +31 -31
  112. package/src/base-client/components/common/XTable/index.md +255 -255
  113. package/src/base-client/components/his/HAi/HAi.vue +1177 -436
  114. package/src/base-client/components/his/XList/XList.vue +337 -58
  115. package/src/base-client/components/his/XSidebar/XSidebar.vue +36 -12
  116. package/src/base-client/components/his/XTransfer/index.md +327 -327
  117. package/src/base-client/components/system/DictionaryDetailsView/DictionaryDetailsView.vue +232 -232
  118. package/src/base-client/plugins/Config.js +19 -19
  119. package/src/base-client/plugins/tabs-page-plugin.js +39 -39
  120. package/src/components/Charts/Bar.vue +62 -62
  121. package/src/components/Charts/ChartCard.vue +134 -134
  122. package/src/components/Charts/Liquid.vue +67 -67
  123. package/src/components/Charts/MiniArea.vue +39 -39
  124. package/src/components/Charts/MiniBar.vue +39 -39
  125. package/src/components/Charts/MiniProgress.vue +75 -75
  126. package/src/components/Charts/MiniSmoothArea.vue +40 -40
  127. package/src/components/Charts/Radar.vue +68 -68
  128. package/src/components/Charts/RankList.vue +77 -77
  129. package/src/components/Charts/TagCloud.vue +113 -113
  130. package/src/components/Charts/TransferBar.vue +64 -64
  131. package/src/components/Charts/Trend.vue +82 -82
  132. package/src/components/Charts/chart.less +12 -12
  133. package/src/components/Charts/smooth.area.less +13 -13
  134. package/src/components/NumberInfo/NumberInfo.vue +54 -54
  135. package/src/components/NumberInfo/index.js +3 -3
  136. package/src/components/NumberInfo/index.less +54 -54
  137. package/src/components/NumberInfo/index.md +43 -43
  138. package/src/components/STable/index.js +953 -953
  139. package/src/components/card/ChartCard.vue +79 -79
  140. package/src/components/chart/Bar.vue +60 -60
  141. package/src/components/chart/MiniArea.vue +67 -67
  142. package/src/components/chart/MiniBar.vue +59 -59
  143. package/src/components/chart/MiniProgress.vue +57 -57
  144. package/src/components/chart/Radar.vue +80 -80
  145. package/src/components/chart/RankingList.vue +60 -60
  146. package/src/components/chart/Trend.vue +79 -79
  147. package/src/components/chart/index.less +9 -9
  148. package/src/components/checkbox/ColorCheckbox.vue +157 -157
  149. package/src/components/input/IInput.vue +66 -66
  150. package/src/components/menu/SideMenu.vue +75 -75
  151. package/src/components/menu/menu.js +273 -273
  152. package/src/components/tool/AStepItem.vue +60 -60
  153. package/src/layouts/CommonLayout.vue +56 -56
  154. package/src/lib.js +1 -1
  155. package/src/mock/extend/index.js +84 -84
  156. package/src/mock/goods/index.js +108 -108
  157. package/src/pages/dashboard/workplace/WorkPlace.vue +141 -141
  158. package/src/pages/system/dictionary/index.vue +44 -44
  159. package/src/pages/system/monitor/loginInfor/index.vue +37 -37
  160. package/src/pages/system/monitor/operLog/index.vue +37 -37
  161. package/src/services/api/cas.js +79 -79
  162. package/src/store/modules/setting.js +119 -119
  163. package/src/utils/errorCode.js +6 -6
  164. package//350/277/201/347/247/273/346/227/245/345/277/227.md +15 -15
  165. package/.idea/MarsCodeWorkspaceAppSettings.xml +0 -7
  166. package/.idea/google-java-format.xml +0 -6
  167. package/.idea/inspectionProfiles/Project_Default.xml +0 -24
  168. package/.idea/jsLinters/eslint.xml +0 -6
  169. package/.idea/vue2-client.iml +0 -12
  170. package/.vscode/settings.json +0 -28
@@ -0,0 +1,1607 @@
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>