vue2-client 1.3.21 → 1.3.23

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 (96) hide show
  1. package/CHANGELOG.md +328 -323
  2. package/index.js +30 -30
  3. package/package.json +76 -76
  4. package/public/img/login/background.webp +0 -0
  5. package/src/assets/login/illustration.webp +0 -0
  6. package/src/base-client/components/common/AddressSearchCombobox/AddressSearchCombobox.vue +225 -225
  7. package/src/base-client/components/common/CreateQuery/CreateQuery.vue +551 -551
  8. package/src/base-client/components/common/CreateQuery/CreateQueryItem.vue +777 -777
  9. package/src/base-client/components/common/CreateSimpleFormQuery/CreateSimpleFormQueryItem.vue +553 -553
  10. package/src/base-client/components/common/CustomColumnsDrawer/index.md +46 -46
  11. package/src/base-client/components/common/FormGroupQuery/FormGroupQuery.vue +165 -165
  12. package/src/base-client/components/common/JSONToTree/jsontotree.vue +275 -275
  13. package/src/base-client/components/common/Upload/Upload.vue +167 -162
  14. package/src/base-client/components/common/XAddForm/XAddForm.vue +354 -354
  15. package/src/base-client/components/common/XAddNativeForm/XAddNativeForm.vue +327 -327
  16. package/src/base-client/components/common/XCard/XCard.vue +64 -64
  17. package/src/base-client/components/common/XForm/XForm.vue +274 -274
  18. package/src/base-client/components/common/XForm/XFormItem.vue +389 -389
  19. package/src/base-client/components/common/XFormTable/index.md +96 -96
  20. package/src/base-client/components/common/XTable/XTable.vue +278 -278
  21. package/src/base-client/components/system/LogDetailsView/LogDetailsView.vue +376 -376
  22. package/src/base-client/components/system/QueryParamsDetailsView/QueryParamsDetailsView.vue +281 -281
  23. package/src/base-client/components/ticket/TicketDetailsView/TicketDetailsView.vue +807 -807
  24. package/src/base-client/components/ticket/TicketDetailsView/index.md +29 -29
  25. package/src/base-client/components/ticket/TicketDetailsView/part/TicketDetailsFlow.vue +260 -260
  26. package/src/base-client/components/ticket/TicketSubmitSuccessView/TicketSubmitSuccessView.vue +532 -532
  27. package/src/base-client/components/ticket/TicketSubmitSuccessView/index.md +29 -29
  28. package/src/base-client/plugins/AppData.js +69 -69
  29. package/src/base-client/plugins/GetLoginInfoService.js +179 -179
  30. package/src/base-client/plugins/PagedList.js +177 -177
  31. package/src/base-client/plugins/compatible/LoginServiceOA.js +20 -20
  32. package/src/base-client/plugins/i18n-extend.js +32 -32
  33. package/src/components/Ellipsis/index.md +38 -38
  34. package/src/components/NumberInfo/index.md +43 -43
  35. package/src/components/STable/README.md +341 -341
  36. package/src/components/STable/index.js +318 -318
  37. package/src/components/Trend/index.md +45 -45
  38. package/src/components/checkbox/ColorCheckbox.vue +157 -157
  39. package/src/components/checkbox/ImgCheckbox.vue +163 -163
  40. package/src/components/exception/ExceptionPage.vue +70 -70
  41. package/src/components/form/FormRow.vue +52 -52
  42. package/src/components/index.js +36 -36
  43. package/src/components/menu/SideMenu.vue +62 -62
  44. package/src/components/menu/menu.js +273 -273
  45. package/src/components/setting/Setting.vue +235 -235
  46. package/src/components/table/StandardTable.vue +141 -141
  47. package/src/components/table/advance/ActionColumns.vue +158 -158
  48. package/src/components/table/advance/SearchArea.vue +355 -355
  49. package/src/components/tool/AStepItem.vue +60 -60
  50. package/src/components/tool/AvatarList.vue +68 -68
  51. package/src/components/tool/Drawer.vue +142 -142
  52. package/src/components/tool/TagSelect.vue +83 -83
  53. package/src/components/transition/PageToggleTransition.vue +97 -97
  54. package/src/config/default/setting.config.js +41 -41
  55. package/src/config/replacer/resolve.config.js +67 -67
  56. package/src/layouts/AdminLayout.vue +174 -174
  57. package/src/layouts/header/AdminHeader.vue +104 -104
  58. package/src/layouts/header/HeaderNotice.vue +167 -167
  59. package/src/layouts/header/HeaderSearch.vue +67 -67
  60. package/src/layouts/header/InstitutionDetail.vue +181 -181
  61. package/src/layouts/tabs/TabsHead.vue +190 -190
  62. package/src/layouts/tabs/TabsView.vue +379 -379
  63. package/src/mock/goods/index.js +108 -108
  64. package/src/pages/CreateQueryPage.vue +65 -65
  65. package/src/pages/login/Login.vue +359 -277
  66. package/src/pages/report/ReportTable.js +124 -124
  67. package/src/pages/report/ReportTableHome.vue +28 -28
  68. package/src/pages/resourceManage/orgListManage.vue +98 -98
  69. package/src/pages/system/dictionary/index.vue +43 -43
  70. package/src/pages/system/file/index.vue +317 -317
  71. package/src/pages/system/queryParams/index.vue +43 -43
  72. package/src/router/async/config.async.js +27 -27
  73. package/src/router/async/router.map.js +56 -56
  74. package/src/router/index.js +27 -27
  75. package/src/services/api/DictionaryDetailsViewApi.js +6 -6
  76. package/src/services/api/LogDetailsViewApi.js +10 -10
  77. package/src/services/api/QueryParamsDetailsViewApi.js +6 -6
  78. package/src/services/api/TicketDetailsViewApi.js +34 -34
  79. package/src/services/api/common.js +58 -58
  80. package/src/services/api/commonTempTable.js +10 -10
  81. package/src/services/api/index.js +17 -17
  82. package/src/services/api/manage.js +8 -8
  83. package/src/store/mutation-types.js +2 -2
  84. package/src/theme/default/nprogress.less +76 -76
  85. package/src/theme/default/style.less +47 -47
  86. package/src/utils/colors.js +103 -103
  87. package/src/utils/excel/Blob.js +180 -180
  88. package/src/utils/excel/Export2Excel.js +141 -141
  89. package/src/utils/formatter.js +68 -68
  90. package/src/utils/i18n.js +80 -80
  91. package/src/utils/request.js +225 -225
  92. package/src/utils/routerUtil.js +364 -364
  93. package/src/utils/theme-color-replacer-extend.js +91 -91
  94. package/src/utils/themeUtil.js +100 -100
  95. package/src/utils/util.js +230 -230
  96. package/vue.config.js +99 -99
