vue2-client 1.2.28-test2 → 1.2.30

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.
@@ -1,1205 +1,1308 @@
1
- <template>
2
- <a-drawer
3
- title="查询配置生成"
4
- placement="right"
5
- :width="isMobile ? screenWidth : screenWidth * 0.85"
6
- :visible="visible"
7
- @close="onClose"
8
- >
9
- <a-row :gutter="24">
10
- <a-col :xl="14" :lg="12" :md="12" :sm="24" :xs="24">
11
- <a-form-model
12
- ref="businessCreateForm"
13
- :rules="rules"
14
- :model="form"
15
- :label-col="labelCol"
16
- :wrapper-col="wrapperCol"
17
- >
18
- <a-form-model-item label="查询主表名" prop="tableName">
19
- <a-input v-model="form.tableName" placeholder="查询用的主表+别名,用空格隔开,如:t_userfiles u" />
20
- </a-form-model-item>
21
- <a-form-model-item label="预设关联表" prop="joinArray">
22
- <a-popover title="说明" placement="right">
23
- <template slot="content">
24
- <p>配置你的查询中可能涉及到的所有关联表</p>
25
- <p>比如你的查询中涉及到了t_userinfo表,就需要加入t_userinfo表的关联,和你写SQL的关联一样</p>
26
- <p>请注意,你关联的<span style="color: #ff0000">除主表外的任何表</span>都需要配置</p>
27
- <a-input-group compact style="width: 400px;">
28
- <a-input style="width: 20%" placeholder="表别名" readOnly/>
29
- <a-input style="width: 80%" placeholder="关联条件" readOnly/>
30
- </a-input-group>
31
- <a-input-group compact style="width: 400px;">
32
- <a-input value="ui" style="width: 20%" placeholder="表别名" readOnly/>
33
- <a-input value="t_userinfo ui on i.f_userinfo_id = ui.f_userinfo_id" style="width: 80%" placeholder="关联条件" readOnly/>
34
- </a-input-group>
35
- </template>
36
- <a-button type="primary" @click="addJoinItem()">增加</a-button>
37
- </a-popover>
38
- <div v-for="(itemObj, index) in joinArray" :key="index">
39
- <a-input-group compact>
40
- <a-input @change="changeJoinArray()" v-model="itemObj.key" style="width: 20%;position: relative;bottom: 1px;" placeholder="表别名" />
41
- <a-input @change="changeJoinArray()" v-model="itemObj.value" style="width: 80%" placeholder="关联条件">
42
- <a-icon slot="addonAfter" type="close" @click="removeJoinItem(index)"/>
43
- </a-input>
44
- </a-input-group>
45
- </div>
46
- </a-form-model-item>
47
- <a-form-model-item label="SQL查询表达式" prop="condition">
48
- <a-input v-model="form.condition.value" placeholder="用作SQL查询的固定条件表达式,如:gb.f_meter_type='物联网表',可选" />
49
- <template v-if="form.condition.value && Object.keys(form.joinArray).length > 0">
50
- <a-alert message="提示:如果SQL查询表达式中用到了关联表,需要勾选用到的关联表别名" type="success" />
51
- <a-checkbox-group v-model="form.condition.join" :options="conditionJoinArray"/>
52
- </template>
53
- </a-form-model-item>
54
- <a-form-model-item label="排序方式" prop="orderBy">
55
- <a-input v-model="form.orderBy" placeholder="排序字段,用别名+字段名+排序方式(可选)表示,如:u.id desc" />
56
- </a-form-model-item>
57
- <a-form-model-item label="数据字段" prop="column">
58
- <a-button type="primary" @click="addColumnItem()">增加</a-button>
59
- <div v-for="(columnItem, index) in form.column" :key="index">
60
- <a-row :gutter="16">
61
- <a-col :span="16">
62
- <span style="font-weight: bold">{{ columnItem.title }}({{ columnItem.key }})</span>
63
- </a-col>
64
- <a-col v-if="index > 0 && form.column.length > 1" :span="2">
65
- <a-icon type="up-square" @click="upColumnItem(columnItem.key,index)"/>
66
- </a-col>
67
- <a-col v-if="(index !== form.column.length - 1) && form.column.length > 1" :span="2">
68
- <a-icon type="down-square" @click="downColumnItem(columnItem.key,index)"/>
69
- </a-col>
70
- <a-col :span="2">
71
- <a-icon type="edit" @click="editColumnItem(columnItem.key,index)"/>
72
- </a-col>
73
- <a-col :span="2">
74
- <a-icon type="close" @click="removeColumnItem(columnItem.key,index)"/>
75
- </a-col>
76
- </a-row>
77
- </div>
78
- </a-form-model-item>
79
- <a-form-model-item label="操作按钮配置" prop="buttonState">
80
- <a-checkbox-group v-model="buttonStateData" :options="buttonStateArray" />
81
- </a-form-model-item>
82
- </a-form-model>
83
- <a-modal
84
- title="数据字段配置"
85
- :visible="dataColumnVisible"
86
- :width="1000"
87
- :zIndex="1001"
88
- @cancel="modelCancel"
89
- @ok="submitItem">
90
- <a-form-model
91
- ref="itemForm"
92
- :rules="itemRules"
93
- :model="item">
94
- <a-row :gutter="16">
95
- <a-col :span="8">
96
- <a-form-model-item label="数据字段名" prop="key">
97
- <a-input v-model="item.key" placeholder="请输入数据字段名" ref="key">
98
- <a-popover slot="suffix" title="关于数据字段名" placement="bottom">
99
- <template slot="content">
100
- <p>设置数据字段的名称</p>
101
- <p>用作SQL查询时必须遵守<span style="font-weight: bold">表别名.列名</span>的格式,如:i.id</p>
102
- <p>其他情况下不限制</p>
103
- </template>
104
- <a-icon type="info-circle" style="color: rgba(0,0,0,.45)" />
105
- </a-popover>
106
- </a-input>
107
- </a-form-model-item>
108
- </a-col>
109
- <a-col :span="8">
110
- <a-form-model-item label="数据字段中文名" prop="title">
111
- <a-input v-model="item.title" placeholder="请输入数据字段中文名,如:编号" />
112
- </a-form-model-item>
113
- </a-col>
114
- </a-row>
115
- <a-row :gutter="16">
116
- <a-col :span="24">
117
- <a-form-model-item label="数据模式" prop="dataMode">
118
- <a-checkbox-group v-model="dataModeArrayData" :options="dataModeArray" />
119
- </a-form-model-item>
120
- </a-col>
121
- </a-row>
122
- <template v-if="dataMode.queryForm || dataMode.addOrEditForm">
123
- <a-row :gutter="16">
124
- <a-col :span="8">
125
- <a-form-model-item label="表单类型" prop="formType">
126
- <a-select v-model="item.formType" placeholder="表单类型,可选" @change="changeFormType(item)">
127
- <a-select-option key="input">输入框</a-select-option>
128
- <a-select-option key="select">选择框</a-select-option>
129
- <a-select-option key="checkbox">多选框</a-select-option>
130
- <a-select-option key="radio">单选框</a-select-option>
131
- <a-select-option key="rangePicker">日期范围选择框</a-select-option>
132
- <a-select-option key="monthPicker">月份选择框</a-select-option>
133
- <a-select-option key="datePicker">单日选择框</a-select-option>
134
- <!-- <a-select-option key="cascader">级联选择框(单个下拉)</a-select-option>-->
135
- <a-select-option key="selects">级联选择框</a-select-option>
136
- <a-select-option key="textarea">文本域</a-select-option>
137
- <a-select-option key="file">文件上传</a-select-option>
138
- <a-select-option key="image">图片上传</a-select-option>
139
- <a-popover slot="suffixIcon" title="关于表单类型" placement="right">
140
- <template slot="content">
141
- <p>预览设置的表单类型</p>
142
- <a-input-group compact style="width: 400px;">
143
- <a-input value="输入框" style="width: 20%" readOnly/>
144
- <a-input style="width: 80%" placeholder="请输入"/>
145
- </a-input-group>
146
- <br/>
147
- <a-input-group compact style="width: 400px;">
148
- <a-input value="选择框" style="width: 20%" readOnly/>
149
- <a-select style="width: 80%" placeholder="请选择"/>
150
- </a-input-group>
151
- <br/>
152
- <a-input-group compact style="width: 400px;">
153
- <a-input value="多选框" style="width: 20%" readOnly/>
154
- <a-checkbox-group style="margin-left: 10px;margin-top: 5px; width: 70%" :options="['数据1','数据2']"/>
155
- </a-input-group>
156
- <br/>
157
- <a-input-group compact style="width: 400px;">
158
- <a-input value="单选框" style="width: 20%" readOnly/>
159
- <a-radio-group style="margin-left: 10px;margin-top: 5px; width: 70%" :options="[{label: '数据1', value: 'a'},{label: '数据2', value: 'b'}]" name="radioGroup" />
160
- </a-input-group>
161
- <br/>
162
- <a-input-group compact style="width: 400px;">
163
- <a-input value="日期范围选择框" style="width: 20%" readOnly/>
164
- <a-range-picker style="width: 80%" :show-time="true" format="YYYY-MM-DD HH:mm:ss" valueFormat="YYYY-MM-DD HH:mm:ss" />
165
- </a-input-group>
166
- <br/>
167
- <a-input-group compact style="width: 400px;">
168
- <a-input value="月份选择框" style="width: 20%" readOnly/>
169
- <a-month-picker style="width: 80%"/>
170
- </a-input-group>
171
- <br/>
172
- <a-input-group compact style="width: 400px;">
173
- <a-input value="单日选择框" style="width: 20%" readOnly/>
174
- <a-date-picker style="width: 80%"/>
175
- </a-input-group>
176
- <br/>
177
- <a-input-group compact style="width: 400px;">
178
- <a-input value="级联选择框" style="width: 20%" readOnly/>
179
- <a-cascader style="width: 80%" placeholder="请选择"/>
180
- </a-input-group>
181
- <br/>
182
- <a-input-group compact style="width: 400px;">
183
- <a-input value="文本域" style="width: 20%" readOnly/>
184
- <a-textarea style="width: 80%" placeholder="请输入" :rows="1"/>
185
- </a-input-group>
186
- <br/>
187
- <a-input-group compact style="width: 400px;">
188
- <a-input value="文件上传" style="width: 20%" readOnly/>
189
- <a-upload-dragger
190
- name="file"
191
- :multiple="true"
192
- style="margin-left: 5px; width: 75%"
193
- action="https://www.mocky.io/v2/5cc8019d300000980a055e76">
194
- <p class="ant-upload-drag-icon">
195
- <a-icon type="inbox" />
196
- </p>
197
- <p class="ant-upload-text">
198
- 点击或拖动文件到该区域上传
199
- </p>
200
- <p class="ant-upload-hint">
201
- 支持单个或多个文件
202
- </p>
203
- </a-upload-dragger>
204
- </a-input-group>
205
- <br/>
206
- <a-input-group compact style="width: 400px;">
207
- <a-input value="图片上传" style="width: 20%" readOnly/>
208
- <a-upload style="margin-left: 5px; width: 75%" list-type="picture-card" :file-list="[]">
209
- <a-icon type="plus" />
210
- <div class="ant-upload-text">
211
- Upload
212
- </div>
213
- </a-upload>
214
- </a-input-group>
215
- </template>
216
- <a-icon type="info-circle" style="color: rgba(0,0,0,.45)" />
217
- </a-popover>
218
- </a-select>
219
- </a-form-model-item>
220
- </a-col>
221
- <a-col :span="8">
222
- <a-form-model-item
223
- label="表单水印"
224
- prop="placeholder"
225
- v-if="item.formType !== 'checkbox' && item.formType !== 'radio' && item.formType !== 'file' && item.formType !== 'image'">
226
- <a-input v-model="item.placeholder" placeholder="表单水印(placeholder),可选" />
227
- </a-form-model-item>
228
- </a-col>
229
- <a-col :span="8">
230
- <a-form-model-item label="表单查询方式" prop="queryType" v-if="dataMode.queryForm && dataMode.sqlQueryCondition">
231
- <a-select v-model="item.queryType" placeholder="表单查询方式,可选">
232
- <template v-for="queryTypeItem in queryTypeV">
233
- <a-select-option :key="queryTypeItem.key">{{ queryTypeItem.label }}</a-select-option>
234
- </template>
235
- </a-select>
236
- </a-form-model-item>
237
- </a-col>
238
- </a-row>
239
- <a-row :gutter="16" v-if="item.formType === 'file' || item.formType === 'image'">
240
- <a-col :span="8">
241
- <a-form-model-item
242
- label="允许上传文件数量"
243
- prop="accept"
244
- v-if="item.formType === 'file' || item.formType === 'image'">
245
- <a-slider
246
- v-model="item.acceptCount"
247
- :min="1"
248
- :max="20"
249
- :marks="{ 1: '1', 3: '3', 5: '5', 10: '10', 15: '15', 20: '20'}"
250
- :default-value="3"
251
- />
252
- </a-form-model-item>
253
- </a-col>
254
- <a-col :span="8">
255
- <a-form-model-item
256
- label="文件上传模式"
257
- prop="resUploadMode"
258
- v-if="item.formType === 'file' || item.formType === 'image'">
259
- <a-select v-model="item.resUploadMode" placeholder="文件上传模式,默认为服务器" @change="changeFormType(item)">
260
- <a-select-option key="server">服务器</a-select-option>
261
- <a-select-option key="oss">腾讯云对象存储</a-select-option>
262
- <a-select-option key="base64" :disabled="item.formType === 'file'">Base64</a-select-option>
263
- <a-popover slot="suffixIcon" title="关于资源上传模式" placement="right">
264
- <template slot="content">
265
- <p>指定文件上传到服务器,对象存储还是以base64方式存储</p>
266
- <br/>
267
- <p><span style="font-weight: bold">服务器:</span>文件上传到服务器,数据库需存储文件于服务器的路径</p>
268
- <p><span style="font-weight: bold">对象存储:</span>文件上传到云对象存储,数据库需存储文件于对象存储的路径</p>
269
- <p><span style="font-weight: bold">base64:</span>文件以base64字符串方式存入数据库中(仅图片上传表单支持)</p>
270
- </template>
271
- <a-icon type="info-circle" style="color: rgba(0,0,0,.45)" />
272
- </a-popover>
273
- </a-select>
274
- </a-form-model-item>
275
- </a-col>
276
- <a-col :span="8">
277
- <a-form-model-item
278
- label="允许上传文件类型"
279
- prop="accept"
280
- v-if="item.formType === 'file'">
281
- <a-input v-model="item.accept" placeholder="指定文件类型,默认不限制,可选">
282
- <a-popover slot="suffix" title="关于允许上传文件类型" placement="bottom">
283
- <template slot="content">
284
- <p>指定允许上传的文件类型扩展名,如:.doc,.docx等,详情请参考<a target="_blank" @click="visitAcceptFile">允许上传文件类型</a></p>
285
- </template>
286
- <a-icon type="info-circle" style="color: rgba(0,0,0,.45)" />
287
- </a-popover>
288
- </a-input>
289
- </a-form-model-item>
290
- </a-col>
291
- <!-- TODO 配置文件上传表单-所属模块 -->
292
- <!-- TODO 配置文件上传表单-上传扩展目录Key -->
293
- </a-row>
294
- <a-row :gutter="16" v-if="item.formType === 'selects'">
295
- <a-col :span="8">
296
- <a-form-model-item label="是否根节点" prop="groupIndexView">
297
- <a-radio-group defaultValue="None" v-model="item.groupIndexView" @change="groupIndexChange" default-value="false" button-style="solid">
298
- <a-radio-button :value="1">
299
-
300
- </a-radio-button>
301
- <a-radio-button value="None">
302
-
303
- </a-radio-button>
304
- </a-radio-group>
305
- </a-form-model-item>
306
- </a-col>
307
- <a-col :span="8" v-if="item.groupIndex !== 1">
308
- <a-form-model-item label="数据所属节点" prop="groupIndex">
309
- <a-select v-model="item.parent_title" placeholder="请选择父节点" ref="groupIndex" @change="parent_title_change">
310
- <a-select-option v-for="parent_item in parent_node" :key="parent_item.key">{{ parent_item.title }}</a-select-option>
311
- <a-popover slot="suffixIcon" title="关于父节点" placement="bottom">
312
- <template slot="content">
313
- <p>多个下拉框为一组时,需要首先选择的为父节点</p>
314
- </template>
315
- <a-icon type="info-circle" style="color: rgba(0,0,0,.45)" />
316
- </a-popover>
317
- </a-select>
318
- </a-form-model-item>
319
- </a-col>
320
- </a-row>
321
- <a-row :gutter="16">
322
- <a-col :span="8">
323
- <a-form-model-item label="数据源类型" prop="selectType" v-if="item.formType === 'select' || (item.formType === 'selects' && item.groupIndex == 1) || item.formType === 'cascader'">
324
- <a-select v-model="item.selectType" placeholder="请选择数据源类型" @change="changeSelectKey(item)">
325
- <a-select-option key="key">字典键</a-select-option>
326
- <a-select-option key="fixArray">固定集合</a-select-option>
327
- <a-select-option key="logic">业务逻辑</a-select-option>
328
- <a-popover
329
- slot="suffixIcon"
330
- title="关于下拉框或级联框数据源类型"
331
- placement="bottom">
332
- <template slot="content">
333
- <p>设置下拉框或级联框的数据源</p>
334
- <p>数据源类型分为三种,你可以根据需要选择</p>
335
- <p>字典键:选项从字典表(t_dictionary)获取,你只需要选择字典键的名称即可</p>
336
- <p>业务逻辑名称:选项通过发起http请求调用指定的业务逻辑(Logic)接口获取</p>
337
- <p>固定集合:选项为静态值,JSONArray格式</p>
338
- <p>当表单类型为 " 级联选择框(多个下拉) " 是数据模式为 [{lable,value,children[{lable,value,children[]},{lable,value,children[]}]}] 形式</p>
339
- <p>如:</p>
340
- <json-viewer :value="DemoJson" :expand-depth="parseInt('100')" style="overflow: auto;max-height: 440px"></json-viewer>
341
- </template>
342
- <a-icon type="info-circle" style="color: rgba(0,0,0,.45)" />
343
- </a-popover>
344
- </a-select>
345
- </a-form-model-item>
346
- </a-col>
347
- <a-col :span="8">
348
- <a-form-model-item label="数据源" prop="selectKey" v-if="(item.formType === 'select' || (item.formType === 'selects' && item.groupIndex == 1) || item.formType === 'cascader') && item.selectType">
349
- <a-select
350
- show-search
351
- v-model="item.selectKey"
352
- v-if="item.selectType === 'key'"
353
- placeholder="请选择字典键"
354
- :filter-option="filterOption"
355
- @change="changeSelectKey(item)"
356
- >
357
- <template>
358
- <a-select-option
359
- v-for="(optionItem,index) in option"
360
- :key="index"
361
- :value="Object.keys(optionItem)[0]">{{ optionItem[Object.keys(optionItem)[0]] }}
362
- </a-select-option>
363
- </template>
364
- </a-select>
365
- <a-input v-model="item.selectKey" v-if="item.selectType === 'logic'" placeholder="请输入业务逻辑名称"/>
366
- <a-textarea v-model="item.selectKey" v-if="item.selectType === 'fixArray'" placeholder="请录入数据源" />
367
- </a-form-model-item>
368
- </a-col>
369
- <a-col :span="8">
370
- <a-form-model-item label="数据外键字段名" prop="selectKeyName" v-if="item.formType === 'select'">
371
- <a-input v-model="item.selectKeyName" placeholder="该列所在表在主表的外键名,可选">
372
- <a-popover slot="suffix" title="关于数据外键字段名" placement="bottom">
373
- <template slot="content">
374
- <p>当该列所属表为主表的关联表,且存在主外键关联关系,你可以指定<span style="font-weight: bold">该列所在表在主表的外键名</span>,如:i.f_type_id</p>
375
- <p>如果你的<a @click="$refs['key'].focus()">数据字段名</a>所属表为主表,或字段名已经是主表外键名时,不用设置该值</p>
376
- <p>设置该参数是为了表单查询时可以通过外键id列而非具体值筛选数据</p>
377
- <p>示例:</p>
378
- <p>主表为t_userfiles表,别名为u,与t_gasbrand(气表品牌表)有关联关系,别名为g,数据字段名设置为g.f_gasbrand</p>
379
- <p>如果指定了数据外键字段名,例如u.f_gasbrand_id,则使用数据外键字段名筛选数据,如果不指定该值,则使用<a @click="$refs['key'].focus()">数据字段名</a>筛选</p>
380
- </template>
381
- <a-icon type="info-circle" style="color: rgba(0,0,0,.45)" />
382
- </a-popover>
383
- </a-input>
384
- </a-form-model-item>
385
- </a-col>
386
- </a-row>
387
- <a-form-model-item label="数据源加载方式" prop="selectLoadType" v-if="item.formType === 'select' && item.selectType === 'logic'">
388
- <a-row :guttor="16">
389
- <a-col :span="8">
390
- <a-radio-group v-model="item.lazyLoad" default-value="false" button-style="solid">
391
- <a-radio-button value="true">
392
- 懒加载搜索
393
- </a-radio-button>
394
- <a-radio-button value="false">
395
- 一次性加载
396
- </a-radio-button>
397
- </a-radio-group>
398
- </a-col>
399
- </a-row>
400
- </a-form-model-item>
401
- <a-form-model-item label="表单校验类型" prop="rule">
402
- <a-row :gutter="16">
403
- <a-col :span="8" v-if="item.formType === 'input' || item.formType === 'textarea'">
404
- <a-select v-model="item.rule.type" placeholder="校验类型,可选">
405
- <a-select-option key="string">字符串</a-select-option>
406
- <a-select-option key="number">数字</a-select-option>
407
- <a-select-option key="boolean">布尔值</a-select-option>
408
- <a-select-option key="regexp">正则表达式</a-select-option>
409
- <a-select-option key="integer">整数</a-select-option>
410
- <a-select-option key="float">小数</a-select-option>
411
- <a-select-option key="array">数组或集合</a-select-option>
412
- <a-select-option key="date">日期</a-select-option>
413
- <a-select-option key="email">邮箱</a-select-option>
414
- <a-popover slot="suffixIcon" title="关于表单校验类型" placement="bottom">
415
- <template slot="content">
416
- <p>设置表单项的校验类型,默认字符串类型</p>
417
- <p>你也可以设置该表单项是否必填</p>
418
- </template>
419
- <a-icon type="info-circle" style="color: rgba(0,0,0,.45)" />
420
- </a-popover>
421
- </a-select>
422
- </a-col>
423
- <a-col :span="8">
424
- <a-radio-group v-model="item.rule.required" default-value="false" button-style="solid">
425
- <a-radio-button value="true">
426
- 必选项
427
- </a-radio-button>
428
- <a-radio-button value="false">
429
- 非必选项
430
- </a-radio-button>
431
- </a-radio-group>
432
- </a-col>
433
- </a-row>
434
- </a-form-model-item>
435
- <a-row :gutter="16" v-if="dataMode.addOrEditForm && dataMode.sqlQueryItem">
436
- <a-col :span="8">
437
- <a-form-model-item ref="addOrEdit" label="新增/修改场景选择" prop="addOrEdit">
438
- <a-select v-model="item.addOrEdit" placeholder="请选择场景">
439
- <a-select-option key="all">新增和修改</a-select-option>
440
- <a-select-option key="add">仅支持新增</a-select-option>
441
- <a-select-option key="edit">仅支持修改</a-select-option>
442
- <a-select-option key="silenceAdd">静默新增(不生成表单)</a-select-option>
443
- <a-select-option key="version">版本号</a-select-option>
444
- <a-popover
445
- slot="suffixIcon"
446
- title="关于新增/修改场景选择"
447
- placement="bottom">
448
- <template slot="content">
449
- <p>设置表单项的新增/修改场景</p>
450
- <p>静默新增类型用于非人为新增的数据,不会生成表单项,且必须设置字段用途</p>
451
- </template>
452
- <a-icon type="info-circle" style="color: rgba(0,0,0,.45)" />
453
- </a-popover>
454
- </a-select>
455
- </a-form-model-item>
456
- </a-col>
457
- <a-col :span="8">
458
- <a-form-model-item v-if="item.addOrEdit === 'silenceAdd'" ref="silencePurpose" label="字段用途" prop="silencePurpose">
459
- <a-select v-model="item.silencePurpose" placeholder="请选择字段用途">
460
- <a-select-option key="createTime">创建时间</a-select-option>
461
- <a-select-option key="operator">创建/操作人</a-select-option>
462
- <a-select-option key="orgId">组织机构ID</a-select-option>
463
- <a-select-option key="customize">自定义</a-select-option>
464
- <a-popover
465
- slot="suffixIcon"
466
- title="关于字段用途"
467
- placement="bottom">
468
- <template slot="content">
469
- <p>用于静默新增时设置字段用途</p>
470
- <p>在新增数据的表单提交时,页面会根据设置的字段用途获取相关数据并追加到表单中</p>
471
- <p>当字段用途选择为<span style="font-weight: bold">自定义</span>时,必须指定一个业务逻辑(Logic)名称,表单提交前会将表单内容作为参数调用该Logic接口,并将Logic返回值作为表单值</p>
472
- </template>
473
- <a-icon type="info-circle" style="color: rgba(0,0,0,.45)" />
474
- </a-popover>
475
- </a-select>
476
- </a-form-model-item>
477
- </a-col>
478
- <a-col :span="8">
479
- <a-form-model-item v-if="item.silencePurpose === 'customize'" label="业务逻辑" prop="silenceSource">
480
- <a-input v-model="item.silenceSource" placeholder="请输入业务逻辑名称"/>
481
- </a-form-model-item>
482
- </a-col>
483
- </a-row>
484
- </template>
485
- <template v-if="dataMode.table">
486
- <a-row :gutter="16">
487
- <a-col :span="8">
488
- <a-form-model-item label="作用域插槽" prop="slot">
489
- <a-select v-model="item.slot.type" placeholder="插槽类型,可选">
490
- <a-select-option key="default">不设置</a-select-option>
491
- <a-select-option key="ellipsis">文本溢出省略</a-select-option>
492
- <a-select-option key="badge">多彩徽标</a-select-option>
493
- <a-select-option key="date">日期格式化</a-select-option>
494
- <a-select-option key="dateTime">日期时间格式化</a-select-option>
495
- <a-select-option key="action">操作列</a-select-option>
496
- <a-popover slot="suffixIcon" title="关于作用域插槽" placement="bottom">
497
- <template slot="content">
498
- <p>你可以通过设置表格列的作用域插槽实现一些效果</p>
499
- <p>如果没有指定,默认会设置为文本溢出省略(长度:16)</p>
500
- <p>如果你选择文本溢出省略,需要设置文本溢出上限长度</p>
501
- <p>如果你选择多彩徽标,需要设置徽标对应的数据样式字典键</p>
502
- </template>
503
- <a-icon type="info-circle" style="color: rgba(0,0,0,.45)" />
504
- </a-popover>
505
- </a-select>
506
- </a-form-model-item>
507
- </a-col>
508
- <a-col :span="8">
509
- <a-form-model-item label="表格列宽度" prop="width">
510
- <a-popover
511
- title="关于表格列宽度"
512
- placement="bottom">
513
- <template slot="content">
514
- <p>当作用域插槽设置为文本溢出省略时,表格列宽度将自适应,计算方式为文本溢出上限长度 * 7 + 42</p>
515
- <p>当作用域插槽设置为多彩徽标时,表格列宽度为固定为130</p>
516
- <p>当作用域插槽设置为日期时间格式化时,表格列宽度为固定为160</p>
517
- <p>当该列数据过长导致换行时,建议设置作用域插槽为文本溢出省略,或将表格列设置为固定宽度值</p>
518
- </template>
519
- <a-input-number style="width: 100%" v-model="item.width" placeholder="表格列宽度,可选"/>
520
- </a-popover>
521
- </a-form-model-item>
522
- </a-col>
523
- <a-col :span="8">
524
- <a-form-model-item label="字段默认值" prop="default" v-if="dataMode.sqlQueryItem">
525
- <a-input v-model="item.default" placeholder="当查询结果为null时,指定默认值,可选" />
526
- </a-form-model-item>
527
- </a-col>
528
- </a-row>
529
- <a-row :gutter="16">
530
- <a-col :span="8">
531
- <a-form-model-item label="文本溢出上限长度" prop="slotValue" v-if="item.slot.type === 'ellipsis'">
532
- <a-input-number style="width: 100%" v-model="item.slotValue" placeholder="请输入文本溢出上限长度"/>
533
- </a-form-model-item>
534
- <a-form-model-item label="徽标字典键" prop="slotKeyMap" v-if="item.slot.type === 'badge'">
535
- <a-input v-model="item.slotKeyMap" placeholder="请输入徽标字典键">
536
- <a-popover
537
- title="关于徽标字典键"
538
- placement="bottom"
539
- slot="suffix">
540
- <template slot="content">
541
- <p>如果你设置了表单类型为选择框,且数据源是字典键,该值会自动带出</p>
542
- </template>
543
- <a-icon type="info-circle" style="color: rgba(0,0,0,.45)" />
544
- </a-popover>
545
- </a-input>
546
- </a-form-model-item>
547
- <a-form-model-item label="操作列文本" prop="actionText" v-if="item.slot.type === 'action'">
548
- <a-input v-model="item.actionText" placeholder="请输入操作列显示文本,默认为详情"/>
549
- </a-form-model-item>
550
- </a-col>
551
- </a-row>
552
- </template>
553
- <a-alert style="margin-top: 5px" v-if="dataModeArrayData.length === 0" show-icon message="错误:请至少选择一种数据模式" type="error" />
554
- <a-alert style="margin-top: 5px" v-if="dataMode.addOrEditForm && !dataMode.sqlQueryItem" show-icon message="错误:如果要生成新增/修改表单项,必须勾选生成SQL查询项" type="error" />
555
- <a-alert style="margin-top: 5px" v-if="(item.formType === 'file' || item.formType === 'image') && !(!dataMode.table && !dataMode.sqlQueryCondition && !dataMode.queryForm)" show-icon message="错误:上传类表单的数据模式只能选择 生成新增/修改表单项 和 生成SQL查询项 " type="error" />
556
- <a-alert style="margin-top: 5px" v-if="dataMode.queryForm && !dataMode.sqlQueryCondition" show-icon message="提示:您没有勾选生成SQL查询表达式,渲染的表单项不会生成SQL查询条件" type="info" />
557
- <a-alert style="margin-top: 5px" v-if="dataMode.table && !dataMode.sqlQueryItem" show-icon message="提示:您没有勾选生成SQL查询项,渲染的表格列不会绑定SQL结果集数据" type="info" />
558
- </a-form-model>
559
- </a-modal>
560
- <a-button type="primary" @click="view">操作</a-button>
561
- </a-col>
562
- <a-col :xl="10" :lg="12" :md="12" :sm="24" :xs="24">
563
- <a-card :bordered="false" title="预览" size="small" style="overflow: auto">
564
- <json-viewer :copyable="{copyText: '复制', copiedText: '已复制'}" :value="result" :expand-depth="parseInt('100')" style="overflow: auto;max-height: 440px"></json-viewer>
565
- </a-card>
566
- </a-col>
567
- </a-row>
568
- <a-modal
569
- title="效果预览"
570
- :width="isMobile ? screenWidth : screenWidth * 0.8"
571
- :centered="true"
572
- :visible="modelVisible"
573
- :zIndex="1001"
574
- @cancel="onModelClose"
575
- :destroyOnClose="true">
576
- <template slot="footer">
577
- <a-button key="close" @click="onModelClose">
578
- 返回
579
- </a-button>
580
- <a-button key="submit" type="primary" @click="submit">
581
- 保存
582
- </a-button>
583
- </template>
584
- <x-form-table
585
- :view-mode="true"
586
- :queryParamsJson="result">
587
- </x-form-table>
588
- </a-modal>
589
- </a-drawer>
590
- </template>
591
-
592
- <script>
593
- import XFormItem from '@vue2-client/base-client/components/common/XForm/XFormItem'
594
- import XFormTable from '@vue2-client/base-client/components/common/XFormTable/XFormTable'
595
- import JsonViewer from 'vue-json-viewer'
596
- import FileSaver from 'file-saver'
597
- import { queryType } from '@vue2-client/config/CreateQueryConfig'
598
- import { mapState } from 'vuex'
599
- import { commonApi, post } from '@vue2-client/services/api'
600
- const DemoJson = [{ value: 'zhejiang', label: 'Zhejiang', children: [{ value: 'hangzhou', label: 'Hangzhou', children: [{ value: 'xihu', label: 'West Lake' }] }] }]
601
- export default {
602
- name: 'CreateQuery',
603
- components: {
604
- JsonViewer,
605
- XFormTable,
606
- XFormItem
607
- },
608
- data () {
609
- return {
610
- DemoJson,
611
- // 页面宽度
612
- screenWidth: document.documentElement.clientWidth,
613
- // 效果预览模态框是否展示
614
- modelVisible: false,
615
- // 数据列配置模态框是否展示
616
- dataColumnVisible: false,
617
- // 数据列操作类型:新增,修改
618
- type: '新增',
619
- // 数据模式类型集合
620
- dataModeArray: [
621
- { label: '生成查询表单项', value: 'queryForm' },
622
- { label: '生成表格列', value: 'table' },
623
- { label: '生成新增/修改表单项', value: 'addOrEditForm' },
624
- { label: '生成SQL查询项', value: 'sqlQueryItem' },
625
- { label: '生成SQL查询表达式', value: 'sqlQueryCondition' }
626
- ],
627
- // 操作按钮状态集合
628
- buttonStateArray: [
629
- { label: '新增', value: 'add' },
630
- { label: '修改', value: 'edit' },
631
- { label: '删除', value: 'delete' },
632
- { label: '导出', value: 'export' }
633
- ],
634
- // 数据模式类型集合值
635
- dataModeArrayData: ['queryForm', 'table', 'addOrEditForm', 'sqlQueryItem', 'sqlQueryCondition'],
636
- // 操作按钮状态集合值
637
- buttonStateData: ['add', 'edit', 'delete', 'export'],
638
- labelCol: { span: 4 },
639
- wrapperCol: { span: 14 },
640
- form: {
641
- tableName: '',
642
- joinArray: {},
643
- condition: {},
644
- orderBy: '',
645
- column: []
646
- },
647
- result: {},
648
- item: {
649
- key: '',
650
- title: '',
651
- slot: {},
652
- rule: {
653
- required: 'false'
654
- },
655
- dataModeArray: []
656
- },
657
- itemMap: {},
658
- selectIndex: null,
659
- selectType: undefined,
660
- joinArray: [],
661
- rules: {
662
- tableName: [{ required: true, message: '请输入查询表名', trigger: 'blur' }],
663
- orderBy: [{ required: true, message: '请输入排序方式', trigger: 'blur' }]
664
- },
665
- itemRules: {
666
- key: [{ required: true, message: '请输入数据列名', trigger: 'blur' }],
667
- title: [{ required: true, message: '请输入中文名称', trigger: 'blur' }],
668
- selectType: [{ required: true, message: '请选择数据源类型', trigger: 'change' }],
669
- selectKey: [{ required: true, message: '请输入数据源内容', trigger: 'blur' }],
670
- slotValue: [{ required: true, message: '请输入文本溢出上限长度', trigger: 'blur' }],
671
- slotKeyMap: [{ required: true, message: '请输入徽标字典键', trigger: 'blur' }],
672
- silencePurpose: [{ required: true, message: '请选择字段用途', trigger: 'change' }],
673
- silenceSource: [{ required: true, message: '请输入业务逻辑名称', trigger: 'blur' }],
674
- group: [{ required: true, message: '请选择父节点', trigger: 'blur' }],
675
- groupIndex: [{ required: true, message: '如果不是根节点请选择自己的父节点', trigger: 'blur' }]
676
-
677
- },
678
- // 字典键集合
679
- option: []
680
- }
681
- },
682
- mounted () {
683
- this.initView()
684
- },
685
- computed: {
686
- ...mapState('setting', ['isMobile']),
687
- parent_node () {
688
- return this.form.column.filter(item => item.formType === 'selects' && item.key != this.item.key)
689
- },
690
- queryTypeV () {
691
- if (this.item.formType) {
692
- return queryType.filter(item => item.match.includes(this.item.formType))
693
- }
694
- return queryType
695
- },
696
- conditionJoinArray: function () {
697
- const result = []
698
- for (const item in this.form.joinArray) {
699
- if (item !== '') {
700
- result.push({
701
- label: item,
702
- value: item
703
- })
704
- }
705
- }
706
- if (result.length === 0) {
707
- result.push({
708
- label: '-',
709
- value: '-'
710
- })
711
- }
712
- return result
713
- },
714
- dataMode: function () {
715
- const result = {
716
- queryForm: false,
717
- table: false,
718
- addOrEditForm: false,
719
- sqlQueryItem: false,
720
- sqlQueryCondition: false
721
- }
722
- for (const item of this.dataModeArrayData) {
723
- result[item] = true
724
- }
725
- return result
726
- },
727
- buttonState: function () {
728
- const result = {
729
- add: false,
730
- edit: false,
731
- delete: false,
732
- export: false
733
- }
734
- for (const item of this.buttonStateData) {
735
- result[item] = true
736
- }
737
- return result
738
- }
739
- },
740
- props: {
741
- visible: {
742
- type: Boolean,
743
- default: false
744
- },
745
- toEditJson: {
746
- type: Object,
747
- default: () => {}
748
- }
749
- },
750
- watch: {
751
- visible (rel) {
752
- if (rel) {
753
- this.initView()
754
- }
755
- if (rel && this.toEditJson) {
756
- // 处理预设关联表
757
- if (this.joinArray.length === 0) {
758
- for (const key in this.toEditJson.joinArray) {
759
- this.joinArray.push({
760
- key: key,
761
- value: this.toEditJson.joinArray[key]
762
- })
763
- }
764
- }
765
- // 处理具体表单项
766
- this.form = Object.assign(
767
- {
768
- tableName: '',
769
- joinArray: {},
770
- condition: {},
771
- orderBy: '',
772
- column: []
773
- }, this.toEditJson
774
- )
775
- for (const columnItem of this.form.column) {
776
- // 数据模式兼容性处理
777
- if (!(columnItem.dataMode || columnItem.dataModeArray)) {
778
- columnItem.dataModeArray = ['queryForm', 'table', 'addOrEditForm', 'sqlQueryItem', 'sqlQueryCondition']
779
- } else if (columnItem.dataMode) {
780
- if (columnItem.dataMode === 'all') {
781
- columnItem.dataModeArray = ['queryForm', 'table', 'addOrEditForm', 'sqlQueryItem', 'sqlQueryCondition']
782
- } else if (columnItem.dataMode === 'form') {
783
- columnItem.dataModeArray = ['queryForm', 'addOrEditForm', 'sqlQueryCondition']
784
- } else if (columnItem.dataMode === 'table') {
785
- columnItem.dataModeArray = ['table', 'sqlQueryItem']
786
- } else if (columnItem.dataMode === 'table_form') {
787
- columnItem.dataModeArray = ['table', 'sqlQueryItem', 'sqlQueryCondition']
788
- } else if (columnItem.dataMode === 'only_form') {
789
- columnItem.dataModeArray = ['queryForm']
790
- } else if (columnItem.dataMode === 'only_table') {
791
- columnItem.dataModeArray = ['table']
792
- } else if (columnItem.dataMode === 'clear') {
793
- columnItem.dataModeArray = ['sqlQueryItem', 'sqlQueryCondition']
794
- } else if (columnItem.dataMode === 'only_add_modify') {
795
- columnItem.dataModeArray = ['addOrEditForm', 'sqlQueryItem']
796
- }
797
- }
798
- delete columnItem.dataMode
799
- // 插槽兼容处理
800
- if (columnItem.slot) {
801
- if (columnItem.slot.value && columnItem.slot.type === 'ellipsis') {
802
- columnItem.slotValue = columnItem.slot.value
803
- } else if (columnItem.slot.keyMap && columnItem.slot.type === 'badge') {
804
- columnItem.slotKeyMap = columnItem.slot.keyMap
805
- } else if (columnItem.slot.actionText && columnItem.slot.type === 'action') {
806
- columnItem.actionText = columnItem.slot.actionText
807
- }
808
- }
809
- // 必选项兼容处理
810
- if (columnItem.rule && columnItem.rule.required && columnItem.rule.required !== 'false') {
811
- columnItem.rule.required = columnItem.rule.required.toString()
812
- } else {
813
- if (!columnItem.rule) {
814
- columnItem.rule = {}
815
- }
816
- columnItem.rule.required = 'false'
817
- }
818
- // 数据源加载方式兼容处理
819
- if (columnItem.lazyLoad && columnItem.lazyLoad !== 'false') {
820
- columnItem.lazyLoad = columnItem.lazyLoad.toString()
821
- } else {
822
- columnItem.lazyLoad = 'false'
823
- }
824
- // 下拉框数据源兼容处理
825
- if ((columnItem.formType === 'select' || columnItem.formType === 'cascader') && columnItem.selectKey) {
826
- // 数据源为logic
827
- if (columnItem.selectKey.toString().startsWith('logic@')) {
828
- columnItem.selectType = 'logic'
829
- } else if (columnItem.selectKey instanceof Array || this.isJSON(columnItem.selectKey)) {
830
- // 数据源为固定json集合
831
- if (columnItem.selectKey instanceof Array) {
832
- columnItem.selectKey = JSON.stringify(columnItem.selectKey)
833
- }
834
- columnItem.selectType = 'fixArray'
835
- } else {
836
- columnItem.selectType = 'key'
837
- }
838
- }
839
- this.itemMap[columnItem.key] = Object.assign({
840
- key: '',
841
- title: '',
842
- slot: {},
843
- rule: {
844
- required: 'false'
845
- },
846
- dataModeArray: []
847
- }, columnItem)
848
- }
849
- // 处理操作按钮配置
850
- if (this.toEditJson.buttonState) {
851
- this.buttonStateData = []
852
- for (const buttonStateKey of Object.keys(this.toEditJson.buttonState)) {
853
- if (this.toEditJson.buttonState[buttonStateKey]) {
854
- this.buttonStateData.push(buttonStateKey)
855
- }
856
- }
857
- } else {
858
- this.buttonStateData = ['add', 'edit', 'delete', 'export']
859
- }
860
- }
861
- }
862
- },
863
- methods: {
864
- parent_title_change (parentKey) {
865
- const parentArr = this.form.column.filter(item => item.formType === 'selects' && item.key === parentKey)
866
- if (parentArr.length === 1) {
867
- this.item.groupIndex = parentArr[0].groupIndex + 1
868
- this.item.group = parentArr[0].group
869
- this.item.parent_title = parentArr[0].title
870
- } else {
871
- this.$message.error('数据字段中有字段别名相同,请检查!')
872
- }
873
- },
874
- groupIndexChange ({ target }) {
875
- if (target.value === 1) {
876
- this.item.groupIndex = 1
877
- if (this.item.title) {
878
- this.item.group = this.item.title + '组'
879
- } else {
880
- this.item.groupIndex = ''
881
- this.$message.error('请先输入字段中文名称!')
882
- }
883
- } else {
884
- this.item.groupIndex = ''
885
- }
886
- },
887
- // 初始化组件
888
- initView () {
889
- this.joinArray = []
890
- this.result = {}
891
- post(commonApi.getDictionaryParam, {}).then(res => {
892
- this.option = res
893
- })
894
- },
895
- onClose () {
896
- this.$emit('update:visible', false)
897
- },
898
- filterOption (input, option) {
899
- return (
900
- option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
901
- )
902
- },
903
- onModelClose () {
904
- this.modelVisible = false
905
- },
906
- addJoinItem () {
907
- this.joinArray.push({
908
- key: '',
909
- value: ''
910
- })
911
- this.changeJoinArray()
912
- },
913
- removeJoinItem (index) {
914
- this.joinArray.splice(index, 1)
915
- this.changeJoinArray()
916
- },
917
- addColumnItem () {
918
- this.type = '新增'
919
- this.dataColumnVisible = true
920
- },
921
- editColumnItem (key, index) {
922
- if (this.itemMap[key]) {
923
- this.type = '修改'
924
- this.item = this.itemMap[key]
925
- if (this.item.formType === 'selects') {
926
- // 因为 groupIndex 可能有很多值 单选框不行 赋给一个新的变量
927
- this.item.groupIndexView = this.item.groupIndex === 1 ? 1 : 'None'
928
- }
929
- this.dataModeArrayData = this.item.dataModeArray
930
- this.selectIndex = index
931
- this.dataColumnVisible = true
932
- } else {
933
- this.$message.warn('编辑失败')
934
- }
935
- },
936
- removeColumnItem (key, index) {
937
- const _this = this
938
- this.$confirm({
939
- title: '您确定要删除该数据项?',
940
- content: '删除的数据项无法恢复',
941
- okText: '确定',
942
- okType: 'danger',
943
- cancelText: '取消',
944
- onOk () {
945
- delete _this.itemMap[key]
946
- _this.form.column.splice(index, 1)
947
- }
948
- })
949
- },
950
- upColumnItem (key, index) {
951
- const newIndex = index - 1
952
- const itemA = this.form.column[newIndex]
953
- const itemB = this.form.column[index]
954
- this.form.column.splice(index, 1, itemA)
955
- this.form.column.splice(newIndex, 1, itemB)
956
- },
957
- downColumnItem (key, index) {
958
- const newIndex = index + 1
959
- const itemA = this.form.column[newIndex]
960
- const itemB = this.form.column[index]
961
- this.form.column.splice(index, 1, itemA)
962
- this.form.column.splice(newIndex, 1, itemB)
963
- },
964
- changeJoinArray () {
965
- const joinArrayObject = {}
966
- for (const item of this.joinArray) {
967
- joinArrayObject[item.key] = item.value
968
- }
969
- this.form.joinArray = joinArrayObject
970
- },
971
- submitItem () {
972
- this.$refs.itemForm.validate(valid => {
973
- if (valid) {
974
- if (this.dataModeArrayData.length === 0) {
975
- this.$message.error('请至少选择一种数据模式')
976
- return
977
- }
978
- if (this.dataMode.addOrEditForm && !this.dataMode.sqlQueryItem) {
979
- this.$message.error('如果要生成新增/修改表单项,必须勾选生成SQL查询项')
980
- return
981
- }
982
- if ((this.item.formType === 'file' || this.item.formType === 'image') && !(!this.dataMode.table && !this.dataMode.sqlQueryCondition && !this.dataMode.queryForm)) {
983
- this.$message.error('上传类表单的数据模式只能选择 生成新增/修改表单项 和 生成SQL查询项')
984
- return
985
- }
986
- this.itemHandle()
987
- }
988
- })
989
- },
990
- itemHandle () {
991
- const str = JSON.stringify(this.item)
992
- const item = JSON.parse(str)
993
- this.itemMap[item.key] = JSON.parse(str)
994
- this.itemMap[item.key].dataModeArray = this.dataModeArrayData
995
- // 查询表单项或者新增/修改表单项
996
- if (this.dataMode.queryForm || this.dataMode.addOrEditForm) {
997
- if (!this.dataMode.sqlQueryItem || !this.dataMode.addOrEditForm) {
998
- delete item.addOrEdit
999
- delete item.silencePurpose
1000
- delete item.silenceSource
1001
- }
1002
- // 不生成SQL查询表达式,或者表单查询类型为=
1003
- if (!this.dataMode.sqlQueryCondition || (item.queryType && item.queryType === '=')) {
1004
- delete item.queryType
1005
- }
1006
- // 表单类型为输入框
1007
- if (item.formType && item.formType === 'input') {
1008
- delete item.formType
1009
- }
1010
- // 校验类型
1011
- if (item.rule.required) {
1012
- item.rule.required = item.rule.required.toString() === 'true'
1013
- } else {
1014
- item.rule.required = false
1015
- }
1016
- // 下拉框
1017
- if ((item.formType === 'select' || (item.formType === 'selects' && item.groupIndex == '1') || item.formType === 'cascader') && item.selectKey) {
1018
- // 数据源为logic
1019
- if (item.selectType === 'logic') {
1020
- // 如果已经有了 logic@ 将不再拼接
1021
- if (item.selectKey.substring(0, 6) !== 'logic@') {
1022
- item.selectKey = 'logic@' + item.selectKey
1023
- }
1024
- if (!item.lazyLoad) {
1025
- delete item.lazyLoad
1026
- }
1027
- } else if (item.selectType === 'fixArray') {
1028
- // 数据源为固定json集合
1029
- if (!this.isJSON(item.selectKey)) {
1030
- this.$message.warning('下拉框数据源不是JSON集合')
1031
- return
1032
- }
1033
- delete item.lazyLoad
1034
- } else {
1035
- delete item.lazyLoad
1036
- }
1037
- if (item.formType !== 'selects') {
1038
- delete item.selectType
1039
- }
1040
- } else {
1041
- if (item.formType !== 'selects') {
1042
- delete item.group
1043
- delete item.groupIndex
1044
- }
1045
- delete item.selectType
1046
- delete item.selectKey
1047
- delete item.selectKeyName
1048
- delete item.lazyLoad
1049
- }
1050
- } else {
1051
- delete item.queryType
1052
- delete item.formType
1053
- delete item.addOrEdit
1054
- delete item.silencePurpose
1055
- delete item.silenceSource
1056
- delete item.placeholder
1057
- delete item.rule
1058
- delete item.selectType
1059
- delete item.selectKey
1060
- delete item.selectKeyName
1061
- delete item.lazyLoad
1062
- }
1063
- // 表格列
1064
- if (this.dataMode.table) {
1065
- if (item.slot.type && item.slot.type !== 'default') {
1066
- if (item.slotValue && item.slot.type === 'ellipsis') {
1067
- item.slot.value = item.slotValue
1068
- } else if (item.slotKeyMap && item.slot.type === 'badge') {
1069
- item.slot.keyMap = item.slotKeyMap
1070
- } else if (item.actionText && item.slot.type === 'action') {
1071
- item.slot.actionText = item.actionText
1072
- }
1073
- } else {
1074
- delete item.slot
1075
- }
1076
- if (!item.width) {
1077
- delete item.width
1078
- }
1079
- delete item.slotValue
1080
- delete item.slotKeyMap
1081
- delete item.actionText
1082
- } else {
1083
- delete item.slot
1084
- delete item.slotValue
1085
- delete item.slotKeyMap
1086
- delete item.actionText
1087
- delete item.width
1088
- }
1089
- // SQL查询项
1090
- if (!this.dataMode.sqlQueryItem) {
1091
- delete item.default
1092
- }
1093
- item.dataModeArray = this.dataModeArrayData
1094
- if (this.type === '新增') {
1095
- this.form.column.push(item)
1096
- } else {
1097
- this.form.column[this.selectIndex] = item
1098
- }
1099
- this.item = {
1100
- key: '',
1101
- title: '',
1102
- slot: {},
1103
- rule: {
1104
- required: 'false'
1105
- },
1106
- dataModeArray: []
1107
- }
1108
- this.$message.success('增加成功')
1109
- this.dataModeArrayData = ['queryForm', 'table', 'addOrEditForm', 'sqlQueryItem', 'sqlQueryCondition']
1110
- this.dataColumnVisible = false
1111
- },
1112
- // 判断是否为json字符串
1113
- isJSON (str) {
1114
- if (typeof str == 'string') {
1115
- try {
1116
- const obj = JSON.parse(str)
1117
- return !!(typeof obj == 'object' && obj)
1118
- } catch (e) {
1119
- return false
1120
- }
1121
- }
1122
- },
1123
- exportJson () {
1124
- const data = JSON.stringify(this.form, null, 2)
1125
- const blob = new Blob([data], { type: 'application/json' })
1126
- FileSaver.saveAs(blob, `Query.json`)
1127
- this.$message.success('导出成功!')
1128
- },
1129
- viewHandle (then) {
1130
- if (this.form.column.length === 0) {
1131
- this.$message.error('你没有增加任何数据字段')
1132
- return
1133
- }
1134
- this.result = JSON.parse(JSON.stringify(this.form))
1135
- if (this.result.condition && (!this.result.condition.value || this.result.condition.value === '')) {
1136
- delete this.result.condition
1137
- }
1138
- for (const item of this.result.column) {
1139
- if (item.selectType === 'fixArray') {
1140
- item.selectKey = JSON.parse(item.selectKey)
1141
- }
1142
- if (item.dataModeArray.length === 5) {
1143
- delete item.dataModeArray
1144
- }
1145
- }
1146
- if (this.buttonStateData.length !== 4) {
1147
- this.result.buttonState = this.buttonState
1148
- }
1149
- then()
1150
- },
1151
- view () {
1152
- this.$refs.businessCreateForm.validate(valid => {
1153
- if (valid) {
1154
- this.viewHandle(() => {
1155
- this.modelVisible = true
1156
- })
1157
- }
1158
- })
1159
- },
1160
- submit () {
1161
- this.onModelClose()
1162
- this.$refs.businessCreateForm.validate(valid => {
1163
- if (valid) {
1164
- this.viewHandle(() => {
1165
- // saveQueryParams
1166
- this.$emit('saveQueryParams', this.result)
1167
- })
1168
- }
1169
- })
1170
- },
1171
- modelCancel () {
1172
- this.dataColumnVisible = false
1173
- // 延迟是为了避免编辑数据窗口关闭时重置表单导致的闪烁
1174
- setTimeout(() => {
1175
- this.item = {
1176
- key: '',
1177
- title: '',
1178
- slot: {},
1179
- rule: {
1180
- required: 'false'
1181
- },
1182
- dataModeArray: []
1183
- }
1184
- this.dataModeArrayData = ['queryForm', 'table', 'addOrEditForm', 'sqlQueryItem', 'sqlQueryCondition']
1185
- }, 100)
1186
- },
1187
- changeFormType (item) {
1188
- if (item.formType === 'file' || item.formType === 'image') {
1189
- this.dataModeArrayData = ['addOrEditForm', 'sqlQueryItem']
1190
- }
1191
- },
1192
- changeSelectKey (item) {
1193
- if (item.selectType === 'key' && item.selectKey) {
1194
- item.slot.type = 'badge'
1195
- item.slotKeyMap = item.selectKey
1196
- }
1197
- },
1198
- visitAcceptFile () {
1199
- window.open('https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/input/file#attr-accept')
1200
- }
1201
- }
1202
- }
1203
- </script>
1204
- <style lang="less" scoped>
1205
- </style>
1
+ <template>
2
+ <a-drawer
3
+ title="查询配置生成"
4
+ placement="right"
5
+ :width="isMobile ? screenWidth : screenWidth * 0.85"
6
+ :visible="visible"
7
+ @close="onClose"
8
+ >
9
+ <a-row :gutter="24">
10
+ <a-col :xl="14" :lg="12" :md="12" :sm="24" :xs="24">
11
+ <a-form-model
12
+ ref="businessCreateForm"
13
+ :rules="rules"
14
+ :model="form"
15
+ :label-col="labelCol"
16
+ :wrapper-col="wrapperCol"
17
+ >
18
+ <a-form-model-item label="查询主表名" prop="tableName">
19
+ <a-input v-model="form.tableName" placeholder="查询用的主表+别名,用空格隔开,如:t_userfiles u"/>
20
+ </a-form-model-item>
21
+ <a-form-model-item label="预设关联表" prop="joinArray">
22
+ <a-popover title="说明" placement="right">
23
+ <template slot="content">
24
+ <p>配置你的查询中可能涉及到的所有关联表</p>
25
+ <p>比如你的查询中涉及到了t_userinfo表,就需要加入t_userinfo表的关联,和你写SQL的关联一样</p>
26
+ <p>请注意,你关联的<span style="color: #ff0000">除主表外的任何表</span>都需要配置</p>
27
+ <a-input-group compact style="width: 400px;">
28
+ <a-input style="width: 20%" placeholder="表别名" readOnly/>
29
+ <a-input style="width: 80%" placeholder="关联条件" readOnly/>
30
+ </a-input-group>
31
+ <a-input-group compact style="width: 400px;">
32
+ <a-input value="ui" style="width: 20%" placeholder="表别名" readOnly/>
33
+ <a-input
34
+ value="t_userinfo ui on i.f_userinfo_id = ui.f_userinfo_id"
35
+ style="width: 80%"
36
+ placeholder="关联条件"
37
+ readOnly/>
38
+ </a-input-group>
39
+ </template>
40
+ <a-button type="primary" @click="addJoinItem()">增加</a-button>
41
+ </a-popover>
42
+ <div v-for="(itemObj, index) in joinArray" :key="index">
43
+ <a-input-group compact>
44
+ <a-input
45
+ @change="changeJoinArray()"
46
+ v-model="itemObj.key"
47
+ style="width: 20%;position: relative;bottom: 1px;"
48
+ placeholder="表别名"/>
49
+ <a-input @change="changeJoinArray()" v-model="itemObj.value" style="width: 80%" placeholder="关联条件">
50
+ <a-icon slot="addonAfter" type="close" @click="removeJoinItem(index)"/>
51
+ </a-input>
52
+ </a-input-group>
53
+ </div>
54
+ </a-form-model-item>
55
+ <a-form-model-item label="SQL查询表达式" prop="condition">
56
+ <a-input v-model="form.condition.value" placeholder="用作SQL查询的固定条件表达式,如:gb.f_meter_type='物联网表',可选"/>
57
+ <template v-if="form.condition.value && Object.keys(form.joinArray).length > 0">
58
+ <a-alert message="提示:如果SQL查询表达式中用到了关联表,需要勾选用到的关联表别名" type="success"/>
59
+ <a-checkbox-group v-model="form.condition.join" :options="conditionJoinArray"/>
60
+ </template>
61
+ </a-form-model-item>
62
+ <a-form-model-item label="排序方式" prop="orderBy">
63
+ <a-input v-model="form.orderBy" placeholder="排序字段,用别名+字段名+排序方式(可选)表示,如:u.id desc"/>
64
+ </a-form-model-item>
65
+ <a-form-model-item label="数据字段" prop="column">
66
+ <a-button type="primary" @click="addColumnItem()">增加</a-button>
67
+ <div v-for="(columnItem, index) in form.column" :key="index">
68
+ <a-row :gutter="16">
69
+ <a-col :span="16">
70
+ <span style="font-weight: bold">{{ columnItem.title }}({{ columnItem.key }})</span>
71
+ </a-col>
72
+ <a-col v-if="index > 0 && form.column.length > 1" :span="2">
73
+ <a-icon type="up-square" @click="upColumnItem(columnItem.key,index)"/>
74
+ </a-col>
75
+ <a-col v-if="(index !== form.column.length - 1) && form.column.length > 1" :span="2">
76
+ <a-icon type="down-square" @click="downColumnItem(columnItem.key,index)"/>
77
+ </a-col>
78
+ <a-col :span="2">
79
+ <a-icon type="edit" @click="editColumnItem(columnItem.key,index)"/>
80
+ </a-col>
81
+ <a-col :span="2">
82
+ <a-icon type="close" @click="removeColumnItem(columnItem.key,index)"/>
83
+ </a-col>
84
+ </a-row>
85
+ </div>
86
+ </a-form-model-item>
87
+ <a-form-model-item label="操作按钮配置" prop="buttonState">
88
+ <a-checkbox-group v-model="buttonStateData" :options="buttonStateArray"/>
89
+ </a-form-model-item>
90
+ </a-form-model>
91
+ <a-modal
92
+ title="数据字段配置"
93
+ :visible="dataColumnVisible"
94
+ :width="1000"
95
+ :zIndex="1001"
96
+ @cancel="modelCancel"
97
+ @ok="submitItem">
98
+ <a-form-model
99
+ ref="itemForm"
100
+ :rules="itemRules"
101
+ :model="item">
102
+ <a-row :gutter="16">
103
+ <a-col :span="8">
104
+ <a-form-model-item label="表单类型" prop="formType">
105
+ <a-select v-model="item.formType" placeholder="表单类型,可选" @change="changeFormType(item)">
106
+ <a-select-option key="input">输入框</a-select-option>
107
+ <a-select-option key="select">选择框</a-select-option>
108
+ <a-select-option key="checkbox">多选框</a-select-option>
109
+ <a-select-option key="radio">单选框</a-select-option>
110
+ <a-select-option key="rangePicker">日期范围选择框</a-select-option>
111
+ <a-select-option key="monthPicker">月份选择框</a-select-option>
112
+ <a-select-option key="datePicker">单日选择框</a-select-option>
113
+ <!-- <a-select-option key="cascader">级联选择框(单个下拉)</a-select-option>-->
114
+ <a-select-option key="selects">级联选择框</a-select-option>
115
+ <a-select-option key="textarea">文本域</a-select-option>
116
+ <a-select-option key="file">文件上传</a-select-option>
117
+ <a-select-option key="image">图片上传</a-select-option>
118
+ <a-popover slot="suffixIcon" title="关于表单类型" placement="right">
119
+ <template slot="content">
120
+ <p>预览设置的表单类型</p>
121
+ <a-input-group compact style="width: 400px;">
122
+ <a-input value="输入框" style="width: 20%" readOnly/>
123
+ <a-input style="width: 80%" placeholder="请输入"/>
124
+ </a-input-group>
125
+ <br/>
126
+ <a-input-group compact style="width: 400px;">
127
+ <a-input value="选择框" style="width: 20%" readOnly/>
128
+ <a-select style="width: 80%" placeholder="请选择"/>
129
+ </a-input-group>
130
+ <br/>
131
+ <a-input-group compact style="width: 400px;">
132
+ <a-input value="多选框" style="width: 20%" readOnly/>
133
+ <a-checkbox-group
134
+ style="margin-left: 10px;margin-top: 5px; width: 70%"
135
+ :options="['数据1','数据2']"/>
136
+ </a-input-group>
137
+ <br/>
138
+ <a-input-group compact style="width: 400px;">
139
+ <a-input value="单选框" style="width: 20%" readOnly/>
140
+ <a-radio-group
141
+ style="margin-left: 10px;margin-top: 5px; width: 70%"
142
+ :options="[{label: '数据1', value: 'a'},{label: '数据2', value: 'b'}]"
143
+ name="radioGroup"/>
144
+ </a-input-group>
145
+ <br/>
146
+ <a-input-group compact style="width: 400px;">
147
+ <a-input value="日期范围选择框" style="width: 20%" readOnly/>
148
+ <a-range-picker
149
+ style="width: 80%"
150
+ :show-time="true"
151
+ format="YYYY-MM-DD HH:mm:ss"
152
+ valueFormat="YYYY-MM-DD HH:mm:ss"/>
153
+ </a-input-group>
154
+ <br/>
155
+ <a-input-group compact style="width: 400px;">
156
+ <a-input value="月份选择框" style="width: 20%" readOnly/>
157
+ <a-month-picker style="width: 80%"/>
158
+ </a-input-group>
159
+ <br/>
160
+ <a-input-group compact style="width: 400px;">
161
+ <a-input value="单日选择框" style="width: 20%" readOnly/>
162
+ <a-date-picker style="width: 80%"/>
163
+ </a-input-group>
164
+ <br/>
165
+ <a-input-group compact style="width: 400px;">
166
+ <a-input value="级联选择框" style="width: 20%" readOnly/>
167
+ <a-cascader style="width: 80%" placeholder="请选择"/>
168
+ </a-input-group>
169
+ <br/>
170
+ <a-input-group compact style="width: 400px;">
171
+ <a-input value="文本域" style="width: 20%" readOnly/>
172
+ <a-textarea style="width: 80%" placeholder="请输入" :rows="1"/>
173
+ </a-input-group>
174
+ <br/>
175
+ <a-input-group compact style="width: 400px;">
176
+ <a-input value="文件上传" style="width: 20%" readOnly/>
177
+ <a-upload-dragger
178
+ name="file"
179
+ :multiple="true"
180
+ style="margin-left: 5px; width: 75%"
181
+ action="https://www.mocky.io/v2/5cc8019d300000980a055e76">
182
+ <p class="ant-upload-drag-icon">
183
+ <a-icon type="inbox"/>
184
+ </p>
185
+ <p class="ant-upload-text">
186
+ 点击或拖动文件到该区域上传
187
+ </p>
188
+ <p class="ant-upload-hint">
189
+ 支持单个或多个文件
190
+ </p>
191
+ </a-upload-dragger>
192
+ </a-input-group>
193
+ <br/>
194
+ <a-input-group compact style="width: 400px;">
195
+ <a-input value="图片上传" style="width: 20%" readOnly/>
196
+ <a-upload style="margin-left: 5px; width: 75%" list-type="picture-card" :file-list="[]">
197
+ <a-icon type="plus"/>
198
+ <div class="ant-upload-text">
199
+ Upload
200
+ </div>
201
+ </a-upload>
202
+ </a-input-group>
203
+ </template>
204
+ <a-icon type="info-circle" style="color: rgba(0,0,0,.45)"/>
205
+ </a-popover>
206
+ </a-select>
207
+ </a-form-model-item>
208
+ </a-col>
209
+ <a-col :span="8">
210
+ <a-form-model-item label="数据字段中文名" prop="title">
211
+ <a-input v-model="item.title" placeholder="请输入数据字段中文名,如:编号"/>
212
+ </a-form-model-item>
213
+ </a-col>
214
+ <a-col :span="8">
215
+ <a-form-model-item
216
+ v-show="!(item.formType === 'file' || item.formType === 'image')"
217
+ label="数据字段名"
218
+ prop="key">
219
+ <a-input v-model="item.key" placeholder="请输入数据字段名" ref="key">
220
+ <a-popover slot="suffix" title="关于数据字段名" placement="bottom">
221
+ <template slot="content">
222
+ <p>设置数据字段的名称</p>
223
+ <p>用作SQL查询时必须遵守<span style="font-weight: bold">表别名.列名</span>的格式,如:i.id</p>
224
+ <p>其他情况下不限制</p>
225
+ </template>
226
+ <a-icon type="info-circle" style="color: rgba(0,0,0,.45)"/>
227
+ </a-popover>
228
+ </a-input>
229
+ </a-form-model-item>
230
+ </a-col>
231
+ </a-row>
232
+ <a-row :gutter="16">
233
+ <a-col :span="24">
234
+ <a-form-model-item label="数据模式" prop="dataMode">
235
+ <a-checkbox-group v-model="dataModeArrayData" :options="dataModeArray"/>
236
+ </a-form-model-item>
237
+ </a-col>
238
+ </a-row>
239
+ <template v-if="dataMode.queryForm || dataMode.addOrEditForm">
240
+ <a-row :gutter="16" v-if="item.formType === 'file' || item.formType === 'image'">
241
+ <a-col :span="8">
242
+ <a-form-model-item
243
+ label="允许上传文件数量"
244
+ prop="accept"
245
+ v-if="item.formType === 'file' || item.formType === 'image'">
246
+ <a-slider
247
+ v-model="item.acceptCount"
248
+ :min="1"
249
+ :max="20"
250
+ :marks="{ 1: '1', 3: '3', 5: '5', 10: '10', 15: '15', 20: '20'}"
251
+ :default-value="3"
252
+ />
253
+ </a-form-model-item>
254
+ </a-col>
255
+ <a-col :span="8">
256
+ <a-form-model-item
257
+ label="文件上传模式"
258
+ prop="resUploadMode"
259
+ v-if="item.formType === 'file' || item.formType === 'image'">
260
+ <a-select v-model="item.resUploadMode" placeholder="文件上传模式,默认为服务器" @change="changeFormType(item)">
261
+ <a-select-option key="server">服务器</a-select-option>
262
+ <a-select-option key="oss">腾讯云对象存储</a-select-option>
263
+ <a-select-option key="base64" :disabled="item.formType === 'file'">Base64</a-select-option>
264
+ <a-popover slot="suffixIcon" title="关于资源上传模式" placement="right">
265
+ <template slot="content">
266
+ <p>指定文件上传到服务器,对象存储还是以base64方式存储</p>
267
+ <br/>
268
+ <p><span style="font-weight: bold">服务器:</span>文件上传到服务器,数据库需存储文件于服务器的路径</p>
269
+ <p><span style="font-weight: bold">对象存储:</span>文件上传到云对象存储,数据库需存储文件于对象存储的路径</p>
270
+ <p><span style="font-weight: bold">base64:</span>文件以base64字符串方式存入数据库中(仅图片上传表单支持)</p>
271
+ </template>
272
+ <a-icon type="info-circle" style="color: rgba(0,0,0,.45)"/>
273
+ </a-popover>
274
+ </a-select>
275
+ </a-form-model-item>
276
+ </a-col>
277
+ <a-col :span="8">
278
+ <a-form-model-item
279
+ label="允许上传文件类型"
280
+ prop="accept"
281
+ v-if="item.formType === 'file'">
282
+ <a-select
283
+ mode="tags"
284
+ v-model="item.accept"
285
+ placeholder="指定文件类型,默认不限制,可选"
286
+ @change="itemAcceptChange">
287
+ <a-select-option v-for="type_item in fileType" :key="type_item.accept">{{ type_item.label }}
288
+ </a-select-option>
289
+ <a-popover slot="suffixIcon" title="关于允许上传文件类型" placement="right">
290
+ <template slot="content">
291
+ <p>指定允许上传的文件类型扩展名,如:.doc,.docx等,详情请参考<a target="_blank" @click="visitAcceptFile">允许上传文件类型</a>
292
+ </p>
293
+ </template>
294
+ <a-icon type="info-circle" style="color: rgba(0,0,0,.45)"/>
295
+ </a-popover>
296
+ </a-select>
297
+ </a-form-model-item>
298
+ </a-col>
299
+ <!-- TODO 配置文件上传表单-所属模块 -->
300
+ <!-- TODO 配置文件上传表单-上传扩展目录Key -->
301
+ </a-row>
302
+ <a-row :gutter="16" v-if="item.formType === 'selects'">
303
+ <a-col :span="8">
304
+ <a-form-model-item label="是否根节点" prop="groupIndexView">
305
+ <a-radio-group
306
+ defaultValue="None"
307
+ v-model="item.groupIndexView"
308
+ @change="groupIndexChange"
309
+ default-value="false"
310
+ button-style="solid">
311
+ <a-radio-button :value="1">
312
+
313
+ </a-radio-button>
314
+ <a-radio-button value="None">
315
+
316
+ </a-radio-button>
317
+ </a-radio-group>
318
+ </a-form-model-item>
319
+ </a-col>
320
+ <a-col :span="8" v-if="item.groupIndex !== 1">
321
+ <a-form-model-item label="数据所属节点" prop="groupIndex">
322
+ <a-select
323
+ v-model="item.parent_title"
324
+ placeholder="请选择父节点"
325
+ ref="groupIndex"
326
+ @change="parent_title_change">
327
+ <a-select-option v-for="parent_item in parent_node" :key="parent_item.key">{{
328
+ parent_item.title
329
+ }}
330
+ </a-select-option>
331
+ <a-popover slot="suffixIcon" title="关于父节点" placement="bottom">
332
+ <template slot="content">
333
+ <p>多个下拉框为一组时,需要首先选择的为父节点</p>
334
+ </template>
335
+ <a-icon type="info-circle" style="color: rgba(0,0,0,.45)"/>
336
+ </a-popover>
337
+ </a-select>
338
+ </a-form-model-item>
339
+ </a-col>
340
+ </a-row>
341
+ <a-row :gutter="16">
342
+ <a-col :span="8">
343
+ <a-form-model-item
344
+ label="数据源类型"
345
+ prop="selectType"
346
+ v-if="item.formType === 'select' || (item.formType === 'selects' && item.groupIndex == 1) || item.formType === 'cascader'">
347
+ <a-select v-model="item.selectType" placeholder="请选择数据源类型" @change="changeSelectKey(item)">
348
+ <a-select-option key="key">字典键</a-select-option>
349
+ <a-select-option key="fixArray">固定集合</a-select-option>
350
+ <a-select-option key="logic">业务逻辑</a-select-option>
351
+ <a-popover
352
+ slot="suffixIcon"
353
+ title="关于下拉框或级联框数据源类型"
354
+ placement="bottom">
355
+ <template slot="content">
356
+ <p>设置下拉框或级联框的数据源</p>
357
+ <p>数据源类型分为三种,你可以根据需要选择</p>
358
+ <p>字典键:选项从字典表(t_dictionary)获取,你只需要选择字典键的名称即可</p>
359
+ <p>业务逻辑名称:选项通过发起http请求调用指定的业务逻辑(Logic)接口获取</p>
360
+ <p>固定集合:选项为静态值,JSONArray格式</p>
361
+ <p>当表单类型为 " 级联选择框(多个下拉) " 是数据模式为
362
+ [{lable,value,children[{lable,value,children[]},{lable,value,children[]}]}] 形式</p>
363
+ <p>如:</p>
364
+ <json-viewer
365
+ :value="DemoJson"
366
+ :expand-depth="parseInt('100')"
367
+ style="overflow: auto;max-height: 440px"></json-viewer>
368
+ </template>
369
+ <a-icon type="info-circle" style="color: rgba(0,0,0,.45)"/>
370
+ </a-popover>
371
+ </a-select>
372
+ </a-form-model-item>
373
+ </a-col>
374
+ <a-col :span="8">
375
+ <a-form-model-item
376
+ label="数据源"
377
+ prop="selectKey"
378
+ v-if="(item.formType === 'select' || (item.formType === 'selects' && item.groupIndex == 1) || item.formType === 'cascader') && item.selectType">
379
+ <a-select
380
+ show-search
381
+ v-model="item.selectKey"
382
+ v-if="item.selectType === 'key'"
383
+ placeholder="请选择字典键"
384
+ :filter-option="filterOption"
385
+ @change="changeSelectKey(item)"
386
+ >
387
+ <template>
388
+ <a-select-option
389
+ v-for="(optionItem,index) in option"
390
+ :key="index"
391
+ :value="Object.keys(optionItem)[0]">{{ optionItem[Object.keys(optionItem)[0]] }}
392
+ </a-select-option>
393
+ </template>
394
+ </a-select>
395
+ <a-input v-model="item.selectKey" v-if="item.selectType === 'logic'" placeholder="请输入业务逻辑名称"/>
396
+ <a-textarea v-model="item.selectKey" v-if="item.selectType === 'fixArray'" placeholder="请录入数据源"/>
397
+ </a-form-model-item>
398
+ </a-col>
399
+ <a-col :span="8">
400
+ <a-form-model-item label="数据外键字段名" prop="selectKeyName" v-if="item.formType === 'select'">
401
+ <a-input v-model="item.selectKeyName" placeholder="该列所在表在主表的外键名,可选">
402
+ <a-popover slot="suffix" title="关于数据外键字段名" placement="bottom">
403
+ <template slot="content">
404
+ <p>当该列所属表为主表的关联表,且存在主外键关联关系,你可以指定<span style="font-weight: bold">该列所在表在主表的外键名</span>,如:i.f_type_id
405
+ </p>
406
+ <p>如果你的<a @click="$refs['key'].focus()">数据字段名</a>所属表为主表,或字段名已经是主表外键名时,不用设置该值</p>
407
+ <p>设置该参数是为了表单查询时可以通过外键id列而非具体值筛选数据</p>
408
+ <p>示例:</p>
409
+ <p>主表为t_userfiles表,别名为u,与t_gasbrand(气表品牌表)有关联关系,别名为g,数据字段名设置为g.f_gasbrand</p>
410
+ <p>如果指定了数据外键字段名,例如u.f_gasbrand_id,则使用数据外键字段名筛选数据,如果不指定该值,则使用<a @click="$refs['key'].focus()">数据字段名</a>筛选
411
+ </p>
412
+ </template>
413
+ <a-icon type="info-circle" style="color: rgba(0,0,0,.45)"/>
414
+ </a-popover>
415
+ </a-input>
416
+ </a-form-model-item>
417
+ </a-col>
418
+ </a-row>
419
+ <a-form-model-item
420
+ label="数据源加载方式"
421
+ prop="selectLoadType"
422
+ v-if="item.formType === 'select' && item.selectType === 'logic'">
423
+ <a-row :guttor="16">
424
+ <a-col :span="8">
425
+ <a-radio-group v-model="item.lazyLoad" default-value="false" button-style="solid">
426
+ <a-radio-button value="true">
427
+ 懒加载搜索
428
+ </a-radio-button>
429
+ <a-radio-button value="false">
430
+ 一次性加载
431
+ </a-radio-button>
432
+ </a-radio-group>
433
+ </a-col>
434
+ </a-row>
435
+ </a-form-model-item>
436
+ <a-form-model-item label="表单校验类型" prop="rule">
437
+ <a-row :gutter="16">
438
+ <a-col :span="8" v-if="item.formType === 'input' || item.formType === 'textarea'">
439
+ <a-select v-model="item.rule.type" placeholder="校验类型,可选">
440
+ <a-select-option key="string">字符串</a-select-option>
441
+ <a-select-option key="number">数字</a-select-option>
442
+ <a-select-option key="boolean">布尔值</a-select-option>
443
+ <a-select-option key="regexp">正则表达式</a-select-option>
444
+ <a-select-option key="integer">整数</a-select-option>
445
+ <a-select-option key="float">小数</a-select-option>
446
+ <a-select-option key="array">数组或集合</a-select-option>
447
+ <a-select-option key="date">日期</a-select-option>
448
+ <a-select-option key="email">邮箱</a-select-option>
449
+ <a-popover slot="suffixIcon" title="关于表单校验类型" placement="bottom">
450
+ <template slot="content">
451
+ <p>设置表单项的校验类型,默认字符串类型</p>
452
+ <p>你也可以设置该表单项是否必填</p>
453
+ </template>
454
+ <a-icon type="info-circle" style="color: rgba(0,0,0,.45)"/>
455
+ </a-popover>
456
+ </a-select>
457
+ </a-col>
458
+ <a-col :span="8">
459
+ <a-radio-group v-model="item.rule.required" default-value="false" button-style="solid">
460
+ <a-radio-button value="true">
461
+ 必选项
462
+ </a-radio-button>
463
+ <a-radio-button value="false">
464
+ 非必选项
465
+ </a-radio-button>
466
+ </a-radio-group>
467
+ </a-col>
468
+ </a-row>
469
+ </a-form-model-item>
470
+ <a-row :gutter="16" v-if="dataMode.addOrEditForm">
471
+ <a-col :span="8">
472
+ <a-form-model-item ref="addOrEdit" label="新增/修改场景选择" prop="addOrEdit">
473
+ <a-select v-model="item.addOrEdit" placeholder="请选择场景">
474
+ <a-select-option key="all">新增和修改</a-select-option>
475
+ <a-select-option key="add">仅支持新增</a-select-option>
476
+ <a-select-option key="edit">仅支持修改</a-select-option>
477
+ <a-select-option key="silenceAdd">静默新增(不生成表单)</a-select-option>
478
+ <a-select-option key="version">版本号</a-select-option>
479
+ <a-popover
480
+ slot="suffixIcon"
481
+ title="关于新增/修改场景选择"
482
+ placement="bottom">
483
+ <template slot="content">
484
+ <p>设置表单项的新增/修改场景</p>
485
+ <p>静默新增类型用于非人为新增的数据,不会生成表单项,且必须设置字段用途</p>
486
+ </template>
487
+ <a-icon type="info-circle" style="color: rgba(0,0,0,.45)"/>
488
+ </a-popover>
489
+ </a-select>
490
+ </a-form-model-item>
491
+ </a-col>
492
+ <a-col :span="8">
493
+ <a-form-model-item
494
+ v-if="item.addOrEdit === 'silenceAdd'"
495
+ ref="silencePurpose"
496
+ label="字段用途"
497
+ prop="silencePurpose">
498
+ <a-select v-model="item.silencePurpose" placeholder="请选择字段用途">
499
+ <a-select-option key="createTime">创建时间</a-select-option>
500
+ <a-select-option key="operator">创建/操作人</a-select-option>
501
+ <a-select-option key="orgId">组织机构ID</a-select-option>
502
+ <a-select-option key="customize">自定义</a-select-option>
503
+ <a-popover
504
+ slot="suffixIcon"
505
+ title="关于字段用途"
506
+ placement="bottom">
507
+ <template slot="content">
508
+ <p>用于静默新增时设置字段用途</p>
509
+ <p>在新增数据的表单提交时,页面会根据设置的字段用途获取相关数据并追加到表单中</p>
510
+ <p>当字段用途选择为<span style="font-weight: bold">自定义</span>时,必须指定一个业务逻辑(Logic)名称,表单提交前会将表单内容作为参数调用该Logic接口,并将Logic返回值作为表单值
511
+ </p>
512
+ </template>
513
+ <a-icon type="info-circle" style="color: rgba(0,0,0,.45)"/>
514
+ </a-popover>
515
+ </a-select>
516
+ </a-form-model-item>
517
+ </a-col>
518
+ <a-col :span="8">
519
+ <a-form-model-item v-if="item.silencePurpose === 'customize'" label="业务逻辑" prop="silenceSource">
520
+ <a-input v-model="item.silenceSource" placeholder="请输入业务逻辑名称"/>
521
+ </a-form-model-item>
522
+ </a-col>
523
+ </a-row>
524
+ </template>
525
+ <template v-if="dataMode.table">
526
+ <a-row :gutter="16">
527
+ <a-col :span="8">
528
+ <a-form-model-item label="作用域插槽" prop="slot">
529
+ <a-select v-model="item.slot.type" placeholder="插槽类型,可选">
530
+ <a-select-option key="default">不设置</a-select-option>
531
+ <a-select-option key="ellipsis">文本溢出省略</a-select-option>
532
+ <a-select-option key="badge">多彩徽标</a-select-option>
533
+ <a-select-option key="date">日期格式化</a-select-option>
534
+ <a-select-option key="dateTime">日期时间格式化</a-select-option>
535
+ <a-select-option key="action">操作列</a-select-option>
536
+ <a-popover slot="suffixIcon" title="关于作用域插槽" placement="bottom">
537
+ <template slot="content">
538
+ <p>你可以通过设置表格列的作用域插槽实现一些效果</p>
539
+ <p>如果没有指定,默认会设置为文本溢出省略(长度:16)</p>
540
+ <p>如果你选择文本溢出省略,需要设置文本溢出上限长度</p>
541
+ <p>如果你选择多彩徽标,需要设置徽标对应的数据样式字典键</p>
542
+ </template>
543
+ <a-icon type="info-circle" style="color: rgba(0,0,0,.45)"/>
544
+ </a-popover>
545
+ </a-select>
546
+ </a-form-model-item>
547
+ </a-col>
548
+ <a-col :span="8">
549
+ <a-form-model-item label="表格列宽度" prop="width">
550
+ <a-popover
551
+ title="关于表格列宽度"
552
+ placement="bottom">
553
+ <template slot="content">
554
+ <p>当作用域插槽设置为文本溢出省略时,表格列宽度将自适应,计算方式为文本溢出上限长度 * 7 + 42</p>
555
+ <p>当作用域插槽设置为多彩徽标时,表格列宽度为固定为130</p>
556
+ <p>当作用域插槽设置为日期时间格式化时,表格列宽度为固定为160</p>
557
+ <p>当该列数据过长导致换行时,建议设置作用域插槽为文本溢出省略,或将表格列设置为固定宽度值</p>
558
+ </template>
559
+ <a-input-number style="width: 100%" v-model="item.width" placeholder="表格列宽度,可选"/>
560
+ </a-popover>
561
+ </a-form-model-item>
562
+ </a-col>
563
+ <a-col :span="8">
564
+ <a-form-model-item label="字段默认值" prop="default" v-if="dataMode.sqlQueryItem">
565
+ <a-input v-model="item.default" placeholder="当查询结果为null时,指定默认值,可选"/>
566
+ </a-form-model-item>
567
+ </a-col>
568
+ </a-row>
569
+ <a-row :gutter="16">
570
+ <a-col :span="8">
571
+ <a-form-model-item label="文本溢出上限长度" prop="slotValue" v-if="item.slot.type === 'ellipsis'">
572
+ <a-input-number style="width: 100%" v-model="item.slotValue" placeholder="请输入文本溢出上限长度"/>
573
+ </a-form-model-item>
574
+ <a-form-model-item label="徽标字典键" prop="slotKeyMap" v-if="item.slot.type === 'badge'">
575
+ <a-input v-model="item.slotKeyMap" placeholder="请输入徽标字典键">
576
+ <a-popover
577
+ title="关于徽标字典键"
578
+ placement="bottom"
579
+ slot="suffix">
580
+ <template slot="content">
581
+ <p>如果你设置了表单类型为选择框,且数据源是字典键,该值会自动带出</p>
582
+ </template>
583
+ <a-icon type="info-circle" style="color: rgba(0,0,0,.45)"/>
584
+ </a-popover>
585
+ </a-input>
586
+ </a-form-model-item>
587
+ <a-form-model-item label="操作列文本" prop="actionText" v-if="item.slot.type === 'action'">
588
+ <a-input v-model="item.actionText" placeholder="请输入操作列显示文本,默认为详情"/>
589
+ </a-form-model-item>
590
+ </a-col>
591
+ </a-row>
592
+ </template>
593
+ <a-alert
594
+ style="margin-top: 5px"
595
+ v-if="dataModeArrayData.length === 0"
596
+ show-icon
597
+ message="错误:请至少选择一种数据模式"
598
+ type="error"/>
599
+ <a-alert
600
+ style="margin-top: 5px"
601
+ v-if="!(item.formType === 'file' || item.formType === 'image') && dataMode.addOrEditForm && !dataMode.sqlQueryItem"
602
+ show-icon
603
+ message="错误:如果要生成新增/修改表单项,必须勾选生成SQL查询项"
604
+ type="error"/>
605
+ <a-alert
606
+ style="margin-top: 5px"
607
+ v-if="(item.formType === 'file' || item.formType === 'image') && !(!dataMode.table && !dataMode.sqlQueryCondition && !dataMode.queryForm)"
608
+ show-icon
609
+ message="错误:上传类表单的数据模式只能选择 生成新增/修改表单项 和 生成SQL查询项 "
610
+ type="error"/>
611
+ <a-alert
612
+ style="margin-top: 5px"
613
+ v-if="dataMode.queryForm && !dataMode.sqlQueryCondition"
614
+ show-icon
615
+ message="提示:您没有勾选生成SQL查询表达式,渲染的表单项不会生成SQL查询条件"
616
+ type="info"/>
617
+ <a-alert
618
+ style="margin-top: 5px"
619
+ v-if="dataMode.table && !dataMode.sqlQueryItem"
620
+ show-icon
621
+ message="提示:您没有勾选生成SQL查询项,渲染的表格列不会绑定SQL结果集数据"
622
+ type="info"/>
623
+ </a-form-model>
624
+ </a-modal>
625
+ <a-button type="primary" @click="view">操作</a-button>
626
+ </a-col>
627
+ <a-col :xl="10" :lg="12" :md="12" :sm="24" :xs="24">
628
+ <a-card :bordered="false" title="预览" size="small" style="overflow: auto">
629
+ <json-viewer
630
+ :copyable="{copyText: '复制', copiedText: '已复制'}"
631
+ :value="result"
632
+ :expand-depth="parseInt('100')"
633
+ style="overflow: auto;max-height: 440px"></json-viewer>
634
+ </a-card>
635
+ </a-col>
636
+ </a-row>
637
+ <a-modal
638
+ title="效果预览"
639
+ :width="isMobile ? screenWidth : screenWidth * 0.8"
640
+ :centered="true"
641
+ :visible="modelVisible"
642
+ :zIndex="1001"
643
+ @cancel="onModelClose"
644
+ :destroyOnClose="true">
645
+ <template slot="footer">
646
+ <a-button key="close" @click="onModelClose">
647
+ 返回
648
+ </a-button>
649
+ <a-button key="submit" type="primary" @click="submit">
650
+ 保存
651
+ </a-button>
652
+ </template>
653
+ <x-form-table
654
+ :view-mode="true"
655
+ :queryParamsJson="result">
656
+ </x-form-table>
657
+ </a-modal>
658
+ </a-drawer>
659
+ </template>
660
+
661
+ <script>
662
+ import XFormItem from '@vue2-client/base-client/components/common/XForm/XFormItem'
663
+ import XFormTable from '@vue2-client/base-client/components/common/XFormTable/XFormTable'
664
+ import JsonViewer from 'vue-json-viewer'
665
+ import FileSaver from 'file-saver'
666
+ import { queryType, fileType } from '@vue2-client/config/CreateQueryConfig'
667
+ import { mapState } from 'vuex'
668
+ import { commonApi, post } from '@vue2-client/services/api'
669
+
670
+ const DemoJson = [{
671
+ value: 'zhejiang',
672
+ label: 'Zhejiang',
673
+ children: [{ value: 'hangzhou', label: 'Hangzhou', children: [{ value: 'xihu', label: 'West Lake' }] }]
674
+ }]
675
+ export default {
676
+ name: 'CreateQuery',
677
+ components: {
678
+ JsonViewer,
679
+ XFormTable,
680
+ XFormItem
681
+ },
682
+ data () {
683
+ return {
684
+ DemoJson,
685
+ fileType,
686
+ // 页面宽度
687
+ screenWidth: document.documentElement.clientWidth,
688
+ // 效果预览模态框是否展示
689
+ modelVisible: false,
690
+ // 数据列配置模态框是否展示
691
+ dataColumnVisible: false,
692
+ // 数据列操作类型:新增,修改
693
+ type: '新增',
694
+ // 数据模式类型集合
695
+ dataModeArray: [
696
+ { label: '生成查询表单项', value: 'queryForm' },
697
+ { label: '生成表格列', value: 'table' },
698
+ { label: '生成新增/修改表单项', value: 'addOrEditForm' },
699
+ { label: '生成SQL查询项', value: 'sqlQueryItem' },
700
+ { label: '生成SQL查询表达式', value: 'sqlQueryCondition' }
701
+ ],
702
+ // 操作按钮状态集合
703
+ buttonStateArray: [
704
+ { label: '新增', value: 'add' },
705
+ { label: '修改', value: 'edit' },
706
+ { label: '删除', value: 'delete' },
707
+ { label: '导出', value: 'export' }
708
+ ],
709
+ // 数据模式类型集合值
710
+ dataModeArrayData: ['queryForm', 'table', 'addOrEditForm', 'sqlQueryItem', 'sqlQueryCondition'],
711
+ // 操作按钮状态集合值
712
+ buttonStateData: ['add', 'edit', 'delete', 'export'],
713
+ labelCol: { span: 4 },
714
+ wrapperCol: { span: 14 },
715
+ form: {
716
+ tableName: '',
717
+ joinArray: {},
718
+ condition: {},
719
+ orderBy: '',
720
+ column: []
721
+ },
722
+ result: {},
723
+ item: {
724
+ key: '',
725
+ title: '',
726
+ slot: {},
727
+ rule: {
728
+ required: 'false'
729
+ },
730
+ formType: '',
731
+ accept: '',
732
+ addOrEdit: '',
733
+ selectKeyName: '',
734
+ acceptCount: '',
735
+ dataModeArray: []
736
+ },
737
+ itemMap: {},
738
+ selectIndex: null,
739
+ selectType: undefined,
740
+ joinArray: [],
741
+ rules: {
742
+ tableName: [{ required: true, message: '请输入查询表名', trigger: 'blur' }],
743
+ orderBy: [{ required: true, message: '请输入排序方式', trigger: 'blur' }]
744
+ },
745
+ itemRules: {
746
+ key: [{ required: true, message: '请输入数据列名', trigger: 'blur' }],
747
+ title: [{ required: true, message: '请输入中文名称', trigger: 'blur' }],
748
+ selectType: [{ required: true, message: '请选择数据源类型', trigger: 'change' }],
749
+ selectKey: [{ required: true, message: '请输入数据源内容', trigger: 'blur' }],
750
+ slotValue: [{ required: true, message: '请输入文本溢出上限长度', trigger: 'blur' }],
751
+ slotKeyMap: [{ required: true, message: '请输入徽标字典键', trigger: 'blur' }],
752
+ silencePurpose: [{ required: true, message: '请选择字段用途', trigger: 'change' }],
753
+ silenceSource: [{ required: true, message: '请输入业务逻辑名称', trigger: 'blur' }],
754
+ group: [{ required: true, message: '请选择父节点', trigger: 'blur' }],
755
+ groupIndex: [{ required: true, message: '如果不是根节点请选择自己的父节点', trigger: 'blur' }]
756
+
757
+ },
758
+ // 字典键集合
759
+ option: []
760
+ }
761
+ },
762
+ mounted () {
763
+ this.initView()
764
+ },
765
+ computed: {
766
+ ...mapState('setting', ['isMobile']),
767
+ parent_node () {
768
+ return this.form.column.filter(item => item.formType === 'selects' && item.key != this.item.key)
769
+ },
770
+ queryTypeV () {
771
+ if (this.item.formType) {
772
+ return queryType.filter(item => item.match.includes(this.item.formType))
773
+ }
774
+ return queryType
775
+ },
776
+ conditionJoinArray: function () {
777
+ const result = []
778
+ for (const item in this.form.joinArray) {
779
+ if (item !== '') {
780
+ result.push({
781
+ label: item,
782
+ value: item
783
+ })
784
+ }
785
+ }
786
+ if (result.length === 0) {
787
+ result.push({
788
+ label: '-',
789
+ value: '-'
790
+ })
791
+ }
792
+ return result
793
+ },
794
+ dataMode: function () {
795
+ const result = {
796
+ queryForm: false,
797
+ table: false,
798
+ addOrEditForm: false,
799
+ sqlQueryItem: false,
800
+ sqlQueryCondition: false
801
+ }
802
+ for (const item of this.dataModeArrayData) {
803
+ result[item] = true
804
+ }
805
+ return result
806
+ },
807
+ buttonState: function () {
808
+ const result = {
809
+ add: false,
810
+ edit: false,
811
+ delete: false,
812
+ export: false
813
+ }
814
+ for (const item of this.buttonStateData) {
815
+ result[item] = true
816
+ }
817
+ return result
818
+ }
819
+ },
820
+ props: {
821
+ visible: {
822
+ type: Boolean,
823
+ default: false
824
+ },
825
+ toEditJson: {
826
+ type: Object,
827
+ default: () => {}
828
+ }
829
+ },
830
+ watch: {
831
+ visible (rel) {
832
+ if (rel) {
833
+ this.initView()
834
+ }
835
+ if (rel && this.toEditJson) {
836
+ // 处理预设关联表
837
+ if (this.joinArray.length === 0) {
838
+ for (const key in this.toEditJson.joinArray) {
839
+ this.joinArray.push({
840
+ key: key,
841
+ value: this.toEditJson.joinArray[key]
842
+ })
843
+ }
844
+ }
845
+ // 处理具体表单项
846
+ this.form = Object.assign(
847
+ {
848
+ tableName: '',
849
+ joinArray: {},
850
+ condition: {},
851
+ orderBy: '',
852
+ column: []
853
+ }, this.toEditJson
854
+ )
855
+ for (const columnItem of this.form.column) {
856
+ // 数据模式兼容性处理
857
+ if (!(columnItem.dataMode || columnItem.dataModeArray)) {
858
+ columnItem.dataModeArray = ['queryForm', 'table', 'addOrEditForm', 'sqlQueryItem', 'sqlQueryCondition']
859
+ } else if (columnItem.dataMode) {
860
+ if (columnItem.dataMode === 'all') {
861
+ columnItem.dataModeArray = ['queryForm', 'table', 'addOrEditForm', 'sqlQueryItem', 'sqlQueryCondition']
862
+ } else if (columnItem.dataMode === 'form') {
863
+ columnItem.dataModeArray = ['queryForm', 'addOrEditForm', 'sqlQueryCondition']
864
+ } else if (columnItem.dataMode === 'table') {
865
+ columnItem.dataModeArray = ['table', 'sqlQueryItem']
866
+ } else if (columnItem.dataMode === 'table_form') {
867
+ columnItem.dataModeArray = ['table', 'sqlQueryItem', 'sqlQueryCondition']
868
+ } else if (columnItem.dataMode === 'only_form') {
869
+ columnItem.dataModeArray = ['queryForm']
870
+ } else if (columnItem.dataMode === 'only_table') {
871
+ columnItem.dataModeArray = ['table']
872
+ } else if (columnItem.dataMode === 'clear') {
873
+ columnItem.dataModeArray = ['sqlQueryItem', 'sqlQueryCondition']
874
+ } else if (columnItem.dataMode === 'only_add_modify') {
875
+ columnItem.dataModeArray = ['addOrEditForm', 'sqlQueryItem']
876
+ }
877
+ }
878
+ delete columnItem.dataMode
879
+ // 插槽兼容处理
880
+ if (columnItem.slot) {
881
+ if (columnItem.slot.value && columnItem.slot.type === 'ellipsis') {
882
+ columnItem.slotValue = columnItem.slot.value
883
+ } else if (columnItem.slot.keyMap && columnItem.slot.type === 'badge') {
884
+ columnItem.slotKeyMap = columnItem.slot.keyMap
885
+ } else if (columnItem.slot.actionText && columnItem.slot.type === 'action') {
886
+ columnItem.actionText = columnItem.slot.actionText
887
+ }
888
+ }
889
+ // 必选项兼容处理
890
+ if (columnItem.rule && columnItem.rule.required && columnItem.rule.required !== 'false') {
891
+ columnItem.rule.required = columnItem.rule.required.toString()
892
+ } else {
893
+ if (!columnItem.rule) {
894
+ columnItem.rule = {}
895
+ }
896
+ columnItem.rule.required = 'false'
897
+ }
898
+ // 数据源加载方式兼容处理
899
+ if (columnItem.lazyLoad && columnItem.lazyLoad !== 'false') {
900
+ columnItem.lazyLoad = columnItem.lazyLoad.toString()
901
+ } else {
902
+ columnItem.lazyLoad = 'false'
903
+ }
904
+ // 下拉框数据源兼容处理
905
+ if ((columnItem.formType === 'select' || columnItem.formType === 'cascader') && columnItem.selectKey) {
906
+ // 数据源为logic
907
+ if (columnItem.selectKey.toString().startsWith('logic@')) {
908
+ columnItem.selectType = 'logic'
909
+ } else if (columnItem.selectKey instanceof Array || this.isJSON(columnItem.selectKey)) {
910
+ // 数据源为固定json集合
911
+ if (columnItem.selectKey instanceof Array) {
912
+ columnItem.selectKey = JSON.stringify(columnItem.selectKey)
913
+ }
914
+ columnItem.selectType = 'fixArray'
915
+ } else {
916
+ columnItem.selectType = 'key'
917
+ }
918
+ }
919
+ this.itemMap[columnItem.key] = Object.assign({
920
+ key: '',
921
+ title: '',
922
+ slot: {},
923
+ rule: {
924
+ required: 'false'
925
+ },
926
+ dataModeArray: []
927
+ }, columnItem)
928
+ }
929
+ // 处理操作按钮配置
930
+ if (this.toEditJson.buttonState) {
931
+ this.buttonStateData = []
932
+ for (const buttonStateKey of Object.keys(this.toEditJson.buttonState)) {
933
+ if (this.toEditJson.buttonState[buttonStateKey]) {
934
+ this.buttonStateData.push(buttonStateKey)
935
+ }
936
+ }
937
+ } else {
938
+ this.buttonStateData = ['add', 'edit', 'delete', 'export']
939
+ }
940
+ }
941
+ }
942
+ },
943
+ methods: {
944
+ // 文件上传限制类型修改
945
+ itemAcceptChange (newVal) {
946
+ // newVal = [accept1,accept2,...]
947
+ if (newVal.includes('*')) {
948
+ this.item.accept = ['*']
949
+ // return
950
+ }
951
+ // 如果除了 无限制 都选择 改成无限制
952
+ // if (newVal.length === this.fileType.length - 1){
953
+ // this.item.accept = ['*']
954
+ // }
955
+ },
956
+ parent_title_change (parentKey) {
957
+ const parentArr = this.form.column.filter(item => item.formType === 'selects' && item.key === parentKey)
958
+ if (parentArr.length === 1) {
959
+ this.item.groupIndex = parentArr[0].groupIndex + 1
960
+ this.item.group = parentArr[0].group
961
+ this.item.parent_title = parentArr[0].title
962
+ } else {
963
+ this.$message.error('数据字段中有字段别名相同,请检查!')
964
+ }
965
+ },
966
+ groupIndexChange ({ target }) {
967
+ if (target.value === 1) {
968
+ this.item.groupIndex = 1
969
+ if (this.item.title) {
970
+ this.item.group = this.item.title + '组'
971
+ } else {
972
+ this.item.groupIndex = ''
973
+ this.$message.error('请先输入字段中文名称!')
974
+ }
975
+ } else {
976
+ this.item.groupIndex = ''
977
+ }
978
+ },
979
+ // 初始化组件
980
+ initView () {
981
+ this.joinArray = []
982
+ this.result = {}
983
+ post(commonApi.getDictionaryParam, {}).then(res => {
984
+ this.option = res
985
+ })
986
+ },
987
+ onClose () {
988
+ this.$emit('update:visible', false)
989
+ },
990
+ filterOption (input, option) {
991
+ return (
992
+ option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
993
+ )
994
+ },
995
+ onModelClose () {
996
+ this.modelVisible = false
997
+ },
998
+ addJoinItem () {
999
+ this.joinArray.push({
1000
+ key: '',
1001
+ value: ''
1002
+ })
1003
+ this.changeJoinArray()
1004
+ },
1005
+ removeJoinItem (index) {
1006
+ this.joinArray.splice(index, 1)
1007
+ this.changeJoinArray()
1008
+ },
1009
+ addColumnItem () {
1010
+ this.type = '新增'
1011
+ this.dataColumnVisible = true
1012
+ },
1013
+ editColumnItem (key, index) {
1014
+ if (this.itemMap[key]) {
1015
+ this.type = '修改'
1016
+ this.item = Object.assign({ formType: 'input', type: 'string' }, this.itemMap[key])
1017
+ if (this.item.formType === 'selects') {
1018
+ // 因为 groupIndex 可能有很多值 单选框不行 赋给一个新的变量
1019
+ this.item.groupIndexView = this.item.groupIndex === 1 ? 1 : 'None'
1020
+ }
1021
+ if (this.item.formType === 'selects') {
1022
+ // 因为 groupIndex 可能有很多值 单选框不行 赋给一个新的变量
1023
+ this.item.groupIndexView = this.item.groupIndex === 1 ? 1 : 'None'
1024
+ }
1025
+ this.dataModeArrayData = this.item.dataModeArray
1026
+ this.selectIndex = index
1027
+ this.dataColumnVisible = true
1028
+ } else {
1029
+ this.$message.warn('编辑失败')
1030
+ }
1031
+ },
1032
+ removeColumnItem (key, index) {
1033
+ const _this = this
1034
+ this.$confirm({
1035
+ title: '您确定要删除该数据项?',
1036
+ content: '删除的数据项无法恢复',
1037
+ okText: '确定',
1038
+ okType: 'danger',
1039
+ cancelText: '取消',
1040
+ onOk () {
1041
+ delete _this.itemMap[key]
1042
+ _this.form.column.splice(index, 1)
1043
+ }
1044
+ })
1045
+ },
1046
+ upColumnItem (key, index) {
1047
+ const newIndex = index - 1
1048
+ const itemA = this.form.column[newIndex]
1049
+ const itemB = this.form.column[index]
1050
+ this.form.column.splice(index, 1, itemA)
1051
+ this.form.column.splice(newIndex, 1, itemB)
1052
+ },
1053
+ downColumnItem (key, index) {
1054
+ const newIndex = index + 1
1055
+ const itemA = this.form.column[newIndex]
1056
+ const itemB = this.form.column[index]
1057
+ this.form.column.splice(index, 1, itemA)
1058
+ this.form.column.splice(newIndex, 1, itemB)
1059
+ },
1060
+ changeJoinArray () {
1061
+ const joinArrayObject = {}
1062
+ for (const item of this.joinArray) {
1063
+ joinArrayObject[item.key] = item.value
1064
+ }
1065
+ this.form.joinArray = joinArrayObject
1066
+ },
1067
+ submitItem () {
1068
+ this.$refs.itemForm.validate(valid => {
1069
+ if (valid) {
1070
+ const fileBool = this.item.formType === 'file' || this.item.formType === 'image'
1071
+ if (this.dataModeArrayData.length === 0) {
1072
+ this.$message.error('请至少选择一种数据模式')
1073
+ return
1074
+ }
1075
+ if (!fileBool && (this.dataMode.addOrEditForm && !this.dataMode.sqlQueryItem)) {
1076
+ this.$message.error('如果要生成新增/修改表单项,必须勾选生成SQL查询项')
1077
+ return
1078
+ }
1079
+ if (fileBool && !(!this.dataMode.table && !this.dataMode.sqlQueryCondition && !this.dataMode.queryForm)) {
1080
+ this.$message.error(`上传类表单项只能选择 "生成新增/修改表单项"`)
1081
+ return
1082
+ }
1083
+ this.itemHandle()
1084
+ }
1085
+ })
1086
+ },
1087
+ itemHandle () {
1088
+ const str = JSON.stringify(this.item)
1089
+ const item = JSON.parse(str)
1090
+ this.itemMap[item.key] = JSON.parse(str)
1091
+ this.itemMap[item.key].dataModeArray = this.dataModeArrayData
1092
+ // 查询表单项或者新增/修改表单项
1093
+ if (this.dataMode.queryForm || this.dataMode.addOrEditForm) {
1094
+ if (!this.dataMode.sqlQueryItem || !this.dataMode.addOrEditForm) {
1095
+ delete item.addOrEdit
1096
+ delete item.silencePurpose
1097
+ delete item.silenceSource
1098
+ }
1099
+ // 不生成SQL查询表达式,或者表单查询类型为=
1100
+ if (!this.dataMode.sqlQueryCondition || (item.queryType && item.queryType === '=')) {
1101
+ delete item.queryType
1102
+ }
1103
+ // 表单类型为输入框
1104
+ if (item.formType && item.formType === 'input') {
1105
+ delete item.formType
1106
+ }
1107
+ // 校验类型
1108
+ if (item.rule.required) {
1109
+ item.rule.required = item.rule.required.toString() === 'true'
1110
+ } else {
1111
+ item.rule.required = false
1112
+ }
1113
+ // 下拉框
1114
+ if ((item.formType === 'select' || (item.formType === 'selects' && item.groupIndex == '1') || item.formType === 'cascader') && item.selectKey) {
1115
+ // 数据源为logic
1116
+ if (item.selectType === 'logic') {
1117
+ // 如果已经有了 logic@ 将不再拼接
1118
+ if (item.selectKey.substring(0, 6) !== 'logic@') {
1119
+ item.selectKey = 'logic@' + item.selectKey
1120
+ }
1121
+ if (!item.lazyLoad) {
1122
+ delete item.lazyLoad
1123
+ }
1124
+ } else if (item.selectType === 'fixArray') {
1125
+ // 数据源为固定json集合
1126
+ if (!this.isJSON(item.selectKey)) {
1127
+ this.$message.warning('下拉框数据源不是JSON集合')
1128
+ return
1129
+ }
1130
+ delete item.lazyLoad
1131
+ } else {
1132
+ delete item.lazyLoad
1133
+ }
1134
+ if (item.formType !== 'selects') {
1135
+ delete item.selectType
1136
+ }
1137
+ } else {
1138
+ if (item.formType !== 'selects') {
1139
+ delete item.group
1140
+ delete item.groupIndex
1141
+ }
1142
+ delete item.selectType
1143
+ delete item.selectKey
1144
+ delete item.selectKeyName
1145
+ delete item.lazyLoad
1146
+ }
1147
+ } else {
1148
+ delete item.queryType
1149
+ delete item.formType
1150
+ delete item.addOrEdit
1151
+ delete item.silencePurpose
1152
+ delete item.silenceSource
1153
+ delete item.placeholder
1154
+ delete item.rule
1155
+ delete item.selectType
1156
+ delete item.selectKey
1157
+ delete item.selectKeyName
1158
+ delete item.lazyLoad
1159
+ }
1160
+ // 表格列
1161
+ if (this.dataMode.table) {
1162
+ if (item.slot.type && item.slot.type !== 'default') {
1163
+ if (item.slotValue && item.slot.type === 'ellipsis') {
1164
+ item.slot.value = item.slotValue
1165
+ } else if (item.slotKeyMap && item.slot.type === 'badge') {
1166
+ item.slot.keyMap = item.slotKeyMap
1167
+ } else if (item.actionText && item.slot.type === 'action') {
1168
+ item.slot.actionText = item.actionText
1169
+ }
1170
+ } else {
1171
+ delete item.slot
1172
+ }
1173
+ if (!item.width) {
1174
+ delete item.width
1175
+ }
1176
+ delete item.slotValue
1177
+ delete item.slotKeyMap
1178
+ delete item.actionText
1179
+ } else {
1180
+ delete item.slot
1181
+ delete item.slotValue
1182
+ delete item.slotKeyMap
1183
+ delete item.actionText
1184
+ delete item.width
1185
+ }
1186
+ // SQL查询项
1187
+ if (!this.dataMode.sqlQueryItem) {
1188
+ delete item.default
1189
+ }
1190
+ item.dataModeArray = this.dataModeArrayData
1191
+ if (this.type === '新增') {
1192
+ this.form.column.push(item)
1193
+ } else {
1194
+ this.form.column[this.selectIndex] = item
1195
+ }
1196
+ this.item = {
1197
+ key: '',
1198
+ title: '',
1199
+ slot: {},
1200
+ rule: {
1201
+ required: 'false'
1202
+ },
1203
+ dataModeArray: []
1204
+ }
1205
+ this.$message.success('增加成功')
1206
+ this.dataModeArrayData = ['queryForm', 'table', 'addOrEditForm', 'sqlQueryItem', 'sqlQueryCondition']
1207
+ this.dataColumnVisible = false
1208
+ },
1209
+ // 判断是否为json字符串
1210
+ isJSON (str) {
1211
+ if (typeof str == 'string') {
1212
+ try {
1213
+ const obj = JSON.parse(str)
1214
+ return !!(typeof obj == 'object' && obj)
1215
+ } catch (e) {
1216
+ return false
1217
+ }
1218
+ }
1219
+ },
1220
+ exportJson () {
1221
+ const data = JSON.stringify(this.form, null, 2)
1222
+ const blob = new Blob([data], { type: 'application/json' })
1223
+ FileSaver.saveAs(blob, `Query.json`)
1224
+ this.$message.success('导出成功!')
1225
+ },
1226
+ viewHandle (then) {
1227
+ if (this.form.column.length === 0) {
1228
+ this.$message.error('你没有增加任何数据字段')
1229
+ return
1230
+ }
1231
+ this.result = JSON.parse(JSON.stringify(this.form))
1232
+ if (this.result.condition && (!this.result.condition.value || this.result.condition.value === '')) {
1233
+ delete this.result.condition
1234
+ }
1235
+ for (const item of this.result.column) {
1236
+ if (item.selectType === 'fixArray') {
1237
+ item.selectKey = JSON.parse(item.selectKey)
1238
+ }
1239
+ if (item.dataModeArray.length === 5) {
1240
+ delete item.dataModeArray
1241
+ }
1242
+ }
1243
+ if (this.buttonStateData.length !== 4) {
1244
+ this.result.buttonState = this.buttonState
1245
+ }
1246
+ then()
1247
+ },
1248
+ view () {
1249
+ this.$refs.businessCreateForm.validate(valid => {
1250
+ if (valid) {
1251
+ this.viewHandle(() => {
1252
+ this.modelVisible = true
1253
+ })
1254
+ }
1255
+ })
1256
+ },
1257
+ submit () {
1258
+ this.onModelClose()
1259
+ this.$refs.businessCreateForm.validate(valid => {
1260
+ if (valid) {
1261
+ this.viewHandle(() => {
1262
+ // saveQueryParams
1263
+ this.$emit('saveQueryParams', this.result)
1264
+ })
1265
+ }
1266
+ })
1267
+ },
1268
+ modelCancel () {
1269
+ this.dataColumnVisible = false
1270
+ // 延迟是为了避免编辑数据窗口关闭时重置表单导致的闪烁
1271
+ setTimeout(() => {
1272
+ this.item = {
1273
+ key: '',
1274
+ title: '',
1275
+ slot: {},
1276
+ rule: {
1277
+ required: 'false'
1278
+ },
1279
+ dataModeArray: []
1280
+ }
1281
+ this.dataModeArrayData = ['queryForm', 'table', 'addOrEditForm', 'sqlQueryItem', 'sqlQueryCondition']
1282
+ }, 100)
1283
+ },
1284
+ changeFormType (item) {
1285
+ if (item.formType === 'file' || item.formType === 'image') {
1286
+ this.item.accept = item.formType === 'file' ? ['*'] : ['.jpg,.jpeg,.ico,.gif,svg,.webp,.png,.bmp,.pjpeg,']
1287
+ this.item.resUploadMode = 'server'
1288
+ this.dataModeArrayData = ['addOrEditForm']
1289
+ } else {
1290
+ this.dataModeArrayData = ['queryForm', 'table', 'addOrEditForm', 'sqlQueryItem', 'sqlQueryCondition']
1291
+ delete this.item.accept
1292
+ delete this.item.resUploadMode
1293
+ }
1294
+ },
1295
+ changeSelectKey (item) {
1296
+ if (item.selectType === 'key' && item.selectKey) {
1297
+ item.slot.type = 'badge'
1298
+ item.slotKeyMap = item.selectKey
1299
+ }
1300
+ },
1301
+ visitAcceptFile () {
1302
+ window.open('https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/input/file#attr-accept')
1303
+ }
1304
+ }
1305
+ }
1306
+ </script>
1307
+ <style lang="less" scoped>
1308
+ </style>