@@ -1,777 +1,777 @@
1
- <template>
2
- <a-modal
3
- :destroyOnClose="true"
4
- :visible="visible"
5
- :width="1250"
6
- :zIndex="1001"
7
- title="数据字段配置"
8
- @cancel="modelCancel"
9
- @ok="submitItem">
10
- <a-form-model
11
- ref="itemForm"
12
- :model="item"
13
- :rules="itemRules"
14
- layout="vertical">
15
- <a-row :gutter="16">
16
- <a-col :span="6">
17
- <a-card :bodyStyle="bodyStyle" title="基本属性">
18
- <a-divider style="font-size: 14px;margin-top: 0">字段信息</a-divider>
19
- <a-form-model-item label="标签名称" prop="title">
20
- <a-input v-model="item.title" placeholder="请输入标签名称"/>
21
- </a-form-model-item>
22
- <a-form-model-item
23
- label="字段名称"
24
- prop="key">
25
- <a-input ref="key" v-model="item.key" :disabled="keyDisabled" placeholder="请输入字段名">
26
- <a-popover slot="suffix" placement="bottom" title="关于字段名称">
27
- <template slot="content">
28
- <p>设置数据字段的名称</p>
29
- <p>用作SQL查询时为<span style="font-weight: bold">表别名.数据列名</span>的格式,如:i.id</p>
30
- </template>
31
- <a-icon style="color: rgba(0,0,0,.45)" type="info-circle"/>
32
- </a-popover>
33
- </a-input>
34
- </a-form-model-item>
35
- <a-form-model-item
36
- v-if="item.formType ==='addressSearch'"
37
- label="坐标字段名">
38
- <a-input :disabled="true" :value="`${item.key}_lng_lat`">
39
- <a-popover slot="suffix" placement="bottom" title="坐标字段名">
40
- <template slot="content">
41
- <p>表单类型为地点搜索框时:</p>
42
- <p>新增/修改表单内,字段名称会存放地址名称,坐标字段名会存放坐标信息</p>
43
- </template>
44
- <a-icon style="color: rgba(0,0,0,.45)" type="info-circle"/>
45
- </a-popover>
46
- </a-input>
47
- </a-form-model-item>
48
- <a-divider style="font-size: 14px;margin-top: 0">数据模式</a-divider>
49
- <a-form-model-item
50
- prop="dataMode"
51
- style="margin-top: 10px;">
52
- <a-checkbox-group v-model="dataModeArrayData" :disabled="dataModeDisabled" :options="dataModeTypeV"/>
53
- </a-form-model-item>
54
- </a-card>
55
- </a-col>
56
- <a-col :span="9">
57
- <a-card v-if="dataMode.queryForm || dataMode.addOrEditForm || dataMode.table" :bodyStyle="bodyStyle" title="核心配置">
58
- <template v-if="dataMode.queryForm || dataMode.addOrEditForm">
59
- <a-divider style="font-size: 14px;margin-top: 0">表单配置</a-divider>
60
- <a-form-model-item label="表单类型" prop="formType">
61
- <a-select v-model="item.formType" placeholder="请选择表单类型" @change="changeFormType(item)">
62
- <a-select-option v-for="formTypeItem in formType" :key="formTypeItem.key">{{ formTypeItem.label }}</a-select-option>
63
- </a-select>
64
- </a-form-model-item>
65
- <template v-if="item.formType">
66
- <a-form-model-item v-if="dataMode.sqlQueryCondition && item.formType !=='file' && item.formType !=='image' " label="表单查询方式" prop="queryType">
67
- <a-select
68
- v-model="item.queryType"
69
- :disabled="formQueryTypeDisabled"
70
- :getPopupContainer=" triggerNode => { return triggerNode.parentNode } "
71
- placeholder="表单查询方式">
72
- <a-select-option v-for="queryTypeItem in queryTypeV" :key="queryTypeItem.key">{{ queryTypeItem.label }}</a-select-option>
73
- </a-select>
74
- </a-form-model-item>
75
- <a-form-model-item v-if="dataMode.addOrEditForm" label="表单校验" prop="rule">
76
- <a-row :gutter="16">
77
- <a-col v-if="(item.formType === 'input' || item.formType === 'textarea' ) && item.formType !=='file' && item.formType !=='image' " :span="12" >
78
- <a-select v-model="item.rule.type" :getPopupContainer=" triggerNode => { return triggerNode.parentNode } " placeholder="校验类型">
79
- <a-select-option v-for="ruleTypeItem in formRuleType" :key="ruleTypeItem.key">{{ ruleTypeItem.label }}</a-select-option>
80
- <a-popover slot="suffixIcon" placement="bottom" title="关于表单校验类型">
81
- <template slot="content">
82
- <p>设置表单项的校验类型</p>
83
- </template>
84
- <a-icon style="color: rgba(0,0,0,.45)" type="info-circle"/>
85
- </a-popover>
86
- </a-select>
87
- </a-col>
88
- <a-col :span="12">
89
- <a-radio-group v-model="item.rule.required" button-style="solid" default-value="false">
90
- <a-radio-button value="true">
91
- 必选项
92
- </a-radio-button>
93
- <a-radio-button value="false">
94
- 非必选项
95
- </a-radio-button>
96
- </a-radio-group>
97
- </a-col>
98
- </a-row>
99
- </a-form-model-item>
100
- <a-form-model-item v-if="dataMode.addOrEditForm" label="新增/修改场景选择" prop="addOrEdit">
101
- <a-select v-model="item.addOrEdit" placeholder="请选择场景">
102
- <a-select-option v-for="addOrEditItem in addOrEditTypeV" :key="addOrEditItem.key">{{ addOrEditItem.label }}</a-select-option>
103
- <a-popover
104
- slot="suffixIcon"
105
- placement="bottom"
106
- title="关于新增/修改场景选择">
107
- <template slot="content">
108
- <p>设置表单项的新增/修改场景</p>
109
- <p>静默新增类型用于非人为新增的数据,不会生成表单项,且必须设置字段用途</p>
110
- </template>
111
- <a-icon style="color: rgba(0,0,0,.45)" type="info-circle"/>
112
- </a-popover>
113
- </a-select>
114
- </a-form-model-item>
115
- <a-form-model-item v-if="item.addOrEdit === 'silenceAdd'" label="字段用途" prop="silencePurpose">
116
- <a-select v-model="item.silencePurpose" :getPopupContainer=" triggerNode => { return triggerNode.parentNode } " placeholder="请选择字段用途">
117
- <a-select-option v-for="silencePurposeTypeItem in silencePurposeType" :key="silencePurposeTypeItem.key">{{ silencePurposeTypeItem.label }}</a-select-option>
118
- <a-popover
119
- slot="suffixIcon"
120
- placement="bottom"
121
- title="关于字段用途">
122
- <template slot="content">
123
- <p>用于静默新增时设置字段用途</p>
124
- <p>在新增数据的表单提交时,页面会根据设置的字段用途自动获取相关数据并追加到表单中</p>
125
- <p>当字段用途选择为<span style="font-weight: bold">自定义</span>时,必须指定一个业务逻辑(Logic)名称,表单提交前会将表单内容作为参数调用该Logic接口,并将Logic返回值作为表单值
126
- </p>
127
- </template>
128
- <a-icon style="color: rgba(0,0,0,.45)" type="info-circle"/>
129
- </a-popover>
130
- </a-select>
131
- </a-form-model-item>
132
- <a-form-model-item v-if="item.silencePurpose === 'customize'" label="字段用途对应Logic" prop="silenceSource">
133
- <a-input v-model="item.silenceSource" placeholder="请输入业务逻辑名称"/>
134
- </a-form-model-item>
135
- </template>
136
- </template>
137
- <template v-if="dataMode.table">
138
- <a-divider style="font-size: 14px;margin-top: 0">表格列配置</a-divider>
139
- <a-form-model-item v-if="item.formType" label="作用域插槽" prop="slot">
140
- <a-select v-model="item.slot.type" :disabled="slotTypeDisabled" :getPopupContainer=" triggerNode => { return triggerNode.parentNode } " placeholder="插槽类型">
141
- <a-select-option v-for="slotTypeItem in slotTypeV" :key="slotTypeItem.key">{{ slotTypeItem.label }}</a-select-option>
142
- <a-popover slot="suffixIcon" placement="bottom" title="关于作用域插槽">
143
- <template slot="content">
144
- <p>你可以通过设置表格列的作用域插槽实现一些效果</p>
145
- <p>如果没有指定,默认会设置为文本溢出省略(长度:16)</p>
146
- <p>如果你选择文本溢出省略,需要设置文本溢出上限长度,建议ID主键等类型设置为8</p>
147
- <p>如果你选择多彩徽标,需要设置徽标对应的数据样式字典键</p>
148
- <a-divider style="font-size: 14px;margin-top: 0">关于表格列宽度</a-divider>
149
- <p>V1.1之后不再支持自定义表格列宽度,表格列宽度将通过作用域插槽类型自适应</p>
150
- <p>设置为文本溢出省略时,表格列宽度 = 文本溢出上限长度 * 7 + 42</p>
151
- <p>设置为多彩徽标时,表格列宽度为130</p>
152
- <p>设置为日期时间格式化时,表格列宽度为160</p>
153
- </template>
154
- <a-icon style="color: rgba(0,0,0,.45)" type="info-circle"/>
155
- </a-popover>
156
- </a-select>
157
- </a-form-model-item>
158
- <a-form-model-item v-if="item.slot.type === 'badge'" label="徽标字典键" prop="slot.keyMap">
159
- <a-input v-model="item.slot.keyMap" :disabled="slotTypeDisabled" placeholder="请输入徽标字典键">
160
- <a-popover
161
- slot="suffix"
162
- placement="bottom"
163
- title="关于徽标字典键">
164
- <template slot="content">
165
- <p>如果你设置了表单类型为选择框,且数据源是字典键,该值会自动带出</p>
166
- </template>
167
- <a-icon style="color: rgba(0,0,0,.45)" type="info-circle"/>
168
- </a-popover>
169
- </a-input>
170
- </a-form-model-item>
171
- <a-form-model-item v-if="item.slot.type === 'ellipsis'" label="文本溢出上限长度" prop="slot.value">
172
- <a-input-number v-model="item.slot.value" placeholder="请输入文本溢出上限长度" style="width: 100%"/>
173
- </a-form-model-item>
174
- <a-form-model-item v-if="item.slot.type === 'action'" label="操作列文本" prop="slot.actionText">
175
- <a-input v-model="item.slot.actionText" placeholder="请输入操作列显示文本,默认为详情"/>
176
- </a-form-model-item>
177
- <a-form-model-item v-if="dataMode.sqlQueryItem || dataMode.sqlQueryCondition" label="字段默认值" prop="default">
178
- <a-input v-model="item.default" placeholder="当查询结果为null时,指定默认值"/>
179
- </a-form-model-item>
180
- </template>
181
- </a-card>
182
- </a-col>
183
- <a-col v-if="item.formType" :span="9">
184
- <a-card :bodyStyle="bodyStyle" title="扩展属性">
185
- <template v-if="(dataMode.addOrEditForm || dataMode.queryForm ) && (item.formType === 'input' || item.formType === 'select' || item.formType === 'selects' || item.formType === 'cascader')">
186
- <a-divider style="font-size: 14px;margin-top: 0">提示相关</a-divider>
187
- <a-form-model-item label="表单水印" prop="placeholder">
188
- <a-input v-model="item.placeholder" placeholder="表单水印(placeholder)" />
189
- </a-form-model-item>
190
- </template>
191
- <template v-if="item.formType === 'selects'">
192
- <a-divider style="font-size: 14px;margin-top: 0">级联选择相关</a-divider>
193
- <a-form-model-item label="是否根节点" prop="groupIndexView">
194
- <a-radio-group
195
- v-model="item.groupIndexView"
196
- button-style="solid"
197
- @change="groupIndexChange">
198
- <a-radio-button value="1">
199
-
200
- </a-radio-button>
201
- <a-radio-button value="0">
202
-
203
- </a-radio-button>
204
- </a-radio-group>
205
- </a-form-model-item>
206
- <a-form-model-item v-if="item.groupIndexView === '0' && item.groupIndex !== -1" label="所属父级联动框" prop="groupIndex">
207
- <a-select
208
- ref="groupIndex"
209
- v-model="item.parent_title"
210
- :getPopupContainer=" triggerNode => { return triggerNode.parentNode } "
211
- placeholder="请选择父级联动框"
212
- @change="parent_title_change">
213
- <a-select-option v-for="parent_item in parent_node" :key="parent_item.key">
214
- {{ parent_item.title }}
215
- </a-select-option>
216
- </a-select>
217
- </a-form-model-item>
218
- </template>
219
- <template v-if="selectDataShow">
220
- <a-divider style="font-size: 14px;margin-top: 0">数据源相关</a-divider>
221
- <a-form-model-item label="数据源类型" prop="selectType">
222
- <a-select v-model="item.selectType" placeholder="请选择数据源类型" @change="changeSelectKType">
223
- <a-select-option v-for="selectDataTypeItem in selectDataType.filter(h=>!h.noMatch.includes(item.formType))" :key="selectDataTypeItem.key">{{ selectDataTypeItem.label }}</a-select-option>
224
- <a-popover
225
- slot="suffixIcon"
226
- placement="bottom"
227
- title="关于数据源类型">
228
- <template slot="content">
229
- <p>设置数据源</p>
230
- <p>数据源类型分为三种,你可以根据需要选择</p>
231
- <p>字典键:选项从字典表(t_dictionary)获取,你只需要选择字典键的名称即可</p>
232
- <p>业务逻辑名称:选项通过发起http请求调用指定的业务逻辑(Logic)接口获取</p>
233
- <p>固定集合:选项为静态值,JSONArray格式</p>
234
- <p>当表单为级联选择框类型时,返回的数据需按照以下形式:</p>
235
- <json-viewer
236
- :expand-depth="parseInt('100')"
237
- :value="DemoJson"
238
- style="overflow: auto;max-height: 440px"></json-viewer>
239
- </template>
240
- <a-icon style="color: rgba(0,0,0,.45)" type="info-circle"/>
241
- </a-popover>
242
- </a-select>
243
- </a-form-model-item>
244
- <a-form-model-item v-if="item.selectType" label="数据源" prop="selectKey">
245
- <a-select
246
- v-if="item.selectType === 'key'"
247
- v-model="item.selectKey"
248
- :filter-option="filterOption"
249
- placeholder="请选择字典键"
250
- show-search
251
- @change="changeSelectKey(item)">
252
- <template>
253
- <a-select-option
254
- v-for="(optionItem,index) in option"
255
- :key="index"
256
- :value="Object.keys(optionItem)[0]">{{ optionItem[Object.keys(optionItem)[0]] }}
257
- </a-select-option>
258
- </template>
259
- </a-select>
260
- <a-input v-if="item.selectType === 'logic'" v-model="item.selectKey" placeholder="请输入业务逻辑名称"/>
261
- <a-textarea v-if="item.selectType === 'fixArray'" v-model="item.selectKey" placeholder="请录入数据源"/>
262
- </a-form-model-item>
263
- <a-form-model-item v-if="item.selectType === 'logic'" label="数据源加载方式" prop="selectLoadType">
264
- <a-radio-group v-model="item.lazyLoad" button-style="solid" default-value="false">
265
- <a-radio-button value="true">
266
- 懒加载搜索
267
- </a-radio-button>
268
- <a-radio-button value="false">
269
- 一次性加载
270
- </a-radio-button>
271
- </a-radio-group>
272
- </a-form-model-item>
273
- </template>
274
- <a-form-model-item v-if="selectDataShow || item.groupIndexView" label="关联外键字段" prop="selectKeyName">
275
- <a-input v-model="item.selectKeyName" placeholder="该列关联的外键字段">
276
- <a-popover slot="suffix" placement="bottom" title="关于关联外键字段">
277
- <template slot="content">
278
- <p><span style="font-weight: bold;"><span style="color: #FF0036">非必需的实验性功能:</span>设置该参数需开发岗指导</span></p>
279
- <p>当字段与主子表外键有关系时,你可以指定<span style="font-weight: bold">该列所关联的外键字段名</span>
280
- </p>
281
- <p>设置该参数是为了该字段用作表单查询时,系统可以通过设置的关联外键字段,而非字面值作为查询条件</p>
282
- <p>示例:</p>
283
- <p>主表为t_userfiles(表档案)表,别名为u,与t_gasbrand(气表品牌表)有关联关系,别名为g,为了显示表档案对应的气表品牌数据,我们将数据字段名设置为g.f_gasbrand</p>
284
- <p>这样我们就可以在table中看到气表品牌了,但是用户如果通过气表品牌下拉框进行筛选,我们指定的g.f_gasbrand只是气表品牌的值,而实际关联字段是u.f_gasbrand_id</p>
285
- <p>所以如果我们指定了关联外键字段u.f_gasbrand_id,系统则会使用u.f_gasbrand_id筛选数据,而不是g.f_gasbrand,从而优化了查询效率
286
- </p>
287
- </template>
288
- <a-icon style="color: rgba(0,0,0,.45)" type="info-circle"/>
289
- </a-popover>
290
- </a-input>
291
- </a-form-model-item>
292
- <template v-if="item.formType === 'file' || item.formType === 'image'">
293
- <a-divider style="font-size: 14px;margin-top: 0">文件上传相关</a-divider>
294
- <a-form-model-item label="允许上传文件数量" prop="accept" style="margin-bottom: 5px;">
295
- <a-slider
296
- v-model="item.acceptCount"
297
- :marks="{ 1: '1', 3: '3', 5: '5', 10: '10', 15: '15', 20: '20'}"
298
- :max="20"
299
- :min="1"
300
- />
301
- </a-form-model-item>
302
- <a-form-model-item label="附件用途" prop="useType">
303
- <a-select v-model="item.useType" placeholder="指定文件用途,同表单不同用途">
304
- <a-select-option v-for="userTypeItem in $appdata.getDictionaryList('useType')" :key="userTypeItem.value">{{ userTypeItem.value }}</a-select-option>
305
- </a-select>
306
- </a-form-model-item>
307
- <a-form-model-item label="上传的仓库" prop="resUploadStock">
308
- <a-select v-model="item.resUploadStock" placeholder="选择文件上传到的仓库" @change="changeStock">
309
- <a-select-option v-for="stock in stockList" :key="stock.id">{{ stock.f_name }}</a-select-option>
310
- </a-select>
311
- </a-form-model-item>
312
- <a-form-model-item v-if="item.resUploadStock" label="具体路径" prop="pathKey">
313
- <a-select v-model="item.pathKey" placeholder="仓库扩展路径">
314
- <a-select-option v-for="pathKey in lowerPath" :key="pathKey.label">{{ pathKey.label }}</a-select-option>
315
- </a-select>
316
- </a-form-model-item>
317
- <a-form-model-item v-if="item.formType === 'file'" label="允许上传文件类型" prop="accept">
318
- <a-select v-model="item.accept" mode="tags" placeholder="指定文件类型,默认不限制" @change="itemAcceptChange">
319
- <a-select-option v-for="type_item in fileType" :key="type_item.accept">{{ type_item.label }}</a-select-option>
320
- </a-select>
321
- </a-form-model-item>
322
- </template>
323
- </a-card>
324
- </a-col>
325
- </a-row>
326
- <a-alert
327
- v-if="dataModeArrayData.length === 0"
328
- message="错误:请至少选择一种数据模式"
329
- show-icon
330
- style="margin-top: 5px"
331
- type="error"/>
332
- <a-alert
333
- v-if="dataMode.addOrEditForm && !dataMode.sqlQueryItem && item.formType !== 'file' && item.formType !== 'image' && item.formType !== 'personSetting' && item.formType !== 'cascader' "
334
- message="错误:如果要生成新增/修改表单项,必须勾选生成SQL查询项"
335
- show-icon
336
- style="margin-top: 5px"
337
- type="error"/>
338
- <a-alert
339
- v-if="dataMode.queryForm && !dataMode.sqlQueryCondition"
340
- message="提示:您没有勾选生成SQL查询表达式,渲染的表单项不会生成SQL查询条件"
341
- show-icon
342
- style="margin-top: 5px"
343
- type="info"/>
344
- <a-alert
345
- v-if="dataMode.table && !dataMode.sqlQueryItem"
346
- message="提示:您没有勾选生成SQL查询项,渲染的表格列不会绑定SQL结果集数据"
347
- show-icon
348
- style="margin-top: 5px"
349
- type="info"/>
350
- </a-form-model>
351
- </a-modal>
352
- </template>
353
-
354
- <script>
355
- import {
356
- dataModeType,
357
- fileType,
358
- formRuleType,
359
- formType,
360
- queryType,
361
- slotType,
362
- silencePurposeType,
363
- addOrEditType,
364
- selectDataType
365
- } from '@vue2-client/config/CreateQueryConfig'
366
- import { commonApi, post } from '@vue2-client/services/api'
367
- import JsonViewer from 'vue-json-viewer'
368
-
369
- const DemoJson = [{
370
- value: 'zhejiang',
371
- label: 'Zhejiang',
372
- children: [{ value: 'hangzhou', label: 'Hangzhou', children: [{ value: 'xihu', label: 'West Lake' }] }]
373
- }]
374
-
375
- export default {
376
- name: 'CreateQueryItem',
377
- components: {
378
- JsonViewer
379
- },
380
- computed: {
381
- // 是否展示数据源相关字段
382
- selectDataShow () {
383
- return this.item.formType === 'select' || this.item.formType === 'cascader' || (this.item.formType === 'selects' && this.item.groupIndexView === '1') || this.item.formType === 'checkbox' || this.item.formType === 'radio'
384
- },
385
- // 作用域插槽是否禁用
386
- slotTypeDisabled () {
387
- return this.item.selectType === 'key' && this.item.selectKey
388
- },
389
- // 字段名称是否禁用
390
- keyDisabled () {
391
- return this.item.formType === 'file' || this.item.formType === 'image'
392
- },
393
- // 数据模式是否禁用
394
- dataModeDisabled () {
395
- return this.item.formType === 'file' || this.item.formType === 'image' || this.item.formType === 'addressSearch'
396
- },
397
- dataMode: function () {
398
- const result = {
399
- queryForm: false,
400
- table: false,
401
- addOrEditForm: false,
402
- sqlQueryItem: false,
403
- sqlQueryCondition: false
404
- }
405
- for (const item of this.dataModeArrayData) {
406
- result[item] = true
407
- }
408
- return result
409
- },
410
- queryTypeV () {
411
- return queryType.filter(item => {
412
- return item.match.findIndex(type => type === this.item.formType || type === 'all') > -1
413
- })
414
- },
415
- dataModeTypeV () {
416
- if (this.item.formType) {
417
- return dataModeType.filter(item => {
418
- return item.noMatch.findIndex(type => type === this.item.formType) === -1
419
- })
420
- } else {
421
- return dataModeType
422
- }
423
- },
424
- slotTypeV () {
425
- return slotType.filter(item => {
426
- return item.match.findIndex(type => type === this.item.formType || type === 'all') > -1
427
- })
428
- },
429
- addOrEditTypeV () {
430
- return addOrEditType.filter(item => {
431
- return item.match.findIndex(type => type === this.item.formType || type === 'all') > -1
432
- })
433
- }
434
- },
435
- data () {
436
- return {
437
- DemoJson,
438
- dataModeType,
439
- queryType,
440
- formType,
441
- formRuleType,
442
- slotType,
443
- fileType,
444
- silencePurposeType,
445
- addOrEditType,
446
- selectDataType,
447
- // 控制modal框
448
- visible: false,
449
- type: '',
450
- bodyStyle: {
451
- height: '500px',
452
- overflowY: 'auto'
453
- },
454
- // 表单查询方式是否禁用
455
- formQueryTypeDisabled: false,
456
- // 数据模式类型集合值
457
- dataModeArrayData: [],
458
- // 表单项
459
- item: {
460
- key: '',
461
- title: '',
462
- slot: {
463
- type: 'default'
464
- },
465
- rule: {
466
- required: 'false'
467
- },
468
- queryType: '=',
469
- formType: 'input',
470
- accept: undefined,
471
- pathKey: undefined,
472
- groupIndexView: undefined,
473
- selectType: undefined,
474
- addOrEdit: 'all',
475
- fileRootPath: undefined,
476
- selectKeyName: undefined,
477
- resUploadStock: undefined,
478
- dataModeArray: []
479
- },
480
- // 数据仓库列表
481
- stockList: [],
482
- // 扩展目录
483
- lowerPath: [],
484
- parent_node: [],
485
- // 必填控制
486
- itemRules: {
487
- formType: [{ required: true, message: '请输入表单类型', trigger: 'change' }],
488
- key: [{ required: true, message: '请输入字段名称', trigger: 'blur' }],
489
- title: [{ required: true, message: '请输入标签名称', trigger: 'blur' }],
490
- selectType: [{ required: true, message: '请选择数据源类型', trigger: 'change' }],
491
- selectKey: [{ required: true, message: '请输入数据源内容', trigger: 'blur' }],
492
- 'slot.value': [{ required: true, message: '请输入文本溢出上限长度', trigger: 'blur' }],
493
- 'slot.keyMap': [{ required: true, message: '请输入徽标字典键', trigger: 'blur' }],
494
- silencePurpose: [{ required: true, message: '请选择字段用途', trigger: 'change' }],
495
- silenceSource: [{ required: true, message: '请输入业务逻辑名称', trigger: 'blur' }],
496
- groupIndex: [{ required: true, message: '请选择父级联动框', trigger: 'blur' }],
497
- resUploadStock: [{ required: true, message: '请选择上传到的仓库', trigger: 'blur' }],
498
- pathKey: [{ required: true, message: '请选择上传到的扩展目录', trigger: 'blur' }]
499
- },
500
- // 字典键集合
501
- option: []
502
- }
503
- },
504
- mounted () {
505
- this.resetDataMode()
506
- },
507
- props: { },
508
- methods: {
509
- initItem (lysis = {}) {
510
- this.item = Object.assign({
511
- key: '',
512
- title: '',
513
- slot: {
514
- type: 'default'
515
- },
516
- rule: {
517
- required: 'false'
518
- },
519
- selectKey: undefined,
520
- queryType: '=',
521
- formType: 'input',
522
- fileRootPath: undefined,
523
- pathKey: undefined,
524
- accept: undefined,
525
- selectType: undefined,
526
- groupIndexView: undefined,
527
- addOrEdit: 'all',
528
- selectKeyName: undefined,
529
- resUploadStock: undefined,
530
- dataModeArray: []
531
- }, lysis)
532
- },
533
- // 控制 展示
534
- flashModal (show = 'None') {
535
- const bool = show === 'None' ? !this.visible : !!show
536
- if (bool && this.option.length === 0) {
537
- post(commonApi.getDictionaryParam, {}).then(res => {
538
- this.option = res
539
- })
540
- }
541
- this.visible = bool
542
- },
543
- // 编辑数据字段前准备数据
544
- editColumnItemExecute (_item) {
545
- this.type = '修改'
546
- const defaultValue = { formType: 'input', type: 'string', addOrEdit: 'all', slot: { type: 'default' }, rule: {}, selectKey: {} }
547
- if (!_item.queryType) {
548
- defaultValue.queryType = '='
549
- }
550
- _item = Object.assign({}, defaultValue, _item)
551
- if (_item.formType === 'file' || _item.formType === 'image') {
552
- this.getStocks()
553
- // 如果有仓库 则获取该仓库的扩展路径
554
- if (_item.resUploadStock) {
555
- this.lowerPath = this.stockList.filter(item => item.id === _item.resUploadStock)[0]?.f_lower_path_json ?? []
556
- }
557
- }
558
- if (_item.selectKey && _item.selectType === 'logic' && _item.selectKey.substring(0, 6) === 'logic@') {
559
- _item.selectKey = _item.selectKey.substring(6)
560
- }
561
- if (_item.formType === 'selects') {
562
- // 因为 groupIndex 可能有很多值 单选框不行 赋给一个新的变量
563
- _item.groupIndexView = _item.groupIndex === 1 ? '1' : '0'
564
- }
565
- // 兼容旧作用域插槽属性
566
- this.compatibleTheSlot(_item)
567
- this.item = _item
568
- this.dataModeArrayData = this.item.dataModeArray
569
- this.flashModal()
570
- },
571
- // 增加数据字段前数据处理
572
- addColumnItemExecute () {
573
- this.type = '新增'
574
- this.dataModeArrayData = ['queryForm', 'table', 'addOrEditForm', 'sqlQueryItem', 'sqlQueryCondition']
575
- this.initItem()
576
- this.flashModal()
577
- },
578
- modelCancel () {
579
- this.flashModal()
580
- // this.$emit('update:visible', false)
581
- // // 延迟是为了避免编辑数据窗口关闭时重置表单导致的闪烁
582
- // setTimeout(() => {
583
- // this.resetDataMode()
584
- // this.resetFormProp()
585
- // }, 100)
586
- },
587
- submitItem () {
588
- this.$refs.itemForm.validate(valid => {
589
- if (valid) {
590
- const fileBool = this.item.formType === 'file' || this.item.formType === 'image'
591
- if (this.dataModeArrayData.length === 0) {
592
- this.$message.error('请至少选择一种数据模式')
593
- return
594
- }
595
- if (!fileBool && (this.dataMode.addOrEditForm && !this.dataMode.sqlQueryItem) && this.item.formType !== 'personSetting' && this.item.formType !== 'cascader') {
596
- this.$message.error('如果要生成新增/修改表单项,必须勾选生成SQL查询项')
597
- return
598
- }
599
- if (fileBool && !(!this.dataMode.table && !this.dataMode.sqlQueryCondition && !this.dataMode.queryForm)) {
600
- this.$message.error(`上传类表单项只能选择 "渲染新增/修改表单项"`)
601
- return
602
- }
603
- this.itemHandle()
604
- }
605
- })
606
- },
607
- visitAcceptFile () {
608
- window.open('https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/input/file#attr-accept')
609
- },
610
- // 修改上传到哪个仓库
611
- changeStock (stock) {
612
- if (stock) {
613
- const stockValue = this.stockList.filter(item => item.id === stock)[0]
614
- this.lowerPath = stockValue.f_lower_path_json ?? []
615
- this.item.resUploadMode = stockValue.f_stock_type
616
- this.item.fileRootPath = stockValue.f_root_path
617
- this.item.stockAlias = stockValue.f_alias
618
- this.item.pathKey = undefined
619
- }
620
- },
621
- // 文件上传限制类型修改
622
- itemAcceptChange (newVal) {
623
- if (newVal.includes('*')) {
624
- this.item.accept = ['*']
625
- }
626
- },
627
- parent_title_change (parentKey) {
628
- const parentArr = this.getColumn().filter(item => item.formType === 'selects' && item.key === parentKey)
629
- if (parentArr.length === 1) {
630
- this.item.groupIndex = parentArr[0].groupIndex + 1
631
- this.item.group = parentArr[0].group
632
- this.item.parent_title = parentArr[0].title
633
- } else {
634
- this.$message.error('数据字段中有字段别名相同,请检查!')
635
- }
636
- },
637
- groupIndexChange ({ target }) {
638
- if (target.value === '1') {
639
- this.item.groupIndex = 1
640
- this.item.groupIndexView = '1'
641
- if (this.item.title) {
642
- this.item.group = this.item.title + '组'
643
- } else {
644
- this.item.groupIndex = undefined
645
- this.item.groupIndexView = undefined
646
- this.$message.error('请先输入字段中文名称!')
647
- }
648
- } else {
649
- if (!this.item.title) {
650
- this.$message.error('请先输入字段名称!')
651
- this.item.groupIndex = -1
652
- this.item.groupIndexView = undefined
653
- return
654
- }
655
- this.item.groupIndex = undefined
656
- // 获取所有可以当作父节点的字段
657
- this.parent_node = this.getColumn().filter(item => item.formType === 'selects' && item.key !== this.item.key)
658
- }
659
- },
660
- getColumn () {
661
- let result = {}
662
- this.$emit('getColumn', val => { result = val })
663
- return result
664
- },
665
- changeFormType (item) {
666
- this.initItem({ key: item.key, title: item.title, formType: item.formType })
667
- if (item.formType === 'file' || item.formType === 'image') {
668
- this.item.acceptCount = 3
669
- this.getStocks()
670
- this.item.accept = item.formType === 'file' ? ['*'] : ['.jpg,.jpeg,.ico,.gif,svg,.webp,.png,.bmp,.pjpeg,']
671
- this.item.resUploadMode = 'server'
672
- this.item.key = item.formType === 'file' ? 'FilesId' : 'Images'
673
- this.dataModeArrayData = ['addOrEditForm']
674
- } else if (item.formType === 'addressSearch') {
675
- this.dataModeArrayData = ['addOrEditForm', 'sqlQueryItem']
676
- } else {
677
- if (['FilesId', 'Images'].includes(this.item.key)) { this.item.key = '' }
678
- this.resetDataMode()
679
- // 表单查询方式有预选项时
680
- if (this.queryTypeV.length === 1) {
681
- this.item.queryType = this.queryTypeV[0].value
682
- }
683
- }
684
- },
685
- // 获取所有仓库
686
- getStocks () {
687
- if (this.stockList.length === 0) {
688
- post('/api/af-system/logic/getFilesStock', {}).then(res => {
689
- this.stockList = res.sort((a, b) => b.progress - a.progress)
690
- }).catch(e => {})
691
- }
692
- },
693
- // 重置数据模式
694
- resetDataMode () {
695
- this.dataModeArrayData = this.dataModeTypeV.map(item => item.value)
696
- },
697
- itemHandle () {
698
- // 查询表单项或者新增/修改表单项
699
- if (this.dataMode.queryForm || this.dataMode.addOrEditForm) {
700
- if (!this.dataMode.sqlQueryItem || !this.dataMode.addOrEditForm) {
701
- this.delKey(this.item, 'addOrEdit', 'silencePurpose', 'silenceSource')
702
- }
703
- if (this.item.selectType && this.item.selectType === 'logic' && this.item.selectKey.substring(0, 6) !== 'logic@') {
704
- // 数据源为logic
705
- this.item.selectKey = 'logic@' + this.item.selectKey
706
- } else if (this.item.selectType && this.item.selectType === 'fixArray' && !this.isJSON(this.item.selectKey)) {
707
- // 数据源为固定json集合
708
- this.$message.warning('下拉框数据源不是JSON集合')
709
- return
710
- }
711
- } else {
712
- this.delKey(this.item, 'queryType', 'formType', 'addOrEdit', 'silencePurpose', 'silenceSource', 'placeholder', 'rule', 'selectKey', 'selectKeyName', 'lazyLoad')
713
- }
714
- // 如果和数据源字段无关
715
- if (!this.selectDataShow) {
716
- this.delKey(this.item, 'selectType', 'selectKey', 'lazyLoad', 'selectKeyName')
717
- }
718
- // 默认插槽就先删除
719
- if (this.item.slot && (this.item.slot.type === 'default' || !this.item.slot.type)) { delete this.item.slot }
720
- // 根据数据模式处理数据
721
- if (!this.dataMode.sqlQueryCondition) {
722
- delete this.item.queryType
723
- }
724
- if (!this.dataMode.sqlQueryItem) { this.delKey(this.item, 'default') }
725
- this.item.dataModeArray = this.dataModeArrayData
726
- this.$emit('itemHandle', this.item, this.type)
727
- this.initItem()
728
- this.resetDataMode()
729
- },
730
- changeSelectKType () {
731
- this.item.selectKey = undefined
732
- },
733
- changeSelectKey (item) {
734
- if (item.selectType === 'key' && item.selectKey) {
735
- this.item.slot = Object.assign({}, this.item.slot, { keyMap: item.selectKey, type: 'badge' })
736
- }
737
- },
738
- filterOption (input, option) {
739
- return (
740
- option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
741
- )
742
- },
743
- delKey (obj, ...args) {
744
- args.forEach(v => {
745
- delete obj[v]
746
- })
747
- return obj
748
- },
749
- // 判断是否为json字符串
750
- isJSON (str) {
751
- if (typeof str == 'string') {
752
- try {
753
- const obj = JSON.parse(str)
754
- return !!(typeof obj == 'object' && obj)
755
- } catch (e) {
756
- return false
757
- }
758
- }
759
- },
760
- // 兼容旧插槽函数
761
- compatibleTheSlot (_item) {
762
- if (_item.slotKeyMap) {
763
- _item.slot.keyMap = _item.slotKeyMap
764
- delete _item.slotKeyMap
765
- }
766
- if (_item.slotValue) {
767
- _item.slot.value = _item.slotValue
768
- delete _item.slotValue
769
- }
770
- if (_item.actionText) {
771
- _item.slot.actionText = _item.actionText
772
- delete _item.actionText
773
- }
774
- }
775
- }
776
- }
777
- </script>
1
+ <template>
2
+ <a-modal
3
+ :destroyOnClose="true"
4
+ :visible="visible"
5
+ :width="1250"
6
+ :zIndex="1001"
7
+ title="数据字段配置"
8
+ @cancel="modelCancel"
9
+ @ok="submitItem">
10
+ <a-form-model
11
+ ref="itemForm"
12
+ :model="item"
13
+ :rules="itemRules"
14
+ layout="vertical">
15
+ <a-row :gutter="16">
16
+ <a-col :span="6">
17
+ <a-card :bodyStyle="bodyStyle" title="基本属性">
18
+ <a-divider style="font-size: 14px;margin-top: 0">字段信息</a-divider>
19
+ <a-form-model-item label="标签名称" prop="title">
20
+ <a-input v-model="item.title" placeholder="请输入标签名称"/>
21
+ </a-form-model-item>
22
+ <a-form-model-item
23
+ label="字段名称"
24
+ prop="key">
25
+ <a-input ref="key" v-model="item.key" :disabled="keyDisabled" placeholder="请输入字段名">
26
+ <a-popover slot="suffix" placement="bottom" title="关于字段名称">
27
+ <template slot="content">
28
+ <p>设置数据字段的名称</p>
29
+ <p>用作SQL查询时为<span style="font-weight: bold">表别名.数据列名</span>的格式,如:i.id</p>
30
+ </template>
31
+ <a-icon style="color: rgba(0,0,0,.45)" type="info-circle"/>
32
+ </a-popover>
33
+ </a-input>
34
+ </a-form-model-item>
35
+ <a-form-model-item
36
+ v-if="item.formType ==='addressSearch'"
37
+ label="坐标字段名">
38
+ <a-input :disabled="true" :value="`${item.key}_lng_lat`">
39
+ <a-popover slot="suffix" placement="bottom" title="坐标字段名">
40
+ <template slot="content">
41
+ <p>表单类型为地点搜索框时:</p>
42
+ <p>新增/修改表单内,字段名称会存放地址名称,坐标字段名会存放坐标信息</p>
43
+ </template>
44
+ <a-icon style="color: rgba(0,0,0,.45)" type="info-circle"/>
45
+ </a-popover>
46
+ </a-input>
47
+ </a-form-model-item>
48
+ <a-divider style="font-size: 14px;margin-top: 0">数据模式</a-divider>
49
+ <a-form-model-item
50
+ prop="dataMode"
51
+ style="margin-top: 10px;">
52
+ <a-checkbox-group v-model="dataModeArrayData" :disabled="dataModeDisabled" :options="dataModeTypeV"/>
53
+ </a-form-model-item>
54
+ </a-card>
55
+ </a-col>
56
+ <a-col :span="9">
57
+ <a-card v-if="dataMode.queryForm || dataMode.addOrEditForm || dataMode.table" :bodyStyle="bodyStyle" title="核心配置">
58
+ <template v-if="dataMode.queryForm || dataMode.addOrEditForm">
59
+ <a-divider style="font-size: 14px;margin-top: 0">表单配置</a-divider>
60
+ <a-form-model-item label="表单类型" prop="formType">
61
+ <a-select v-model="item.formType" placeholder="请选择表单类型" @change="changeFormType(item)">
62
+ <a-select-option v-for="formTypeItem in formType" :key="formTypeItem.key">{{ formTypeItem.label }}</a-select-option>
63
+ </a-select>
64
+ </a-form-model-item>
65
+ <template v-if="item.formType">
66
+ <a-form-model-item v-if="dataMode.sqlQueryCondition && item.formType !=='file' && item.formType !=='image' " label="表单查询方式" prop="queryType">
67
+ <a-select
68
+ v-model="item.queryType"
69
+ :disabled="formQueryTypeDisabled"
70
+ :getPopupContainer=" triggerNode => { return triggerNode.parentNode } "
71
+ placeholder="表单查询方式">
72
+ <a-select-option v-for="queryTypeItem in queryTypeV" :key="queryTypeItem.key">{{ queryTypeItem.label }}</a-select-option>
73
+ </a-select>
74
+ </a-form-model-item>
75
+ <a-form-model-item v-if="dataMode.addOrEditForm" label="表单校验" prop="rule">
76
+ <a-row :gutter="16">
77
+ <a-col v-if="(item.formType === 'input' || item.formType === 'textarea' ) && item.formType !=='file' && item.formType !=='image' " :span="12" >
78
+ <a-select v-model="item.rule.type" :getPopupContainer=" triggerNode => { return triggerNode.parentNode } " placeholder="校验类型">
79
+ <a-select-option v-for="ruleTypeItem in formRuleType" :key="ruleTypeItem.key">{{ ruleTypeItem.label }}</a-select-option>
80
+ <a-popover slot="suffixIcon" placement="bottom" title="关于表单校验类型">
81
+ <template slot="content">
82
+ <p>设置表单项的校验类型</p>
83
+ </template>
84
+ <a-icon style="color: rgba(0,0,0,.45)" type="info-circle"/>
85
+ </a-popover>
86
+ </a-select>
87
+ </a-col>
88
+ <a-col :span="12">
89
+ <a-radio-group v-model="item.rule.required" button-style="solid" default-value="false">
90
+ <a-radio-button value="true">
91
+ 必选项
92
+ </a-radio-button>
93
+ <a-radio-button value="false">
94
+ 非必选项
95
+ </a-radio-button>
96
+ </a-radio-group>
97
+ </a-col>
98
+ </a-row>
99
+ </a-form-model-item>
100
+ <a-form-model-item v-if="dataMode.addOrEditForm" label="新增/修改场景选择" prop="addOrEdit">
101
+ <a-select v-model="item.addOrEdit" placeholder="请选择场景">
102
+ <a-select-option v-for="addOrEditItem in addOrEditTypeV" :key="addOrEditItem.key">{{ addOrEditItem.label }}</a-select-option>
103
+ <a-popover
104
+ slot="suffixIcon"
105
+ placement="bottom"
106
+ title="关于新增/修改场景选择">
107
+ <template slot="content">
108
+ <p>设置表单项的新增/修改场景</p>
109
+ <p>静默新增类型用于非人为新增的数据,不会生成表单项,且必须设置字段用途</p>
110
+ </template>
111
+ <a-icon style="color: rgba(0,0,0,.45)" type="info-circle"/>
112
+ </a-popover>
113
+ </a-select>
114
+ </a-form-model-item>
115
+ <a-form-model-item v-if="item.addOrEdit === 'silenceAdd'" label="字段用途" prop="silencePurpose">
116
+ <a-select v-model="item.silencePurpose" :getPopupContainer=" triggerNode => { return triggerNode.parentNode } " placeholder="请选择字段用途">
117
+ <a-select-option v-for="silencePurposeTypeItem in silencePurposeType" :key="silencePurposeTypeItem.key">{{ silencePurposeTypeItem.label }}</a-select-option>
118
+ <a-popover
119
+ slot="suffixIcon"
120
+ placement="bottom"
121
+ title="关于字段用途">
122
+ <template slot="content">
123
+ <p>用于静默新增时设置字段用途</p>
124
+ <p>在新增数据的表单提交时,页面会根据设置的字段用途自动获取相关数据并追加到表单中</p>
125
+ <p>当字段用途选择为<span style="font-weight: bold">自定义</span>时,必须指定一个业务逻辑(Logic)名称,表单提交前会将表单内容作为参数调用该Logic接口,并将Logic返回值作为表单值
126
+ </p>
127
+ </template>
128
+ <a-icon style="color: rgba(0,0,0,.45)" type="info-circle"/>
129
+ </a-popover>
130
+ </a-select>
131
+ </a-form-model-item>
132
+ <a-form-model-item v-if="item.silencePurpose === 'customize'" label="字段用途对应Logic" prop="silenceSource">
133
+ <a-input v-model="item.silenceSource" placeholder="请输入业务逻辑名称"/>
134
+ </a-form-model-item>
135
+ </template>
136
+ </template>
137
+ <template v-if="dataMode.table">
138
+ <a-divider style="font-size: 14px;margin-top: 0">表格列配置</a-divider>
139
+ <a-form-model-item v-if="item.formType" label="作用域插槽" prop="slot">
140
+ <a-select v-model="item.slot.type" :disabled="slotTypeDisabled" :getPopupContainer=" triggerNode => { return triggerNode.parentNode } " placeholder="插槽类型">
141
+ <a-select-option v-for="slotTypeItem in slotTypeV" :key="slotTypeItem.key">{{ slotTypeItem.label }}</a-select-option>
142
+ <a-popover slot="suffixIcon" placement="bottom" title="关于作用域插槽">
143
+ <template slot="content">
144
+ <p>你可以通过设置表格列的作用域插槽实现一些效果</p>
145
+ <p>如果没有指定,默认会设置为文本溢出省略(长度:16)</p>
146
+ <p>如果你选择文本溢出省略,需要设置文本溢出上限长度,建议ID主键等类型设置为8</p>
147
+ <p>如果你选择多彩徽标,需要设置徽标对应的数据样式字典键</p>
148
+ <a-divider style="font-size: 14px;margin-top: 0">关于表格列宽度</a-divider>
149
+ <p>V1.1之后不再支持自定义表格列宽度,表格列宽度将通过作用域插槽类型自适应</p>
150
+ <p>设置为文本溢出省略时,表格列宽度 = 文本溢出上限长度 * 7 + 42</p>
151
+ <p>设置为多彩徽标时,表格列宽度为130</p>
152
+ <p>设置为日期时间格式化时,表格列宽度为160</p>
153
+ </template>
154
+ <a-icon style="color: rgba(0,0,0,.45)" type="info-circle"/>
155
+ </a-popover>
156
+ </a-select>
157
+ </a-form-model-item>
158
+ <a-form-model-item v-if="item.slot.type === 'badge'" label="徽标字典键" prop="slot.keyMap">
159
+ <a-input v-model="item.slot.keyMap" :disabled="slotTypeDisabled" placeholder="请输入徽标字典键">
160
+ <a-popover
161
+ slot="suffix"
162
+ placement="bottom"
163
+ title="关于徽标字典键">
164
+ <template slot="content">
165
+ <p>如果你设置了表单类型为选择框,且数据源是字典键,该值会自动带出</p>
166
+ </template>
167
+ <a-icon style="color: rgba(0,0,0,.45)" type="info-circle"/>
168
+ </a-popover>
169
+ </a-input>
170
+ </a-form-model-item>
171
+ <a-form-model-item v-if="item.slot.type === 'ellipsis'" label="文本溢出上限长度" prop="slot.value">
172
+ <a-input-number v-model="item.slot.value" placeholder="请输入文本溢出上限长度" style="width: 100%"/>
173
+ </a-form-model-item>
174
+ <a-form-model-item v-if="item.slot.type === 'action'" label="操作列文本" prop="slot.actionText">
175
+ <a-input v-model="item.slot.actionText" placeholder="请输入操作列显示文本,默认为详情"/>
176
+ </a-form-model-item>
177
+ <a-form-model-item v-if="dataMode.sqlQueryItem || dataMode.sqlQueryCondition" label="字段默认值" prop="default">
178
+ <a-input v-model="item.default" placeholder="当查询结果为null时,指定默认值"/>
179
+ </a-form-model-item>
180
+ </template>
181
+ </a-card>
182
+ </a-col>
183
+ <a-col v-if="item.formType" :span="9">
184
+ <a-card :bodyStyle="bodyStyle" title="扩展属性">
185
+ <template v-if="(dataMode.addOrEditForm || dataMode.queryForm ) && (item.formType === 'input' || item.formType === 'select' || item.formType === 'selects' || item.formType === 'cascader')">
186
+ <a-divider style="font-size: 14px;margin-top: 0">提示相关</a-divider>
187
+ <a-form-model-item label="表单水印" prop="placeholder">
188
+ <a-input v-model="item.placeholder" placeholder="表单水印(placeholder)" />
189
+ </a-form-model-item>
190
+ </template>
191
+ <template v-if="item.formType === 'selects'">
192
+ <a-divider style="font-size: 14px;margin-top: 0">级联选择相关</a-divider>
193
+ <a-form-model-item label="是否根节点" prop="groupIndexView">
194
+ <a-radio-group
195
+ v-model="item.groupIndexView"
196
+ button-style="solid"
197
+ @change="groupIndexChange">
198
+ <a-radio-button value="1">
199
+
200
+ </a-radio-button>
201
+ <a-radio-button value="0">
202
+
203
+ </a-radio-button>
204
+ </a-radio-group>
205
+ </a-form-model-item>
206
+ <a-form-model-item v-if="item.groupIndexView === '0' && item.groupIndex !== -1" label="所属父级联动框" prop="groupIndex">
207
+ <a-select
208
+ ref="groupIndex"
209
+ v-model="item.parent_title"
210
+ :getPopupContainer=" triggerNode => { return triggerNode.parentNode } "
211
+ placeholder="请选择父级联动框"
212
+ @change="parent_title_change">
213
+ <a-select-option v-for="parent_item in parent_node" :key="parent_item.key">
214
+ {{ parent_item.title }}
215
+ </a-select-option>
216
+ </a-select>
217
+ </a-form-model-item>
218
+ </template>
219
+ <template v-if="selectDataShow">
220
+ <a-divider style="font-size: 14px;margin-top: 0">数据源相关</a-divider>
221
+ <a-form-model-item label="数据源类型" prop="selectType">
222
+ <a-select v-model="item.selectType" placeholder="请选择数据源类型" @change="changeSelectKType">
223
+ <a-select-option v-for="selectDataTypeItem in selectDataType.filter(h=>!h.noMatch.includes(item.formType))" :key="selectDataTypeItem.key">{{ selectDataTypeItem.label }}</a-select-option>
224
+ <a-popover
225
+ slot="suffixIcon"
226
+ placement="bottom"
227
+ title="关于数据源类型">
228
+ <template slot="content">
229
+ <p>设置数据源</p>
230
+ <p>数据源类型分为三种,你可以根据需要选择</p>
231
+ <p>字典键:选项从字典表(t_dictionary)获取,你只需要选择字典键的名称即可</p>
232
+ <p>业务逻辑名称:选项通过发起http请求调用指定的业务逻辑(Logic)接口获取</p>
233
+ <p>固定集合:选项为静态值,JSONArray格式</p>
234
+ <p>当表单为级联选择框类型时,返回的数据需按照以下形式:</p>
235
+ <json-viewer
236
+ :expand-depth="parseInt('100')"
237
+ :value="DemoJson"
238
+ style="overflow: auto;max-height: 440px"></json-viewer>
239
+ </template>
240
+ <a-icon style="color: rgba(0,0,0,.45)" type="info-circle"/>
241
+ </a-popover>
242
+ </a-select>
243
+ </a-form-model-item>
244
+ <a-form-model-item v-if="item.selectType" label="数据源" prop="selectKey">
245
+ <a-select
246
+ v-if="item.selectType === 'key'"
247
+ v-model="item.selectKey"
248
+ :filter-option="filterOption"
249
+ placeholder="请选择字典键"
250
+ show-search
251
+ @change="changeSelectKey(item)">
252
+ <template>
253
+ <a-select-option
254
+ v-for="(optionItem,index) in option"
255
+ :key="index"
256
+ :value="Object.keys(optionItem)[0]">{{ optionItem[Object.keys(optionItem)[0]] }}
257
+ </a-select-option>
258
+ </template>
259
+ </a-select>
260
+ <a-input v-if="item.selectType === 'logic'" v-model="item.selectKey" placeholder="请输入业务逻辑名称"/>
261
+ <a-textarea v-if="item.selectType === 'fixArray'" v-model="item.selectKey" placeholder="请录入数据源"/>
262
+ </a-form-model-item>
263
+ <a-form-model-item v-if="item.selectType === 'logic'" label="数据源加载方式" prop="selectLoadType">
264
+ <a-radio-group v-model="item.lazyLoad" button-style="solid" default-value="false">
265
+ <a-radio-button value="true">
266
+ 懒加载搜索
267
+ </a-radio-button>
268
+ <a-radio-button value="false">
269
+ 一次性加载
270
+ </a-radio-button>
271
+ </a-radio-group>
272
+ </a-form-model-item>
273
+ </template>
274
+ <a-form-model-item v-if="selectDataShow || item.groupIndexView" label="关联外键字段" prop="selectKeyName">
275
+ <a-input v-model="item.selectKeyName" placeholder="该列关联的外键字段">
276
+ <a-popover slot="suffix" placement="bottom" title="关于关联外键字段">
277
+ <template slot="content">
278
+ <p><span style="font-weight: bold;"><span style="color: #FF0036">非必需的实验性功能:</span>设置该参数需开发岗指导</span></p>
279
+ <p>当字段与主子表外键有关系时,你可以指定<span style="font-weight: bold">该列所关联的外键字段名</span>
280
+ </p>
281
+ <p>设置该参数是为了该字段用作表单查询时,系统可以通过设置的关联外键字段,而非字面值作为查询条件</p>
282
+ <p>示例:</p>
283
+ <p>主表为t_userfiles(表档案)表,别名为u,与t_gasbrand(气表品牌表)有关联关系,别名为g,为了显示表档案对应的气表品牌数据,我们将数据字段名设置为g.f_gasbrand</p>
284
+ <p>这样我们就可以在table中看到气表品牌了,但是用户如果通过气表品牌下拉框进行筛选,我们指定的g.f_gasbrand只是气表品牌的值,而实际关联字段是u.f_gasbrand_id</p>
285
+ <p>所以如果我们指定了关联外键字段u.f_gasbrand_id,系统则会使用u.f_gasbrand_id筛选数据,而不是g.f_gasbrand,从而优化了查询效率
286
+ </p>
287
+ </template>
288
+ <a-icon style="color: rgba(0,0,0,.45)" type="info-circle"/>
289
+ </a-popover>
290
+ </a-input>
291
+ </a-form-model-item>
292
+ <template v-if="item.formType === 'file' || item.formType === 'image'">
293
+ <a-divider style="font-size: 14px;margin-top: 0">文件上传相关</a-divider>
294
+ <a-form-model-item label="允许上传文件数量" prop="accept" style="margin-bottom: 5px;">
295
+ <a-slider
296
+ v-model="item.acceptCount"
297
+ :marks="{ 1: '1', 3: '3', 5: '5', 10: '10', 15: '15', 20: '20'}"
298
+ :max="20"
299
+ :min="1"
300
+ />
301
+ </a-form-model-item>
302
+ <a-form-model-item label="附件用途" prop="useType">
303
+ <a-select v-model="item.useType" placeholder="指定文件用途,同表单不同用途">
304
+ <a-select-option v-for="userTypeItem in $appdata.getDictionaryList('useType')" :key="userTypeItem.value">{{ userTypeItem.value }}</a-select-option>
305
+ </a-select>
306
+ </a-form-model-item>
307
+ <a-form-model-item label="上传的仓库" prop="resUploadStock">
308
+ <a-select v-model="item.resUploadStock" placeholder="选择文件上传到的仓库" @change="changeStock">
309
+ <a-select-option v-for="stock in stockList" :key="stock.id">{{ stock.f_name }}</a-select-option>
310
+ </a-select>
311
+ </a-form-model-item>
312
+ <a-form-model-item v-if="item.resUploadStock" label="具体路径" prop="pathKey">
313
+ <a-select v-model="item.pathKey" placeholder="仓库扩展路径">
314
+ <a-select-option v-for="pathKey in lowerPath" :key="pathKey.label">{{ pathKey.label }}</a-select-option>
315
+ </a-select>
316
+ </a-form-model-item>
317
+ <a-form-model-item v-if="item.formType === 'file'" label="允许上传文件类型" prop="accept">
318
+ <a-select v-model="item.accept" mode="tags" placeholder="指定文件类型,默认不限制" @change="itemAcceptChange">
319
+ <a-select-option v-for="type_item in fileType" :key="type_item.accept">{{ type_item.label }}</a-select-option>
320
+ </a-select>
321
+ </a-form-model-item>
322
+ </template>
323
+ </a-card>
324
+ </a-col>
325
+ </a-row>
326
+ <a-alert
327
+ v-if="dataModeArrayData.length === 0"
328
+ message="错误:请至少选择一种数据模式"
329
+ show-icon
330
+ style="margin-top: 5px"
331
+ type="error"/>
332
+ <a-alert
333
+ v-if="dataMode.addOrEditForm && !dataMode.sqlQueryItem && item.formType !== 'file' && item.formType !== 'image' && item.formType !== 'personSetting' && item.formType !== 'cascader' "
334
+ message="错误:如果要生成新增/修改表单项,必须勾选生成SQL查询项"
335
+ show-icon
336
+ style="margin-top: 5px"
337
+ type="error"/>
338
+ <a-alert
339
+ v-if="dataMode.queryForm && !dataMode.sqlQueryCondition"
340
+ message="提示:您没有勾选生成SQL查询表达式,渲染的表单项不会生成SQL查询条件"
341
+ show-icon
342
+ style="margin-top: 5px"
343
+ type="info"/>
344
+ <a-alert
345
+ v-if="dataMode.table && !dataMode.sqlQueryItem"
346
+ message="提示:您没有勾选生成SQL查询项,渲染的表格列不会绑定SQL结果集数据"
347
+ show-icon
348
+ style="margin-top: 5px"
349
+ type="info"/>
350
+ </a-form-model>
351
+ </a-modal>
352
+ </template>
353
+
354
+ <script>
355
+ import {
356
+ dataModeType,
357
+ fileType,
358
+ formRuleType,
359
+ formType,
360
+ queryType,
361
+ slotType,
362
+ silencePurposeType,
363
+ addOrEditType,
364
+ selectDataType
365
+ } from '@vue2-client/config/CreateQueryConfig'
366
+ import { commonApi, post } from '@vue2-client/services/api'
367
+ import JsonViewer from 'vue-json-viewer'
368
+
369
+ const DemoJson = [{
370
+ value: 'zhejiang',
371
+ label: 'Zhejiang',
372
+ children: [{ value: 'hangzhou', label: 'Hangzhou', children: [{ value: 'xihu', label: 'West Lake' }] }]
373
+ }]
374
+
375
+ export default {
376
+ name: 'CreateQueryItem',
377
+ components: {
378
+ JsonViewer
379
+ },
380
+ computed: {
381
+ // 是否展示数据源相关字段
382
+ selectDataShow () {
383
+ return this.item.formType === 'select' || this.item.formType === 'cascader' || (this.item.formType === 'selects' && this.item.groupIndexView === '1') || this.item.formType === 'checkbox' || this.item.formType === 'radio'
384
+ },
385
+ // 作用域插槽是否禁用
386
+ slotTypeDisabled () {
387
+ return this.item.selectType === 'key' && this.item.selectKey
388
+ },
389
+ // 字段名称是否禁用
390
+ keyDisabled () {
391
+ return this.item.formType === 'file' || this.item.formType === 'image'
392
+ },
393
+ // 数据模式是否禁用
394
+ dataModeDisabled () {
395
+ return this.item.formType === 'file' || this.item.formType === 'image' || this.item.formType === 'addressSearch'
396
+ },
397
+ dataMode: function () {
398
+ const result = {
399
+ queryForm: false,
400
+ table: false,
401
+ addOrEditForm: false,
402
+ sqlQueryItem: false,
403
+ sqlQueryCondition: false
404
+ }
405
+ for (const item of this.dataModeArrayData) {
406
+ result[item] = true
407
+ }
408
+ return result
409
+ },
410
+ queryTypeV () {
411
+ return queryType.filter(item => {
412
+ return item.match.findIndex(type => type === this.item.formType || type === 'all') > -1
413
+ })
414
+ },
415
+ dataModeTypeV () {
416
+ if (this.item.formType) {
417
+ return dataModeType.filter(item => {
418
+ return item.noMatch.findIndex(type => type === this.item.formType) === -1
419
+ })
420
+ } else {
421
+ return dataModeType
422
+ }
423
+ },
424
+ slotTypeV () {
425
+ return slotType.filter(item => {
426
+ return item.match.findIndex(type => type === this.item.formType || type === 'all') > -1
427
+ })
428
+ },
429
+ addOrEditTypeV () {
430
+ return addOrEditType.filter(item => {
431
+ return item.match.findIndex(type => type === this.item.formType || type === 'all') > -1
432
+ })
433
+ }
434
+ },
435
+ data () {
436
+ return {
437
+ DemoJson,
438
+ dataModeType,
439
+ queryType,
440
+ formType,
441
+ formRuleType,
442
+ slotType,
443
+ fileType,
444
+ silencePurposeType,
445
+ addOrEditType,
446
+ selectDataType,
447
+ // 控制modal框
448
+ visible: false,
449
+ type: '',
450
+ bodyStyle: {
451
+ height: '500px',
452
+ overflowY: 'auto'
453
+ },
454
+ // 表单查询方式是否禁用
455
+ formQueryTypeDisabled: false,
456
+ // 数据模式类型集合值
457
+ dataModeArrayData: [],
458
+ // 表单项
459
+ item: {
460
+ key: '',
461
+ title: '',
462
+ slot: {
463
+ type: 'default'
464
+ },
465
+ rule: {
466
+ required: 'false'
467
+ },
468
+ queryType: '=',
469
+ formType: 'input',
470
+ accept: undefined,
471
+ pathKey: undefined,
472
+ groupIndexView: undefined,
473
+ selectType: undefined,
474
+ addOrEdit: 'all',
475
+ fileRootPath: undefined,
476
+ selectKeyName: undefined,
477
+ resUploadStock: undefined,
478
+ dataModeArray: []
479
+ },
480
+ // 数据仓库列表
481
+ stockList: [],
482
+ // 扩展目录
483
+ lowerPath: [],
484
+ parent_node: [],
485
+ // 必填控制
486
+ itemRules: {
487
+ formType: [{ required: true, message: '请输入表单类型', trigger: 'change' }],
488
+ key: [{ required: true, message: '请输入字段名称', trigger: 'blur' }],
489
+ title: [{ required: true, message: '请输入标签名称', trigger: 'blur' }],
490
+ selectType: [{ required: true, message: '请选择数据源类型', trigger: 'change' }],
491
+ selectKey: [{ required: true, message: '请输入数据源内容', trigger: 'blur' }],
492
+ 'slot.value': [{ required: true, message: '请输入文本溢出上限长度', trigger: 'blur' }],
493
+ 'slot.keyMap': [{ required: true, message: '请输入徽标字典键', trigger: 'blur' }],
494
+ silencePurpose: [{ required: true, message: '请选择字段用途', trigger: 'change' }],
495
+ silenceSource: [{ required: true, message: '请输入业务逻辑名称', trigger: 'blur' }],
496
+ groupIndex: [{ required: true, message: '请选择父级联动框', trigger: 'blur' }],
497
+ resUploadStock: [{ required: true, message: '请选择上传到的仓库', trigger: 'blur' }],
498
+ pathKey: [{ required: true, message: '请选择上传到的扩展目录', trigger: 'blur' }]
499
+ },
500
+ // 字典键集合
501
+ option: []
502
+ }
503
+ },
504
+ mounted () {
505
+ this.resetDataMode()
506
+ },
507
+ props: { },
508
+ methods: {
509
+ initItem (lysis = {}) {
510
+ this.item = Object.assign({
511
+ key: '',
512
+ title: '',
513
+ slot: {
514
+ type: 'default'
515
+ },
516
+ rule: {
517
+ required: 'false'
518
+ },
519
+ selectKey: undefined,
520
+ queryType: '=',
521
+ formType: 'input',
522
+ fileRootPath: undefined,
523
+ pathKey: undefined,
524
+ accept: undefined,
525
+ selectType: undefined,
526
+ groupIndexView: undefined,
527
+ addOrEdit: 'all',
528
+ selectKeyName: undefined,
529
+ resUploadStock: undefined,
530
+ dataModeArray: []
531
+ }, lysis)
532
+ },
533
+ // 控制 展示
534
+ flashModal (show = 'None') {
535
+ const bool = show === 'None' ? !this.visible : !!show
536
+ if (bool && this.option.length === 0) {
537
+ post(commonApi.getDictionaryParam, {}).then(res => {
538
+ this.option = res
539
+ })
540
+ }
541
+ this.visible = bool
542
+ },
543
+ // 编辑数据字段前准备数据
544
+ editColumnItemExecute (_item) {
545
+ this.type = '修改'
546
+ const defaultValue = { formType: 'input', type: 'string', addOrEdit: 'all', slot: { type: 'default' }, rule: {}, selectKey: {} }
547
+ if (!_item.queryType) {
548
+ defaultValue.queryType = '='
549
+ }
550
+ _item = Object.assign({}, defaultValue, _item)
551
+ if (_item.formType === 'file' || _item.formType === 'image') {
552
+ this.getStocks()
553
+ // 如果有仓库 则获取该仓库的扩展路径
554
+ if (_item.resUploadStock) {
555
+ this.lowerPath = this.stockList.filter(item => item.id === _item.resUploadStock)[0]?.f_lower_path_json ?? []
556
+ }
557
+ }
558
+ if (_item.selectKey && _item.selectType === 'logic' && _item.selectKey.substring(0, 6) === 'logic@') {
559
+ _item.selectKey = _item.selectKey.substring(6)
560
+ }
561
+ if (_item.formType === 'selects') {
562
+ // 因为 groupIndex 可能有很多值 单选框不行 赋给一个新的变量
563
+ _item.groupIndexView = _item.groupIndex === 1 ? '1' : '0'
564
+ }
565
+ // 兼容旧作用域插槽属性
566
+ this.compatibleTheSlot(_item)
567
+ this.item = _item
568
+ this.dataModeArrayData = this.item.dataModeArray
569
+ this.flashModal()
570
+ },
571
+ // 增加数据字段前数据处理
572
+ addColumnItemExecute () {
573
+ this.type = '新增'
574
+ this.dataModeArrayData = ['queryForm', 'table', 'addOrEditForm', 'sqlQueryItem', 'sqlQueryCondition']
575
+ this.initItem()
576
+ this.flashModal()
577
+ },
578
+ modelCancel () {
579
+ this.flashModal()
580
+ // this.$emit('update:visible', false)
581
+ // // 延迟是为了避免编辑数据窗口关闭时重置表单导致的闪烁
582
+ // setTimeout(() => {
583
+ // this.resetDataMode()
584
+ // this.resetFormProp()
585
+ // }, 100)
586
+ },
587
+ submitItem () {
588
+ this.$refs.itemForm.validate(valid => {
589
+ if (valid) {
590
+ const fileBool = this.item.formType === 'file' || this.item.formType === 'image'
591
+ if (this.dataModeArrayData.length === 0) {
592
+ this.$message.error('请至少选择一种数据模式')
593
+ return
594
+ }
595
+ if (!fileBool && (this.dataMode.addOrEditForm && !this.dataMode.sqlQueryItem) && this.item.formType !== 'personSetting' && this.item.formType !== 'cascader') {
596
+ this.$message.error('如果要生成新增/修改表单项,必须勾选生成SQL查询项')
597
+ return
598
+ }
599
+ if (fileBool && !(!this.dataMode.table && !this.dataMode.sqlQueryCondition && !this.dataMode.queryForm)) {
600
+ this.$message.error(`上传类表单项只能选择 "渲染新增/修改表单项"`)
601
+ return
602
+ }
603
+ this.itemHandle()
604
+ }
605
+ })
606
+ },
607
+ visitAcceptFile () {
608
+ window.open('https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/input/file#attr-accept')
609
+ },
610
+ // 修改上传到哪个仓库
611
+ changeStock (stock) {
612
+ if (stock) {
613
+ const stockValue = this.stockList.filter(item => item.id === stock)[0]
614
+ this.lowerPath = stockValue.f_lower_path_json ?? []
615
+ this.item.resUploadMode = stockValue.f_stock_type
616
+ this.item.fileRootPath = stockValue.f_root_path
617
+ this.item.stockAlias = stockValue.f_alias
618
+ this.item.pathKey = undefined
619
+ }
620
+ },
621
+ // 文件上传限制类型修改
622
+ itemAcceptChange (newVal) {
623
+ if (newVal.includes('*')) {
624
+ this.item.accept = ['*']
625
+ }
626
+ },
627
+ parent_title_change (parentKey) {
628
+ const parentArr = this.getColumn().filter(item => item.formType === 'selects' && item.key === parentKey)
629
+ if (parentArr.length === 1) {
630
+ this.item.groupIndex = parentArr[0].groupIndex + 1
631
+ this.item.group = parentArr[0].group
632
+ this.item.parent_title = parentArr[0].title
633
+ } else {
634
+ this.$message.error('数据字段中有字段别名相同,请检查!')
635
+ }
636
+ },
637
+ groupIndexChange ({ target }) {
638
+ if (target.value === '1') {
639
+ this.item.groupIndex = 1
640
+ this.item.groupIndexView = '1'
641
+ if (this.item.title) {
642
+ this.item.group = this.item.title + '组'
643
+ } else {
644
+ this.item.groupIndex = undefined
645
+ this.item.groupIndexView = undefined
646
+ this.$message.error('请先输入字段中文名称!')
647
+ }
648
+ } else {
649
+ if (!this.item.title) {
650
+ this.$message.error('请先输入字段名称!')
651
+ this.item.groupIndex = -1
652
+ this.item.groupIndexView = undefined
653
+ return
654
+ }
655
+ this.item.groupIndex = undefined
656
+ // 获取所有可以当作父节点的字段
657
+ this.parent_node = this.getColumn().filter(item => item.formType === 'selects' && item.key !== this.item.key)
658
+ }
659
+ },
660
+ getColumn () {
661
+ let result = {}
662
+ this.$emit('getColumn', val => { result = val })
663
+ return result
664
+ },
665
+ changeFormType (item) {
666
+ this.initItem({ key: item.key, title: item.title, formType: item.formType })
667
+ if (item.formType === 'file' || item.formType === 'image') {
668
+ this.item.acceptCount = 3
669
+ this.getStocks()
670
+ this.item.accept = item.formType === 'file' ? ['*'] : ['.jpg,.jpeg,.ico,.gif,svg,.webp,.png,.bmp,.pjpeg,']
671
+ this.item.resUploadMode = 'server'
672
+ this.item.key = item.formType === 'file' ? 'FilesId' : 'Images'
673
+ this.dataModeArrayData = ['addOrEditForm']
674
+ } else if (item.formType === 'addressSearch') {
675
+ this.dataModeArrayData = ['addOrEditForm', 'sqlQueryItem']
676
+ } else {
677
+ if (['FilesId', 'Images'].includes(this.item.key)) { this.item.key = '' }
678
+ this.resetDataMode()
679
+ // 表单查询方式有预选项时
680
+ if (this.queryTypeV.length === 1) {
681
+ this.item.queryType = this.queryTypeV[0].value
682
+ }
683
+ }
684
+ },
685
+ // 获取所有仓库
686
+ getStocks () {
687
+ if (this.stockList.length === 0) {
688
+ post('/api/af-system/logic/getFilesStock', {}).then(res => {
689
+ this.stockList = res.sort((a, b) => b.progress - a.progress)
690
+ }).catch(e => {})
691
+ }
692
+ },
693
+ // 重置数据模式
694
+ resetDataMode () {
695
+ this.dataModeArrayData = this.dataModeTypeV.map(item => item.value)
696
+ },
697
+ itemHandle () {
698
+ // 查询表单项或者新增/修改表单项
699
+ if (this.dataMode.queryForm || this.dataMode.addOrEditForm) {
700
+ if (!this.dataMode.sqlQueryItem || !this.dataMode.addOrEditForm) {
701
+ this.delKey(this.item, 'addOrEdit', 'silencePurpose', 'silenceSource')
702
+ }
703
+ if (this.item.selectType && this.item.selectType === 'logic' && this.item.selectKey.substring(0, 6) !== 'logic@') {
704
+ // 数据源为logic
705
+ this.item.selectKey = 'logic@' + this.item.selectKey
706
+ } else if (this.item.selectType && this.item.selectType === 'fixArray' && !this.isJSON(this.item.selectKey)) {
707
+ // 数据源为固定json集合
708
+ this.$message.warning('下拉框数据源不是JSON集合')
709
+ return
710
+ }
711
+ } else {
712
+ this.delKey(this.item, 'queryType', 'formType', 'addOrEdit', 'silencePurpose', 'silenceSource', 'placeholder', 'rule', 'selectKey', 'selectKeyName', 'lazyLoad')
713
+ }
714
+ // 如果和数据源字段无关
715
+ if (!this.selectDataShow) {
716
+ this.delKey(this.item, 'selectType', 'selectKey', 'lazyLoad', 'selectKeyName')
717
+ }
718
+ // 默认插槽就先删除
719
+ if (this.item.slot && (this.item.slot.type === 'default' || !this.item.slot.type)) { delete this.item.slot }
720
+ // 根据数据模式处理数据
721
+ if (!this.dataMode.sqlQueryCondition) {
722
+ delete this.item.queryType
723
+ }
724
+ if (!this.dataMode.sqlQueryItem) { this.delKey(this.item, 'default') }
725
+ this.item.dataModeArray = this.dataModeArrayData
726
+ this.$emit('itemHandle', this.item, this.type)
727
+ this.initItem()
728
+ this.resetDataMode()
729
+ },
730
+ changeSelectKType () {
731
+ this.item.selectKey = undefined
732
+ },
733
+ changeSelectKey (item) {
734
+ if (item.selectType === 'key' && item.selectKey) {
735
+ this.item.slot = Object.assign({}, this.item.slot, { keyMap: item.selectKey, type: 'badge' })
736
+ }
737
+ },
738
+ filterOption (input, option) {
739
+ return (
740
+ option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
741
+ )
742
+ },
743
+ delKey (obj, ...args) {
744
+ args.forEach(v => {
745
+ delete obj[v]
746
+ })
747
+ return obj
748
+ },
749
+ // 判断是否为json字符串
750
+ isJSON (str) {
751
+ if (typeof str == 'string') {
752
+ try {
753
+ const obj = JSON.parse(str)
754
+ return !!(typeof obj == 'object' && obj)
755
+ } catch (e) {
756
+ return false
757
+ }
758
+ }
759
+ },
760
+ // 兼容旧插槽函数
761
+ compatibleTheSlot (_item) {
762
+ if (_item.slotKeyMap) {
763
+ _item.slot.keyMap = _item.slotKeyMap
764
+ delete _item.slotKeyMap
765
+ }
766
+ if (_item.slotValue) {
767
+ _item.slot.value = _item.slotValue
768
+ delete _item.slotValue
769
+ }
770
+ if (_item.actionText) {
771
+ _item.slot.actionText = _item.actionText
772
+ delete _item.actionText
773
+ }
774
+ }
775
+ }
776
+ }
777
+ </script>