Commit 7e5256dcd7c88166813492507e9bf7001d893092
1 parent
650f048b
代码生成器升级
1.支持插入菜单sql生成 2.vue3模板大升级 3.提供vue3原生表单模板生成
Showing
98 changed files
with
5297 additions
and
526 deletions
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/form/native/vue3NativeComponents.ftl
0 → 100644
1 | +<#if need_select_tag> | |
2 | + JDictSelectTag, | |
3 | +</#if> | |
4 | +<#if need_switch> | |
5 | + JSwitch, | |
6 | +</#if> | |
7 | +<#if need_multi> | |
8 | + JSelectMultiple, | |
9 | +</#if> | |
10 | +<#if need_search> | |
11 | + JSearchSelect, | |
12 | +</#if> | |
13 | +<#if need_popup> | |
14 | + JPopup, | |
15 | +</#if> | |
16 | +<#if need_category> | |
17 | + JCategorySelect, | |
18 | +</#if> | |
19 | +<#if need_dept> | |
20 | + JSelectDept, | |
21 | +</#if> | |
22 | +<#if need_dept_user> | |
23 | + JSelectUserByDept, | |
24 | +</#if> | |
25 | +<#if need_select_tree> | |
26 | + JTreeSelect, | |
27 | +</#if> | |
28 | +<#if need_time> | |
29 | + TimePicker, | |
30 | +</#if> | |
31 | +<#if need_pca> | |
32 | + JAreaLinkage, | |
33 | +</#if> | |
34 | +<#if need_upload> | |
35 | + JUpload, | |
36 | +</#if> | |
37 | +<#if need_image_upload> | |
38 | + JImageUpload, | |
39 | +</#if> | |
40 | +<#if need_markdown> | |
41 | + JMarkdownEditor, | |
42 | +</#if> | |
43 | +<#if need_editor> | |
44 | + JEditor, | |
45 | +</#if> | |
46 | +<#if need_checkbox> | |
47 | + JCheckbox, | |
48 | +</#if> | |
0 | 49 | \ No newline at end of file |
... | ... |
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/form/native/vue3NativeForm.ftl
0 → 100644
1 | +<#include "/common/utils.ftl"> | |
2 | +<#if po.isShow =='Y' && po.fieldName != 'id' && isNotPidField(tableVo, po.fieldDbName)> | |
3 | +<#assign form_field_dictCode=""> | |
4 | + <#if po.dictTable?default("")?trim?length gt 1 && po.dictText?default("")?trim?length gt 1 && po.dictField?default("")?trim?length gt 1> | |
5 | + <#assign form_field_dictCode="${po.dictTable},${po.dictText},${po.dictField}"> | |
6 | + <#elseif po.dictField?default("")?trim?length gt 1> | |
7 | + <#assign form_field_dictCode="${po.dictField}"> | |
8 | + </#if> | |
9 | + <a-col :span="${form_span}"> | |
10 | + <a-form-item label="${po.filedComment}" v-bind="validateInfos.${autoStringSuffixForModel(po)}"> | |
11 | + <#if po.classType =='date'> | |
12 | + <a-date-picker placeholder="请选择${po.filedComment}" v-model:value="formData.${po.fieldName}" value-format="YYYY-MM-DD" style="width: 100%" <#if po.readonly=='Y'>disabled<#else>:disabled="disabled"</#if>/> | |
13 | + <#elseif po.classType =='datetime'> | |
14 | + <a-date-picker placeholder="请选择${po.filedComment}" v-model:value="formData.${po.fieldName}" showTime value-format="YYYY-MM-DD HH:mm:ss" style="width: 100%" <#if po.readonly=='Y'>disabled<#else>:disabled="disabled"</#if>/> | |
15 | + <#elseif po.classType =='time'> | |
16 | + <#assign need_time = true> | |
17 | + <time-picker placeholder="请选择${po.filedComment}" value-format="HH:mm:ss" v-model:value="formData.${po.fieldName}" style="width: 100%" <#if po.readonly=='Y'>disabled<#else>:disabled="disabled"</#if>/> | |
18 | + <#elseif po.classType =='popup'> | |
19 | + <#assign need_popup = true> | |
20 | + <#assign sourceFields = po.dictField?default("")?trim?split(",")/> | |
21 | + <#assign targetFields = po.dictText?default("")?trim?split(",")/> | |
22 | + <j-popup | |
23 | + placeholder="请选择${po.filedComment}" | |
24 | + v-model:value="formData.${po.fieldName}" | |
25 | + code="${po.dictTable}" | |
26 | + :fieldConfig="[ | |
27 | + <#list sourceFields as fieldName> | |
28 | + { source: '${fieldName}', target: '${targetFields[fieldName_index]}' }, | |
29 | + </#list> | |
30 | + ]" | |
31 | + :multi="${po.extendParams.popupMulti?c}" | |
32 | + :setFieldsValue="setFieldsValue" | |
33 | + <#if po.readonly=='Y'>disabled<#else>:disabled="disabled"</#if><#rt> | |
34 | + /> | |
35 | + <#elseif po.classType =='sel_depart'> | |
36 | + <#assign need_dept = true> | |
37 | + <j-select-dept v-model:value="formData.${po.fieldName}" :multiple="${po.extendParams.multi?default('true')}" checkStrictly <#if po.readonly=='Y'>disabled<#else>:disabled="disabled"</#if> /> | |
38 | + <#elseif po.classType =='switch'> | |
39 | + <#assign need_switch = true> | |
40 | + <j-switch v-model:value="formData.${po.fieldName}" <#if po.dictField != 'is_open'>:options="${po.dictField}"</#if> <#if po.readonly=='Y'>disabled<#else>:disabled="disabled"</#if>></j-switch> | |
41 | + <#elseif po.classType =='pca'> | |
42 | + <#assign need_pca = true> | |
43 | + <j-area-linkage v-model:value="formData.${po.fieldName}" placeholder="请输入${po.filedComment}" <#if po.readonly=='Y'>disabled<#else>:disabled="disabled"</#if> /> | |
44 | + <#elseif po.classType =='markdown'> | |
45 | + <#assign need_markdown = true> | |
46 | + <j-markdown-editor v-model:value="formData.${autoStringSuffixForModel(po)}" id="${po.fieldName}" placeholder="请输入${po.filedComment}" <#if po.readonly=='Y'>disabled<#else>:disabled="disabled"</#if>></j-markdown-editor> | |
47 | + <#elseif po.classType =='password'> | |
48 | + <a-input-password v-model:value="formData.${po.fieldName}" placeholder="请输入${po.filedComment}" <#if po.readonly=='Y'>disabled<#else>:disabled="disabled"</#if>/> | |
49 | + <#elseif po.classType =='sel_user'> | |
50 | + <#assign need_dept_user = true> | |
51 | + <j-select-user-by-dept v-model:value="formData.${po.fieldName}" <#if po.readonly=='Y'>disabled<#else>:disabled="disabled"</#if>/> | |
52 | + <#elseif po.classType =='textarea'> | |
53 | + <a-textarea v-model:value="formData.${autoStringSuffixForModel(po)}" rows="4" placeholder="请输入${po.filedComment}" <#if po.readonly=='Y'>disabled<#else>:disabled="disabled"</#if>/> | |
54 | + <#elseif po.classType=='radio'> | |
55 | + <#assign need_select_tag = true> | |
56 | + <j-dict-select-tag type='radio' v-model:value="formData.${po.fieldName}" dictCode="${form_field_dictCode}" placeholder="请选择${po.filedComment}" <#if po.readonly=='Y'>disabled<#else>:disabled="disabled"</#if>/> | |
57 | + <#elseif po.classType=='list'> | |
58 | + <#assign need_select_tag = true> | |
59 | + <j-dict-select-tag v-model:value="formData.${po.fieldName}" dictCode="${form_field_dictCode}" placeholder="请选择${po.filedComment}" <#if po.readonly=='Y'>disabled<#else>:disabled="disabled"</#if>/> | |
60 | + <#elseif po.classType=='list_multi'> | |
61 | + <#assign need_multi = true> | |
62 | + <j-select-multiple type="${po.classType}" v-model:value="formData.${po.fieldName}" dictCode="${form_field_dictCode}" placeholder="请选择${po.filedComment}" <#if po.readonly=='Y'>disabled<#else>:disabled="disabled"</#if> :triggerChange="false"/> | |
63 | + <#elseif po.classType=='checkbox'> | |
64 | + <#assign need_checkbox = true> | |
65 | + <j-checkbox type="${po.classType}" v-model:value="formData.${po.fieldName}" dictCode="${form_field_dictCode}" placeholder="请选择${po.filedComment}" <#if po.readonly=='Y'>disabled<#else>:disabled="disabled"</#if>/> | |
66 | + <#elseif po.classType=='sel_search'> | |
67 | + <#assign need_search = true> | |
68 | + <j-search-select v-model:value="formData.${po.fieldName}" dict="${form_field_dictCode}" <#if po.readonly=='Y'>disabled<#else>:disabled="disabled"</#if> /> | |
69 | + <#elseif po.classType=='cat_tree'> | |
70 | + <#assign need_category = true> | |
71 | + <j-category-select v-model:value="formData.${po.fieldName}" pcode="${po.dictField?default("")}" placeholder="请选择${po.filedComment}" <#if po.dictText?default("")?trim?length gt 1>back="${dashedToCamel(po.dictText)}"</#if> <#if po.readonly=='Y'>disabled<#else>:disabled="disabled"</#if> @change="(value) => handleFormChange('${po.fieldName}', value)" /> | |
72 | + <#elseif po.fieldDbType=='int' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'> | |
73 | + <a-input-number v-model:value="formData.${po.fieldName}" placeholder="请输入${po.filedComment}" style="width: 100%" <#if po.readonly=='Y'>disabled<#else>:disabled="disabled"</#if>/> | |
74 | + <#elseif po.classType=='file'> | |
75 | + <#assign need_upload = true> | |
76 | + <j-upload v-model:value="formData.${po.fieldName}" <#if po.readonly=='Y'>disabled<#else>:disabled="disabled"</#if> <#if po.uploadnum??>:maxCount=${po.uploadnum}</#if>></j-upload> | |
77 | + <#elseif po.classType=='image'> | |
78 | + <#assign need_image_upload = true> | |
79 | + <j-image-upload <#if po.uploadnum??>:fileMax=${po.uploadnum}</#if> v-model:value="formData.${po.fieldName}" <#if po.readonly=='Y'>disabled<#else>:disabled="disabled"</#if>></j-image-upload> | |
80 | + <#elseif po.classType=='umeditor'> | |
81 | + <#assign need_editor = true> | |
82 | + <j-editor v-model:value="formData.${autoStringSuffixForModel(po)}" <#if po.readonly=='Y'>disabled<#else>:disabled="disabled"</#if>/> | |
83 | + <#elseif po.fieldDbType=='Blob'> | |
84 | + <a-input v-model:value="formData.${autoStringSuffixForModel(po)}" placeholder="请输入${po.filedComment}" <#if po.readonly=='Y'>disabled<#else>:disabled="disabled"</#if>></a-input> | |
85 | + <#elseif po.classType == 'sel_tree'> | |
86 | + <#assign need_select_tree = true> | |
87 | + <j-tree-select | |
88 | + <#if po.dictText??> | |
89 | + <#if po.dictText?split(',')[2]?? && po.dictText?split(',')[0]??> | |
90 | + dict="${po.dictTable},${po.dictText?split(',')[2]},${po.dictText?split(',')[0]}" | |
91 | + <#elseif po.dictText?split(',')[1]??> | |
92 | + pidField="${po.dictText?split(',')[1]}" | |
93 | + <#elseif po.dictText?split(',')[3]??> | |
94 | + hasChildField="${po.dictText?split(',')[3]}" | |
95 | + </#if> | |
96 | + </#if> | |
97 | + pidValue="${po.dictField}" | |
98 | + <#if po.readonly=='Y'>disabled<#else>:disabled="disabled"</#if> | |
99 | + v-model:value="formData.${po.fieldName}" | |
100 | + @change="(value) => handleFormChange('${po.fieldName}', value)"> | |
101 | + </j-tree-select> | |
102 | + <#else> | |
103 | + <a-input v-model:value="formData.${po.fieldName}" placeholder="请输入${po.filedComment}" <#if po.readonly=='Y'>disabled<#else>:disabled="disabled"</#if>></a-input> | |
104 | + </#if> | |
105 | + </a-form-item> | |
106 | + </a-col> | |
107 | +</#if> | |
0 | 108 | \ No newline at end of file |
... | ... |
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/form/native/vue3NativeImport.ftl
0 → 100644
1 | +<#if need_select_tag> | |
2 | + import JDictSelectTag from '/@/components/Form/src/jeecg/components/JDictSelectTag.vue'; | |
3 | +</#if> | |
4 | +<#if need_switch> | |
5 | + import JSwitch from '/@/components/Form/src/jeecg/components/JSwitch.vue'; | |
6 | +</#if> | |
7 | +<#if need_multi> | |
8 | + import JSelectMultiple from '/@/components/Form/src/jeecg/components/JSelectMultiple.vue'; | |
9 | +</#if> | |
10 | +<#if need_search> | |
11 | + import JSearchSelect from '/@/components/Form/src/jeecg/components/JSearchSelect.vue'; | |
12 | +</#if> | |
13 | +<#if need_popup> | |
14 | + import JPopup from '/@/components/Form/src/jeecg/components/JPopup.vue'; | |
15 | +</#if> | |
16 | +<#if need_category> | |
17 | + import JCategorySelect from '/@/components/Form/src/jeecg/components/JCategorySelect.vue'; | |
18 | +</#if> | |
19 | +<#if need_dept> | |
20 | + import JSelectDept from '/@/components/Form/src/jeecg/components/JSelectDept.vue'; | |
21 | +</#if> | |
22 | +<#if need_dept_user> | |
23 | + import JSelectUserByDept from '/@/components/Form/src/jeecg/components/JSelectUserByDept.vue'; | |
24 | +</#if> | |
25 | +<#if need_select_tree> | |
26 | + import JTreeSelect from '/@/components/Form/src/jeecg/components/JTreeSelect.vue'; | |
27 | +</#if> | |
28 | +<#if need_time> | |
29 | + import { TimePicker } from 'ant-design-vue'; | |
30 | +</#if> | |
31 | +<#if need_pca> | |
32 | + import JAreaLinkage from '/@/components/Form/src/jeecg/components/JAreaLinkage.vue'; | |
33 | +</#if> | |
34 | +<#if need_upload> | |
35 | + import JUpload from '/@/components/Form/src/jeecg/components/JUpload/JUpload.vue'; | |
36 | +</#if> | |
37 | +<#if need_image_upload> | |
38 | + import JImageUpload from '/@/components/Form/src/jeecg/components/JImageUpload.vue'; | |
39 | +</#if> | |
40 | +<#if need_markdown> | |
41 | + import JMarkdownEditor from '/@/components/Form/src/jeecg/components/JMarkdownEditor.vue'; | |
42 | +</#if> | |
43 | +<#if need_editor> | |
44 | + import JEditor from '/@/components/Form/src/jeecg/components/JEditor.vue'; | |
45 | +</#if> | |
46 | +<#if need_checkbox> | |
47 | + import JCheckbox from "/@/components/Form/src/jeecg/components/JCheckbox.vue"; | |
48 | +</#if> | |
0 | 49 | \ No newline at end of file |
... | ... |
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/form/native/vue3NativeSearch.ftl
0 → 100644
1 | +<#if po.isQuery=='Y'> | |
2 | +<#assign query_flag=true> | |
3 | + <#if query_field_no==2> | |
4 | + <template v-if="toggleSearchStatus"> | |
5 | + </#if> | |
6 | + <#assign query_field_dictCode=""> | |
7 | + <#if po.dictTable?default("")?trim?length gt 1> | |
8 | + <#assign need_select_tag = true> | |
9 | + <#assign query_field_dictCode="${po.dictTable},${po.dictText},${po.dictField}"> | |
10 | + <#elseif po.dictField?default("")?trim?length gt 1> | |
11 | + <#assign need_select_tag = true> | |
12 | + <#assign query_field_dictCode="${po.dictField}"> | |
13 | + </#if> | |
14 | + <#if po.queryMode=='single'> | |
15 | + <#if query_field_no gt 1> </#if><a-col :lg="8"> | |
16 | + <#if query_field_no gt 1> </#if><a-form-item label="${po.filedComment}"> | |
17 | + <#if po.classType=='sel_search'> | |
18 | + <#if query_field_no gt 1> </#if><j-search-select placeholder="请选择${po.filedComment}" v-model:value="queryParam.${po.fieldName}" dict="${po.dictTable},${po.dictText},${po.dictField}" /> | |
19 | + <#elseif po.classType=='sel_user'> | |
20 | + <#if query_field_no gt 1> </#if><j-select-user-by-dept placeholder="请选择${po.filedComment}" v-model:value="queryParam.${po.fieldName}" /> | |
21 | + <#elseif po.classType=='switch'> | |
22 | + <#if query_field_no gt 1> </#if><j-switch placeholder="请选择${po.filedComment}" v-model:value="queryParam.${po.fieldName}" <#if po.dictField!= 'is_open'>:options="${po.dictField}"</#if> query /> | |
23 | + <#elseif po.classType=='sel_depart'> | |
24 | + <#if query_field_no gt 1> </#if><j-select-dept placeholder="请选择${po.filedComment}" v-model:value="queryParam.${po.fieldName}" checkStrictly /> | |
25 | + <#elseif po.classType=='list_multi'> | |
26 | + <#if query_field_no gt 1> </#if><j-select-multiple placeholder="请选择${po.filedComment}" dictCode="${query_field_dictCode?default("")}" v-model:value="queryParam.${po.fieldName}" /> | |
27 | + <#elseif po.classType=='cat_tree'> | |
28 | + <#if query_field_no gt 1> </#if><j-category-select placeholder="请选择${po.filedComment}" v-model:value="queryParam.${po.fieldName}" pcode="${po.dictField?default("")}" @change="(value) => handleFormChange('${po.fieldName}', value)" /> | |
29 | + <#elseif po.classType=='date'> | |
30 | + <#if query_field_no gt 1> </#if><a-date-picker valueFormat="YYYY-MM-DD" placeholder="请选择${po.filedComment}" v-model:value="queryParam.${po.fieldName}" /> | |
31 | + <#elseif po.classType=='datetime'> | |
32 | + <#if query_field_no gt 1> </#if><a-date-picker showTime valueFormat="YYYY-MM-DD HH:mm:ss" placeholder="请选择${po.filedComment}" v-model:value="queryParam.${po.fieldName}" /> | |
33 | + <#elseif po.classType=='pca'> | |
34 | + <#if query_field_no gt 1> </#if><j-area-linkage v-model:value="queryParam.${po.fieldName}" placeholder="请选择${po.filedComment}" @change="(value) => handleAreaChange('${po.fieldName}', value)" /> | |
35 | + <#elseif po.classType=='sel_tree'> | |
36 | + <#if query_field_no gt 1> </#if><j-tree-select v-model:value="queryParam.${po.fieldName}" placeholder="请选择${po.filedComment}" <#if po.dictText??><#if po.dictText?split(',')[2]?? && po.dictText?split(',')[0]??>dict="${po.dictTable},${po.dictText?split(',')[2]},${po.dictText?split(',')[0]}" <#elseif po.dictText?split(',')[1]??>pidField:"${po.dictText?split(',')[1]}", <#elseif po.dictText?split(',')[3]??>hasChildField:"${po.dictText?split(',')[3]}"</#if> </#if>pidValue="${po.dictField}" /> | |
37 | + <#elseif po.classType=='popup'> | |
38 | + <#assign sourceFields = po.dictField?default("")?trim?split(",")/> | |
39 | + <#assign targetFields = po.dictText?default("")?trim?split(",")/> | |
40 | + <#if query_field_no gt 1> </#if><j-popup | |
41 | + <#if query_field_no gt 1> </#if>placeholder="请选择${po.filedComment}" | |
42 | + <#if query_field_no gt 1> </#if>v-model:value="queryParam.${po.fieldName}" | |
43 | + <#if query_field_no gt 1> </#if>code="${po.dictTable}" | |
44 | + <#if query_field_no gt 1> </#if>:fieldConfig="[ | |
45 | + <#list sourceFields as fieldName> | |
46 | + <#if query_field_no gt 1> </#if>{ source: '${fieldName}', target: '${targetFields[fieldName_index]}' }, | |
47 | + </#list> | |
48 | + <#if query_field_no gt 1> </#if>]" | |
49 | + <#if query_field_no gt 1> </#if>:multi="${po.extendParams.popupMulti?c}" | |
50 | + <#if query_field_no gt 1> </#if>:setFieldsValue="setFieldsValue" /> | |
51 | + <#elseif po.classType=='list' || po.classType=='radio' || po.classType=='checkbox'> | |
52 | + <#-- ---------------------------下拉或是单选 判断数据字典是表字典还是普通字典------------------------------- --> | |
53 | + <#if po.dictTable?default("")?trim?length gt 1> | |
54 | + <#if query_field_no gt 1> </#if><j-dict-select-tag placeholder="请选择${po.filedComment}" v-model:value="queryParam.${po.fieldName}" dictCode="${po.dictTable},${po.dictText},${po.dictField}"/> | |
55 | + <#elseif po.dictField?default("")?trim?length gt 1> | |
56 | + <#if query_field_no gt 1> </#if><j-dict-select-tag placeholder="请选择${po.filedComment}" v-model:value="queryParam.${po.fieldName}" dictCode="${po.dictField}"/> | |
57 | + <#else> | |
58 | + <#if query_field_no gt 1> </#if><a-input placeholder="请输入${po.filedComment}" v-model:value="queryParam.${po.fieldName}"></a-input> | |
59 | + </#if> | |
60 | + <#else> | |
61 | + <#if query_field_no gt 1> </#if><a-input placeholder="请输入${po.filedComment}" v-model:value="queryParam.${po.fieldName}"></a-input> | |
62 | + </#if> | |
63 | + <#if query_field_no gt 1> </#if></a-form-item> | |
64 | + <#if query_field_no gt 1> </#if></a-col> | |
65 | + <#else> | |
66 | + <#if query_field_no gt 1> </#if><a-col :lg="8"> | |
67 | + <#if query_field_no gt 1> </#if><a-form-item label="${po.filedComment}"> | |
68 | + <#if po.classType=='date'> | |
69 | + <#if query_field_no gt 1> </#if><a-date-picker value-format="YYYY-MM-DD" placeholder="请选择开始时间" v-model:value="queryParam.${po.fieldName}_begin" class="query-group-cust"/> | |
70 | + <#if query_field_no gt 1> </#if><span class="query-group-split-cust">~</span> | |
71 | + <#if query_field_no gt 1> </#if><a-date-picker value-format="YYYY-MM-DD" placeholder="请选择结束日期" v-model:value="queryParam.${po.fieldName}_end" class="query-group-cust"/> | |
72 | + <#elseif po.classType=='datetime'> | |
73 | + <#if query_field_no gt 1> </#if><a-date-picker showTime value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择开始时间" v-model:value="queryParam.${po.fieldName}_begin" class="query-group-cust" /> | |
74 | + <#if query_field_no gt 1> </#if><span class="query-group-split-cust">~</span> | |
75 | + <#if query_field_no gt 1> </#if><a-date-picker showTime value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择结束时间" v-model:value="queryParam.${po.fieldName}_end" class="query-group-cust" /> | |
76 | + <#else> | |
77 | + <#if query_field_no gt 1> </#if><a-input placeholder="请输入最小值" v-model:value="queryParam.${po.fieldName}_begin" class="query-group-cust"></a-input> | |
78 | + <#if query_field_no gt 1> </#if><span class="query-group-split-cust">~</span> | |
79 | + <#if query_field_no gt 1> </#if><a-input placeholder="请输入最大值" v-model:value="queryParam.${po.fieldName}_end" class="query-group-cust"></a-input> | |
80 | + </#if> | |
81 | + <#if query_field_no gt 1> </#if></a-form-item> | |
82 | + <#if query_field_no gt 1> </#if></a-col> | |
83 | + </#if> | |
84 | + <#assign query_field_no=query_field_no+1> | |
85 | + </#if> | |
0 | 86 | \ No newline at end of file |
... | ... |
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/form/vue3Jvxepopup.ftl
0 → 100644
1 | +<#assign sourceFields = col.dictField?default("")?trim?split(",")/> | |
2 | +<#assign targetFields = col.dictText?default("")?trim?split(",")/> | |
3 | + type: JVxeTypes.popup, | |
4 | + popupCode:"${col.dictTable}", | |
5 | + fieldConfig: [ | |
6 | + <#list sourceFields as fieldName> | |
7 | + { source: '${fieldName}', target: '${targetFields[fieldName_index]}' }, | |
8 | + </#list> | |
9 | + ], | |
10 | + <#if col.readonly=='Y'> | |
11 | + disabled:true, | |
12 | + </#if> | |
13 | + | |
... | ... |
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/form/vue3popup.ftl
0 → 100644
1 | +<#assign sourceFields = po.dictField?default("")?trim?split(",")/> | |
2 | +<#assign targetFields = po.dictText?default("")?trim?split(",")/> | |
3 | + component: 'JPopup', | |
4 | + componentProps: ({ formActionType }) => { | |
5 | + const {setFieldsValue} = formActionType; | |
6 | + return{ | |
7 | + setFieldsValue:setFieldsValue, | |
8 | + code:"${po.dictTable}", | |
9 | + fieldConfig: [ | |
10 | + <#list sourceFields as fieldName> | |
11 | + { source: '${fieldName}', target: '${targetFields[fieldName_index]}' }, | |
12 | + </#list> | |
13 | + ], | |
14 | + multi:${po.extendParams.popupMulti?c} | |
15 | + } | |
16 | + }, | |
17 | + | |
... | ... |
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/sql/menu_insert.ftl
0 → 100644
1 | +-- 注意:该页面对应的前台目录为views/${entityPackage}文件夹下 | |
2 | +-- 如果你想更改到其他目录,请修改sql中component字段对应的值 | |
3 | + | |
4 | +INSERT INTO sys_permission(id, parent_id, name, url, component, component_name, redirect, menu_type, perms, perms_type, sort_no, always_show, icon, is_route, is_leaf, keep_alive, hidden, hide_tab, description, status, del_flag, rule_flag, create_by, create_time, update_by, update_time, internal_or_external) | |
5 | +VALUES ('${.now?string["yyyyMMddhhmmSSsss"]}', NULL, '${tableVo.ftlDescription}', '/${entityPackage}/${entityName?uncap_first}List', '${entityPackage}/${entityName}List', NULL, NULL, 0, NULL, '1', 1.00, 0, NULL, 1, 1, 0, 0, 0, NULL, '1', 0, 0, 'admin', '${.now?string["yyyy-MM-dd HH:mm:ss"]}', NULL, NULL, 0); | |
0 | 6 | \ No newline at end of file |
... | ... |
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/utils.ftl
... | ... | @@ -25,7 +25,7 @@ |
25 | 25 | <#return text?uncap_first> |
26 | 26 | </#function> |
27 | 27 | <#-- 驼峰转下划线 --> |
28 | -<#function camelToDashed(str, case='normal')> | |
28 | +<#function camelToDashed(str, case='lower')> | |
29 | 29 | <#return camelToChar(str, "_", case)> |
30 | 30 | </#function> |
31 | 31 | <#----> |
... | ... | @@ -130,4 +130,44 @@ |
130 | 130 | <#return "{type:'${po.fieldDbType}',value:'${po.fieldName}',text:'${po.filedComment}'}"> |
131 | 131 | </#if> |
132 | 132 | </#if> |
133 | +</#function> | |
134 | + | |
135 | + | |
136 | +<#-- vue3 获取表单modal的宽度--> | |
137 | +<#function getModalWidth fieldRowNum> | |
138 | + <#assign modal_width = 800> | |
139 | + <#if fieldRowNum==2> | |
140 | + <#assign modal_width = 896> | |
141 | + <#elseif fieldRowNum==3> | |
142 | + <#assign modal_width = 1024> | |
143 | + <#elseif fieldRowNum==4> | |
144 | + <#assign modal_width = 1280> | |
145 | + </#if> | |
146 | + <#return modal_width> | |
147 | +</#function> | |
148 | + | |
149 | +<#-- vue3 获取表单 colspan --> | |
150 | +<#function getFormSpan fieldRowNum> | |
151 | + <#assign form_span = 24> | |
152 | + <#if fieldRowNum==2> | |
153 | + <#assign form_span = 12> | |
154 | + <#elseif fieldRowNum==3> | |
155 | + <#assign form_span = 8> | |
156 | + <#elseif fieldRowNum==4> | |
157 | + <#assign form_span = 6> | |
158 | + </#if> | |
159 | + <#return form_span> | |
160 | +</#function> | |
161 | + | |
162 | +<#-- vue3 native 判断字段名不是 pidField --> | |
163 | +<#function isNotPidField(tableVo, fieldDbName) > | |
164 | + <#assign flag = true> | |
165 | + <#if tableVo??> | |
166 | + <#if tableVo.extendParams??> | |
167 | + <#if tableVo.extendParams.pidField?default("")?trim == fieldDbName> | |
168 | + <#assign flag = false> | |
169 | + </#if> | |
170 | + </#if> | |
171 | + </#if> | |
172 | + <#return flag> | |
133 | 173 | </#function> |
134 | 174 | \ No newline at end of file |
... | ... |
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/validatorRulesTemplate/native/vue3CoreNative.ftl
0 → 100644
1 | +<#assign fieldValidType = po.fieldValidType!''> | |
2 | +<#-- 非空校验 --> | |
3 | +<#if po.nullable == 'N' || fieldValidType == '*'> | |
4 | +{ required: true, message: '请输入${po.filedComment}!'}<#rt>, | |
5 | +<#elseif fieldValidType!=''> | |
6 | +{ required: false}<#rt>, | |
7 | +</#if> | |
8 | +<#-- 唯一校验 --> | |
9 | +<#if fieldValidType == 'only'> | |
10 | + { validator: ${po.fieldName}Duplicatevalidate }<#rt> | |
11 | +<#-- 6到16位数字 --> | |
12 | +<#elseif fieldValidType == 'n6-16'> | |
13 | + { pattern: /^\d{6,16}$/, message: '请输入6到16位数字!'}<#rt>, | |
14 | +<#-- 6到16位任意字符 --> | |
15 | +<#elseif fieldValidType == '*6-16'> | |
16 | + { pattern: /^.{6,16}$/, message: '请输入6到16位任意字符!'}<#rt>, | |
17 | +<#-- 6到18位字符串 --> | |
18 | +<#elseif fieldValidType == 's6-18'> | |
19 | + { pattern: /^.{6,18}$/, message: '请输入6到18位任意字符!'}<#rt>, | |
20 | +<#-- 网址 --> | |
21 | +<#elseif fieldValidType == 'url'> | |
22 | + { pattern: /^((ht|f)tps?):\/\/[\w\-]+(\.[\w\-]+)+([\w\-.,@?^=%&:\/~+#]*[\w\-@?^=%&\/~+#])?$/, message: '请输入正确的网址!'}<#rt>, | |
23 | +<#-- 电子邮件 --> | |
24 | +<#elseif fieldValidType == 'e'> | |
25 | + { pattern: /^([\w]+\.*)([\w]+)@[\w]+\.\w{3}(\.\w{2}|)$/, message: '请输入正确的电子邮件!'}<#rt>, | |
26 | +<#-- 手机号码 --> | |
27 | +<#elseif fieldValidType == 'm'> | |
28 | + { pattern: /^1[3456789]\d{9}$/, message: '请输入正确的手机号码!'}<#rt>, | |
29 | +<#-- 邮政编码 --> | |
30 | +<#elseif fieldValidType == 'p'> | |
31 | + { pattern: /^[1-9]\d{5}$/, message: '请输入正确的邮政编码!'}<#rt>, | |
32 | +<#-- 字母 --> | |
33 | +<#elseif fieldValidType == 's'> | |
34 | + { pattern: /^[A-Z|a-z]+$/, message: '请输入字母!'}<#rt>, | |
35 | +<#-- 数字 --> | |
36 | +<#elseif fieldValidType == 'n'> | |
37 | + { pattern: /^-?\d+\.?\d*$/, message: '请输入数字!'}<#rt>, | |
38 | +<#-- 整数 --> | |
39 | +<#elseif fieldValidType == 'z'> | |
40 | + { pattern: /^-?\d+$/, message: '请输入整数!'}<#rt>, | |
41 | +<#-- 金额 --> | |
42 | +<#elseif fieldValidType == 'money'> | |
43 | + { pattern: /^(([1-9][0-9]*)|([0]\.\d{0,2}|[1-9][0-9]*\.\d{0,2}))$/, message: '请输入正确的金额!'}<#rt>, | |
44 | +<#-- 正则校验 --> | |
45 | +<#elseif fieldValidType != '' && fieldValidType != '*'> | |
46 | + { pattern: '${fieldValidType}', message: '不符合校验规则!'}<#rt>, | |
47 | +<#else> | |
48 | + <#t> | |
49 | +</#if> | |
0 | 50 | \ No newline at end of file |
... | ... |
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/validatorRulesTemplate/native/vue3MainNative.ftl
0 → 100644
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/validatorRulesTemplate/sub-vue3.ftl
0 → 100644
1 | +<#include "../utils.ftl"> | |
2 | + <#if col.isShow == 'Y' && poHasCheck(col)> | |
3 | + validateRules: [ | |
4 | + <#if col.fieldName != 'id'> | |
5 | + <#assign subFieldValidType = col.fieldValidType!''> | |
6 | + <#-- 非空校验 --> | |
7 | + <#if col.nullable == 'N' || fieldValidType == '*'> | |
8 | + { required: true, message: '${'$'}{title}不能为空' }, | |
9 | + <#elseif fieldValidType!=''> | |
10 | + { required: false}, | |
11 | + </#if> | |
12 | + <#-- 其他情况下,只要有值就被认为是正则校验 --> | |
13 | + <#if subFieldValidType?length gt 0> | |
14 | + <#assign subMessage = '格式不正确'> | |
15 | + <#if subFieldValidType == 'only' > | |
16 | + <#assign subMessage = '不能重复'> | |
17 | + </#if> | |
18 | + { pattern: "${subFieldValidType}", message: "${'$'}{title}${subMessage}" } | |
19 | + <#t> | |
20 | + </#if> | |
21 | + </#if> | |
22 | + ], | |
23 | + </#if> | |
... | ... |
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/entity/${entityName}.javai
1 | +<#include "/common/utils.ftl"> | |
1 | 2 | package ${bussiPackage}.${entityPackage}.entity; |
2 | 3 | |
3 | 4 | import java.io.Serializable; |
... | ... | @@ -36,9 +37,9 @@ public class ${entityName} implements Serializable { |
36 | 37 | <#-- 生成字典Code --> |
37 | 38 | <#assign list_field_dictCode=""> |
38 | 39 | <#if po.classType='sel_user'> |
39 | - <#assign list_field_dictCode=', dictTable = "sys_user", dicText = "realname", dicCode = "username"'> | |
40 | + <#assign list_field_dictCode=', dictTable = "sys_user", dicText = "${camelToDashed(po.extendParams.text?default(\"realname\")?trim)}", dicCode = "${camelToDashed(po.extendParams.store?default(\"username\")?trim)}"'> | |
40 | 41 | <#elseif po.classType='sel_depart'> |
41 | - <#assign list_field_dictCode=', dictTable = "sys_depart", dicText = "depart_name", dicCode = "id"'> | |
42 | + <#assign list_field_dictCode=', dictTable = "sys_depart", dicText = "${camelToDashed(po.extendParams.text?default(\"depart_name\")?trim)}", dicCode = "${camelToDashed(po.extendParams.store?default(\"id\")?trim)}"'> | |
42 | 43 | <#elseif po.classType=='list' || po.classType=='list_multi' || po.classType=='sel_search' || po.classType=='radio' || po.classType=='checkbox'> |
43 | 44 | <#if po.dictTable?default("")?trim?length gt 1> |
44 | 45 | <#assign list_field_dictCode=', dictTable = "${po.dictTable}", dicText = "${po.dictText}", dicCode = "${po.dictField}"'> |
... | ... |
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue/${entityName}_menu_insert.sql
0 → 100644
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue/modules/${entityName}Form.vuei
... | ... | @@ -48,7 +48,7 @@ |
48 | 48 | @input="popupCallback" |
49 | 49 | <#if po.readonly=='Y'>disabled</#if>/> |
50 | 50 | <#elseif po.classType =='sel_depart'> |
51 | - <j-select-depart v-model="model.${po.fieldName}" multi <#if po.readonly=='Y'>disabled</#if> /> | |
51 | + <j-select-depart v-model="model.${po.fieldName}" :multi="${po.extendParams.multi?default('true')}"<#if po.extendParams.store?default("")?trim?length gt 0> store="${po.extendParams.store}"</#if><#if po.extendParams.text?default("")?trim?length gt 0> text="${po.extendParams.text}"</#if> <#if po.readonly=='Y'>disabled</#if> /> | |
52 | 52 | <#elseif po.classType =='switch'> |
53 | 53 | <j-switch v-model="model.${po.fieldName}" <#if po.dictField != 'is_open'>:options="${po.dictField}"</#if> <#if po.readonly=='Y'>disabled</#if>></j-switch> |
54 | 54 | <#elseif po.classType =='pca'> |
... | ... | @@ -58,7 +58,7 @@ |
58 | 58 | <#elseif po.classType =='password'> |
59 | 59 | <a-input-password v-model="model.${po.fieldName}" placeholder="请输入${po.filedComment}" <#if po.readonly=='Y'>disabled</#if>/> |
60 | 60 | <#elseif po.classType =='sel_user'> |
61 | - <j-select-user-by-dep v-model="model.${po.fieldName}" <#if po.readonly=='Y'>disabled</#if>/> | |
61 | + <j-select-user-by-dep v-model="model.${po.fieldName}" :multi="${po.extendParams.multi?default('true')}"<#if po.extendParams.store?default("")?trim?length gt 0> store="${po.extendParams.store}"</#if><#if po.extendParams.text?default("")?trim?length gt 0> text="${po.extendParams.text}"</#if> <#if po.readonly=='Y'>disabled</#if>/> | |
62 | 62 | <#elseif po.classType =='textarea'> |
63 | 63 | <a-textarea v-model="model.${autoStringSuffixForModel(po)}" rows="4" placeholder="请输入${po.filedComment}" <#if po.readonly=='Y'>disabled</#if>/> |
64 | 64 | <#elseif po.classType=='list' || po.classType=='radio'> |
... | ... |
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3/${entityName}List.vuei
... | ... | @@ -46,6 +46,10 @@ |
46 | 46 | <template #htmlSlot="{text}"> |
47 | 47 | <div v-html="text"></div> |
48 | 48 | </template> |
49 | + <!--省市区字段回显插槽--> | |
50 | + <template #pcaSlot="{text}"> | |
51 | + {{ getAreaTextByCode(text) }} | |
52 | + </template> | |
49 | 53 | <template #fileSlot="{text}"> |
50 | 54 | <span v-if="!text" style="font-size: 12px;font-style: italic;">无文件</span> |
51 | 55 | <a-button v-else :ghost="true" type="primary" preIcon="ant-design:download-outlined" size="small" @click="downloadFile(text)">下载</a-button> |
... | ... | @@ -64,6 +68,10 @@ |
64 | 68 | import ${entityName}Modal from './components/${entityName}Modal.vue' |
65 | 69 | import {columns, searchFormSchema} from './${entityName}.data'; |
66 | 70 | import {list, deleteOne, batchDelete, getImportUrl,getExportUrl} from './${entityName}.api'; |
71 | + import { downloadFile } from '/@/utils/common/renderUtils'; | |
72 | + <#if list_need_pca> | |
73 | + import { getAreaTextByCode } from '/@/components/Form/src/utils/Area'; | |
74 | + </#if> | |
67 | 75 | <#if list_need_category> |
68 | 76 | import { loadCategoryData } from '/@/api/common/api' |
69 | 77 | import { getAuthCache, setAuthCache } from '/@/utils/auth'; |
... | ... | @@ -84,6 +92,17 @@ |
84 | 92 | schemas: searchFormSchema, |
85 | 93 | autoSubmitOnEnter:true, |
86 | 94 | showAdvancedButton:true, |
95 | + fieldMapToNumber: [ | |
96 | + <#list columns as po> | |
97 | + <#if po.isQuery=='Y'> | |
98 | + <#if po.queryMode!='single'> | |
99 | + <#if po.fieldDbType=='int' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'> | |
100 | + ['${po.fieldName}', ['${po.fieldName}_begin', '${po.fieldName}_end']], | |
101 | + </#if> | |
102 | + </#if> | |
103 | + </#if> | |
104 | + </#list> | |
105 | + ], | |
87 | 106 | fieldMapToTime: [ |
88 | 107 | <#list columns as po> |
89 | 108 | <#if po.isQuery=='Y'> |
... | ... | @@ -100,6 +119,7 @@ |
100 | 119 | }, |
101 | 120 | actionColumn: { |
102 | 121 | width: 120, |
122 | + fixed:'right' | |
103 | 123 | }, |
104 | 124 | }, |
105 | 125 | exportConfig: { |
... | ... |
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__data.tsi
1 | +<#include "/common/utils.ftl"> | |
1 | 2 | import {BasicColumn} from '/@/components/Table'; |
2 | 3 | import {FormSchema} from '/@/components/Table'; |
3 | 4 | import { rules} from '/@/utils/helper/validator'; |
... | ... | @@ -24,7 +25,7 @@ export const columns: BasicColumn[] = [ |
24 | 25 | slots: { customRender: 'htmlSlot' }, |
25 | 26 | <#elseif po.classType=='pca'> |
26 | 27 | dataIndex: '${po.fieldName}', |
27 | - slots: { customRender: 'pcaSlot' },//TODO 未翻译 | |
28 | + slots: { customRender: 'pcaSlot' }, | |
28 | 29 | <#elseif po.classType=='file'> |
29 | 30 | dataIndex: '${po.fieldName}', |
30 | 31 | slots: { customRender: 'fileSlot' }, |
... | ... | @@ -56,7 +57,7 @@ export const columns: BasicColumn[] = [ |
56 | 57 | return render.renderCategoryTree(text,'${po.dictField?default("")}') |
57 | 58 | }, |
58 | 59 | <#else> |
59 | - customRender: (text, record) => (text ? record['${po.dictText}'] : '') | |
60 | + customRender: ({text, record}) => (text ? record['${po.dictText}'] : '') | |
60 | 61 | </#if> |
61 | 62 | <#else> |
62 | 63 | dataIndex: '${po.fieldName}' |
... | ... | @@ -83,7 +84,7 @@ export const searchFormSchema: FormSchema[] = [ |
83 | 84 | <#if po.queryMode=='single'> |
84 | 85 | { |
85 | 86 | label: "${po.filedComment}", |
86 | - field: "${po.fieldName}", | |
87 | + field: ${autoStringSuffix(po)}, | |
87 | 88 | <#if po.classType=='sel_search'> |
88 | 89 | component: 'JSearchSelect', |
89 | 90 | componentProps:{ |
... | ... | @@ -94,17 +95,23 @@ export const searchFormSchema: FormSchema[] = [ |
94 | 95 | <#elseif po.classType=='switch'> |
95 | 96 | component: 'JSwitch', |
96 | 97 | componentProps:{ |
98 | + query:true, | |
97 | 99 | <#if po.dictField != 'is_open'> |
98 | - options:"${po.dictField}" | |
100 | + options:${po.dictField} | |
99 | 101 | </#if> |
100 | 102 | }, |
101 | 103 | <#elseif po.classType=='sel_depart'> |
102 | 104 | component: 'JSelectDept', |
103 | 105 | <#elseif po.classType=='list_multi'> |
104 | - component: 'JMultiSelectTag',//暂无该组件 | |
106 | + component: 'JSelectMultiple', | |
105 | 107 | componentProps:{ |
106 | - dictCode:"query_field_dictCode?default("")" | |
107 | - }, | |
108 | + <#if po.dictTable?default("")?trim?length gt 1> | |
109 | + dictCode:"${po.dictTable},${po.dictText},${po.dictField}", | |
110 | + <#elseif po.dictField?default("")?trim?length gt 1> | |
111 | + dictCode:"${po.dictField}", | |
112 | + </#if> | |
113 | + triggerChange: true | |
114 | + }, | |
108 | 115 | <#elseif po.classType=='cat_tree'> |
109 | 116 | component: 'JCategorySelect', |
110 | 117 | componentProps:{ |
... | ... | @@ -117,19 +124,15 @@ export const searchFormSchema: FormSchema[] = [ |
117 | 124 | componentProps: { |
118 | 125 | showTime:true |
119 | 126 | }, |
127 | + <#elseif po.classType =='time'> | |
128 | + component: 'TimePicker', | |
129 | + componentProps: { | |
130 | + valueFormat: 'HH:mm:ss' | |
131 | + }, | |
120 | 132 | <#elseif po.classType=='pca'> |
121 | 133 | component: 'JAreaLinkage', |
122 | 134 | <#elseif po.classType=='popup'> |
123 | - component: 'JPopup', | |
124 | - componentProps: ({ formActionType }) => { | |
125 | - const {setFieldsValue} = formActionType; | |
126 | - return{ | |
127 | - setFieldsValue:setFieldsValue, | |
128 | - code:"${po.dictTable}", | |
129 | - fieldConfig:"${po.dictField}", | |
130 | - multi:${po.extendParams.popupMulti?c}, | |
131 | - } | |
132 | - }, | |
135 | + <#include "/common/form/vue3popup.ftl"> | |
133 | 136 | <#elseif po.classType=='list' || po.classType=='radio' || po.classType=='checkbox'> |
134 | 137 | <#-- ---------------------------下拉或是单选 判断数据字典是表字典还是普通字典------------------------------- --> |
135 | 138 | component: 'JDictSelectTag', |
... | ... | @@ -156,6 +159,8 @@ export const searchFormSchema: FormSchema[] = [ |
156 | 159 | componentProps: { |
157 | 160 | showTime:true |
158 | 161 | }, |
162 | +<#elseif po.fieldDbType=='int' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'> | |
163 | + component: 'JRangeNumber', | |
159 | 164 | <#else> |
160 | 165 | component: 'Input', //TODO 范围查询 |
161 | 166 | </#if> |
... | ... | @@ -188,27 +193,22 @@ export const formSchema: FormSchema[] = [ |
188 | 193 | </#if> |
189 | 194 | { |
190 | 195 | label: '${po.filedComment}', |
191 | - field: '${po.fieldName}', | |
196 | + field: ${autoStringSuffix(po)}, | |
192 | 197 | <#if po.classType =='date'> |
193 | 198 | component: 'DatePicker', |
194 | - <#elseif po.fieldType =='datetime'> | |
199 | + <#elseif po.classType =='datetime'> | |
195 | 200 | component: 'DatePicker', |
196 | 201 | componentProps: { |
197 | - showTime:true | |
202 | + showTime: true, | |
203 | + valueFormat: 'YYYY-MM-DD HH:mm:ss' | |
198 | 204 | }, |
199 | - <#elseif po.fieldType =='time'> | |
205 | + <#elseif po.classType =='time'> | |
200 | 206 | component: 'TimePicker', |
207 | + componentProps: { | |
208 | + valueFormat: 'HH:mm:ss' | |
209 | + }, | |
201 | 210 | <#elseif po.classType =='popup'> |
202 | - component: 'JPopup', | |
203 | - componentProps: ({ formActionType }) => { | |
204 | - const {setFieldsValue} = formActionType; | |
205 | - return{ | |
206 | - setFieldsValue:setFieldsValue, | |
207 | - code:"${po.dictTable}", | |
208 | - fieldConfig:${po.dictField}, | |
209 | - multi:${po.extendParams.popupMulti?c}, | |
210 | - } | |
211 | - }, | |
211 | + <#include "/common/form/vue3popup.ftl"> | |
212 | 212 | <#elseif po.classType =='sel_depart'> |
213 | 213 | component: 'JSelectDept', |
214 | 214 | <#elseif po.classType =='switch'> |
... | ... | @@ -230,14 +230,14 @@ export const formSchema: FormSchema[] = [ |
230 | 230 | labelKey:'realname', |
231 | 231 | }, |
232 | 232 | <#elseif po.classType =='textarea'> |
233 | - component: 'InputTextArea',//TODO 注意string转换问题 | |
233 | + component: 'InputTextArea', | |
234 | 234 | <#elseif po.classType=='list' || po.classType=='radio'> |
235 | 235 | component: 'JDictSelectTag', |
236 | 236 | componentProps:{ |
237 | 237 | dictCode:"${form_field_dictCode}" |
238 | 238 | }, |
239 | 239 | <#elseif po.classType=='list_multi' || po.classType=='checkbox'> |
240 | - component: 'JMultiSelectTag',//TODO 暂无该组件 | |
240 | + component: 'JSelectMultiple', | |
241 | 241 | componentProps:{ |
242 | 242 | dictCode:"${form_field_dictCode}" |
243 | 243 | }, |
... | ... | @@ -272,7 +272,7 @@ export const formSchema: FormSchema[] = [ |
272 | 272 | </#if> |
273 | 273 | }, |
274 | 274 | <#elseif po.classType=='umeditor'> |
275 | - component: 'JCodeEditor', //TODO String后缀暂未添加 | |
275 | + component: 'JEditor', | |
276 | 276 | <#elseif po.classType == 'sel_tree'> |
277 | 277 | component: 'JTreeSelect', |
278 | 278 | componentProps:{ |
... | ... | @@ -290,7 +290,6 @@ export const formSchema: FormSchema[] = [ |
290 | 290 | <#else> |
291 | 291 | component: 'Input', |
292 | 292 | </#if> |
293 | - <#include "/common/utils.ftl"> | |
294 | 293 | <#if po.isShow == 'Y' && poHasCheck(po)> |
295 | 294 | dynamicRules: ({model,schema}) => { |
296 | 295 | <#if po.fieldName != 'id'> |
... | ... | @@ -304,16 +303,16 @@ export const formSchema: FormSchema[] = [ |
304 | 303 | </#if> |
305 | 304 | <#-- 唯一校验 --> |
306 | 305 | <#if fieldValidType == 'only'> |
307 | - {...rules.duplicateCheckRule(<#if sub?default("")?trim?length gt 1>'${sub.tableName}'<#else>'${tableName}'</#if>, '${po.fieldDbName}',model,schema,true)[0]}, | |
306 | + {...rules.duplicateCheckRule(<#if sub?default("")?trim?length gt 1>'${sub.tableName}'<#else>'${tableName}'</#if>, '${po.fieldDbName}',model,schema)[0]}, | |
308 | 307 | <#-- 6到16位数字 --> |
309 | 308 | <#elseif fieldValidType == 'n6-16'> |
310 | 309 | { pattern: /^\d{6,16}$/, message: '请输入6到16位数字!'}, |
311 | 310 | <#-- 6到16位任意字符 --> |
312 | 311 | <#elseif fieldValidType == '*6-16'> |
313 | 312 | { pattern: /^.{6,16}$/, message: '请输入6到16位任意字符!'}, |
314 | - <#-- 6到18位字符串 --> | |
313 | + <#-- 6到18位字母 --> | |
315 | 314 | <#elseif fieldValidType == 's6-18'> |
316 | - { pattern: /^.{6,18}$/, message: '请输入6到18位任意字符!'}, | |
315 | + { pattern: /^[a-z|A-Z]{6,18}$/, message: '请输入6到18位字母!'}, | |
317 | 316 | <#-- 网址 --> |
318 | 317 | <#elseif fieldValidType == 'url'> |
319 | 318 | { pattern: /^((ht|f)tps?):\/\/[\w\-]+(\.[\w\-]+)+([\w\-.,@?^=%&:\/~+#]*[\w\-@?^=%&\/~+#])?$/, message: '请输入正确的网址!'}, |
... | ... |
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3/${entityName}_menu_insert.sql
0 → 100644
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3/components/${entityName}Modal.vuei
1 | +<#include "/common/utils.ftl"> | |
1 | 2 | <template> |
2 | - <BasicModal v-bind="$attrs" @register="registerModal" :title="title" @ok="handleSubmit"> | |
3 | + <BasicModal v-bind="$attrs" @register="registerModal" destroyOnClose :title="title" :width="${getModalWidth(tableVo.fieldRowNum?default(1))}" @ok="handleSubmit"> | |
3 | 4 | <BasicForm @register="registerForm"/> |
4 | 5 | </BasicModal> |
5 | 6 | </template> |
... | ... | @@ -18,6 +19,7 @@ |
18 | 19 | labelWidth: 150, |
19 | 20 | schemas: formSchema, |
20 | 21 | showActionButtonGroup: false, |
22 | + baseColProps: {span: ${getFormSpan(tableVo.fieldRowNum?default(1))}} | |
21 | 23 | }); |
22 | 24 | //表单赋值 |
23 | 25 | const [registerModal, {setModalProps, closeModal}] = useModalInner(async (data) => { |
... | ... | @@ -54,5 +56,12 @@ |
54 | 56 | </script> |
55 | 57 | |
56 | 58 | <style lang="less" scoped> |
59 | + /** 时间和数字输入框样式 */ | |
60 | + :deep(.ant-input-number){ | |
61 | + width: 100% | |
62 | + } | |
57 | 63 | |
64 | + :deep(.ant-calendar-picker){ | |
65 | + width: 100% | |
66 | + } | |
58 | 67 | </style> |
59 | 68 | \ No newline at end of file |
... | ... |
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}List.vuei
0 → 100644
1 | +<template> | |
2 | + <div> | |
3 | +<#assign query_field_no=0> | |
4 | +<#assign need_category = false> | |
5 | +<#assign need_pca = false> | |
6 | +<#assign need_search = false> | |
7 | +<#assign need_dept_user = false> | |
8 | +<#assign need_switch = false> | |
9 | +<#assign need_dept = false> | |
10 | +<#assign need_multi = false> | |
11 | +<#assign need_popup = false> | |
12 | +<#assign need_select_tag = false> | |
13 | +<#assign need_select_tree = false> | |
14 | +<#assign need_time = false> | |
15 | +<#assign bpm_flag=false> | |
16 | +<#assign need_markdown = false> | |
17 | +<#assign need_upload = false> | |
18 | +<#assign need_image_upload = false> | |
19 | +<#assign need_editor = false> | |
20 | +<#assign need_checkbox = false> | |
21 | +<#assign query_flag = false> | |
22 | + <!--查询区域--> | |
23 | + <div class="jeecg-basic-table-form-container"> | |
24 | + <a-form @keyup.enter.native="searchQuery" :model="queryParam" :label-col="labelCol" :wrapper-col="wrapperCol"> | |
25 | + <a-row :gutter="24"> | |
26 | +<#-- 开始循环 --> | |
27 | +<#list columns as po> | |
28 | +<#if po.fieldDbName=='bpm_status'> | |
29 | + <#assign bpm_flag=true> | |
30 | +</#if> | |
31 | +<#if po.classType=='cat_tree' && po.dictText?default("")?trim?length == 0> | |
32 | +<#assign need_category=true> | |
33 | +</#if> | |
34 | +<#if po.classType=='pca'> | |
35 | +<#assign need_pca=true> | |
36 | +</#if> | |
37 | +<#if po.classType=='sel_search'> | |
38 | +<#assign need_search = true> | |
39 | +</#if> | |
40 | +<#if po.classType=='sel_user'> | |
41 | +<#assign need_dept_user = true> | |
42 | +</#if> | |
43 | +<#if po.classType=='sel_depart'> | |
44 | +<#assign need_dept = true> | |
45 | +</#if> | |
46 | +<#if po.classType=='switch'> | |
47 | +<#assign need_switch = true> | |
48 | +</#if> | |
49 | +<#if po.classType=='list_multi'> | |
50 | +<#assign need_multi = true> | |
51 | +</#if> | |
52 | +<#if po.classType=='popup'> | |
53 | +<#assign need_popup = true> | |
54 | +</#if> | |
55 | +<#if po.classType=='sel_tree'> | |
56 | +<#assign need_select_tree = true> | |
57 | +</#if> | |
58 | +<#if po.classType=='time'> | |
59 | +<#assign need_time = true> | |
60 | +</#if> | |
61 | + <#include "/common/form/native/vue3NativeSearch.ftl"> | |
62 | +</#list> | |
63 | +<#if query_field_no gt 2> | |
64 | + </template> | |
65 | +</#if> | |
66 | +<#if query_flag> | |
67 | + <a-col :xl="6" :lg="7" :md="8" :sm="24"> | |
68 | + <span style="float: left; overflow: hidden" class="table-page-search-submitButtons"> | |
69 | + <a-col :lg="6"> | |
70 | + <a-button type="primary" preIcon="ant-design:search-outlined" @click="searchQuery">查询</a-button> | |
71 | + <a-button type="primary" preIcon="ant-design:reload-outlined" @click="searchReset" style="margin-left: 8px">重置</a-button> | |
72 | + <a @click="toggleSearchStatus = !toggleSearchStatus" style="margin-left: 8px"> | |
73 | + {{ toggleSearchStatus ? '收起' : '展开' }} | |
74 | + <Icon :icon="toggleSearchStatus ? 'ant-design:up-outlined' : 'ant-design:down-outlined'" /> | |
75 | + </a> | |
76 | + </a-col> | |
77 | + </span> | |
78 | + </a-col> | |
79 | +</#if> | |
80 | + </a-row> | |
81 | + </a-form> | |
82 | + </div> | |
83 | +<#-- 结束循环 --> | |
84 | + <!--引用表格--> | |
85 | + <BasicTable @register="registerTable" :rowSelection="rowSelection"> | |
86 | + <!--插槽:table标题--> | |
87 | + <template #tableTitle> | |
88 | + <a-button type="primary" @click="handleAdd" preIcon="ant-design:plus-outlined"> 新增</a-button> | |
89 | + <a-button type="primary" preIcon="ant-design:export-outlined" @click="onExportXls"> 导出</a-button> | |
90 | + <j-upload-button type="primary" preIcon="ant-design:import-outlined" @click="onImportXls">导入</j-upload-button> | |
91 | + <a-dropdown v-if="selectedRowKeys.length > 0"> | |
92 | + <template #overlay> | |
93 | + <a-menu> | |
94 | + <a-menu-item key="1" @click="batchHandleDelete"> | |
95 | + <Icon icon="ant-design:delete-outlined"></Icon> | |
96 | + 删除 | |
97 | + </a-menu-item> | |
98 | + </a-menu> | |
99 | + </template> | |
100 | + <a-button>批量操作 | |
101 | + <Icon icon="mdi:chevron-down"></Icon> | |
102 | + </a-button> | |
103 | + </a-dropdown> | |
104 | + </template> | |
105 | + <!--操作栏--> | |
106 | + <template #action="{ record }"> | |
107 | + <TableAction :actions="getTableAction(record)" :dropDownActions="getDropDownAction(record)"/> | |
108 | + </template> | |
109 | + <!--字段回显插槽--> | |
110 | + <template #htmlSlot="{text}"> | |
111 | + <div v-html="text"></div> | |
112 | + </template> | |
113 | + <!--省市区字段回显插槽--> | |
114 | + <template #pcaSlot="{text}"> | |
115 | + {{ getAreaTextByCode(text) }} | |
116 | + </template> | |
117 | + <template #fileSlot="{text}"> | |
118 | + <span v-if="!text" style="font-size: 12px;font-style: italic;">无文件</span> | |
119 | + <a-button v-else :ghost="true" type="primary" preIcon="ant-design:download-outlined" size="small" @click="downloadFile(text)">下载</a-button> | |
120 | + </template> | |
121 | + </BasicTable> | |
122 | + <!-- 表单区域 --> | |
123 | + <${entityName}Modal ref="registerModal" @success="handleSuccess"></${entityName}Modal> | |
124 | + </div> | |
125 | +</template> | |
126 | + | |
127 | +<script lang="ts" name="${entityPackage}-${entityName?uncap_first}" setup> | |
128 | + import { ref, reactive } from 'vue'; | |
129 | + import { BasicTable, useTable, TableAction } from '/@/components/Table'; | |
130 | + import { useListPage } from '/@/hooks/system/useListPage'; | |
131 | + import { columns } from './${entityName}.data'; | |
132 | + import { list, deleteOne, batchDelete, getImportUrl, getExportUrl } from './${entityName}.api'; | |
133 | + import { downloadFile } from '/@/utils/common/renderUtils'; | |
134 | + import ${entityName}Modal from './components/${entityName}Modal.vue' | |
135 | + <#include "/common/form/native/vue3NativeImport.ftl"> | |
136 | +<#if need_category> | |
137 | + import { loadCategoryData } from '/@/api/common/api'; | |
138 | + import { getAuthCache, setAuthCache } from '/@/utils/auth'; | |
139 | + import { DB_DICT_DATA_KEY } from '/@/enums/cacheEnum'; | |
140 | +</#if> | |
141 | +<#if need_pca> | |
142 | + import { getAreaTextByCode } from '/@/components/Form/src/utils/Area'; | |
143 | +</#if> | |
144 | + | |
145 | + const queryParam = ref<any>({}); | |
146 | + const toggleSearchStatus = ref<boolean>(false); | |
147 | + const registerModal = ref(); | |
148 | + //注册table数据 | |
149 | + const { prefixCls, tableContext, onExportXls, onImportXls } = useListPage({ | |
150 | + tableProps: { | |
151 | + title: '${tableVo.ftlDescription}', | |
152 | + api: list, | |
153 | + columns, | |
154 | + canResize:false, | |
155 | + useSearchForm: false, | |
156 | + actionColumn: { | |
157 | + width: 120, | |
158 | + fixed: 'right', | |
159 | + }, | |
160 | + beforeFetch: (params) => { | |
161 | + return Object.assign(params, queryParam.value); | |
162 | + }, | |
163 | + }, | |
164 | + exportConfig: { | |
165 | + name: "${tableVo.ftlDescription}", | |
166 | + url: getExportUrl, | |
167 | + }, | |
168 | + importConfig: { | |
169 | + url: getImportUrl, | |
170 | + success: handleSuccess | |
171 | + }, | |
172 | + }); | |
173 | + const [registerTable, { reload, collapseAll, updateTableDataRecord, findTableDataRecord, getDataSource }, { rowSelection, selectedRowKeys }] = tableContext; | |
174 | + const labelCol = reactive({ | |
175 | + xs: { span: 24 }, | |
176 | + sm: { span: 7 }, | |
177 | + }); | |
178 | + const wrapperCol = reactive({ | |
179 | + xs: { span: 24 }, | |
180 | + sm: { span: 16 }, | |
181 | + }); | |
182 | + | |
183 | + /** | |
184 | + * 新增事件 | |
185 | + */ | |
186 | + function handleAdd() { | |
187 | + registerModal.value.disableSubmit = false; | |
188 | + registerModal.value.add(); | |
189 | + } | |
190 | + | |
191 | + /** | |
192 | + * 编辑事件 | |
193 | + */ | |
194 | + function handleEdit(record: Recordable) { | |
195 | + registerModal.value.disableSubmit = false; | |
196 | + registerModal.value.edit(record); | |
197 | + } | |
198 | + | |
199 | + /** | |
200 | + * 详情 | |
201 | + */ | |
202 | + function handleDetail(record: Recordable) { | |
203 | + registerModal.value.disableSubmit = true; | |
204 | + registerModal.value.edit(record); | |
205 | + } | |
206 | + | |
207 | + /** | |
208 | + * 删除事件 | |
209 | + */ | |
210 | + async function handleDelete(record) { | |
211 | + await deleteOne({ id: record.id }, handleSuccess); | |
212 | + } | |
213 | + | |
214 | + /** | |
215 | + * 批量删除事件 | |
216 | + */ | |
217 | + async function batchHandleDelete() { | |
218 | + await batchDelete({ ids: selectedRowKeys.value }, handleSuccess); | |
219 | + } | |
220 | + | |
221 | + /** | |
222 | + * 成功回调 | |
223 | + */ | |
224 | + function handleSuccess() { | |
225 | + (selectedRowKeys.value = []) && reload(); | |
226 | + } | |
227 | + | |
228 | + /** | |
229 | + * 操作栏 | |
230 | + */ | |
231 | + function getTableAction(record) { | |
232 | + return [ | |
233 | + { | |
234 | + label: '编辑', | |
235 | + onClick: handleEdit.bind(null, record), | |
236 | + }, | |
237 | + ]; | |
238 | + } | |
239 | + | |
240 | + /** | |
241 | + * 下拉操作栏 | |
242 | + */ | |
243 | + function getDropDownAction(record) { | |
244 | + return [ | |
245 | + { | |
246 | + label: '详情', | |
247 | + onClick: handleDetail.bind(null, record), | |
248 | + }, | |
249 | + { | |
250 | + label: '删除', | |
251 | + popConfirm: { | |
252 | + title: '是否确认删除', | |
253 | + confirm: handleDelete.bind(null, record), | |
254 | + }, | |
255 | + }, | |
256 | + ]; | |
257 | + } | |
258 | + | |
259 | + /** | |
260 | + * 查询 | |
261 | + */ | |
262 | + function searchQuery() { | |
263 | + reload(); | |
264 | + } | |
265 | + | |
266 | + /** | |
267 | + * 重置 | |
268 | + */ | |
269 | + function searchReset() { | |
270 | + queryParam.value = {}; | |
271 | + selectedRowKeys.value = []; | |
272 | + //刷新数据 | |
273 | + reload(); | |
274 | + } | |
275 | + | |
276 | + <#if need_popup> | |
277 | + /** | |
278 | + * popup组件值改变事件 | |
279 | + */ | |
280 | + function setFieldsValue(map) { | |
281 | + Object.keys(map).map((key) => { | |
282 | + queryParam.value[key] = map[key]; | |
283 | + }); | |
284 | + } | |
285 | + </#if> | |
286 | + | |
287 | + <#if need_pca> | |
288 | + /** | |
289 | + * 省市区点击事件 | |
290 | + * @param key | |
291 | + * @param value | |
292 | + */ | |
293 | + function handleAreaChange(key, value) { | |
294 | + queryParam.value[key] = value.join(','); | |
295 | + } | |
296 | + </#if> | |
297 | + | |
298 | + <#if need_category> | |
299 | + /** | |
300 | + * form点击事件 | |
301 | + * @param value | |
302 | + */ | |
303 | + function handleFormChange(key, value) { | |
304 | + queryParam.value[key] = value; | |
305 | + } | |
306 | + | |
307 | + /** | |
308 | + * 初始化字典配置 | |
309 | + */ | |
310 | + function initDictConfig() { | |
311 | + <#list columns as po> | |
312 | + <#if (po.isQuery=='Y' || po.isShowList=='Y') && po.classType!='popup'> | |
313 | + <#if po.classType=='cat_tree' && need_category==true> | |
314 | + loadCategoryData({code:'${po.dictField?default("")}'}).then((res) => { | |
315 | + if (res) { | |
316 | + let allDictDate = getAuthCache(DB_DICT_DATA_KEY); | |
317 | + if(!allDictDate['${po.dictField?default("")}']){ | |
318 | + Object.assign(allDictDate,{'${po.dictField?default("")}':res}) | |
319 | + } | |
320 | + setAuthCache(DB_DICT_DATA_KEY,allDictDate) | |
321 | + } | |
322 | + }); | |
323 | + </#if> | |
324 | + </#if> | |
325 | + </#list> | |
326 | + } | |
327 | + initDictConfig(); | |
328 | + </#if> | |
329 | +</script> | |
330 | + | |
331 | +<style lang="less" scoped> | |
332 | + .jeecg-basic-table-form-container { | |
333 | + .table-page-search-submitButtons { | |
334 | + display: block; | |
335 | + margin-bottom: 24px; | |
336 | + white-space: nowrap; | |
337 | + } | |
338 | + .query-group-cust{ | |
339 | + width: calc(50% - 15px); | |
340 | + min-width: 100px !important; | |
341 | + } | |
342 | + .query-group-split-cust{ | |
343 | + width: 30px; | |
344 | + display: inline-block; | |
345 | + text-align: center | |
346 | + } | |
347 | + } | |
348 | +</style> | |
... | ... |
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}__api.tsi
0 → 100644
1 | +import { defHttp } from '/@/utils/http/axios'; | |
2 | +import { Modal } from 'ant-design-vue'; | |
3 | + | |
4 | +enum Api { | |
5 | + list = '/${entityPackage}/${entityName?uncap_first}/list', | |
6 | + save='/${entityPackage}/${entityName?uncap_first}/add', | |
7 | + edit='/${entityPackage}/${entityName?uncap_first}/edit', | |
8 | + deleteOne = '/${entityPackage}/${entityName?uncap_first}/delete', | |
9 | + deleteBatch = '/${entityPackage}/${entityName?uncap_first}/deleteBatch', | |
10 | + importExcel = '/${entityPackage}/${entityName?uncap_first}/importExcel', | |
11 | + exportXls = '/${entityPackage}/${entityName?uncap_first}/exportXls', | |
12 | +} | |
13 | + | |
14 | +/** | |
15 | + * 导出api | |
16 | + * @param params | |
17 | + */ | |
18 | +export const getExportUrl = Api.exportXls; | |
19 | + | |
20 | +/** | |
21 | + * 导入api | |
22 | + */ | |
23 | +export const getImportUrl = Api.importExcel; | |
24 | + | |
25 | +/** | |
26 | + * 列表接口 | |
27 | + * @param params | |
28 | + */ | |
29 | +export const list = (params) => defHttp.get({ url: Api.list, params }); | |
30 | + | |
31 | +/** | |
32 | + * 删除单个 | |
33 | + * @param params | |
34 | + * @param handleSuccess | |
35 | + */ | |
36 | +export const deleteOne = (params,handleSuccess) => { | |
37 | + return defHttp.delete({url: Api.deleteOne, params}, {joinParamsToUrl: true}).then(() => { | |
38 | + handleSuccess(); | |
39 | + }); | |
40 | +} | |
41 | + | |
42 | +/** | |
43 | + * 批量删除 | |
44 | + * @param params | |
45 | + * @param handleSuccess | |
46 | + */ | |
47 | +export const batchDelete = (params, handleSuccess) => { | |
48 | + Modal.confirm({ | |
49 | + title: '确认删除', | |
50 | + content: '是否删除选中数据', | |
51 | + okText: '确认', | |
52 | + cancelText: '取消', | |
53 | + onOk: () => { | |
54 | + return defHttp.delete({url: Api.deleteBatch, data: params}, {joinParamsToUrl: true}).then(() => { | |
55 | + handleSuccess(); | |
56 | + }); | |
57 | + } | |
58 | + }); | |
59 | +} | |
60 | + | |
61 | +/** | |
62 | + * 保存或者更新 | |
63 | + * @param params | |
64 | + * @param isUpdate | |
65 | + */ | |
66 | +export const saveOrUpdate = (params, isUpdate) => { | |
67 | + let url = isUpdate ? Api.edit : Api.save; | |
68 | + return defHttp.post({ url: url, params }, { isTransformResponse: false }); | |
69 | +} | |
... | ... |
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}__data.tsi
0 → 100644
1 | +<#include "/common/utils.ftl"> | |
2 | +import {BasicColumn} from '/@/components/Table'; | |
3 | +import {FormSchema} from '/@/components/Table'; | |
4 | +import { rules} from '/@/utils/helper/validator'; | |
5 | +import { render } from '/@/utils/common/renderUtils'; | |
6 | +//列表数据 | |
7 | +export const columns: BasicColumn[] = [ | |
8 | + <#list columns as po> | |
9 | + <#if po.isShowList =='Y' && po.fieldName !='id'> | |
10 | + { | |
11 | + title: '${po.filedComment}', | |
12 | + align: "center", | |
13 | + <#if po.sort=='Y'> | |
14 | + sorter: true, | |
15 | + </#if> | |
16 | + <#if po.classType=='date'> | |
17 | + dataIndex: '${po.fieldName}', | |
18 | + customRender:({text}) =>{ | |
19 | + return !text?"":(text.length>10?text.substr(0,10):text); | |
20 | + }, | |
21 | + <#elseif po.fieldDbType=='Blob'> | |
22 | + dataIndex: '${po.fieldName}String' | |
23 | + <#elseif po.classType=='umeditor'> | |
24 | + dataIndex: '${po.fieldName}', | |
25 | + slots: { customRender: 'htmlSlot' }, | |
26 | + <#elseif po.classType=='pca'> | |
27 | + dataIndex: '${po.fieldName}', | |
28 | + slots: { customRender: 'pcaSlot' }, | |
29 | + <#elseif po.classType=='file'> | |
30 | + dataIndex: '${po.fieldName}', | |
31 | + slots: { customRender: 'fileSlot' }, | |
32 | + <#elseif po.classType=='image'> | |
33 | + dataIndex: '${po.fieldName}', | |
34 | + customRender: render.renderImage, | |
35 | + <#elseif po.classType=='switch'> | |
36 | + dataIndex: '${po.fieldName}', | |
37 | +<#assign switch_extend_arr=['Y','N']> | |
38 | +<#if po.dictField?default("")?contains("[")> | |
39 | +<#assign switch_extend_arr=po.dictField?eval> | |
40 | +</#if> | |
41 | +<#list switch_extend_arr as a> | |
42 | +<#if a_index == 0> | |
43 | +<#assign switch_extend_arr1=a> | |
44 | +<#else> | |
45 | +<#assign switch_extend_arr2=a> | |
46 | +</#if> | |
47 | +</#list> | |
48 | + customRender:({text}) => { | |
49 | + return render.renderSwitch(text, [{text:'是',value:'${switch_extend_arr1}'},{text:'否',value:'${switch_extend_arr2}'}]); | |
50 | + }, | |
51 | + <#elseif po.classType == 'sel_tree' || po.classType=='list' || po.classType=='list_multi' || po.classType=='sel_search' || po.classType=='radio' || po.classType=='checkbox' || po.classType=='sel_depart' || po.classType=='sel_user'> | |
52 | + dataIndex: '${po.fieldName}_dictText' | |
53 | + <#elseif po.classType=='cat_tree'> | |
54 | + dataIndex: '${po.fieldName}', | |
55 | + <#if po.dictText?default("")?trim?length == 0> | |
56 | + customRender:({text}) => { | |
57 | + return render.renderCategoryTree(text,'${po.dictField?default("")}'); | |
58 | + }, | |
59 | + <#else> | |
60 | + customRender: ({text, record}) => (text ? record['${po.dictText}'] : ''); | |
61 | + </#if> | |
62 | + <#else> | |
63 | + dataIndex: '${po.fieldName}' | |
64 | + </#if> | |
65 | + }, | |
66 | + </#if> | |
67 | + </#list> | |
68 | +]; | |
69 | + | |
70 | +//查询数据 | |
71 | +export const searchFormSchema: FormSchema[] = [ | |
72 | +<#-- 开始循环 --> | |
73 | +<#list columns as po> | |
74 | +<#if po.fieldDbName=='bpm_status'> | |
75 | + <#assign bpm_flag=true> | |
76 | +</#if> | |
77 | +<#if po.isQuery=='Y'> | |
78 | +<#assign query_flag=true> | |
79 | + <#assign query_field_dictCode=""> | |
80 | + <#if po.dictTable?default("")?trim?length gt 1> | |
81 | + <#assign query_field_dictCode="${po.dictTable},${po.dictText},${po.dictField}"> | |
82 | + <#elseif po.dictField?default("")?trim?length gt 1> | |
83 | + <#assign query_field_dictCode="${po.dictField}"> | |
84 | + </#if> | |
85 | +<#if po.queryMode=='single'> | |
86 | + { | |
87 | + label: "${po.filedComment}", | |
88 | + field: ${autoStringSuffix(po)}, | |
89 | +<#if po.classType=='sel_search'> | |
90 | + component: 'JSearchSelect', | |
91 | + componentProps:{ | |
92 | + dict: "${po.dictTable},${po.dictText},${po.dictField}" | |
93 | + }, | |
94 | +<#elseif po.classType=='sel_user'> | |
95 | + component: 'JSelectUserByDept', | |
96 | +<#elseif po.classType=='switch'> | |
97 | + component: 'JSwitch', | |
98 | + componentProps:{ | |
99 | + <#if po.dictField != 'is_open'> | |
100 | + options: "${po.dictField}" | |
101 | + </#if> | |
102 | + }, | |
103 | + <#elseif po.classType=='sel_depart'> | |
104 | + component: 'JSelectDept', | |
105 | + <#elseif po.classType=='list_multi'> | |
106 | + component: 'JSelectMultiple', | |
107 | + componentProps: { | |
108 | + <#if po.dictTable?default("")?trim?length gt 1> | |
109 | + dictCode: "${po.dictTable},${po.dictText},${po.dictField}" | |
110 | + <#elseif po.dictField?default("")?trim?length gt 1> | |
111 | + dictCode: "${po.dictField}" | |
112 | + </#if> | |
113 | + }, | |
114 | + <#elseif po.classType=='cat_tree'> | |
115 | + component: 'JCategorySelect', | |
116 | + componentProps:{ | |
117 | + pcode: "${po.dictField?default("")}",//back和事件未添加,暂时有问题 | |
118 | + }, | |
119 | +<#elseif po.classType=='date'> | |
120 | + component: 'DatePicker', | |
121 | +<#elseif po.classType=='datetime'> | |
122 | + component: 'DatePicker', | |
123 | + componentProps: { | |
124 | + showTime: true, | |
125 | + }, | |
126 | + <#elseif po.classType =='time'> | |
127 | + component: 'TimePicker', | |
128 | + componentProps: { | |
129 | + valueFormat: 'HH:mm:ss', | |
130 | + }, | |
131 | +<#elseif po.classType=='pca'> | |
132 | + component: 'JAreaLinkage', | |
133 | +<#elseif po.classType=='popup'> | |
134 | + <#include "/common/form/vue3popup.ftl"> | |
135 | +<#elseif po.classType=='list' || po.classType=='radio' || po.classType=='checkbox'> | |
136 | +<#-- ---------------------------下拉或是单选 判断数据字典是表字典还是普通字典------------------------------- --> | |
137 | + component: 'JDictSelectTag', | |
138 | + componentProps:{ | |
139 | + <#if po.dictTable?default("")?trim?length gt 1> | |
140 | + dictCode: "${po.dictTable},${po.dictText},${po.dictField}" | |
141 | + <#elseif po.dictField?default("")?trim?length gt 1> | |
142 | + dictCode: "${po.dictField}" | |
143 | + </#if> | |
144 | + }, | |
145 | +<#else> | |
146 | + component: 'Input', | |
147 | +</#if> | |
148 | + colProps: {span: 6}, | |
149 | + }, | |
150 | +<#else> | |
151 | + { | |
152 | + label: "${po.filedComment}", | |
153 | + field: "${po.fieldName}", | |
154 | +<#if po.classType=='date'> | |
155 | + component: 'RangePicker', | |
156 | +<#elseif po.classType=='datetime'> | |
157 | + component: 'RangePicker', | |
158 | + componentProps: { | |
159 | + showTime: true, | |
160 | + }, | |
161 | +<#elseif po.fieldDbType=='int' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'> | |
162 | + component: 'JRangeNumber', | |
163 | +<#else> | |
164 | + component: 'Input', //TODO 范围查询 | |
165 | +</#if> | |
166 | + colProps: {span: 6}, | |
167 | + }, | |
168 | +</#if> | |
169 | +</#if> | |
170 | +</#list> | |
171 | +<#-- 结束循环 --> | |
172 | +]; | |
173 | + | |
174 | +//表单数据 | |
175 | +export const formSchema: FormSchema[] = [ | |
176 | +<#assign form_cat_tree = false> | |
177 | +<#assign form_cat_back = ""> | |
178 | +<#assign bpm_flag=false> | |
179 | +<#assign id_exists = false> | |
180 | +<#list columns as po><#rt/> | |
181 | +<#if po.fieldDbName=='bpm_status'> | |
182 | + <#assign bpm_flag=true> | |
183 | +</#if> | |
184 | +<#if po.fieldDbName == 'id'> | |
185 | + <#assign id_exists = true> | |
186 | +</#if> | |
187 | +<#if po.isShow =='Y'> | |
188 | +<#assign form_field_dictCode=""> | |
189 | + <#if po.dictTable?default("")?trim?length gt 1 && po.dictText?default("")?trim?length gt 1 && po.dictField?default("")?trim?length gt 1> | |
190 | + <#assign form_field_dictCode="${po.dictTable},${po.dictText},${po.dictField}"> | |
191 | + <#elseif po.dictField?default("")?trim?length gt 1> | |
192 | + <#assign form_field_dictCode="${po.dictField}"> | |
193 | + </#if> | |
194 | + { | |
195 | + label: '${po.filedComment}', | |
196 | + field: ${autoStringSuffix(po)}, | |
197 | + <#if po.classType =='date'> | |
198 | + component: 'DatePicker', | |
199 | + <#elseif po.classType =='datetime'> | |
200 | + component: 'DatePicker', | |
201 | + componentProps: { | |
202 | + showTime: true, | |
203 | + valueFormat: 'YYYY-MM-DD HH:mm:ss' | |
204 | + }, | |
205 | + <#elseif po.classType =='time'> | |
206 | + component: 'TimePicker', | |
207 | + componentProps: { | |
208 | + valueFormat: 'HH:mm:ss' | |
209 | + }, | |
210 | + <#elseif po.classType =='popup'> | |
211 | + <#include "/common/form/vue3popup.ftl"> | |
212 | + <#elseif po.classType =='sel_depart'> | |
213 | + component: 'JSelectDept', | |
214 | + <#elseif po.classType =='switch'> | |
215 | + component: 'JSwitch', | |
216 | + componentProps:{ | |
217 | + <#if po.dictField != 'is_open'> | |
218 | + options: ${po.dictField} | |
219 | + </#if> | |
220 | + }, | |
221 | + <#elseif po.classType =='pca'> | |
222 | + component: 'JAreaLinkage', | |
223 | + <#elseif po.classType =='markdown'> | |
224 | + component: 'JMarkdownEditor',//注意string转换问题 | |
225 | + <#elseif po.classType =='password'> | |
226 | + component: 'InputPassword', | |
227 | + <#elseif po.classType =='sel_user'> | |
228 | + component: 'JSelectUserByDept', | |
229 | + componentProps:{ | |
230 | + labelKey: 'realname', | |
231 | + }, | |
232 | + <#elseif po.classType =='textarea'> | |
233 | + component: 'InputTextArea', | |
234 | + <#elseif po.classType=='list' || po.classType=='radio'> | |
235 | + component: 'JDictSelectTag', | |
236 | + componentProps:{ | |
237 | + dictCode: "${form_field_dictCode}" | |
238 | + }, | |
239 | + <#elseif po.classType=='list_multi' || po.classType=='checkbox'> | |
240 | + component: 'JSelectMultiple', | |
241 | + componentProps:{ | |
242 | + dictCode: "${form_field_dictCode}" | |
243 | + }, | |
244 | + <#elseif po.classType=='sel_search'> | |
245 | + component: 'JSearchSelect', | |
246 | + componentProps:{ | |
247 | + dict: "${form_field_dictCode}" | |
248 | + }, | |
249 | +<#elseif po.classType=='cat_tree'> | |
250 | + <#assign form_cat_tree = true> | |
251 | + component: 'JCategorySelect', | |
252 | + componentProps:{ | |
253 | + pcode: "${po.dictField?default("")}", //TODO back和事件未添加,暂时有问题 | |
254 | + }, | |
255 | + <#if po.dictText?default("")?trim?length gt 1> | |
256 | + <#assign form_cat_back = "${po.dictText}"> | |
257 | + </#if> | |
258 | + <#elseif po.fieldDbType=='int' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'> | |
259 | + component: 'InputNumber', | |
260 | + <#elseif po.classType=='file'> | |
261 | + component: 'JUpload', | |
262 | + componentProps:{ | |
263 | + <#if po.uploadnum??> | |
264 | + maxCount: ${po.uploadnum} | |
265 | + </#if> | |
266 | + }, | |
267 | + <#elseif po.classType=='image'> | |
268 | + component: 'JImageUpload', | |
269 | + componentProps:{ | |
270 | + <#if po.uploadnum??> | |
271 | + fileMax: ${po.uploadnum} | |
272 | + </#if> | |
273 | + }, | |
274 | + <#elseif po.classType=='umeditor'> | |
275 | + component: 'JEditor', | |
276 | + <#elseif po.classType == 'sel_tree'> | |
277 | + component: 'JTreeSelect', | |
278 | + componentProps:{ | |
279 | + <#if po.dictText??> | |
280 | + <#if po.dictText?split(',')[2]?? && po.dictText?split(',')[0]??> | |
281 | + dict: "${po.dictTable},${po.dictText?split(',')[2]},${po.dictText?split(',')[0]}", | |
282 | + <#elseif po.dictText?split(',')[1]??> | |
283 | + pidField: "${po.dictText?split(',')[1]}", | |
284 | + <#elseif po.dictText?split(',')[3]??> | |
285 | + hasChildField: "${po.dictText?split(',')[3]}", | |
286 | + </#if> | |
287 | + </#if> | |
288 | + pidValue: "${po.dictField}", | |
289 | + }, | |
290 | + <#else> | |
291 | + component: 'Input', | |
292 | + </#if> | |
293 | + <#if po.isShow == 'Y' && poHasCheck(po)> | |
294 | + dynamicRules: ({model,schema}) => { | |
295 | + <#if po.fieldName != 'id'> | |
296 | + <#assign fieldValidType = po.fieldValidType!''> | |
297 | + return [ | |
298 | + <#-- 非空校验 --> | |
299 | + <#if po.nullable == 'N' || fieldValidType == '*'> | |
300 | + { required: true, message: '请输入${po.filedComment}!'}, | |
301 | + <#elseif fieldValidType!=''> | |
302 | + { required: false}, | |
303 | + </#if> | |
304 | + <#-- 唯一校验 --> | |
305 | + <#if fieldValidType == 'only'> | |
306 | + {...rules.duplicateCheckRule(<#if sub?default("")?trim?length gt 1>'${sub.tableName}'<#else>'${tableName}'</#if>, '${po.fieldDbName}',model,schema)[0]}, | |
307 | + <#-- 6到16位数字 --> | |
308 | + <#elseif fieldValidType == 'n6-16'> | |
309 | + { pattern: /^\d{6,16}$/, message: '请输入6到16位数字!'}, | |
310 | + <#-- 6到16位任意字符 --> | |
311 | + <#elseif fieldValidType == '*6-16'> | |
312 | + { pattern: /^.{6,16}$/, message: '请输入6到16位任意字符!'}, | |
313 | + <#-- 6到18位字符串 --> | |
314 | + <#elseif fieldValidType == 's6-18'> | |
315 | + { pattern: /^.{6,18}$/, message: '请输入6到18位任意字符!'}, | |
316 | + <#-- 网址 --> | |
317 | + <#elseif fieldValidType == 'url'> | |
318 | + { pattern: /^((ht|f)tps?):\/\/[\w\-]+(\.[\w\-]+)+([\w\-.,@?^=%&:\/~+#]*[\w\-@?^=%&\/~+#])?$/, message: '请输入正确的网址!'}, | |
319 | + <#-- 电子邮件 --> | |
320 | + <#elseif fieldValidType == 'e'> | |
321 | + { pattern: /^([\w]+\.*)([\w]+)@[\w]+\.\w{3}(\.\w{2}|)$/, message: '请输入正确的电子邮件!'}, | |
322 | + <#-- 手机号码 --> | |
323 | + <#elseif fieldValidType == 'm'> | |
324 | + { pattern: /^1[3456789]\d{9}$/, message: '请输入正确的手机号码!'}, | |
325 | + <#-- 邮政编码 --> | |
326 | + <#elseif fieldValidType == 'p'> | |
327 | + { pattern: /^[1-9]\d{5}$/, message: '请输入正确的邮政编码!'}, | |
328 | + <#-- 字母 --> | |
329 | + <#elseif fieldValidType == 's'> | |
330 | + { pattern: /^[A-Z|a-z]+$/, message: '请输入字母!'}, | |
331 | + <#-- 数字 --> | |
332 | + <#elseif fieldValidType == 'n'> | |
333 | + { pattern: /^-?\d+\.?\d*$/, message: '请输入数字!'}, | |
334 | + <#-- 整数 --> | |
335 | + <#elseif fieldValidType == 'z'> | |
336 | + { pattern: /^-?\d+$/, message: '请输入整数!'}, | |
337 | + <#-- 金额 --> | |
338 | + <#elseif fieldValidType == 'money'> | |
339 | + { pattern: /^(([1-9][0-9]*)|([0]\.\d{0,2}|[1-9][0-9]*\.\d{0,2}))$/, message: '请输入正确的金额!'}, | |
340 | + <#-- 正则校验 --> | |
341 | + <#elseif fieldValidType != '' && fieldValidType != '*'> | |
342 | + { pattern: '${fieldValidType}', message: '不符合校验规则!'}, | |
343 | + <#-- 无校验 --> | |
344 | + <#else> | |
345 | + <#t> | |
346 | + </#if> | |
347 | + ]; | |
348 | + </#if> | |
349 | + }, | |
350 | + </#if> | |
351 | + <#if po.readonly=='Y'> | |
352 | + dynamicDisabled: true | |
353 | + </#if> | |
354 | + }, | |
355 | +</#if> | |
356 | +</#list> | |
357 | +<#if id_exists == false> | |
358 | + // TODO 主键隐藏字段,目前写死为ID | |
359 | + { | |
360 | + label: '', | |
361 | + field: 'id', | |
362 | + component: 'Input', | |
363 | + show: false, | |
364 | + }, | |
365 | +</#if> | |
366 | +]; | |
... | ... |
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}_menu_insert.sql
0 → 100644
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3Native/components/${entityName}Form.vuei
0 → 100644
1 | +<#include "/common/utils.ftl"> | |
2 | +<template> | |
3 | + <a-spin :spinning="confirmLoading"> | |
4 | + <a-form ref="formRef" class="antd-modal-form" :labelCol="labelCol" :wrapperCol="wrapperCol"> | |
5 | + <a-row> | |
6 | +<#assign need_category = false> | |
7 | +<#assign bpm_flag=false> | |
8 | +<#assign need_pca = false> | |
9 | +<#assign need_search = false> | |
10 | +<#assign need_dept_user = false> | |
11 | +<#assign need_switch = false> | |
12 | +<#assign need_dept = false> | |
13 | +<#assign need_multi = false> | |
14 | +<#assign need_popup = false> | |
15 | +<#assign need_select_tag = false> | |
16 | +<#assign need_select_tree = false> | |
17 | +<#assign need_time = false> | |
18 | +<#assign need_markdown = false> | |
19 | +<#assign need_upload = false> | |
20 | +<#assign need_image_upload = false> | |
21 | +<#assign need_editor = false> | |
22 | +<#assign need_checkbox = false> | |
23 | +<#assign hasOnlyValidate = false> | |
24 | +<#assign form_span = 24> | |
25 | +<#if tableVo.fieldRowNum==2> | |
26 | +<#assign form_span = 12> | |
27 | +<#elseif tableVo.fieldRowNum==3> | |
28 | +<#assign form_span = 8> | |
29 | +<#elseif tableVo.fieldRowNum==4> | |
30 | +<#assign form_span = 6> | |
31 | +</#if> | |
32 | +<#list columns as po> | |
33 | +<#if po.fieldDbName=='bpm_status'> | |
34 | + <#assign bpm_flag=true> | |
35 | +</#if> | |
36 | +<#if po.isShow == 'Y' && po.fieldValidType?default("") == 'only'> | |
37 | + <#assign hasOnlyValidate = true> | |
38 | +</#if> | |
39 | + <#include "/common/form/native/vue3NativeForm.ftl"> | |
40 | +</#list> | |
41 | + </a-row> | |
42 | + </a-form> | |
43 | + </a-spin> | |
44 | +</template> | |
45 | + | |
46 | +<script lang="ts" setup> | |
47 | + import { ref, reactive, defineExpose, nextTick, defineProps, computed } from 'vue'; | |
48 | + import { defHttp } from '/@/utils/http/axios'; | |
49 | + import { useMessage } from '/@/hooks/web/useMessage'; | |
50 | + import moment from 'moment'; | |
51 | + <#include "/common/form/native/vue3NativeImport.ftl"> | |
52 | + import { getValueType } from '/@/utils'; | |
53 | + import { saveOrUpdate } from '../${entityName}.api'; | |
54 | + import { Form } from 'ant-design-vue'; | |
55 | + <#if hasOnlyValidate == true> | |
56 | + import { duplicateValidate } from '/@/utils/helper/validator' | |
57 | + </#if> | |
58 | + | |
59 | + const props = defineProps({ | |
60 | + disabled: { type: Boolean, default: false }, | |
61 | + }); | |
62 | + const formRef = ref(); | |
63 | + const useForm = Form.useForm; | |
64 | + const emit = defineEmits(['register', 'ok']); | |
65 | + const formData = reactive<Record<string, any>>({ | |
66 | +<#list columns as po> | |
67 | + <#if po.isShow == 'Y'> | |
68 | + <#if po.fieldDbType=='int' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'> | |
69 | + ${po.fieldName}: undefined, | |
70 | + <#elseif po.fieldDbType=='Blob'> | |
71 | + ${po.fieldName}String: '', | |
72 | + <#else> | |
73 | + ${po.fieldName}: '', | |
74 | + </#if> | |
75 | + </#if> | |
76 | +</#list> | |
77 | + }); | |
78 | + const { createMessage } = useMessage(); | |
79 | + const labelCol = ref<any>({ xs: { span: 24 }, sm: { span: 5 } }); | |
80 | + const wrapperCol = ref<any>({ xs: { span: 24 }, sm: { span: 16 } }); | |
81 | + const confirmLoading = ref<boolean>(false); | |
82 | + //表单验证 | |
83 | + const validatorRules = { | |
84 | + <#include "/common/validatorRulesTemplate/native/vue3MainNative.ftl"> | |
85 | + }; | |
86 | + const { resetFields, validate, validateInfos } = useForm(formData, validatorRules, { immediate: true }); | |
87 | + | |
88 | + /** | |
89 | + * 新增 | |
90 | + */ | |
91 | + function add() { | |
92 | + edit({}); | |
93 | + } | |
94 | + | |
95 | + /** | |
96 | + * 编辑 | |
97 | + */ | |
98 | + function edit(record) { | |
99 | + nextTick(() => { | |
100 | + resetFields(); | |
101 | + //赋值 | |
102 | + Object.assign(formData, record); | |
103 | + }); | |
104 | + } | |
105 | + | |
106 | + /** | |
107 | + * 提交数据 | |
108 | + */ | |
109 | + async function submitForm() { | |
110 | + // 触发表单验证 | |
111 | + await validate(); | |
112 | + confirmLoading.value = true; | |
113 | + const isUpdate = ref<boolean>(false); | |
114 | + //时间格式化 | |
115 | + let model = formData; | |
116 | + if (model.id) { | |
117 | + isUpdate.value = true; | |
118 | + } | |
119 | + //循环数据 | |
120 | + for (let data in model) { | |
121 | + //如果该数据是数组并且是字符串类型 | |
122 | + if (model[data] instanceof Array) { | |
123 | + let valueType = getValueType(formRef.value.getProps, data); | |
124 | + //如果是字符串类型的需要变成以逗号分割的字符串 | |
125 | + if (valueType === 'string') { | |
126 | + model[data] = model[data].join(','); | |
127 | + } | |
128 | + } | |
129 | + } | |
130 | + await saveOrUpdate(model, isUpdate.value) | |
131 | + .then((res) => { | |
132 | + if (res.success) { | |
133 | + createMessage.success(res.message); | |
134 | + emit('ok'); | |
135 | + } else { | |
136 | + createMessage.warning(res.message); | |
137 | + } | |
138 | + }) | |
139 | + .finally(() => { | |
140 | + confirmLoading.value = false; | |
141 | + }); | |
142 | + } | |
143 | + | |
144 | + <#if need_popup> | |
145 | + /** | |
146 | + * popup组件值改变事件 | |
147 | + */ | |
148 | + function setFieldsValue(map) { | |
149 | + Object.keys(map).map((key) => { | |
150 | + formData[key] = map[key]; | |
151 | + }); | |
152 | + } | |
153 | + </#if> | |
154 | + | |
155 | + <#if need_category || need_select_tree> | |
156 | + /** | |
157 | + * 值改变事件触发 | |
158 | + * @param key | |
159 | + * @param value | |
160 | + */ | |
161 | + function handleFormChange(key, value) { | |
162 | + formData[key] = value; | |
163 | + } | |
164 | + </#if> | |
165 | + <#list columns as po> | |
166 | + <#if po.isShow == 'Y' && po.fieldValidType?default("") == 'only'> | |
167 | + async function ${po.fieldName}Duplicatevalidate(_r, value) { | |
168 | + return duplicateValidate('${tableName}', '${po.fieldDbName}', value, formData.id || '') | |
169 | + } | |
170 | + </#if> | |
171 | + </#list> | |
172 | + defineExpose({ | |
173 | + add, | |
174 | + edit, | |
175 | + submitForm, | |
176 | + }); | |
177 | +</script> | |
178 | + | |
179 | +<style lang="less" scoped> | |
180 | + .antd-modal-form { | |
181 | + height: 500px !important; | |
182 | + overflow-y: auto; | |
183 | + padding: 24px 24px 24px 24px; | |
184 | + } | |
185 | +</style> | |
... | ... |
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/vue3Native/components/${entityName}Modal.vuei
0 → 100644
1 | +<template> | |
2 | + <a-modal :title="title" :width="width" :visible="visible" @ok="handleOk" :okButtonProps="{ class: { 'jee-hidden': disableSubmit } }" @cancel="handleCancel" cancelText="关闭"> | |
3 | + <${entityName}Form ref="registerForm" @ok="submitCallback" :disabled="disableSubmit"></${entityName}Form> | |
4 | + </a-modal> | |
5 | +</template> | |
6 | + | |
7 | +<script lang="ts" setup> | |
8 | + import { ref, nextTick, defineExpose } from 'vue'; | |
9 | + import ${entityName}Form from './${entityName}Form.vue' | |
10 | + | |
11 | + const title = ref<string>(''); | |
12 | + const width = ref<number>(800); | |
13 | + const visible = ref<boolean>(false); | |
14 | + const disableSubmit = ref<boolean>(false); | |
15 | + const registerForm = ref(); | |
16 | + const emit = defineEmits(['register', 'success']); | |
17 | + | |
18 | + /** | |
19 | + * 新增 | |
20 | + */ | |
21 | + function add() { | |
22 | + title.value = '新增'; | |
23 | + visible.value = true; | |
24 | + nextTick(() => { | |
25 | + registerForm.value.add(); | |
26 | + }); | |
27 | + } | |
28 | + | |
29 | + /** | |
30 | + * 编辑 | |
31 | + * @param record | |
32 | + */ | |
33 | + function edit(record) { | |
34 | + title.value = disableSubmit.value ? '详情' : '编辑'; | |
35 | + visible.value = true; | |
36 | + nextTick(() => { | |
37 | + registerForm.value.edit(record); | |
38 | + }); | |
39 | + } | |
40 | + | |
41 | + /** | |
42 | + * 确定按钮点击事件 | |
43 | + */ | |
44 | + function handleOk() { | |
45 | + registerForm.value.submitForm(); | |
46 | + } | |
47 | + | |
48 | + /** | |
49 | + * form保存回调事件 | |
50 | + */ | |
51 | + function submitCallback() { | |
52 | + handleCancel(); | |
53 | + emit('success'); | |
54 | + } | |
55 | + | |
56 | + /** | |
57 | + * 取消按钮回调事件 | |
58 | + */ | |
59 | + function handleCancel() { | |
60 | + visible.value = false; | |
61 | + } | |
62 | + | |
63 | + defineExpose({ | |
64 | + add, | |
65 | + edit, | |
66 | + disableSubmit, | |
67 | + }); | |
68 | +</script> | |
69 | + | |
70 | +<style> | |
71 | + /**隐藏样式-modal确定按钮 */ | |
72 | + .jee-hidden { | |
73 | + display: none !important; | |
74 | + } | |
75 | +</style> | |
... | ... |
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai
... | ... | @@ -205,17 +205,14 @@ public class ${entityName}Controller { |
205 | 205 | QueryWrapper<${entityName}> queryWrapper = QueryGenerator.initQueryWrapper(${entityName?uncap_first}, request.getParameterMap()); |
206 | 206 | LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); |
207 | 207 | |
208 | - //Step.2 获取导出数据 | |
209 | - List<${entityName}> queryList = ${entityName?uncap_first}Service.list(queryWrapper); | |
210 | - // 过滤选中数据 | |
208 | + //配置选中数据查询条件 | |
211 | 209 | String selections = request.getParameter("selections"); |
212 | - List<${entityName}> ${entityName?uncap_first}List = new ArrayList<${entityName}>(); | |
213 | - if(oConvertUtils.isEmpty(selections)) { | |
214 | - ${entityName?uncap_first}List = queryList; | |
215 | - }else { | |
210 | + if(oConvertUtils.isNotEmpty(selections)) { | |
216 | 211 | List<String> selectionList = Arrays.asList(selections.split(",")); |
217 | - ${entityName?uncap_first}List = queryList.stream().filter(item -> selectionList.contains(item.getId())).collect(Collectors.toList()); | |
212 | + queryWrapper.in("id",selectionList); | |
218 | 213 | } |
214 | + //Step.2 获取导出数据 | |
215 | + List<${entityName}> ${entityName?uncap_first}List = ${entityName?uncap_first}Service.list(queryWrapper); | |
219 | 216 | |
220 | 217 | // Step.3 组装pageList |
221 | 218 | List<${entityName}Page> pageList = new ArrayList<${entityName}Page>(); |
... | ... |
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/entity/${entityName}.javai
1 | +<#include "/common/utils.ftl"> | |
1 | 2 | package ${bussiPackage}.${entityPackage}.entity; |
2 | 3 | |
3 | 4 | import java.io.Serializable; |
... | ... | @@ -31,9 +32,9 @@ public class ${entityName} implements Serializable { |
31 | 32 | <#-- 生成字典Code --> |
32 | 33 | <#assign list_field_dictCode=""> |
33 | 34 | <#if po.classType='sel_user'> |
34 | - <#assign list_field_dictCode=', dictTable = "sys_user", dicText = "realname", dicCode = "username"'> | |
35 | + <#assign list_field_dictCode=', dictTable = "sys_user", dicText = "${camelToDashed(po.extendParams.text?default(\"realname\")?trim)}", dicCode = "${camelToDashed(po.extendParams.store?default(\"username\")?trim)}"'> | |
35 | 36 | <#elseif po.classType='sel_depart'> |
36 | - <#assign list_field_dictCode=', dictTable = "sys_depart", dicText = "depart_name", dicCode = "id"'> | |
37 | + <#assign list_field_dictCode=', dictTable = "sys_depart", dicText = "${camelToDashed(po.extendParams.text?default(\"depart_name\")?trim)}", dicCode = "${camelToDashed(po.extendParams.store?default(\"id\")?trim)}"'> | |
37 | 38 | <#elseif po.classType=='list' || po.classType=='list_multi' || po.classType=='sel_search' || po.classType=='radio' || po.classType=='checkbox'> |
38 | 39 | <#if po.dictTable?default("")?trim?length gt 1> |
39 | 40 | <#assign list_field_dictCode=', dictTable = "${po.dictTable}", dicText = "${po.dictText}", dicCode = "${po.dictField}"'> |
... | ... |
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/entity/[1-n]Entity.javai
1 | +<#include "/common/utils.ftl"> | |
1 | 2 | <#list subTables as subTab> |
2 | 3 | #segment#${subTab.entityName}.java |
3 | 4 | package ${bussiPackage}.${entityPackage}.entity; |
... | ... | @@ -32,9 +33,9 @@ public class ${subTab.entityName} implements Serializable { |
32 | 33 | <#-- 生成字典Code --> |
33 | 34 | <#assign list_field_dictCode=""> |
34 | 35 | <#if po.classType='sel_user'> |
35 | - <#assign list_field_dictCode=', dictTable = "sys_user", dicText = "realname", dicCode = "username"'> | |
36 | + <#assign list_field_dictCode=', dictTable = "sys_user", dicText = "${camelToDashed(po.extendParams.text?default(\"realname\")?trim)}", dicCode = "${camelToDashed(po.extendParams.store?default(\"username\")?trim)}"'> | |
36 | 37 | <#elseif po.classType='sel_depart'> |
37 | - <#assign list_field_dictCode=', dictTable = "sys_depart", dicText = "depart_name", dicCode = "id"'> | |
38 | + <#assign list_field_dictCode=', dictTable = "sys_depart", dicText = "${camelToDashed(po.extendParams.text?default(\"depart_name\")?trim)}", dicCode = "${camelToDashed(po.extendParams.store?default(\"id\")?trim)}"'> | |
38 | 39 | <#elseif po.classType=='list' || po.classType=='list_multi' || po.classType=='sel_search' || po.classType=='radio' || po.classType=='checkbox'> |
39 | 40 | <#if po.dictTable?default("")?trim?length gt 1> |
40 | 41 | <#assign list_field_dictCode=', dictTable = "${po.dictTable}", dicText = "${po.dictText}", dicCode = "${po.dictField}"'> |
... | ... |
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/vue/${entityName}_menu_insert.sql
0 → 100644
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/${entityName}Form.vuei
... | ... | @@ -48,7 +48,7 @@ |
48 | 48 | @input="popupCallback" |
49 | 49 | <#if po.readonly=='Y'>disabled</#if>/> |
50 | 50 | <#elseif po.classType =='sel_depart'> |
51 | - <j-select-depart v-model="model.${po.fieldName}" multi <#if po.readonly=='Y'>disabled</#if>/> | |
51 | + <j-select-depart v-model="model.${po.fieldName}" :multi="${po.extendParams.multi?default('true')}"<#if po.extendParams.store?default("")?trim?length gt 0> store="${po.extendParams.store}"</#if><#if po.extendParams.text?default("")?trim?length gt 0> text="${po.extendParams.text}"</#if> <#if po.readonly=='Y'>disabled</#if> /> | |
52 | 52 | <#elseif po.classType =='switch'> |
53 | 53 | <j-switch v-model="model.${po.fieldName}" <#if po.dictField != 'is_open'>:options="${po.dictField}"</#if> <#if po.readonly=='Y'>disabled</#if>></j-switch> |
54 | 54 | <#elseif po.classType =='pca'> |
... | ... | @@ -58,7 +58,7 @@ |
58 | 58 | <#elseif po.classType =='password'> |
59 | 59 | <a-input-password v-model="model.${po.fieldName}" placeholder="请输入${po.filedComment}" <#if po.readonly=='Y'>disabled</#if>/> |
60 | 60 | <#elseif po.classType =='sel_user'> |
61 | - <j-select-user-by-dep v-model="model.${po.fieldName}" <#if po.readonly=='Y'>disabled</#if>/> | |
61 | + <j-select-user-by-dep v-model="model.${po.fieldName}" :multi="${po.extendParams.multi?default('true')}"<#if po.extendParams.store?default("")?trim?length gt 0> store="${po.extendParams.store}"</#if><#if po.extendParams.text?default("")?trim?length gt 0> text="${po.extendParams.text}"</#if> <#if po.readonly=='Y'>disabled</#if>/> | |
62 | 62 | <#elseif po.classType =='textarea'> |
63 | 63 | <a-textarea v-model="model.${autoStringSuffixForModel(po)}" rows="4" placeholder="请输入${po.filedComment}" <#if po.readonly=='Y'>disabled</#if>/> |
64 | 64 | <#elseif po.classType=='list' || po.classType=='radio'> |
... | ... |
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/[1-n]Form.vuei
... | ... | @@ -44,7 +44,7 @@ |
44 | 44 | :multi="${po.extendParams.popupMulti?c}" |
45 | 45 | @input="popupCallback"/> |
46 | 46 | <#elseif po.classType =='sel_depart'> |
47 | - <j-select-depart v-model="model.${po.fieldName}" multi/> | |
47 | + <j-select-depart v-model="model.${po.fieldName}" :multi="${po.extendParams.multi?default('true')}"<#if po.extendParams.store?default("")?trim?length gt 0> store="${po.extendParams.store}"</#if><#if po.extendParams.text?default("")?trim?length gt 0> text="${po.extendParams.text}"</#if> <#if po.readonly=='Y'>disabled</#if> /> | |
48 | 48 | <#elseif po.classType =='switch'> |
49 | 49 | <j-switch v-model="model.${po.fieldName}" <#if po.dictField!= 'is_open'>:options="${po.dictField}"</#if>></j-switch> |
50 | 50 | <#elseif po.classType =='pca'> |
... | ... | @@ -54,7 +54,7 @@ |
54 | 54 | <#elseif po.classType =='password'> |
55 | 55 | <a-input-password v-model="model.${po.fieldName}" placeholder="请输入${po.filedComment}"/> |
56 | 56 | <#elseif po.classType =='sel_user'> |
57 | - <j-select-user-by-dep v-model="model.${po.fieldName}"/> | |
57 | + <j-select-user-by-dep v-model="model.${po.fieldName}" :multi="${po.extendParams.multi?default('true')}"<#if po.extendParams.store?default("")?trim?length gt 0> store="${po.extendParams.store}"</#if><#if po.extendParams.text?default("")?trim?length gt 0> text="${po.extendParams.text}"</#if> <#if po.readonly=='Y'>disabled</#if>/> | |
58 | 58 | <#elseif po.classType =='textarea'> |
59 | 59 | <a-textarea v-model="model.${autoStringSuffixForModel(po)}" rows="4" placeholder="请输入${po.filedComment}"/> |
60 | 60 | <#elseif po.classType=='list' || po.classType=='radio'> |
... | ... |
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/entity/${entityName}.javai
1 | +<#include "/common/utils.ftl"> | |
1 | 2 | package ${bussiPackage}.${entityPackage}.entity; |
2 | 3 | |
3 | 4 | import java.io.Serializable; |
... | ... | @@ -32,9 +33,9 @@ public class ${entityName} implements Serializable { |
32 | 33 | <#-- 生成字典Code --> |
33 | 34 | <#assign list_field_dictCode=""> |
34 | 35 | <#if po.classType='sel_user'> |
35 | - <#assign list_field_dictCode=', dictTable = "sys_user", dicText = "realname", dicCode = "username"'> | |
36 | + <#assign list_field_dictCode=', dictTable = "sys_user", dicText = "${camelToDashed(po.extendParams.text?default(\"realname\")?trim)}", dicCode = "${camelToDashed(po.extendParams.store?default(\"username\")?trim)}"'> | |
36 | 37 | <#elseif po.classType='sel_depart'> |
37 | - <#assign list_field_dictCode=', dictTable = "sys_depart", dicText = "depart_name", dicCode = "id"'> | |
38 | + <#assign list_field_dictCode=', dictTable = "sys_depart", dicText = "${camelToDashed(po.extendParams.text?default(\"depart_name\")?trim)}", dicCode = "${camelToDashed(po.extendParams.store?default(\"id\")?trim)}"'> | |
38 | 39 | <#elseif po.classType=='list' || po.classType=='list_multi' || po.classType=='sel_search' || po.classType=='radio' || po.classType=='checkbox'> |
39 | 40 | <#if po.dictTable?default("")?trim?length gt 1> |
40 | 41 | <#assign list_field_dictCode=', dictTable = "${po.dictTable}", dicText = "${po.dictText}", dicCode = "${po.dictField}"'> |
... | ... |
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue/${entityName}_menu_insert.sql
0 → 100644
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue/modules/${entityName}Modal.vuei
... | ... | @@ -56,9 +56,9 @@ |
56 | 56 | @input="popupCallback" |
57 | 57 | <#if po.readonly=='Y'>disabled</#if>/> |
58 | 58 | <#elseif po.classType =='sel_depart'> |
59 | - <j-select-depart v-model="model.${po.fieldName}" <#if po.readonly=='Y'>disabled</#if>/> | |
59 | + <j-select-depart v-model="model.${po.fieldName}" :multi="${po.extendParams.multi?default('true')}"<#if po.extendParams.store?default("")?trim?length gt 0> store="${po.extendParams.store}"</#if><#if po.extendParams.text?default("")?trim?length gt 0> text="${po.extendParams.text}"</#if> <#if po.readonly=='Y'>disabled</#if> /> | |
60 | 60 | <#elseif po.classType =='sel_user'> |
61 | - <j-select-user-by-dep v-model="model.${po.fieldName}" <#if po.readonly=='Y'>disabled</#if>/> | |
61 | + <j-select-user-by-dep v-model="model.${po.fieldName}" :multi="${po.extendParams.multi?default('true')}"<#if po.extendParams.store?default("")?trim?length gt 0> store="${po.extendParams.store}"</#if><#if po.extendParams.text?default("")?trim?length gt 0> text="${po.extendParams.text}"</#if> <#if po.readonly=='Y'>disabled</#if>/> | |
62 | 62 | <#elseif po.classType =='textarea'> |
63 | 63 | <a-textarea v-model="model.${autoStringSuffixForModel(po)}" rows="4" placeholder="请输入${po.filedComment}" <#if po.readonly=='Y'>disabled</#if>/> |
64 | 64 | <#elseif po.classType=='list' || po.classType=='radio'> |
... | ... |
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3/${entityName}List.vuei
... | ... | @@ -8,6 +8,13 @@ |
8 | 8 | <#assign hasChildrenField = po.fieldName> |
9 | 9 | </#if> |
10 | 10 | </#list> |
11 | +<#assign list_need_pca=false> | |
12 | +<#-- 开始循环 --> | |
13 | +<#list columns as po> | |
14 | +<#if po.classType=='pca'> | |
15 | +<#assign list_need_pca=true> | |
16 | +</#if> | |
17 | +</#list> | |
11 | 18 | <template> |
12 | 19 | <div> |
13 | 20 | <!--引用表格--> |
... | ... | @@ -34,8 +41,20 @@ |
34 | 41 | </template> |
35 | 42 | <!--操作栏--> |
36 | 43 | <template #action="{ record }"> |
37 | - <TableAction :actions="getTableAction(record)"/> | |
44 | + <TableAction :actions="getTableAction(record)" :dropDownActions="getDropDownAction(record)"/> | |
38 | 45 | </template> |
46 | + <!--字段回显插槽--> | |
47 | + <template #htmlSlot="{text}"> | |
48 | + <div v-html="text"></div> | |
49 | + </template> | |
50 | + <!--省市区字段回显插槽--> | |
51 | + <template #pcaSlot="{text}"> | |
52 | + {{ getAreaTextByCode(text) }} | |
53 | + </template> | |
54 | + <template #fileSlot="{text}"> | |
55 | + <span v-if="!text" style="font-size: 12px;font-style: italic;">无文件</span> | |
56 | + <a-button v-else :ghost="true" type="primary" preIcon="ant-design:download-outlined" size="small" @click="downloadFile(text)">下载</a-button> | |
57 | + </template> | |
39 | 58 | </BasicTable> |
40 | 59 | <!--字典弹窗--> |
41 | 60 | <${entityName}Modal @register="registerModal" @success="handleSuccess"/> |
... | ... | @@ -49,9 +68,12 @@ |
49 | 68 | import {useModal} from '/@/components/Modal'; |
50 | 69 | import { useListPage } from '/@/hooks/system/useListPage' |
51 | 70 | import ${entityName}Modal from './components/${entityName}Modal.vue'; |
52 | - import {columns} from './${entityName}.data'; | |
71 | + import {columns,searchFormSchema} from './${entityName}.data'; | |
72 | + import { downloadFile } from '/@/utils/common/renderUtils'; | |
53 | 73 | import {list, delete${entityName}, batchDelete${entityName}, getExportUrl,getImportUrl, getChildList,getChildListBatch} from './${entityName}.api'; |
54 | - | |
74 | + <#if list_need_pca> | |
75 | + import { getAreaTextByCode } from '/@/components/Form/src/utils/Area'; | |
76 | + </#if> | |
55 | 77 | const expandedRowKeys = ref([]); |
56 | 78 | //字典model |
57 | 79 | const [registerModal, {openModal}] = useModal(); |
... | ... | @@ -62,6 +84,36 @@ |
62 | 84 | title: '${tableVo.ftlDescription}', |
63 | 85 | columns, |
64 | 86 | canResize:false, |
87 | + formConfig: { | |
88 | + labelWidth: 120, | |
89 | + schemas: searchFormSchema, | |
90 | + autoSubmitOnEnter:true, | |
91 | + showAdvancedButton:true, | |
92 | + fieldMapToNumber: [ | |
93 | + <#list columns as po> | |
94 | + <#if po.isQuery=='Y'> | |
95 | + <#if po.queryMode!='single'> | |
96 | + <#if po.fieldDbType=='int' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'> | |
97 | + ['${po.fieldName}', ['${po.fieldName}_begin', '${po.fieldName}_end']], | |
98 | + </#if> | |
99 | + </#if> | |
100 | + </#if> | |
101 | + </#list> | |
102 | + ], | |
103 | + fieldMapToTime: [ | |
104 | + <#list columns as po> | |
105 | + <#if po.isQuery=='Y'> | |
106 | + <#if po.queryMode!='single'> | |
107 | + <#if po.classType=='date'> | |
108 | + ['${po.fieldName}', ['${po.fieldName}_begin', '${po.fieldName}_end'], 'YYYY-MM-DD'], | |
109 | + <#elseif po.classType=='datetime'> | |
110 | + ['${po.fieldName}', ['${po.fieldName}_begin', '${po.fieldName}_end'], 'YYYY-MM-DD HH:mm:ss'], | |
111 | + </#if> | |
112 | + </#if> | |
113 | + </#if> | |
114 | + </#list> | |
115 | + ], | |
116 | + }, | |
65 | 117 | actionColumn: { |
66 | 118 | width: 240, |
67 | 119 | }, |
... | ... | @@ -120,13 +172,13 @@ |
120 | 172 | */ |
121 | 173 | async function batchHandleDelete() { |
122 | 174 | const ids = selectedRowKeys.value.filter(item => !item.includes('loading')) |
123 | - await batchDelete${entityName}({ids: ids}, importSuccess); | |
175 | + await batchDelete${entityName}({id: ids}, importSuccess); | |
124 | 176 | } |
125 | 177 | /** |
126 | 178 | * 导入 |
127 | 179 | */ |
128 | 180 | function importSuccess() { |
129 | - reload() && (expandedRowKeys.value = []); | |
181 | + (selectedRowKeys.value = []) && reload(); | |
130 | 182 | } |
131 | 183 | /** |
132 | 184 | * 添加下级 |
... | ... | @@ -140,12 +192,16 @@ |
140 | 192 | /** |
141 | 193 | * 成功回调 |
142 | 194 | */ |
143 | - async function handleSuccess({isUpdate, values, expandedArr}) { | |
195 | + async function handleSuccess({isUpdate, values, expandedArr, changeParent}) { | |
144 | 196 | if (isUpdate) { |
145 | - //编辑回调 | |
146 | - updateTableDataRecord(values.id, values); | |
197 | + if (changeParent) { | |
198 | + reload(); | |
199 | + } else { | |
200 | + // 编辑回调 | |
201 | + updateTableDataRecord(values.id, values); | |
202 | + } | |
147 | 203 | } else { |
148 | - if(!values['${pidFieldName}']){ | |
204 | + if(!values['id'] || !values['${pidFieldName}']){ | |
149 | 205 | //新增根节点 |
150 | 206 | reload(); |
151 | 207 | }else{ |
... | ... | @@ -264,18 +320,28 @@ |
264 | 320 | onClick: handleEdit.bind(null, record), |
265 | 321 | }, |
266 | 322 | { |
267 | - label: '删除', | |
268 | - popConfirm: { | |
269 | - title: '确定删除吗?', | |
270 | - confirm: handleDelete.bind(null, record), | |
271 | - }, | |
272 | - }, | |
273 | - { | |
274 | 323 | label: '添加下级', |
275 | 324 | onClick: handleAddSub.bind(null, {${pidFieldName}: record.id}), |
276 | 325 | } |
277 | 326 | ] |
278 | 327 | } |
328 | + /** | |
329 | + * 下拉操作栏 | |
330 | + */ | |
331 | + function getDropDownAction(record){ | |
332 | + return [ | |
333 | + { | |
334 | + label: '详情', | |
335 | + onClick: handleDetail.bind(null, record), | |
336 | + }, { | |
337 | + label: '删除', | |
338 | + popConfirm: { | |
339 | + title: '确定删除吗?', | |
340 | + confirm: handleDelete.bind(null, record), | |
341 | + } | |
342 | + } | |
343 | + ] | |
344 | + } | |
279 | 345 | </script> |
280 | 346 | |
281 | 347 | <style scoped> |
... | ... |
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__api.tsi
... | ... | @@ -6,7 +6,6 @@ enum Api { |
6 | 6 | save='/${entityPackage}/${entityName?uncap_first}/add', |
7 | 7 | edit='/${entityPackage}/${entityName?uncap_first}/edit', |
8 | 8 | delete${entityName} = '/${entityPackage}/${entityName?uncap_first}/delete', |
9 | - deleteBatch = '/${entityPackage}/${entityName?uncap_first}/deleteBatch', | |
10 | 9 | importExcel = '/${entityPackage}/${entityName?uncap_first}/importExcel', |
11 | 10 | exportXls = '/${entityPackage}/${entityName?uncap_first}/exportXls', |
12 | 11 | loadTreeData = '/${entityPackage}/${entityName?uncap_first}/loadTreeRoot', |
... | ... | @@ -49,7 +48,7 @@ export const batchDelete${entityName} = (params, handleSuccess) => { |
49 | 48 | okText: '确认', |
50 | 49 | cancelText: '取消', |
51 | 50 | onOk: () => { |
52 | - return defHttp.delete({url: Api.deleteBatch, data: params}, {joinParamsToUrl: true}).then(() => { | |
51 | + return defHttp.delete({url: Api.delete${entityName}, data: params}, {joinParamsToUrl: true}).then(() => { | |
53 | 52 | handleSuccess(); |
54 | 53 | }); |
55 | 54 | } |
... | ... |
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__data.tsi
1 | +<#include "/common/utils.ftl"> | |
1 | 2 | import {BasicColumn} from '/@/components/Table'; |
2 | 3 | import {FormSchema} from '/@/components/Table'; |
3 | 4 | import { rules} from '/@/utils/helper/validator'; |
... | ... | @@ -28,7 +29,7 @@ export const columns: BasicColumn[] = [ |
28 | 29 | slots: { customRender: 'htmlSlot' }, |
29 | 30 | <#elseif po.classType=='pca'> |
30 | 31 | dataIndex: '${po.fieldName}', |
31 | - slots: { customRender: 'pcaSlot' },//TODO 未翻译 | |
32 | + slots: { customRender: 'pcaSlot' }, | |
32 | 33 | <#elseif po.classType=='file'> |
33 | 34 | dataIndex: '${po.fieldName}', |
34 | 35 | slots: { customRender: 'fileSlot' }, |
... | ... | @@ -60,7 +61,7 @@ export const columns: BasicColumn[] = [ |
60 | 61 | return render.renderCategoryTree(text,'${po.dictField?default("")}') |
61 | 62 | }, |
62 | 63 | <#else> |
63 | - customRender: (text, record) => (text ? record['${po.dictText}'] : '') | |
64 | + customRender: ({text, record}) => (text ? record['${po.dictText}'] : '') | |
64 | 65 | </#if> |
65 | 66 | <#else> |
66 | 67 | dataIndex: '${po.fieldName}' |
... | ... | @@ -105,9 +106,14 @@ export const searchFormSchema: FormSchema[] = [ |
105 | 106 | <#elseif po.classType=='sel_depart'> |
106 | 107 | component: 'JSelectDept', |
107 | 108 | <#elseif po.classType=='list_multi'> |
108 | - component: 'JMultiSelectTag',//暂无该组件 | |
109 | - componentProps:{ | |
110 | - dictCode:"query_field_dictCode?default("")" | |
109 | + component: 'JSelectMultiple', | |
110 | + componentProps:{ | |
111 | + <#if po.dictTable?default("")?trim?length gt 1> | |
112 | + dictCode:"${po.dictTable},${po.dictText},${po.dictField}", | |
113 | + <#elseif po.dictField?default("")?trim?length gt 1> | |
114 | + dictCode:"${po.dictField}", | |
115 | + </#if> | |
116 | + triggerChange: true | |
111 | 117 | }, |
112 | 118 | <#elseif po.classType=='cat_tree'> |
113 | 119 | component: 'JCategorySelect', |
... | ... | @@ -124,15 +130,22 @@ export const searchFormSchema: FormSchema[] = [ |
124 | 130 | <#elseif po.classType=='pca'> |
125 | 131 | component: 'JAreaLinkage', |
126 | 132 | <#elseif po.classType=='popup'> |
127 | - component: 'JPopup', | |
128 | - componentProps: ({ formActionType }) => { | |
129 | - const {setFieldsValue} = formActionType; | |
130 | - return{ | |
131 | - setFieldsValue:setFieldsValue, | |
132 | - code:"${po.dictTable}", | |
133 | - fieldConfig:"${po.dictField}", | |
134 | - multi:${po.extendParams.popupMulti?c}, | |
135 | - } | |
133 | + <#include "/common/form/vue3popup.ftl"> | |
134 | +<#elseif po.classType == 'sel_tree'> | |
135 | + component: 'JTreeSelect', | |
136 | + componentProps:{ | |
137 | + <#if po.dictText??> | |
138 | + <#if po.dictText?split(',')[2]?? && po.dictText?split(',')[0]??> | |
139 | + dict:"${po.dictTable},${po.dictText?split(',')[2]},${po.dictText?split(',')[0]}", | |
140 | + </#if> | |
141 | + <#if po.dictText?split(',')[1]??> | |
142 | + pidField:"${po.dictText?split(',')[1]}", | |
143 | + </#if> | |
144 | + <#if po.dictText?split(',')[3]??> | |
145 | + hasChildField:"${po.dictText?split(',')[3]}", | |
146 | + </#if> | |
147 | + </#if> | |
148 | + pidValue:"${po.dictField}", | |
136 | 149 | }, |
137 | 150 | <#elseif po.classType=='list' || po.classType=='radio' || po.classType=='checkbox'> |
138 | 151 | <#-- ---------------------------下拉或是单选 判断数据字典是表字典还是普通字典------------------------------- --> |
... | ... | @@ -160,6 +173,13 @@ export const searchFormSchema: FormSchema[] = [ |
160 | 173 | componentProps: { |
161 | 174 | showTime:true |
162 | 175 | }, |
176 | +<#elseif po.classType == 'time'> | |
177 | + component: 'TimePicker', | |
178 | + componentProps:{ | |
179 | + valueFormat: 'HH:mm:ss', | |
180 | + }, | |
181 | +<#elseif po.fieldDbType=='int' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'> | |
182 | + component: 'JRangeNumber', | |
163 | 183 | <#else> |
164 | 184 | component: 'Input', //TODO 范围查询 |
165 | 185 | </#if> |
... | ... | @@ -192,7 +212,7 @@ export const formSchema: FormSchema[] = [ |
192 | 212 | </#if> |
193 | 213 | { |
194 | 214 | label: '${po.filedComment}', |
195 | - field: '${po.fieldName}', | |
215 | + field: ${autoStringSuffix(po)}, | |
196 | 216 | <#if po.fieldDbName == tableVo.extendParams.pidField> |
197 | 217 | component: 'JTreeSelect', |
198 | 218 | componentProps: { |
... | ... | @@ -203,24 +223,19 @@ export const formSchema: FormSchema[] = [ |
203 | 223 | }, |
204 | 224 | <#elseif po.classType =='date'> |
205 | 225 | component: 'DatePicker', |
206 | - <#elseif po.fieldType =='datetime'> | |
226 | + <#elseif po.classType =='datetime'> | |
207 | 227 | component: 'DatePicker', |
208 | 228 | componentProps: { |
209 | - showTime:true | |
229 | + showTime:true, | |
230 | + valueFormat: 'YYYY-MM-DD hh:mm:ss' | |
210 | 231 | }, |
211 | - <#elseif po.fieldType =='time'> | |
232 | + <#elseif po.classType =='time'> | |
212 | 233 | component: 'TimePicker', |
234 | + componentProps:{ | |
235 | + valueFormat: 'HH:mm:ss', | |
236 | + }, | |
213 | 237 | <#elseif po.classType =='popup'> |
214 | - component: 'JPopup', | |
215 | - componentProps: ({ formActionType }) => { | |
216 | - const {setFieldsValue} = formActionType; | |
217 | - return{ | |
218 | - setFieldsValue:setFieldsValue, | |
219 | - code:"${po.dictTable}", | |
220 | - fieldConfig:${po.dictField}, | |
221 | - multi:${po.extendParams.popupMulti?c}, | |
222 | - } | |
223 | - }, | |
238 | + <#include "/common/form/vue3popup.ftl"> | |
224 | 239 | <#elseif po.classType =='sel_depart'> |
225 | 240 | component: 'JSelectDept', |
226 | 241 | <#elseif po.classType =='switch'> |
... | ... | @@ -242,14 +257,14 @@ export const formSchema: FormSchema[] = [ |
242 | 257 | labelKey:'realname', |
243 | 258 | }, |
244 | 259 | <#elseif po.classType =='textarea'> |
245 | - component: 'InputTextArea',//TODO 注意string转换问题 | |
260 | + component: 'InputTextArea', | |
246 | 261 | <#elseif po.classType=='list' || po.classType=='radio'> |
247 | 262 | component: 'JDictSelectTag', |
248 | 263 | componentProps:{ |
249 | 264 | dictCode:"${form_field_dictCode}" |
250 | 265 | }, |
251 | 266 | <#elseif po.classType=='list_multi' || po.classType=='checkbox'> |
252 | - component: 'JMultiSelectTag',//TODO 暂无该组件 | |
267 | + component: 'JSelectMultiple', | |
253 | 268 | componentProps:{ |
254 | 269 | dictCode:"${form_field_dictCode}" |
255 | 270 | }, |
... | ... | @@ -284,7 +299,7 @@ export const formSchema: FormSchema[] = [ |
284 | 299 | </#if> |
285 | 300 | }, |
286 | 301 | <#elseif po.classType=='umeditor'> |
287 | - component: 'JCodeEditor', //TODO String后缀暂未添加 | |
302 | + component: 'JEditor', | |
288 | 303 | <#elseif po.classType == 'sel_tree'> |
289 | 304 | component: 'JTreeSelect', |
290 | 305 | componentProps:{ |
... | ... | @@ -318,16 +333,16 @@ export const formSchema: FormSchema[] = [ |
318 | 333 | </#if> |
319 | 334 | <#-- 唯一校验 --> |
320 | 335 | <#if fieldValidType == 'only'> |
321 | - {...rules.duplicateCheckRule(<#if sub?default("")?trim?length gt 1>'${sub.tableName}'<#else>'${tableName}'</#if>, '${po.fieldDbName}',model,schema,true)[0]}, | |
336 | + {...rules.duplicateCheckRule(<#if sub?default("")?trim?length gt 1>'${sub.tableName}'<#else>'${tableName}'</#if>, '${po.fieldDbName}',model,schema)[0]}, | |
322 | 337 | <#-- 6到16位数字 --> |
323 | 338 | <#elseif fieldValidType == 'n6-16'> |
324 | 339 | { pattern: /^\d{6,16}$/, message: '请输入6到16位数字!'}, |
325 | 340 | <#-- 6到16位任意字符 --> |
326 | 341 | <#elseif fieldValidType == '*6-16'> |
327 | 342 | { pattern: /^.{6,16}$/, message: '请输入6到16位任意字符!'}, |
328 | - <#-- 6到18位字符串 --> | |
343 | + <#-- 6到18位字母 --> | |
329 | 344 | <#elseif fieldValidType == 's6-18'> |
330 | - { pattern: /^.{6,18}$/, message: '请输入6到18位任意字符!'}, | |
345 | + { pattern:/^[a-z|A-Z]{6,18}$/, message: '请输入6到18位字母!'}, | |
331 | 346 | <#-- 网址 --> |
332 | 347 | <#elseif fieldValidType == 'url'> |
333 | 348 | { pattern: /^((ht|f)tps?):\/\/[\w\-]+(\.[\w\-]+)+([\w\-.,@?^=%&:\/~+#]*[\w\-@?^=%&\/~+#])?$/, message: '请输入正确的网址!'}, |
... | ... |
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3/${entityName}_menu_insert.sql
0 → 100644
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3/components/${entityName}Modal.vuei
1 | +<#include "/common/utils.ftl"> | |
1 | 2 | <#assign pidFieldName = ""> |
2 | 3 | <#assign hasChildrenField = ""> |
3 | 4 | <#list originalColumns as po> |
... | ... | @@ -9,7 +10,7 @@ |
9 | 10 | </#if> |
10 | 11 | </#list> |
11 | 12 | <template> |
12 | - <BasicModal v-bind="$attrs" @register="registerModal" :title="getTitle" @ok="handleSubmit"> | |
13 | + <BasicModal v-bind="$attrs" @register="registerModal" destroyOnClose :width="${getModalWidth(tableVo.fieldRowNum?default(1))}" :title="getTitle" @ok="handleSubmit"> | |
13 | 14 | <BasicForm @register="registerForm"/> |
14 | 15 | </BasicModal> |
15 | 16 | </template> |
... | ... | @@ -24,10 +25,13 @@ |
24 | 25 | const isUpdate = ref(true); |
25 | 26 | const expandedRowKeys = ref([]); |
26 | 27 | const treeData = ref([]); |
28 | + // 当前编辑的数据 | |
29 | + let model:Nullable<Recordable> = null; | |
27 | 30 | //表单配置 |
28 | - const [registerForm, {resetFields, setFieldsValue, validate, updateSchema}] = useForm({ | |
31 | + const [registerForm, {setProps,resetFields, setFieldsValue, validate, updateSchema}] = useForm({ | |
29 | 32 | schemas: formSchema, |
30 | 33 | showActionButtonGroup: false, |
34 | + baseColProps: {span: ${getFormSpan(tableVo.fieldRowNum?default(1))}}, | |
31 | 35 | labelCol: { |
32 | 36 | xs: { span: 24 }, |
33 | 37 | sm: { span: 4 }, |
... | ... | @@ -42,16 +46,21 @@ |
42 | 46 | //重置表单 |
43 | 47 | await resetFields(); |
44 | 48 | expandedRowKeys.value = []; |
45 | - setModalProps({confirmLoading: false, minHeight: 80}); | |
49 | + setModalProps({confirmLoading: false, minHeight: 80 ,showOkBtn: !!!data?.hideFooter}); | |
46 | 50 | isUpdate.value = !!data?.isUpdate; |
47 | 51 | if (data?.record) { |
52 | + model = data.record; | |
48 | 53 | //表单赋值 |
49 | 54 | await setFieldsValue({ |
50 | 55 | ...data.record, |
51 | 56 | }); |
57 | + } else { | |
58 | + model = null; | |
52 | 59 | } |
53 | 60 | //父级节点树信息 |
54 | 61 | treeData.value = await loadTreeData({'async': false,'pcode':''}); |
62 | + // 隐藏底部时禁用整个表单 | |
63 | + setProps({ disabled: !!data?.hideFooter }) | |
55 | 64 | }); |
56 | 65 | //设置标题 |
57 | 66 | const getTitle = computed(() => (!unref(isUpdate) ? '新增' : '编辑')); |
... | ... | @@ -85,9 +94,25 @@ |
85 | 94 | //展开的节点信息 |
86 | 95 | await getExpandKeysByPid(values['${pidFieldName}'],unref(treeData)) |
87 | 96 | //刷新列表(isUpdate:是否编辑;values:表单信息;expandedArr:展开的节点信息) |
88 | - emit('success', {isUpdate: unref(isUpdate), values:{...values},expandedArr: unref(expandedRowKeys).reverse()}); | |
97 | + emit('success', { | |
98 | + isUpdate: unref(isUpdate), | |
99 | + values: {...values}, | |
100 | + expandedArr: unref(expandedRowKeys).reverse(), | |
101 | + // 是否更改了父级节点 | |
102 | + changeParent: model != null && (model['${pidFieldName}'] != values['${pidFieldName}']), | |
103 | + }); | |
89 | 104 | } finally { |
90 | 105 | setModalProps({confirmLoading: false}); |
91 | 106 | } |
92 | 107 | } |
93 | 108 | </script> |
109 | +<style lang="less" scoped> | |
110 | + /** 时间和数字输入框样式 */ | |
111 | + :deep(.ant-input-number){ | |
112 | + width: 100% | |
113 | + } | |
114 | + | |
115 | + :deep(.ant-calendar-picker){ | |
116 | + width: 100% | |
117 | + } | |
118 | +</style> | |
94 | 119 | \ No newline at end of file |
... | ... |
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}List.vuei
0 → 100644
1 | +<template> | |
2 | + <div> | |
3 | +<#assign pidFieldName = ""> | |
4 | +<#assign hasChildrenField = ""> | |
5 | +<#list originalColumns as po> | |
6 | + <#if po.fieldDbName == tableVo.extendParams.pidField> | |
7 | + <#assign pidFieldName = po.fieldName> | |
8 | + </#if> | |
9 | + <#if po.fieldDbName == tableVo.extendParams.hasChildren> | |
10 | + <#assign hasChildrenField = po.fieldName> | |
11 | + </#if> | |
12 | +</#list> | |
13 | +<#assign query_field_no=0> | |
14 | +<#assign need_category = false> | |
15 | +<#assign need_pca = false> | |
16 | +<#assign need_search = false> | |
17 | +<#assign need_dept_user = false> | |
18 | +<#assign need_switch = false> | |
19 | +<#assign need_dept = false> | |
20 | +<#assign need_multi = false> | |
21 | +<#assign need_popup = false> | |
22 | +<#assign need_select_tag = false> | |
23 | +<#assign need_select_tree = false> | |
24 | +<#assign need_time = false> | |
25 | +<#assign bpm_flag=false> | |
26 | +<#assign need_markdown = false> | |
27 | +<#assign need_upload = false> | |
28 | +<#assign need_image_upload = false> | |
29 | +<#assign need_editor = false> | |
30 | +<#assign need_checkbox = false> | |
31 | +<#assign query_flag = false> | |
32 | + <!--查询区域--> | |
33 | + <div class="jeecg-basic-table-form-container"> | |
34 | + <a-form @keyup.enter.native="searchQuery" :model="queryParam" :label-col="labelCol" :wrapper-col="wrapperCol"> | |
35 | + <a-row :gutter="24"> | |
36 | +<#-- 开始循环 --> | |
37 | +<#list columns as po> | |
38 | +<#if po.fieldDbName=='bpm_status'> | |
39 | + <#assign bpm_flag=true> | |
40 | +</#if> | |
41 | +<#if po.classType=='cat_tree' && po.dictText?default("")?trim?length == 0> | |
42 | +<#assign need_category=true> | |
43 | +</#if> | |
44 | +<#if po.classType=='pca'> | |
45 | +<#assign need_pca=true> | |
46 | +</#if> | |
47 | +<#if po.classType=='sel_search'> | |
48 | +<#assign need_search = true> | |
49 | +</#if> | |
50 | +<#if po.classType=='sel_user'> | |
51 | +<#assign need_dept_user = true> | |
52 | +</#if> | |
53 | +<#if po.classType=='sel_depart'> | |
54 | +<#assign need_dept = true> | |
55 | +</#if> | |
56 | +<#if po.classType=='switch'> | |
57 | +<#assign need_switch = true> | |
58 | +</#if> | |
59 | +<#if po.classType=='list_multi'> | |
60 | +<#assign need_multi = true> | |
61 | +</#if> | |
62 | +<#if po.classType=='popup'> | |
63 | +<#assign need_popup = true> | |
64 | +</#if> | |
65 | +<#if po.classType=='sel_tree'> | |
66 | +<#assign need_select_tree = true> | |
67 | +</#if> | |
68 | +<#if po.classType=='time'> | |
69 | +<#assign need_time = true> | |
70 | +</#if> | |
71 | + <#include "/common/form/native/vue3NativeSearch.ftl"> | |
72 | +</#list> | |
73 | +<#if query_field_no gt 2> | |
74 | + </template> | |
75 | +</#if> | |
76 | +<#if query_flag> | |
77 | + <a-col :xl="6" :lg="7" :md="8" :sm="24"> | |
78 | + <span style="float: left; overflow: hidden" class="table-page-search-submitButtons"> | |
79 | + <a-col :lg="6"> | |
80 | + <a-button type="primary" preIcon="ant-design:search-outlined" @click="searchQuery">查询</a-button> | |
81 | + <a-button type="primary" preIcon="ant-design:reload-outlined" @click="searchReset" style="margin-left: 8px">重置</a-button> | |
82 | + <a @click="toggleSearchStatus = !toggleSearchStatus" style="margin-left: 8px"> | |
83 | + {{ toggleSearchStatus ? '收起' : '展开' }} | |
84 | + <Icon :icon="toggleSearchStatus ? 'ant-design:up-outlined' : 'ant-design:down-outlined'" /> | |
85 | + </a> | |
86 | + </a-col> | |
87 | + </span> | |
88 | + </a-col> | |
89 | +</#if> | |
90 | + </a-row> | |
91 | + </a-form> | |
92 | + </div> | |
93 | +<#-- 结束循环 --> | |
94 | + <!--引用表格--> | |
95 | + <BasicTable @register="registerTable" :rowSelection="rowSelection" :expandedRowKeys="expandedRowKeys" @expand="handleExpand" @fetch-success="onFetchSuccess"> | |
96 | + <!--插槽:table标题--> | |
97 | + <template #tableTitle> | |
98 | + <a-button type="primary" @click="handleAdd" preIcon="ant-design:plus-outlined"> 新增</a-button> | |
99 | + <a-dropdown v-if="selectedRowKeys.length > 0"> | |
100 | + <template #overlay> | |
101 | + <a-menu> | |
102 | + <a-menu-item key="1" @click="batchHandleDelete"> | |
103 | + <Icon icon="ant-design:delete-outlined"></Icon> | |
104 | + 删除 | |
105 | + </a-menu-item> | |
106 | + </a-menu> | |
107 | + </template> | |
108 | + <a-button | |
109 | + >批量操作 | |
110 | + <Icon icon="ant-design:down-outlined"></Icon> | |
111 | + </a-button> | |
112 | + </a-dropdown> | |
113 | + </template> | |
114 | + <!--操作栏--> | |
115 | + <template #action="{ record }"> | |
116 | + <TableAction :actions="getTableAction(record)" :dropDownActions="getDropDownAction(record)" /> | |
117 | + </template> | |
118 | + <!--字段回显插槽--> | |
119 | + <template #htmlSlot="{ text }"> | |
120 | + <div v-html="text"></div> | |
121 | + </template> | |
122 | + <!--省市区字段回显插槽--> | |
123 | + <template #pcaSlot="{ text }"> | |
124 | + {{ getAreaTextByCode(text) }} | |
125 | + </template> | |
126 | + <template #fileSlot="{ text }"> | |
127 | + <span v-if="!text" style="font-size: 12px; font-style: italic">无文件</span> | |
128 | + <a-button v-else :ghost="true" type="primary" preIcon="ant-design:download-outlined" size="small" @click="downloadFile(text)">下载</a-button> | |
129 | + </template> | |
130 | + </BasicTable> | |
131 | + <!-- 表单区域 --> | |
132 | + <${entityName}Modal ref="registerModal" @success="handleSuccess"></${entityName}Modal> | |
133 | + </div> | |
134 | +</template> | |
135 | + | |
136 | +<script lang="ts" name="${entityPackage}-${entityName?uncap_first}" setup> | |
137 | + import { ref, reactive, unref } from 'vue'; | |
138 | + import { BasicTable, useTable, TableAction } from '/@/components/Table'; | |
139 | + import { useListPage } from '/@/hooks/system/useListPage'; | |
140 | + import { columns } from './${entityName}.data'; | |
141 | + import {list, delete${entityName}, batchDelete${entityName}, getExportUrl,getImportUrl, getChildList,getChildListBatch} from './${entityName}.api'; | |
142 | + import { downloadFile } from '/@/utils/common/renderUtils'; | |
143 | + import ${entityName}Modal from './components/${entityName}Modal.vue' | |
144 | + <#include "/common/form/native/vue3NativeImport.ftl"> | |
145 | +<#if need_category> | |
146 | + import { loadCategoryData } from '/@/api/common/api'; | |
147 | + import { getAuthCache, setAuthCache } from '/@/utils/auth'; | |
148 | + import { DB_DICT_DATA_KEY } from '/@/enums/cacheEnum'; | |
149 | +</#if> | |
150 | +<#if need_pca> | |
151 | + import { getAreaTextByCode } from '/@/components/Form/src/utils/Area'; | |
152 | +</#if> | |
153 | + | |
154 | + const expandedRowKeys = ref([]); | |
155 | + const queryParam = ref<any>({}); | |
156 | + const toggleSearchStatus = ref<boolean>(false); | |
157 | + const registerModal = ref(); | |
158 | + //注册table数据 | |
159 | + const { prefixCls, tableContext, onExportXls, onImportXls } = useListPage({ | |
160 | + tableProps: { | |
161 | + title: '${tableVo.ftlDescription}', | |
162 | + api: list, | |
163 | + columns, | |
164 | + canResize:false, | |
165 | + useSearchForm: false, | |
166 | + actionColumn: { | |
167 | + width: 120, | |
168 | + fixed: 'right', | |
169 | + }, | |
170 | + beforeFetch: (params) => { | |
171 | + return Object.assign(params, queryParam.value); | |
172 | + }, | |
173 | + }, | |
174 | + exportConfig: { | |
175 | + name: "${tableVo.ftlDescription}", | |
176 | + url: getExportUrl, | |
177 | + }, | |
178 | + importConfig: { | |
179 | + url: getImportUrl, | |
180 | + success: success | |
181 | + }, | |
182 | + }); | |
183 | + const [registerTable, {reload, collapseAll, updateTableDataRecord, findTableDataRecord,getDataSource},{ rowSelection, selectedRowKeys }] = tableContext | |
184 | + const labelCol = reactive({ | |
185 | + xs: { span: 24 }, | |
186 | + sm: { span: 7 }, | |
187 | + }); | |
188 | + const wrapperCol = reactive({ | |
189 | + xs: { span: 24 }, | |
190 | + sm: { span: 16 }, | |
191 | + }); | |
192 | + | |
193 | + /** | |
194 | + * 新增事件 | |
195 | + */ | |
196 | + function handleAdd() { | |
197 | + registerModal.value.disableSubmit = false; | |
198 | + registerModal.value.add(); | |
199 | + } | |
200 | + | |
201 | + /** | |
202 | + * 编辑事件 | |
203 | + */ | |
204 | + async function handleEdit(record) { | |
205 | + registerModal.value.disableSubmit = false; | |
206 | + registerModal.value.edit(record); | |
207 | + } | |
208 | + | |
209 | + /** | |
210 | + * 详情 | |
211 | + */ | |
212 | + async function handleDetail(record) { | |
213 | + registerModal.value.disableSubmit = true; | |
214 | + registerModal.value.edit(record); | |
215 | + } | |
216 | + | |
217 | + /** | |
218 | + * 删除事件 | |
219 | + */ | |
220 | + async function handleDelete(record) { | |
221 | + await delete${entityName}({ id: record.id }, success); | |
222 | + } | |
223 | + | |
224 | + /** | |
225 | + * 批量删除事件 | |
226 | + */ | |
227 | + async function batchHandleDelete() { | |
228 | + const ids = selectedRowKeys.value.filter((item) => !item.includes('loading')); | |
229 | + await batchDelete${entityName}({ id: ids }, success); | |
230 | + } | |
231 | + | |
232 | + /** | |
233 | + * 成功回调刷新页面 | |
234 | + */ | |
235 | + function success() { | |
236 | + (selectedRowKeys.value = []) && reload(); | |
237 | + } | |
238 | + | |
239 | + /** | |
240 | + * 添加下级 | |
241 | + */ | |
242 | + function handleAddSub(record) { | |
243 | + registerModal.value.disableSubmit = false; | |
244 | + registerModal.value.add(record); | |
245 | + } | |
246 | + | |
247 | + /** | |
248 | + * 成功回调 | |
249 | + */ | |
250 | + async function handleSuccess({ isUpdate, values, expandedArr, changeParent }) { | |
251 | + if (isUpdate) { | |
252 | + if (changeParent) { | |
253 | + reload(); | |
254 | + } else { | |
255 | + // 编辑回调 | |
256 | + updateTableDataRecord(values.id, values); | |
257 | + } | |
258 | + } else { | |
259 | + if (!values['id'] || !values['pid']) { | |
260 | + //新增根节点 | |
261 | + reload(); | |
262 | + } else { | |
263 | + //新增子集 | |
264 | + expandedRowKeys.value = []; | |
265 | + for (let key of unref(expandedArr)) { | |
266 | + await expandTreeNode(key); | |
267 | + } | |
268 | + } | |
269 | + } | |
270 | + } | |
271 | + | |
272 | + /** | |
273 | + * 接口请求成功后回调 | |
274 | + */ | |
275 | + function onFetchSuccess(result) { | |
276 | + getDataByResult(result.items) && loadDataByExpandedRows(); | |
277 | + } | |
278 | + | |
279 | + /** | |
280 | + * 根据已展开的行查询数据(用于保存后刷新时异步加载子级的数据) | |
281 | + */ | |
282 | + async function loadDataByExpandedRows() { | |
283 | + if (unref(expandedRowKeys).length > 0) { | |
284 | + const res = await getChildListBatch({ parentIds: unref(expandedRowKeys).join(',') }); | |
285 | + if (res.success && res.result.records.length > 0) { | |
286 | + //已展开的数据批量子节点 | |
287 | + let records = res.result.records; | |
288 | + const listMap = new Map(); | |
289 | + for (let item of records) { | |
290 | + let pid = item['${pidFieldName}']; | |
291 | + if (unref(expandedRowKeys).includes(pid)) { | |
292 | + let mapList = listMap.get(pid); | |
293 | + if (mapList == null) { | |
294 | + mapList = []; | |
295 | + } | |
296 | + mapList.push(item); | |
297 | + listMap.set(pid, mapList); | |
298 | + } | |
299 | + } | |
300 | + let childrenMap = listMap; | |
301 | + let fn = (list) => { | |
302 | + if (list) { | |
303 | + list.forEach((data) => { | |
304 | + if (unref(expandedRowKeys).includes(data.id)) { | |
305 | + data.children = getDataByResult(childrenMap.get(data.id)); | |
306 | + fn(data.children); | |
307 | + } | |
308 | + }); | |
309 | + } | |
310 | + }; | |
311 | + fn(getDataSource()); | |
312 | + } | |
313 | + } | |
314 | + } | |
315 | + | |
316 | + /** | |
317 | + * 处理数据集 | |
318 | + */ | |
319 | + function getDataByResult(result) { | |
320 | + if (result && result.length > 0) { | |
321 | + return result.map((item) => { | |
322 | + //判断是否标记了带有子节点 | |
323 | + if (item['hasChild'] == '1') { | |
324 | + let loadChild = { id: item.id + '_loadChild', name: 'loading...', isLoading: true }; | |
325 | + item.children = [loadChild]; | |
326 | + } | |
327 | + return item; | |
328 | + }); | |
329 | + } | |
330 | + } | |
331 | + | |
332 | + /** | |
333 | + *树节点展开合并 | |
334 | + */ | |
335 | + async function handleExpand(expanded, record) { | |
336 | + // 判断是否是展开状态,展开状态(expanded)并且存在子集(children)并且未加载过(isLoading)的就去查询子节点数据 | |
337 | + if (expanded) { | |
338 | + expandedRowKeys.value.push(record.id); | |
339 | + if (record.children.length > 0 && !!record.children[0].isLoading) { | |
340 | + let result = await getChildList({ ${pidFieldName}: record.id}); | |
341 | + result = result.records ? result.records : result; | |
342 | + if (result && result.length > 0) { | |
343 | + record.children = getDataByResult(result); | |
344 | + } else { | |
345 | + record.children = null; | |
346 | + record.hasChild = '0'; | |
347 | + } | |
348 | + } | |
349 | + } else { | |
350 | + let keyIndex = expandedRowKeys.value.indexOf(record.id); | |
351 | + if (keyIndex >= 0) { | |
352 | + expandedRowKeys.value.splice(keyIndex, 1); | |
353 | + } | |
354 | + } | |
355 | + } | |
356 | + | |
357 | + /** | |
358 | + * 操作表格后处理树节点展开合并 | |
359 | + */ | |
360 | + async function expandTreeNode(key) { | |
361 | + let record = findTableDataRecord(key); | |
362 | + expandedRowKeys.value.push(key); | |
363 | + let result = await getChildList({ ${pidFieldName}: key }); | |
364 | + if (result && result.length > 0) { | |
365 | + record.children = getDataByResult(result); | |
366 | + } else { | |
367 | + record.children = null; | |
368 | + record.hasChild = '0'; | |
369 | + } | |
370 | + updateTableDataRecord(key, record); | |
371 | + } | |
372 | + | |
373 | + /** | |
374 | + * 操作栏 | |
375 | + */ | |
376 | + function getTableAction(record) { | |
377 | + return [ | |
378 | + { | |
379 | + label: '编辑', | |
380 | + onClick: handleEdit.bind(null, record), | |
381 | + } | |
382 | + ]; | |
383 | + } | |
384 | + | |
385 | + /** | |
386 | + * 下拉操作栏 | |
387 | + */ | |
388 | + function getDropDownAction(record) { | |
389 | + return [ | |
390 | + { | |
391 | + label: '详情', | |
392 | + onClick: handleDetail.bind(null, record), | |
393 | + }, | |
394 | + { | |
395 | + label: '添加下级', | |
396 | + onClick: handleAddSub.bind(null, { pid: record.id }), | |
397 | + }, | |
398 | + { | |
399 | + label: '删除', | |
400 | + popConfirm: { | |
401 | + title: '确定删除吗?', | |
402 | + confirm: handleDelete.bind(null, record), | |
403 | + }, | |
404 | + }, | |
405 | + ]; | |
406 | + } | |
407 | + | |
408 | + /** | |
409 | + * 查询 | |
410 | + */ | |
411 | + function searchQuery() { | |
412 | + reload(); | |
413 | + } | |
414 | + | |
415 | + /** | |
416 | + * 重置 | |
417 | + */ | |
418 | + function searchReset() { | |
419 | + queryParam.value = {}; | |
420 | + selectedRowKeys.value = []; | |
421 | + //刷新数据 | |
422 | + reload(); | |
423 | + } | |
424 | + | |
425 | + <#if need_popup> | |
426 | + /** | |
427 | + * popup组件值改变事件 | |
428 | + */ | |
429 | + function setFieldsValue(map) { | |
430 | + Object.keys(map).map((key) => { | |
431 | + queryParam.value[key] = map[key]; | |
432 | + }); | |
433 | + } | |
434 | + </#if> | |
435 | + | |
436 | + <#if need_pca> | |
437 | + /** | |
438 | + * 省市区点击事件 | |
439 | + * @param key | |
440 | + * @param value | |
441 | + */ | |
442 | + function handleAreaChange(key, value) { | |
443 | + queryParam.value[key] = value.join(','); | |
444 | + } | |
445 | + </#if> | |
446 | + | |
447 | + <#if need_category> | |
448 | + /** | |
449 | + * form点击事件 | |
450 | + * @param value | |
451 | + */ | |
452 | + function handleFormChange(key, value) { | |
453 | + queryParam.value[key] = value; | |
454 | + } | |
455 | + | |
456 | + /** | |
457 | + * 初始化字典配置 | |
458 | + */ | |
459 | + function initDictConfig() { | |
460 | + <#list columns as po> | |
461 | + <#if (po.isQuery=='Y' || po.isShowList=='Y') && po.classType!='popup'> | |
462 | + <#if po.classType=='cat_tree' && need_category==true> | |
463 | + loadCategoryData({code:'${po.dictField?default("")}'}).then((res) => { | |
464 | + if (res) { | |
465 | + let allDictDate = getAuthCache(DB_DICT_DATA_KEY); | |
466 | + if(!allDictDate['${po.dictField?default("")}']){ | |
467 | + Object.assign(allDictDate,{'${po.dictField?default("")}':res}) | |
468 | + } | |
469 | + setAuthCache(DB_DICT_DATA_KEY,allDictDate) | |
470 | + } | |
471 | + }); | |
472 | + </#if> | |
473 | + </#if> | |
474 | + </#list> | |
475 | + } | |
476 | + initDictConfig(); | |
477 | + </#if> | |
478 | +</script> | |
479 | + | |
480 | +<style lang="less" scoped> | |
481 | + .jeecg-basic-table-form-container { | |
482 | + .table-page-search-submitButtons { | |
483 | + display: block; | |
484 | + margin-bottom: 24px; | |
485 | + white-space: nowrap; | |
486 | + } | |
487 | + .query-group-cust{ | |
488 | + width: calc(50% - 15px); | |
489 | + min-width: 100px !important; | |
490 | + } | |
491 | + .query-group-split-cust{ | |
492 | + width: 30px; | |
493 | + display: inline-block; | |
494 | + text-align: center | |
495 | + } | |
496 | + } | |
497 | +</style> | |
... | ... |
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}__api.tsi
0 → 100644
1 | +import { defHttp } from "/@/utils/http/axios"; | |
2 | +import { Modal } from 'ant-design-vue'; | |
3 | + | |
4 | +enum Api { | |
5 | + list = '/${entityPackage}/${entityName?uncap_first}/rootList', | |
6 | + save='/${entityPackage}/${entityName?uncap_first}/add', | |
7 | + edit='/${entityPackage}/${entityName?uncap_first}/edit', | |
8 | + delete${entityName} = '/${entityPackage}/${entityName?uncap_first}/delete', | |
9 | + importExcel = '/${entityPackage}/${entityName?uncap_first}/importExcel', | |
10 | + exportXls = '/${entityPackage}/${entityName?uncap_first}/exportXls', | |
11 | + loadTreeData = '/${entityPackage}/${entityName?uncap_first}/loadTreeRoot', | |
12 | + getChildList = '/${entityPackage}/${entityName?uncap_first}/childList', | |
13 | + getChildListBatch = '/${entityPackage}/${entityName?uncap_first}/getChildListBatch', | |
14 | +} | |
15 | + | |
16 | +/** | |
17 | + * 导出api | |
18 | + * @param params | |
19 | + */ | |
20 | +export const getExportUrl = Api.exportXls; | |
21 | + | |
22 | +/** | |
23 | + * 导入api | |
24 | + * @param params | |
25 | + */ | |
26 | +export const getImportUrl = Api.importExcel; | |
27 | + | |
28 | +/** | |
29 | + * 列表接口 | |
30 | + * @param params | |
31 | + */ | |
32 | +export const list = (params) => defHttp.get({ url: Api.list, params }); | |
33 | + | |
34 | +/** | |
35 | + * 删除 | |
36 | + * @param params | |
37 | + * @param handleSuccess | |
38 | + */ | |
39 | +export const delete${entityName} = (params,handleSuccess) => { | |
40 | + return defHttp.delete({ url: Api.delete${entityName}, params }, { joinParamsToUrl: true }).then(() => { | |
41 | + handleSuccess(); | |
42 | + }); | |
43 | +} | |
44 | + | |
45 | +/** | |
46 | + * 批量删除 | |
47 | + * @param params | |
48 | + * @param handleSuccess | |
49 | + */ | |
50 | +export const batchDelete${entityName} = (params, handleSuccess) => { | |
51 | + Modal.confirm({ | |
52 | + title: '确认删除', | |
53 | + content: '是否删除选中数据', | |
54 | + okText: '确认', | |
55 | + cancelText: '取消', | |
56 | + onOk: () => { | |
57 | + return defHttp.delete({ url: Api.delete${entityName}, data: params }, { joinParamsToUrl: true }).then(() => { | |
58 | + handleSuccess(); | |
59 | + }); | |
60 | + } | |
61 | + }); | |
62 | +} | |
63 | + | |
64 | +/** | |
65 | + * 保存或者更新 | |
66 | + * @param params | |
67 | + * @param isUpdate | |
68 | + */ | |
69 | +export const saveOrUpdateDict = (params, isUpdate) => { | |
70 | + let url = isUpdate ? Api.edit : Api.save; | |
71 | + return defHttp.post({ url: url, params },{ isTransformResponse:false }); | |
72 | +} | |
73 | + | |
74 | +/** | |
75 | + * 查询全部树形节点数据 | |
76 | + * @param params | |
77 | + */ | |
78 | +export const loadTreeData = (params) => defHttp.get({ url: Api.loadTreeData,params }); | |
79 | + | |
80 | +/** | |
81 | + * 查询子节点数据 | |
82 | + * @param params | |
83 | + */ | |
84 | +export const getChildList = (params) => defHttp.get({ url: Api.getChildList, params }); | |
85 | + | |
86 | +/** | |
87 | + * 批量查询子节点数据 | |
88 | + * @param params | |
89 | + */ | |
90 | +export const getChildListBatch = (params) => defHttp.get({ url: Api.getChildListBatch, params },{ isTransformResponse:false }); | |
... | ... |
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}__data.tsi
0 → 100644
1 | +<#include "/common/utils.ftl"> | |
2 | +import {BasicColumn} from '/@/components/Table'; | |
3 | +import {FormSchema} from '/@/components/Table'; | |
4 | +import { rules} from '/@/utils/helper/validator'; | |
5 | +import { render } from '/@/utils/common/renderUtils'; | |
6 | +//列表数据 | |
7 | +export const columns: BasicColumn[] = [ | |
8 | + <#list columns as po> | |
9 | + <#if po.isShowList =='Y' && po.fieldName !='id'> | |
10 | + { | |
11 | + title: '${po.filedComment}', | |
12 | + <#if po.fieldDbName == tableVo.extendParams.textField> | |
13 | + align: 'left', | |
14 | + <#else> | |
15 | + align: 'center', | |
16 | + </#if> | |
17 | + <#if po.sort=='Y'> | |
18 | + sorter: true, | |
19 | + </#if> | |
20 | + <#if po.classType=='date'> | |
21 | + dataIndex: '${po.fieldName}', | |
22 | + customRender:({text}) =>{ | |
23 | + return !text?"":(text.length>10?text.substr(0,10):text); | |
24 | + }, | |
25 | + <#elseif po.fieldDbType=='Blob'> | |
26 | + dataIndex: '${po.fieldName}String' | |
27 | + <#elseif po.classType=='umeditor'> | |
28 | + dataIndex: '${po.fieldName}', | |
29 | + slots: { customRender: 'htmlSlot' }, | |
30 | + <#elseif po.classType=='pca'> | |
31 | + dataIndex: '${po.fieldName}', | |
32 | + slots: { customRender: 'pcaSlot' }, | |
33 | + <#elseif po.classType=='file'> | |
34 | + dataIndex: '${po.fieldName}', | |
35 | + slots: { customRender: 'fileSlot' }, | |
36 | + <#elseif po.classType=='image'> | |
37 | + dataIndex: '${po.fieldName}', | |
38 | + customRender: render.renderImage, | |
39 | + <#elseif po.classType=='switch'> | |
40 | + dataIndex: '${po.fieldName}', | |
41 | +<#assign switch_extend_arr=['Y','N']> | |
42 | +<#if po.dictField?default("")?contains("[")> | |
43 | +<#assign switch_extend_arr=po.dictField?eval> | |
44 | +</#if> | |
45 | +<#list switch_extend_arr as a> | |
46 | +<#if a_index == 0> | |
47 | +<#assign switch_extend_arr1=a> | |
48 | +<#else> | |
49 | +<#assign switch_extend_arr2=a> | |
50 | +</#if> | |
51 | +</#list> | |
52 | + customRender:({text}) => { | |
53 | + return render.renderSwitch(text, [{text:'是',value:'${switch_extend_arr1}'},{text:'否',value:'${switch_extend_arr2}'}]); | |
54 | + }, | |
55 | + <#elseif po.classType == 'sel_tree' || po.classType=='list' || po.classType=='list_multi' || po.classType=='sel_search' || po.classType=='radio' || po.classType=='checkbox' || po.classType=='sel_depart' || po.classType=='sel_user'> | |
56 | + dataIndex: '${po.fieldName}_dictText' | |
57 | + <#elseif po.classType=='cat_tree'> | |
58 | + dataIndex: '${po.fieldName}', | |
59 | + <#if po.dictText?default("")?trim?length == 0> | |
60 | + customRender:({text}) => { | |
61 | + return render.renderCategoryTree(text,'${po.dictField?default("")}'); | |
62 | + }, | |
63 | + <#else> | |
64 | + customRender: ({text, record}) => (text ? record['${po.dictText}'] : ''); | |
65 | + </#if> | |
66 | + <#else> | |
67 | + dataIndex: '${po.fieldName}' | |
68 | + </#if> | |
69 | + }, | |
70 | + </#if> | |
71 | + </#list> | |
72 | +]; | |
73 | + | |
74 | +//查询数据 | |
75 | +export const searchFormSchema: FormSchema[] = [ | |
76 | +<#-- 开始循环 --> | |
77 | +<#list columns as po> | |
78 | +<#if po.fieldDbName=='bpm_status'> | |
79 | + <#assign bpm_flag=true> | |
80 | +</#if> | |
81 | +<#if po.isQuery=='Y'> | |
82 | +<#assign query_flag=true> | |
83 | + <#assign query_field_dictCode=""> | |
84 | + <#if po.dictTable?default("")?trim?length gt 1> | |
85 | + <#assign query_field_dictCode="${po.dictTable},${po.dictText},${po.dictField}"> | |
86 | + <#elseif po.dictField?default("")?trim?length gt 1> | |
87 | + <#assign query_field_dictCode="${po.dictField}"> | |
88 | + </#if> | |
89 | +<#if po.queryMode=='single'> | |
90 | + { | |
91 | + label: "${po.filedComment}", | |
92 | + field: "${po.fieldName}", | |
93 | +<#if po.classType=='sel_search'> | |
94 | + component: 'JSearchSelect', | |
95 | + componentProps: { | |
96 | + dict:"${po.dictTable},${po.dictText},${po.dictField}" | |
97 | + }, | |
98 | +<#elseif po.classType=='sel_user'> | |
99 | + component: 'JSelectUserByDept', | |
100 | +<#elseif po.classType=='switch'> | |
101 | + component: 'JSwitch', | |
102 | + componentProps: { | |
103 | + <#if po.dictField != 'is_open'> | |
104 | + options: '${po.dictField}', | |
105 | + </#if> | |
106 | + }, | |
107 | + <#elseif po.classType=='sel_depart'> | |
108 | + component: 'JSelectDept', | |
109 | + <#elseif po.classType=='list_multi'> | |
110 | + component: 'JSelectMultiple', | |
111 | + componentProps: { | |
112 | + <#if po.dictTable?default("")?trim?length gt 1> | |
113 | + options: "${po.dictField}", | |
114 | + dictCode: "${po.dictTable},${po.dictText},${po.dictField}", | |
115 | + <#elseif po.dictField?default("")?trim?length gt 1> | |
116 | + dictCode: "${po.dictField}", | |
117 | + </#if> | |
118 | + triggerChange: true | |
119 | + }, | |
120 | + <#elseif po.classType=='cat_tree'> | |
121 | + component: 'JCategorySelect', | |
122 | + componentProps:{ | |
123 | + pcode:"${po.dictField?default("")}",//back和事件未添加,暂时有问题 | |
124 | + }, | |
125 | +<#elseif po.classType=='date'> | |
126 | + component: 'DatePicker', | |
127 | +<#elseif po.classType=='datetime'> | |
128 | + component: 'DatePicker', | |
129 | + componentProps: { | |
130 | + showTime: true | |
131 | + }, | |
132 | +<#elseif po.classType=='pca'> | |
133 | + component: 'JAreaLinkage', | |
134 | +<#elseif po.classType=='popup'> | |
135 | + <#include "/common/form/vue3popup.ftl"> | |
136 | +<#elseif po.classType == 'sel_tree'> | |
137 | + component: 'JTreeSelect', | |
138 | + componentProps: { | |
139 | + <#if po.dictText??> | |
140 | + <#if po.dictText?split(',')[2]?? && po.dictText?split(',')[0]??> | |
141 | + dict: "${po.dictTable},${po.dictText?split(',')[2]},${po.dictText?split(',')[0]}", | |
142 | + </#if> | |
143 | + <#if po.dictText?split(',')[1]??> | |
144 | + pidField: "${po.dictText?split(',')[1]}", | |
145 | + </#if> | |
146 | + <#if po.dictText?split(',')[3]??> | |
147 | + hasChildField: "${po.dictText?split(',')[3]}", | |
148 | + </#if> | |
149 | + </#if> | |
150 | + pidValue: "${po.dictField}", | |
151 | + }, | |
152 | +<#elseif po.classType=='list' || po.classType=='radio' || po.classType=='checkbox'> | |
153 | +<#-- ---------------------------下拉或是单选 判断数据字典是表字典还是普通字典------------------------------- --> | |
154 | + component: 'JDictSelectTag', | |
155 | + componentProps:{ | |
156 | + <#if po.dictTable?default("")?trim?length gt 1> | |
157 | + dictCode: "${po.dictTable},${po.dictText},${po.dictField}" | |
158 | + <#elseif po.dictField?default("")?trim?length gt 1> | |
159 | + dictCode: "${po.dictField}" | |
160 | + </#if> | |
161 | + }, | |
162 | +<#else> | |
163 | + component: 'Input', | |
164 | +</#if> | |
165 | + colProps: {span: 6}, | |
166 | + }, | |
167 | +<#else> | |
168 | + { | |
169 | + label: "${po.filedComment}", | |
170 | + field: "${po.fieldName}", | |
171 | +<#if po.classType=='date'> | |
172 | + component: 'RangePicker', | |
173 | +<#elseif po.classType=='datetime'> | |
174 | + component: 'RangePicker', | |
175 | + componentProps: { | |
176 | + showTime: true | |
177 | + }, | |
178 | +<#elseif po.classType == 'time'> | |
179 | + component: 'TimePicker', | |
180 | + componentProps:{ | |
181 | + valueFormat: 'HH:mm:ss', | |
182 | + }, | |
183 | +<#elseif po.fieldDbType=='int' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'> | |
184 | + component: 'JRangeNumber', | |
185 | +<#else> | |
186 | + component: 'Input', //TODO 范围查询 | |
187 | +</#if> | |
188 | + colProps: {span: 6}, | |
189 | + }, | |
190 | +</#if> | |
191 | +</#if> | |
192 | +</#list> | |
193 | +<#-- 结束循环 --> | |
194 | +]; | |
195 | + | |
196 | +//表单数据 | |
197 | +export const formSchema: FormSchema[] = [ | |
198 | +<#assign form_cat_tree = false> | |
199 | +<#assign form_cat_back = ""> | |
200 | +<#assign bpm_flag=false> | |
201 | +<#assign id_exists = false> | |
202 | +<#list columns as po><#rt/> | |
203 | +<#if po.fieldDbName=='bpm_status'> | |
204 | + <#assign bpm_flag=true> | |
205 | +</#if> | |
206 | +<#if po.fieldDbName == 'id'> | |
207 | + <#assign id_exists = true> | |
208 | +</#if> | |
209 | +<#if po.isShow =='Y'> | |
210 | +<#assign form_field_dictCode=""> | |
211 | + <#if po.dictTable?default("")?trim?length gt 1 && po.dictText?default("")?trim?length gt 1 && po.dictField?default("")?trim?length gt 1> | |
212 | + <#assign form_field_dictCode="${po.dictTable},${po.dictText},${po.dictField}"> | |
213 | + <#elseif po.dictField?default("")?trim?length gt 1> | |
214 | + <#assign form_field_dictCode="${po.dictField}"> | |
215 | + </#if> | |
216 | + { | |
217 | + label: '${po.filedComment}', | |
218 | + field: ${autoStringSuffix(po)}, | |
219 | + <#if po.fieldDbName == tableVo.extendParams.pidField> | |
220 | + component: 'JTreeSelect', | |
221 | + componentProps: { | |
222 | + dict: "${tableVo.tableName},${tableVo.extendParams.textField},id", | |
223 | + pidField: "${tableVo.extendParams.pidField}", | |
224 | + pidValue: "0", | |
225 | + hasChildField: "${tableVo.extendParams.hasChildren}", | |
226 | + }, | |
227 | + <#elseif po.classType =='date'> | |
228 | + component: 'DatePicker', | |
229 | + <#elseif po.classType =='datetime'> | |
230 | + component: 'DatePicker', | |
231 | + componentProps: { | |
232 | + showTime:true, | |
233 | + valueFormat: 'YYYY-MM-DD hh:mm:ss' | |
234 | + }, | |
235 | + <#elseif po.classType =='time'> | |
236 | + component: 'TimePicker', | |
237 | + componentProps:{ | |
238 | + valueFormat: 'HH:mm:ss', | |
239 | + }, | |
240 | + <#elseif po.classType =='popup'> | |
241 | + <#include "/common/form/vue3popup.ftl"> | |
242 | + <#elseif po.classType =='sel_depart'> | |
243 | + component: 'JSelectDept', | |
244 | + <#elseif po.classType =='switch'> | |
245 | + component: 'JSwitch', | |
246 | + componentProps:{ | |
247 | + <#if po.dictField != 'is_open'> | |
248 | + options:${po.dictField} | |
249 | + </#if> | |
250 | + }, | |
251 | + <#elseif po.classType =='pca'> | |
252 | + component: 'JAreaLinkage', | |
253 | + <#elseif po.classType =='markdown'> | |
254 | + component: 'JMarkdownEditor',//注意string转换问题 | |
255 | + <#elseif po.classType =='password'> | |
256 | + component: 'InputPassword', | |
257 | + <#elseif po.classType =='sel_user'> | |
258 | + component: 'JSelectUserByDept', | |
259 | + componentProps:{ | |
260 | + labelKey: 'realname', | |
261 | + }, | |
262 | + <#elseif po.classType =='textarea'> | |
263 | + component: 'InputTextArea', | |
264 | + <#elseif po.classType=='list' || po.classType=='radio'> | |
265 | + component: 'JDictSelectTag', | |
266 | + componentProps:{ | |
267 | + dictCode: "${form_field_dictCode}" | |
268 | + }, | |
269 | + <#elseif po.classType=='list_multi' || po.classType=='checkbox'> | |
270 | + component: 'JSelectMultiple', | |
271 | + componentProps:{ | |
272 | + dictCode: "${form_field_dictCode}" | |
273 | + }, | |
274 | + <#elseif po.classType=='sel_search'> | |
275 | + component: 'JSearchSelect', | |
276 | + componentProps:{ | |
277 | + dict: "${form_field_dictCode}" | |
278 | + }, | |
279 | +<#elseif po.classType=='cat_tree'> | |
280 | + <#assign form_cat_tree = true> | |
281 | + component: 'JCategorySelect', | |
282 | + componentProps:{ | |
283 | + pcode: "${po.dictField?default("")}", //TODO back和事件未添加,暂时有问题 | |
284 | + }, | |
285 | + <#if po.dictText?default("")?trim?length gt 1> | |
286 | + <#assign form_cat_back = "${po.dictText}"> | |
287 | + </#if> | |
288 | + <#elseif po.fieldDbType=='int' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'> | |
289 | + component: 'InputNumber', | |
290 | + <#elseif po.classType=='file'> | |
291 | + component: 'JUpload', | |
292 | + componentProps:{ | |
293 | + <#if po.uploadnum??> | |
294 | + maxCount: ${po.uploadnum} | |
295 | + </#if> | |
296 | + }, | |
297 | + <#elseif po.classType=='image'> | |
298 | + component: 'JImageUpload', | |
299 | + componentProps:{ | |
300 | + <#if po.uploadnum??> | |
301 | + fileMax: ${po.uploadnum} | |
302 | + </#if> | |
303 | + }, | |
304 | + <#elseif po.classType=='umeditor'> | |
305 | + component: 'JEditor', | |
306 | + <#elseif po.classType == 'sel_tree'> | |
307 | + component: 'JTreeSelect', | |
308 | + componentProps:{ | |
309 | + <#if po.dictText??> | |
310 | + <#if po.dictText?split(',')[2]?? && po.dictText?split(',')[0]??> | |
311 | + dict: "${po.dictTable},${po.dictText?split(',')[2]},${po.dictText?split(',')[0]}", | |
312 | + </#if> | |
313 | + <#if po.dictText?split(',')[1]??> | |
314 | + pidField: "${po.dictText?split(',')[1]}", | |
315 | + </#if> | |
316 | + <#if po.dictText?split(',')[3]??> | |
317 | + hasChildField: "${po.dictText?split(',')[3]}", | |
318 | + </#if> | |
319 | + </#if> | |
320 | + pidValue: "${po.dictField}", | |
321 | + }, | |
322 | + <#else> | |
323 | + component: 'Input', | |
324 | + </#if> | |
325 | + <#include "/common/utils.ftl"> | |
326 | + <#if po.isShow == 'Y' && poHasCheck(po)> | |
327 | + dynamicRules: ({ model, schema }) => { | |
328 | + <#if po.fieldName != 'id'> | |
329 | + <#assign fieldValidType = po.fieldValidType!''> | |
330 | + return [ | |
331 | + <#-- 非空校验 --> | |
332 | + <#if po.nullable == 'N' || fieldValidType == '*'> | |
333 | + { required: true, message: '请输入${po.filedComment}!' }, | |
334 | + <#elseif fieldValidType!=''> | |
335 | + { required: false }, | |
336 | + </#if> | |
337 | + <#-- 唯一校验 --> | |
338 | + <#if fieldValidType == 'only'> | |
339 | + {...rules.duplicateCheckRule(<#if sub?default("")?trim?length gt 1>'${sub.tableName}'<#else>'${tableName}'</#if>, '${po.fieldDbName}',model,schema)[0]}, | |
340 | + <#-- 6到16位数字 --> | |
341 | + <#elseif fieldValidType == 'n6-16'> | |
342 | + { pattern: /^\d{6,16}$/, message: '请输入6到16位数字!' }, | |
343 | + <#-- 6到16位任意字符 --> | |
344 | + <#elseif fieldValidType == '*6-16'> | |
345 | + { pattern: /^.{6,16}$/, message: '请输入6到16位任意字符!' }, | |
346 | + <#-- 6到18位字母 --> | |
347 | + <#elseif fieldValidType == 's6-18'> | |
348 | + { pattern:/^[a-z|A-Z]{6,18}$/, message: '请输入6到18位字母!' }, | |
349 | + <#-- 网址 --> | |
350 | + <#elseif fieldValidType == 'url'> | |
351 | + { pattern: /^((ht|f)tps?):\/\/[\w\-]+(\.[\w\-]+)+([\w\-.,@?^=%&:\/~+#]*[\w\-@?^=%&\/~+#])?$/, message: '请输入正确的网址!' }, | |
352 | + <#-- 电子邮件 --> | |
353 | + <#elseif fieldValidType == 'e'> | |
354 | + { pattern: /^([\w]+\.*)([\w]+)@[\w]+\.\w{3}(\.\w{2}|)$/, message: '请输入正确的电子邮件! }, | |
355 | + <#-- 手机号码 --> | |
356 | + <#elseif fieldValidType == 'm'> | |
357 | + { pattern: /^1[3456789]\d{9}$/, message: '请输入正确的手机号码!' }, | |
358 | + <#-- 邮政编码 --> | |
359 | + <#elseif fieldValidType == 'p'> | |
360 | + { pattern: /^[1-9]\d{5}$/, message: '请输入正确的邮政编码!' }, | |
361 | + <#-- 字母 --> | |
362 | + <#elseif fieldValidType == 's'> | |
363 | + { pattern: /^[A-Z|a-z]+$/, message: '请输入字母!' }, | |
364 | + <#-- 数字 --> | |
365 | + <#elseif fieldValidType == 'n'> | |
366 | + { pattern: /^-?\d+\.?\d*$/, message: '请输入数字!' }, | |
367 | + <#-- 整数 --> | |
368 | + <#elseif fieldValidType == 'z'> | |
369 | + { pattern: /^-?\d+$/, message: '请输入整数!' }, | |
370 | + <#-- 金额 --> | |
371 | + <#elseif fieldValidType == 'money'> | |
372 | + { pattern: /^(([1-9][0-9]*)|([0]\.\d{0,2}|[1-9][0-9]*\.\d{0,2}))$/, message: '请输入正确的金额!' }, | |
373 | + <#-- 正则校验 --> | |
374 | + <#elseif fieldValidType != '' && fieldValidType != '*'> | |
375 | + { pattern: '${fieldValidType}', message: '不符合校验规则!' }, | |
376 | + <#-- 无校验 --> | |
377 | + <#else> | |
378 | + <#t> | |
379 | + </#if> | |
380 | + ]; | |
381 | + </#if> | |
382 | + }, | |
383 | + </#if> | |
384 | + <#if po.readonly=='Y'> | |
385 | + dynamicDisabled: true | |
386 | + </#if> | |
387 | + }, | |
388 | +</#if> | |
389 | +</#list> | |
390 | +<#if id_exists == false> | |
391 | + // TODO 主键隐藏字段,目前写死为ID | |
392 | + { | |
393 | + label: '', | |
394 | + field: 'id', | |
395 | + component: 'Input', | |
396 | + show: false, | |
397 | + }, | |
398 | +</#if> | |
399 | +]; | |
... | ... |
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}_menu_insert.sql
0 → 100644
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3Native/components/${entityName}Form.vuei
0 → 100644
1 | +<#include "/common/utils.ftl"> | |
2 | +<template> | |
3 | + <a-spin :spinning="confirmLoading"> | |
4 | + <a-form ref="formRef" class="antd-modal-form" :labelCol="labelCol" :wrapperCol="wrapperCol"> | |
5 | + <a-row> | |
6 | +<#assign need_category = false> | |
7 | +<#assign bpm_flag=false> | |
8 | +<#assign need_pca = false> | |
9 | +<#assign need_search = false> | |
10 | +<#assign need_dept_user = false> | |
11 | +<#assign need_switch = false> | |
12 | +<#assign need_dept = false> | |
13 | +<#assign need_multi = false> | |
14 | +<#assign need_popup = false> | |
15 | +<#assign need_select_tag = false> | |
16 | +<#assign need_select_tree = false> | |
17 | +<#assign need_time = false> | |
18 | +<#assign need_markdown = false> | |
19 | +<#assign need_upload = false> | |
20 | +<#assign need_image_upload = false> | |
21 | +<#assign need_editor = false> | |
22 | +<#assign need_checkbox = false> | |
23 | +<#assign pidFieldName = ""> | |
24 | +<#assign hasOnlyValidate = false> | |
25 | +<#assign form_span = 24> | |
26 | +<#if tableVo.fieldRowNum==2> | |
27 | +<#assign form_span = 12> | |
28 | +<#elseif tableVo.fieldRowNum==3> | |
29 | +<#assign form_span = 8> | |
30 | +<#elseif tableVo.fieldRowNum==4> | |
31 | +<#assign form_span = 6> | |
32 | +</#if> | |
33 | +<#list columns as po> | |
34 | +<#if po.fieldDbName=='bpm_status'> | |
35 | + <#assign bpm_flag=true> | |
36 | +</#if> | |
37 | +<#if po.isShow == 'Y' && po.fieldValidType?default("") == 'only'> | |
38 | + <#assign hasOnlyValidate = true> | |
39 | +</#if> | |
40 | + <#if po.fieldDbName == tableVo.extendParams.pidField> | |
41 | + <#assign pidFieldName = po.fieldName> | |
42 | + <a-col :span="${form_span}"> | |
43 | + <a-form-item label="父级节点" v-bind="validateInfos.${autoStringSuffixForModel(po)}"> | |
44 | + <j-tree-select | |
45 | + placeholder="请选择${po.filedComment}" | |
46 | + v-model:value="formData.${po.fieldName}" | |
47 | + dict="${tableVo.tableName},${tableVo.extendParams.textField},id" | |
48 | + pidField="${tableVo.extendParams.pidField}" | |
49 | + pidValue="0" | |
50 | + hasChildField="${tableVo.extendParams.hasChildren}" | |
51 | + <#if po.readonly=='Y'>disabled<#else>:disabled="disabled"</#if>> | |
52 | + </j-tree-select> | |
53 | + </a-form-item> | |
54 | + </a-col> | |
55 | + </#if> | |
56 | + <#include "/common/form/native/vue3NativeForm.ftl"> | |
57 | +</#list> | |
58 | + </a-row> | |
59 | + </a-form> | |
60 | + </a-spin> | |
61 | +</template> | |
62 | + | |
63 | +<script lang="ts" setup> | |
64 | + import { ref, reactive, defineExpose, nextTick, unref, defineProps, computed } from 'vue'; | |
65 | + import { defHttp } from '/@/utils/http/axios'; | |
66 | + import { useMessage } from '/@/hooks/web/useMessage'; | |
67 | + import moment from 'moment'; | |
68 | + <#include "/common/form/native/vue3NativeImport.ftl"> | |
69 | + import { getValueType } from '/@/utils'; | |
70 | + import { validateDuplicateValue } from '/@/utils/helper/validator'; | |
71 | + import {loadTreeData, saveOrUpdateDict} from '../${entityName}.api'; | |
72 | + import { Form } from 'ant-design-vue'; | |
73 | + <#if hasOnlyValidate == true> | |
74 | + import { duplicateValidate } from '/@/utils/helper/validator' | |
75 | + </#if> | |
76 | + | |
77 | + const useForm = Form.useForm; | |
78 | + const formRef = ref(); | |
79 | + const isUpdate = ref(true); | |
80 | + const expandedRowKeys = ref([]); | |
81 | + const treeData = ref([]); | |
82 | + const pidField = ref<string>('pid'); | |
83 | + const emit = defineEmits(['register', 'ok']); | |
84 | + let model: Nullable<Recordable> = null; | |
85 | + const formData = reactive<Record<string, any>>({ | |
86 | +<#list columns as po> | |
87 | + <#if po.isShow == 'Y'> | |
88 | + <#if po.fieldDbType=='int' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'> | |
89 | + ${po.fieldName}: undefined, | |
90 | + <#elseif po.fieldDbType=='Blob'> | |
91 | + ${po.fieldName}String: '', | |
92 | + <#else> | |
93 | + ${po.fieldName}: '', | |
94 | + </#if> | |
95 | + </#if> | |
96 | +</#list> | |
97 | + }); | |
98 | + const { createMessage } = useMessage(); | |
99 | + const labelCol = ref<any>({ xs: { span: 24 }, sm: { span: 5 } }); | |
100 | + const wrapperCol = ref<any>({ xs: { span: 24 }, sm: { span: 16 } }); | |
101 | + const confirmLoading = ref<boolean>(false); | |
102 | + //表单验证 | |
103 | + const validatorRules = { | |
104 | + <#include "/common/validatorRulesTemplate/native/vue3MainNative.ftl"> | |
105 | + }; | |
106 | + const { resetFields, validate, validateInfos } = useForm(formData, validatorRules, { immediate: true }); | |
107 | + const props = defineProps({ | |
108 | + disabled: { type: Boolean, default: false }, | |
109 | + }); | |
110 | + | |
111 | + /** | |
112 | + * 新增 | |
113 | + */ | |
114 | + function add(obj = {}) { | |
115 | + edit(obj); | |
116 | + } | |
117 | + | |
118 | + /** | |
119 | + * 编辑 | |
120 | + */ | |
121 | + function edit(record) { | |
122 | + nextTick(async () => { | |
123 | + resetFields(); | |
124 | + expandedRowKeys.value = []; | |
125 | + treeData.value = await loadTreeData({ async: false, pcode: '' }); | |
126 | + //赋值 | |
127 | + Object.assign(formData, record); | |
128 | + }); | |
129 | + } | |
130 | + | |
131 | + /** | |
132 | + * 根据pid获取展开的节点 | |
133 | + * @param pid | |
134 | + * @param arr | |
135 | + */ | |
136 | + function getExpandKeysByPid(pid, arr) { | |
137 | + if (pid && arr && arr.length > 0) { | |
138 | + for (let i = 0; i < arr.length; i++) { | |
139 | + if (arr[i].key == pid && unref(expandedRowKeys).indexOf(pid) < 0) { | |
140 | + expandedRowKeys.value.push(arr[i].key); | |
141 | + getExpandKeysByPid(arr[i]['parentId'], unref(treeData)); | |
142 | + } else { | |
143 | + getExpandKeysByPid(pid, arr[i].children); | |
144 | + } | |
145 | + } | |
146 | + } | |
147 | + } | |
148 | + | |
149 | + /** | |
150 | + * 提交数据 | |
151 | + */ | |
152 | + async function submitForm() { | |
153 | + // 触发表单验证 | |
154 | + await validate(); | |
155 | + confirmLoading.value = true; | |
156 | + const isUpdate = ref<boolean>(false); | |
157 | + //时间格式化 | |
158 | + if (formData.id) { | |
159 | + isUpdate.value = true; | |
160 | + } | |
161 | + //循环数据 | |
162 | + for (let data in formData) { | |
163 | + //如果该数据是数组并且是字符串类型 | |
164 | + if (formData[data] instanceof Array) { | |
165 | + let valueType = getValueType(formRef.value.getProps, data); | |
166 | + //如果是字符串类型的需要变成以逗号分割的字符串 | |
167 | + if (valueType === 'string') { | |
168 | + formData[data] = formData[data].join(','); | |
169 | + } | |
170 | + } | |
171 | + } | |
172 | + await saveOrUpdateDict(formData, isUpdate.value) | |
173 | + .then(async (res) => { | |
174 | + if (res.success) { | |
175 | + await getExpandKeysByPid(formData['${pidFieldName}'], unref(treeData)); | |
176 | + emit('ok', { | |
177 | + isUpdate: unref(isUpdate), | |
178 | + values: { ...formData }, | |
179 | + expandedArr: unref(expandedRowKeys).reverse(), | |
180 | + // 是否更改了父级节点 | |
181 | + changeParent: model != null && model['${pidFieldName}'] != formData['${pidFieldName}'], | |
182 | + }); | |
183 | + createMessage.success(res.message); | |
184 | + } else { | |
185 | + createMessage.warning(res.message); | |
186 | + } | |
187 | + }) | |
188 | + .finally(() => { | |
189 | + confirmLoading.value = false; | |
190 | + }); | |
191 | + } | |
192 | + | |
193 | + <#if need_popup> | |
194 | + /** | |
195 | + * popup组件值改变事件 | |
196 | + */ | |
197 | + function setFieldsValue(map) { | |
198 | + Object.keys(map).map((key) => { | |
199 | + formData[key] = map[key]; | |
200 | + }); | |
201 | + } | |
202 | + </#if> | |
203 | + | |
204 | + <#if need_category || need_select_tree> | |
205 | + /** | |
206 | + * 值改变事件触发 | |
207 | + * @param key | |
208 | + * @param value | |
209 | + */ | |
210 | + function handleFormChange(key, value) { | |
211 | + formData[key] = value; | |
212 | + } | |
213 | + </#if> | |
214 | + | |
215 | + <#list columns as po> | |
216 | + <#if po.isShow == 'Y' && po.fieldValidType?default("") == 'only'> | |
217 | + async function ${po.fieldName}Duplicatevalidate(_r, value) { | |
218 | + return duplicateValidate('${tableName}', '${po.fieldDbName}', value, formData.id || '') | |
219 | + } | |
220 | + </#if> | |
221 | + </#list> | |
222 | + defineExpose({ | |
223 | + add, | |
224 | + edit, | |
225 | + submitForm, | |
226 | + }); | |
227 | +</script> | |
228 | + | |
229 | +<style lang="less" scoped> | |
230 | + .antd-modal-form { | |
231 | + height: 500px !important; | |
232 | + overflow-y: auto; | |
233 | + padding: 24px 24px 24px 24px; | |
234 | + } | |
235 | +</style> | |
... | ... |
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/tree/java/${bussiPackage}/${entityPackage}/vue3Native/components/${entityName}Modal.vuei
0 → 100644
1 | +<template> | |
2 | + <a-modal :title="title" :width="width" :visible="visible" @ok="handleOk" :okButtonProps="{ class: { 'jee-hidden': disableSubmit } }" @cancel="handleCancel" cancelText="关闭"> | |
3 | + <${entityName}Form ref="registerForm" @ok="submitCallback" :disabled="disableSubmit"></${entityName}Form> | |
4 | + </a-modal> | |
5 | +</template> | |
6 | + | |
7 | +<script lang="ts" setup> | |
8 | + import { ref, nextTick, defineExpose } from 'vue'; | |
9 | + import ${entityName}Form from './${entityName}Form.vue' | |
10 | + | |
11 | + const title = ref<string>(''); | |
12 | + const width = ref<number>(800); | |
13 | + const visible = ref<boolean>(false); | |
14 | + const disableSubmit = ref<boolean>(false); | |
15 | + const registerForm = ref(); | |
16 | + const emit = defineEmits(['register', 'success']); | |
17 | + | |
18 | + /** | |
19 | + * 新增 | |
20 | + */ | |
21 | + function add(obj={}) { | |
22 | + title.value = '新增'; | |
23 | + visible.value = true; | |
24 | + nextTick(() => { | |
25 | + registerForm.value.add(obj); | |
26 | + }); | |
27 | + } | |
28 | + | |
29 | + /** | |
30 | + * 编辑 | |
31 | + * @param record | |
32 | + */ | |
33 | + function edit(record) { | |
34 | + title.value = disableSubmit.value ? '详情' : '编辑'; | |
35 | + visible.value = true; | |
36 | + nextTick(() => { | |
37 | + registerForm.value.edit(record); | |
38 | + }); | |
39 | + } | |
40 | + | |
41 | + /** | |
42 | + * 确定按钮点击事件 | |
43 | + */ | |
44 | + function handleOk() { | |
45 | + registerForm.value.submitForm(); | |
46 | + } | |
47 | + | |
48 | + /** | |
49 | + * form保存回调事件 | |
50 | + */ | |
51 | + function submitCallback({ isUpdate, values, expandedArr, changeParent }) { | |
52 | + handleCancel(); | |
53 | + emit('success', { | |
54 | + isUpdate: isUpdate, | |
55 | + values: values, | |
56 | + expandedArr: expandedArr, | |
57 | + // 是否更改了父级节点 | |
58 | + changeParent: changeParent, | |
59 | + }); | |
60 | + } | |
61 | + | |
62 | + /** | |
63 | + * 取消按钮回调事件 | |
64 | + */ | |
65 | + function handleCancel() { | |
66 | + visible.value = false; | |
67 | + } | |
68 | + | |
69 | + defineExpose({ | |
70 | + add, | |
71 | + edit, | |
72 | + disableSubmit, | |
73 | + }); | |
74 | +</script> | |
75 | + | |
76 | +<style> | |
77 | + /**隐藏样式-modal确定按钮 */ | |
78 | + .jee-hidden { | |
79 | + display: none !important; | |
80 | + } | |
81 | +</style> | |
... | ... |
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/entity/${entityName}.javai
1 | +<#include "/common/utils.ftl"> | |
1 | 2 | package ${bussiPackage}.${entityPackage}.entity; |
2 | 3 | |
3 | 4 | import java.io.Serializable; |
... | ... | @@ -31,9 +32,9 @@ public class ${entityName} implements Serializable { |
31 | 32 | <#-- 生成字典Code --> |
32 | 33 | <#assign list_field_dictCode=""> |
33 | 34 | <#if po.classType='sel_user'> |
34 | - <#assign list_field_dictCode=', dictTable = "sys_user", dicText = "realname", dicCode = "username"'> | |
35 | + <#assign list_field_dictCode=', dictTable = "sys_user", dicText = "${camelToDashed(po.extendParams.text?default(\"realname\")?trim)}", dicCode = "${camelToDashed(po.extendParams.store?default(\"username\")?trim)}"'> | |
35 | 36 | <#elseif po.classType='sel_depart'> |
36 | - <#assign list_field_dictCode=', dictTable = "sys_depart", dicText = "depart_name", dicCode = "id"'> | |
37 | + <#assign list_field_dictCode=', dictTable = "sys_depart", dicText = "${camelToDashed(po.extendParams.text?default(\"depart_name\")?trim)}", dicCode = "${camelToDashed(po.extendParams.store?default(\"id\")?trim)}"'> | |
37 | 38 | <#elseif po.classType=='list' || po.classType=='list_multi' || po.classType=='sel_search' || po.classType=='radio' || po.classType=='checkbox'> |
38 | 39 | <#if po.dictTable?default("")?trim?length gt 1> |
39 | 40 | <#assign list_field_dictCode=', dictTable = "${po.dictTable}", dicText = "${po.dictText}", dicCode = "${po.dictField}"'> |
... | ... |
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/entity/[1-n]Entity.javai
1 | +<#include "/common/utils.ftl"> | |
1 | 2 | <#list subTables as subTab> |
2 | 3 | #segment#${subTab.entityName}.java |
3 | 4 | package ${bussiPackage}.${entityPackage}.entity; |
... | ... | @@ -65,7 +66,8 @@ public class ${subTab.entityName} implements Serializable { |
65 | 66 | @Dict(dicCode = "id",dicText = "name",dictTable = "sys_category") |
66 | 67 | </#if> |
67 | 68 | <#if po.classType =='sel_depart'> |
68 | - @Dict(dicCode = "id",dicText = "depart_name",dictTable = "sys_depart") | |
69 | + <#assign list_field_dictCode='dicCode = "${camelToDashed(po.extendParams.store?default(\"id\")?trim)}", dicText = "${camelToDashed(po.extendParams.text?default(\"depart_name\")?trim)}", dictTable = "sys_depart"'> | |
70 | + @Dict(${list_field_dictCode}) | |
69 | 71 | </#if> |
70 | 72 | <#-- 大字段转换 --> |
71 | 73 | <#include "/common/blob.ftl"> |
... | ... |
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue/${entityName}List.vuei
... | ... | @@ -193,7 +193,7 @@ |
193 | 193 | <#assign sub_seq=1> |
194 | 194 | <#list subTables as sub> |
195 | 195 | <a-tab-pane tab="${sub.ftlDescription}" key="${sub_seq}" <#if sub_seq gt 1>forceRender</#if>> |
196 | - <${sub.entityName}List :mainId="selectedMainId" /> | |
196 | + <${sub.entityName}List :mainId="${sub.entityName?uncap_first}MainId" /> | |
197 | 197 | </a-tab-pane> |
198 | 198 | <#assign sub_seq=sub_seq+1> |
199 | 199 | </#list> |
... | ... |
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue/${entityName}_menu_insert.sql
0 → 100644
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/${entityName}Modal.vuei
... | ... | @@ -44,7 +44,7 @@ |
44 | 44 | @input="popupCallback" |
45 | 45 | <#if po.readonly=='Y'>disabled</#if>/> |
46 | 46 | <#elseif po.classType =='sel_depart'> |
47 | - <j-select-depart v-model="model.${po.fieldName}" multi <#if po.readonly=='Y'>disabled</#if>/> | |
47 | + <j-select-depart v-model="model.${po.fieldName}" :multi="${po.extendParams.multi?default('true')}"<#if po.extendParams.store?default("")?trim?length gt 0> store="${po.extendParams.store}"</#if><#if po.extendParams.text?default("")?trim?length gt 0> text="${po.extendParams.text}"</#if> <#if po.readonly=='Y'>disabled</#if> /> | |
48 | 48 | <#elseif po.classType =='switch'> |
49 | 49 | <j-switch v-model="model.${po.fieldName}" <#if po.dictField!= 'is_open'>:options="${po.dictField}"</#if> <#if po.readonly=='Y'>disabled</#if>></j-switch> |
50 | 50 | <#elseif po.classType =='pca'> |
... | ... | @@ -54,7 +54,7 @@ |
54 | 54 | <#elseif po.classType =='password'> |
55 | 55 | <a-input-password v-model="model.${po.fieldName}" placeholder="请输入${po.filedComment}" <#if po.readonly=='Y'>disabled</#if>/> |
56 | 56 | <#elseif po.classType =='sel_user'> |
57 | - <j-select-user-by-dep v-model="model.${po.fieldName}" <#if po.readonly=='Y'>disabled</#if>/> | |
57 | + <j-select-user-by-dep v-model="model.${po.fieldName}" :multi="${po.extendParams.multi?default('true')}"<#if po.extendParams.store?default("")?trim?length gt 0> store="${po.extendParams.store}"</#if><#if po.extendParams.text?default("")?trim?length gt 0> text="${po.extendParams.text}"</#if> <#if po.readonly=='Y'>disabled</#if>/> | |
58 | 58 | <#elseif po.classType =='textarea'> |
59 | 59 | <a-textarea v-model="model.${autoStringSuffixForModel(po)}" rows="4" placeholder="请输入${po.filedComment}" <#if po.readonly=='Y'>disabled</#if>/> |
60 | 60 | <#elseif po.classType=='list' || po.classType=='radio'> |
... | ... |
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/[1-n]Modal.vuei
... | ... | @@ -46,7 +46,7 @@ |
46 | 46 | @input="popupCallback" |
47 | 47 | <#if po.readonly=='Y'>disabled</#if>/> |
48 | 48 | <#elseif po.classType =='sel_depart'> |
49 | - <j-select-depart v-model="model.${po.fieldName}"multi <#if po.readonly=='Y'>disabled</#if>/> | |
49 | + <j-select-depart v-model="model.${po.fieldName}" :multi="${po.extendParams.multi?default('true')}"<#if po.extendParams.store?default("")?trim?length gt 0> store="${po.extendParams.store}"</#if><#if po.extendParams.text?default("")?trim?length gt 0> text="${po.extendParams.text}"</#if> <#if po.readonly=='Y'>disabled</#if> /> | |
50 | 50 | <#elseif po.classType =='switch'> |
51 | 51 | <j-switch v-model="model.${po.fieldName}"<#if po.dictField!= 'is_open'>:options="${po.dictField}"</#if> <#if po.readonly=='Y'>disabled</#if>></j-switch> |
52 | 52 | <#elseif po.classType =='pca'> |
... | ... | @@ -56,7 +56,7 @@ |
56 | 56 | <#elseif po.classType =='password'> |
57 | 57 | <a-input-password v-model="model.${po.fieldName}"placeholder="请输入${po.filedComment}" <#if po.readonly=='Y'>disabled</#if>/> |
58 | 58 | <#elseif po.classType =='sel_user'> |
59 | - <j-select-user-by-dep v-model="model.${po.fieldName}"<#if po.readonly=='Y'>disabled</#if>/> | |
59 | + <j-select-user-by-dep v-model="model.${po.fieldName}" :multi="${po.extendParams.multi?default('true')}"<#if po.extendParams.store?default("")?trim?length gt 0> store="${po.extendParams.store}"</#if><#if po.extendParams.text?default("")?trim?length gt 0> text="${po.extendParams.text}"</#if> <#if po.readonly=='Y'>disabled</#if>/> | |
60 | 60 | <#elseif po.classType =='textarea'> |
61 | 61 | <a-textarea v-model="model.${autoStringSuffixForModel(po)}" rows="4" placeholder="请输入${po.filedComment}" <#if po.readonly=='Y'>disabled</#if>/> |
62 | 62 | <#elseif po.classType=='list' || po.classType=='radio'> |
... | ... |
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}List.vuei
... | ... | @@ -46,6 +46,10 @@ |
46 | 46 | <template #htmlSlot="{text}"> |
47 | 47 | <div v-html="text"></div> |
48 | 48 | </template> |
49 | + <!--省市区字段回显插槽--> | |
50 | + <template #pcaSlot="{text}"> | |
51 | + {{ getAreaTextByCode(text) }} | |
52 | + </template> | |
49 | 53 | <template #fileSlot="{text}"> |
50 | 54 | <span v-if="!text" style="font-size: 12px;font-style: italic;">无文件</span> |
51 | 55 | <a-button v-else :ghost="true" type="primary" preIcon="ant-design:download-outlined" size="small" @click="downloadFile(text)">下载</a-button> |
... | ... | @@ -77,6 +81,10 @@ |
77 | 81 | </#list> |
78 | 82 | import {columns, searchFormSchema} from './${entityName}.data'; |
79 | 83 | import {list, deleteOne, batchDelete, getImportUrl,getExportUrl} from './${entityName}.api'; |
84 | + import {downloadFile} from '/@/utils/common/renderUtils'; | |
85 | + <#if list_need_pca> | |
86 | + import { getAreaTextByCode } from '/@/components/Form/src/utils/Area'; | |
87 | + </#if> | |
80 | 88 | <#if list_need_category> |
81 | 89 | import { loadCategoryData } from '/@/api/common/api' |
82 | 90 | import { getAuthCache, setAuthCache } from '/@/utils/auth'; |
... | ... | @@ -94,6 +102,17 @@ |
94 | 102 | rowSelection: {type: 'radio'}, |
95 | 103 | formConfig: { |
96 | 104 | schemas: searchFormSchema, |
105 | + fieldMapToNumber: [ | |
106 | + <#list columns as po> | |
107 | + <#if po.isQuery=='Y'> | |
108 | + <#if po.queryMode!='single'> | |
109 | + <#if po.fieldDbType=='int' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'> | |
110 | + ['${po.fieldName}', ['${po.fieldName}_begin', '${po.fieldName}_end']], | |
111 | + </#if> | |
112 | + </#if> | |
113 | + </#if> | |
114 | + </#list> | |
115 | + ], | |
97 | 116 | fieldMapToTime: [ |
98 | 117 | <#list columns as po> |
99 | 118 | <#if po.isQuery=='Y'> |
... | ... | @@ -108,14 +127,15 @@ |
108 | 127 | </#list> |
109 | 128 | ], |
110 | 129 | }, |
111 | - actionColumn: { | |
130 | + actionColumn: { | |
112 | 131 | width: 120, |
113 | - }, | |
114 | - pagination:{ | |
115 | - current: 1, | |
116 | - pageSize: 5, | |
117 | - pageSizeOptions: ['5', '10', '20'], | |
118 | - } | |
132 | + fixed:'right' | |
133 | + }, | |
134 | + pagination:{ | |
135 | + current: 1, | |
136 | + pageSize: 5, | |
137 | + pageSizeOptions: ['5', '10', '20'], | |
138 | + } | |
119 | 139 | }, |
120 | 140 | exportConfig: { |
121 | 141 | name:"${tableVo.ftlDescription}", |
... | ... |
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__data.tsi
1 | +<#include "/common/utils.ftl"> | |
1 | 2 | import {BasicColumn} from '/@/components/Table'; |
2 | 3 | import {FormSchema} from '/@/components/Table'; |
3 | 4 | import { rules} from '/@/utils/helper/validator'; |
... | ... | @@ -24,7 +25,7 @@ export const columns: BasicColumn[] = [ |
24 | 25 | slots: { customRender: 'htmlSlot' }, |
25 | 26 | <#elseif po.classType=='pca'> |
26 | 27 | dataIndex: '${po.fieldName}', |
27 | - slots: { customRender: 'pcaSlot' },//TODO 未翻译 | |
28 | + slots: { customRender: 'pcaSlot' }, | |
28 | 29 | <#elseif po.classType=='file'> |
29 | 30 | dataIndex: '${po.fieldName}', |
30 | 31 | slots: { customRender: 'fileSlot' }, |
... | ... | @@ -91,17 +92,23 @@ export const searchFormSchema: FormSchema[] = [ |
91 | 92 | <#elseif po.classType=='switch'> |
92 | 93 | component: 'JSwitch', |
93 | 94 | componentProps:{ |
95 | + query:true, | |
94 | 96 | <#if po.dictField != 'is_open'> |
95 | - options:"${po.dictField}" | |
97 | + options:${po.dictField} | |
96 | 98 | </#if> |
97 | 99 | }, |
98 | 100 | <#elseif po.classType=='sel_depart'> |
99 | 101 | component: 'JSelectDept', |
100 | 102 | <#elseif po.classType=='list_multi'> |
101 | - component: 'JMultiSelectTag',//暂无该组件 | |
103 | + component: 'JSelectMultiple', | |
102 | 104 | componentProps:{ |
103 | - dictCode:"query_field_dictCode?default("")" | |
104 | - }, | |
105 | + <#if po.dictTable?default("")?trim?length gt 1> | |
106 | + dictCode:"${po.dictTable},${po.dictText},${po.dictField}", | |
107 | + <#elseif po.dictField?default("")?trim?length gt 1> | |
108 | + dictCode:"${po.dictField}", | |
109 | + </#if> | |
110 | + triggerChange: true | |
111 | + }, | |
105 | 112 | <#elseif po.classType=='cat_tree'> |
106 | 113 | component: 'JCategorySelect', |
107 | 114 | componentProps:{ |
... | ... | @@ -117,16 +124,7 @@ export const searchFormSchema: FormSchema[] = [ |
117 | 124 | <#elseif po.classType=='pca'> |
118 | 125 | component: 'JAreaLinkage', |
119 | 126 | <#elseif po.classType=='popup'> |
120 | - component: 'JPopup', | |
121 | - componentProps: ({ formActionType }) => { | |
122 | - const {setFieldsValue} = formActionType; | |
123 | - return{ | |
124 | - setFieldsValue:setFieldsValue, | |
125 | - code:"${po.dictTable}", | |
126 | - fieldConfig:"${po.dictField}", | |
127 | - multi:${po.extendParams.popupMulti?c}, | |
128 | - } | |
129 | - }, | |
127 | + <#include "/common/form/vue3popup.ftl"> | |
130 | 128 | <#elseif po.classType=='list' || po.classType=='radio' || po.classType=='checkbox'> |
131 | 129 | <#-- ---------------------------下拉或是单选 判断数据字典是表字典还是普通字典------------------------------- --> |
132 | 130 | component: 'JDictSelectTag', |
... | ... | @@ -153,6 +151,8 @@ export const searchFormSchema: FormSchema[] = [ |
153 | 151 | componentProps: { |
154 | 152 | showTime:true |
155 | 153 | }, |
154 | +<#elseif po.fieldDbType=='int' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'> | |
155 | + component: 'JRangeNumber', | |
156 | 156 | <#else> |
157 | 157 | component: 'Input', //TODO 范围查询 |
158 | 158 | </#if> |
... | ... | @@ -186,27 +186,22 @@ export const formSchema: FormSchema[] = [ |
186 | 186 | </#if> |
187 | 187 | { |
188 | 188 | label: '${po.filedComment}', |
189 | - field: '${po.fieldName}', | |
189 | + field: ${autoStringSuffix(po)}, | |
190 | 190 | <#if po.classType =='date'> |
191 | 191 | component: 'DatePicker', |
192 | - <#elseif po.fieldType =='datetime'> | |
192 | + <#elseif po.classType =='datetime'> | |
193 | 193 | component: 'DatePicker', |
194 | 194 | componentProps: { |
195 | - showTime:true | |
195 | + showTime:true, | |
196 | + valueFormat: 'YYYY-MM-DD HH:mm:ss' | |
196 | 197 | }, |
197 | - <#elseif po.fieldType =='time'> | |
198 | + <#elseif po.classType =='time'> | |
198 | 199 | component: 'TimePicker', |
200 | + componentProps: { | |
201 | + valueFormat: 'HH:mm:ss' | |
202 | + }, | |
199 | 203 | <#elseif po.classType =='popup'> |
200 | - component: 'JPopup', | |
201 | - componentProps: ({ formActionType }) => { | |
202 | - const {setFieldsValue} = formActionType; | |
203 | - return{ | |
204 | - setFieldsValue:setFieldsValue, | |
205 | - code:"${po.dictTable}", | |
206 | - fieldConfig:${po.dictField}, | |
207 | - multi:${po.extendParams.popupMulti?c}, | |
208 | - } | |
209 | - }, | |
204 | + <#include "/common/form/vue3popup.ftl"> | |
210 | 205 | <#elseif po.classType =='sel_depart'> |
211 | 206 | component: 'JSelectDept', |
212 | 207 | <#elseif po.classType =='switch'> |
... | ... | @@ -235,7 +230,7 @@ export const formSchema: FormSchema[] = [ |
235 | 230 | dictCode:"${form_field_dictCode}" |
236 | 231 | }, |
237 | 232 | <#elseif po.classType=='list_multi' || po.classType=='checkbox'> |
238 | - component: 'JMultiSelectTag',//TODO 暂无该组件 | |
233 | + component: 'JSelectMultiple', | |
239 | 234 | componentProps:{ |
240 | 235 | dictCode:"${form_field_dictCode}" |
241 | 236 | }, |
... | ... | @@ -270,7 +265,7 @@ export const formSchema: FormSchema[] = [ |
270 | 265 | </#if> |
271 | 266 | }, |
272 | 267 | <#elseif po.classType=='umeditor'> |
273 | - component: 'JCodeEditor', //TODO String后缀暂未添加 | |
268 | + component: 'JEditor', | |
274 | 269 | <#elseif po.classType == 'sel_tree'> |
275 | 270 | component: 'JTreeSelect', |
276 | 271 | componentProps:{ |
... | ... | @@ -302,16 +297,16 @@ export const formSchema: FormSchema[] = [ |
302 | 297 | </#if> |
303 | 298 | <#-- 唯一校验 --> |
304 | 299 | <#if fieldValidType == 'only'> |
305 | - {...rules.duplicateCheckRule(<#if sub?default("")?trim?length gt 1>'${sub.tableName}'<#else>'${tableName}'</#if>, '${po.fieldDbName}',model,schema,true)[0]}, | |
300 | + {...rules.duplicateCheckRule(<#if sub?default("")?trim?length gt 1>'${sub.tableName}'<#else>'${tableName}'</#if>, '${po.fieldDbName}',model,schema)[0]}, | |
306 | 301 | <#-- 6到16位数字 --> |
307 | 302 | <#elseif fieldValidType == 'n6-16'> |
308 | 303 | { pattern: /^\d{6,16}$/, message: '请输入6到16位数字!'}, |
309 | 304 | <#-- 6到16位任意字符 --> |
310 | 305 | <#elseif fieldValidType == '*6-16'> |
311 | 306 | { pattern: /^.{6,16}$/, message: '请输入6到16位任意字符!'}, |
312 | - <#-- 6到18位字符串 --> | |
307 | + <#-- 6到18位字母 --> | |
313 | 308 | <#elseif fieldValidType == 's6-18'> |
314 | - { pattern: /^.{6,18}$/, message: '请输入6到18位任意字符!'}, | |
309 | + { pattern:/^[a-z|A-Z]{6,18}$/, message: '请输入6到18位字母!'}, | |
315 | 310 | <#-- 网址 --> |
316 | 311 | <#elseif fieldValidType == 'url'> |
317 | 312 | { pattern: /^((ht|f)tps?):\/\/[\w\-]+(\.[\w\-]+)+([\w\-.,@?^=%&:\/~+#]*[\w\-@?^=%&\/~+#])?$/, message: '请输入正确的网址!'}, |
... | ... | @@ -387,7 +382,7 @@ export const ${sub.entityName?uncap_first}Columns: BasicColumn[] = [ |
387 | 382 | slots: { customRender: 'htmlSlot' }, |
388 | 383 | <#elseif po.classType=='pca'> |
389 | 384 | dataIndex: '${po.fieldName}', |
390 | - slots: { customRender: 'pcaSlot' },//TODO 未翻译 | |
385 | + slots: { customRender: 'pcaSlot' }, | |
391 | 386 | <#elseif po.classType=='file'> |
392 | 387 | dataIndex: '${po.fieldName}', |
393 | 388 | slots: { customRender: 'fileSlot' }, |
... | ... | @@ -419,7 +414,7 @@ export const ${sub.entityName?uncap_first}Columns: BasicColumn[] = [ |
419 | 414 | return render.renderCategoryTree(text,'${po.dictField?default("")}') |
420 | 415 | }, |
421 | 416 | <#else> |
422 | - customRender: (text, record) => (text ? record['${po.dictText}'] : '') | |
417 | + customRender: ({text, record}) => (text ? record['${po.dictText}'] : '') | |
423 | 418 | </#if> |
424 | 419 | <#else> |
425 | 420 | dataIndex: '${po.fieldName}' |
... | ... | @@ -452,27 +447,22 @@ export const ${sub.entityName?uncap_first}FormSchema: FormSchema[] = [ |
452 | 447 | </#if> |
453 | 448 | { |
454 | 449 | label: '${po.filedComment}', |
455 | - field: '${po.fieldName}', | |
450 | + field: ${autoStringSuffix(po)}, | |
456 | 451 | <#if po.classType =='date'> |
457 | 452 | component: 'DatePicker', |
458 | - <#elseif po.fieldType =='datetime'> | |
453 | + <#elseif po.classType =='datetime'> | |
459 | 454 | component: 'DatePicker', |
460 | 455 | componentProps: { |
461 | - showTime:true | |
456 | + showTime:true, | |
457 | + valueFormat: 'YYYY-MM-DD HH:mm:ss' | |
462 | 458 | }, |
463 | - <#elseif po.fieldType =='time'> | |
459 | + <#elseif po.classType =='time'> | |
464 | 460 | component: 'TimePicker', |
461 | + componentProps: { | |
462 | + valueFormat: 'HH:mm:ss' | |
463 | + }, | |
465 | 464 | <#elseif po.classType =='popup'> |
466 | - component: 'JPopup', | |
467 | - componentProps: ({ formActionType }) => { | |
468 | - const {setFieldsValue} = formActionType; | |
469 | - return{ | |
470 | - setFieldsValue:setFieldsValue, | |
471 | - code:"${po.dictTable}", | |
472 | - fieldConfig:${po.dictField}, | |
473 | - multi:${po.extendParams.popupMulti?c}, | |
474 | - } | |
475 | - }, | |
465 | + <#include "/common/form/vue3popup.ftl"> | |
476 | 466 | <#elseif po.classType =='sel_depart'> |
477 | 467 | component: 'JSelectDept', |
478 | 468 | <#elseif po.classType =='switch'> |
... | ... | @@ -494,14 +484,14 @@ export const ${sub.entityName?uncap_first}FormSchema: FormSchema[] = [ |
494 | 484 | labelKey:'realname', |
495 | 485 | }, |
496 | 486 | <#elseif po.classType =='textarea'> |
497 | - component: 'InputTextArea',//TODO 注意string转换问题 | |
487 | + component: 'InputTextArea', | |
498 | 488 | <#elseif po.classType=='list' || po.classType=='radio'> |
499 | 489 | component: 'JDictSelectTag', |
500 | 490 | componentProps:{ |
501 | 491 | dictCode:"${form_field_dictCode}" |
502 | 492 | }, |
503 | 493 | <#elseif po.classType=='list_multi' || po.classType=='checkbox'> |
504 | - component: 'JMultiSelectTag',//TODO 暂无该组件 | |
494 | + component: 'JSelectMultiple', | |
505 | 495 | componentProps:{ |
506 | 496 | dictCode:"${form_field_dictCode}" |
507 | 497 | }, |
... | ... | @@ -536,7 +526,7 @@ export const ${sub.entityName?uncap_first}FormSchema: FormSchema[] = [ |
536 | 526 | </#if> |
537 | 527 | }, |
538 | 528 | <#elseif po.classType=='umeditor'> |
539 | - component: 'JCodeEditor', //TODO String后缀暂未添加 | |
529 | + component: 'JEditor', | |
540 | 530 | <#elseif po.classType == 'sel_tree'> |
541 | 531 | component: 'JTreeSelect', |
542 | 532 | componentProps:{ |
... | ... | @@ -568,16 +558,16 @@ export const ${sub.entityName?uncap_first}FormSchema: FormSchema[] = [ |
568 | 558 | </#if> |
569 | 559 | <#-- 唯一校验 --> |
570 | 560 | <#if fieldValidType == 'only'> |
571 | - {...rules.duplicateCheckRule(<#if sub?default("")?trim?length gt 1>'${sub.tableName}'<#else>'${tableName}'</#if>, '${po.fieldDbName}',model,schema,true)[0]}, | |
561 | + {...rules.duplicateCheckRule(<#if sub?default("")?trim?length gt 1>'${sub.tableName}'<#else>'${tableName}'</#if>, '${po.fieldDbName}',model,schema)[0]}, | |
572 | 562 | <#-- 6到16位数字 --> |
573 | 563 | <#elseif fieldValidType == 'n6-16'> |
574 | 564 | { pattern: /^\d{6,16}$/, message: '请输入6到16位数字!'}, |
575 | 565 | <#-- 6到16位任意字符 --> |
576 | 566 | <#elseif fieldValidType == '*6-16'> |
577 | 567 | { pattern: /^.{6,16}$/, message: '请输入6到16位任意字符!'}, |
578 | - <#-- 6到18位字符串 --> | |
568 | + <#-- 6到18位字母 --> | |
579 | 569 | <#elseif fieldValidType == 's6-18'> |
580 | - { pattern: /^.{6,18}$/, message: '请输入6到18位任意字符!'}, | |
570 | + { pattern: /^[a-z|A-Z]{6,18}$/, message: '请输入6到18位字母!'}, | |
581 | 571 | <#-- 网址 --> |
582 | 572 | <#elseif fieldValidType == 'url'> |
583 | 573 | { pattern: /^((ht|f)tps?):\/\/[\w\-]+(\.[\w\-]+)+([\w\-.,@?^=%&:\/~+#]*[\w\-@?^=%&\/~+#])?$/, message: '请输入正确的网址!'}, |
... | ... |
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}_menu_insert.sql
0 → 100644
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3/[1-n]List.vuei
... | ... | @@ -51,6 +51,7 @@ |
51 | 51 | import {${sub.entityName?uncap_first}List, ${sub.entityName?uncap_first}Delete, ${sub.entityName?uncap_first}DeleteBatch, ${sub.entityName?uncap_first}ExportXlsUrl, ${sub.entityName?uncap_first}ImportUrl } from './${entityName}.api'; |
52 | 52 | import {isEmpty} from "/@/utils/is"; |
53 | 53 | import {useMessage} from '/@/hooks/web/useMessage'; |
54 | + import {downloadFile} from '/@/utils/common/renderUtils'; | |
54 | 55 | |
55 | 56 | //接收主表id |
56 | 57 | const mainId = inject('mainId') || ''; |
... | ... |
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3/components/${entityName}Modal.vuei
1 | +<#include "/common/utils.ftl"> | |
1 | 2 | <template> |
2 | - <BasicModal v-bind="$attrs" @register="registerModal" :title="title" @ok="handleSubmit"> | |
3 | + <BasicModal v-bind="$attrs" @register="registerModal" destroyOnClose :title="title" :width="${getModalWidth(tableVo.fieldRowNum?default(1))}" @ok="handleSubmit"> | |
3 | 4 | <BasicForm @register="registerForm"/> |
4 | 5 | </BasicModal> |
5 | 6 | </template> |
... | ... | @@ -18,6 +19,7 @@ |
18 | 19 | labelWidth: 150, |
19 | 20 | schemas: formSchema, |
20 | 21 | showActionButtonGroup: false, |
22 | + baseColProps: {span: ${getFormSpan(tableVo.fieldRowNum?default(1))}} | |
21 | 23 | }); |
22 | 24 | //表单赋值 |
23 | 25 | const [registerModal, {setModalProps, closeModal}] = useModalInner(async (data) => { |
... | ... | @@ -54,5 +56,12 @@ |
54 | 56 | </script> |
55 | 57 | |
56 | 58 | <style lang="less" scoped> |
59 | + /** 时间和数字输入框样式 */ | |
60 | + :deep(.ant-input-number){ | |
61 | + width: 100% | |
62 | + } | |
57 | 63 | |
64 | + :deep(.ant-calendar-picker){ | |
65 | + width: 100% | |
66 | + } | |
58 | 67 | </style> |
59 | 68 | \ No newline at end of file |
... | ... |
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/erp/onetomany/java/${bussiPackage}/${entityPackage}/vue3/components/[1-n]Modal.vuei
... | ... | @@ -2,7 +2,7 @@ |
2 | 2 | <#list subTables as sub> |
3 | 3 | #segment#${sub.entityName}Modal.vue |
4 | 4 | <template> |
5 | - <BasicModal v-bind="$attrs" @register="registerModal" :title="title" @ok="handleSubmit"> | |
5 | + <BasicModal v-bind="$attrs" @register="registerModal" destroyOnClose :title="title" :width="${getModalWidth(tableVo.fieldRowNum?default(1))}" @ok="handleSubmit"> | |
6 | 6 | <BasicForm @register="registerForm"/> |
7 | 7 | </BasicModal> |
8 | 8 | </template> |
... | ... | @@ -24,6 +24,7 @@ |
24 | 24 | labelWidth: 150, |
25 | 25 | schemas: ${sub.entityName?uncap_first}FormSchema, |
26 | 26 | showActionButtonGroup: false, |
27 | + baseColProps: {span: ${getFormSpan(tableVo.fieldRowNum?default(1))}} | |
27 | 28 | }); |
28 | 29 | //表单赋值 |
29 | 30 | const [registerModal, {setModalProps, closeModal}] = useModalInner(async (data) => { |
... | ... | @@ -63,4 +64,14 @@ |
63 | 64 | } |
64 | 65 | } |
65 | 66 | </script> |
67 | +<style lang="less" scoped> | |
68 | + /** 时间和数字输入框样式 */ | |
69 | + :deep(.ant-input-number){ | |
70 | + width: 100% | |
71 | + } | |
72 | + | |
73 | + :deep(.ant-calendar-picker){ | |
74 | + width: 100% | |
75 | + } | |
76 | +</style> | |
66 | 77 | </#list> |
67 | 78 | \ No newline at end of file |
... | ... |
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai
... | ... | @@ -200,17 +200,14 @@ public class ${entityName}Controller { |
200 | 200 | QueryWrapper<${entityName}> queryWrapper = QueryGenerator.initQueryWrapper(${entityName?uncap_first}, request.getParameterMap()); |
201 | 201 | LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); |
202 | 202 | |
203 | - //Step.2 获取导出数据 | |
204 | - List<${entityName}> queryList = ${entityName?uncap_first}Service.list(queryWrapper); | |
205 | - // 过滤选中数据 | |
203 | + //配置选中数据查询条件 | |
206 | 204 | String selections = request.getParameter("selections"); |
207 | - List<${entityName}> ${entityName?uncap_first}List = new ArrayList<${entityName}>(); | |
208 | - if(oConvertUtils.isEmpty(selections)) { | |
209 | - ${entityName?uncap_first}List = queryList; | |
210 | - }else { | |
211 | - List<String> selectionList = Arrays.asList(selections.split(",")); | |
212 | - ${entityName?uncap_first}List = queryList.stream().filter(item -> selectionList.contains(item.getId())).collect(Collectors.toList()); | |
205 | + if(oConvertUtils.isNotEmpty(selections)) { | |
206 | + List<String> selectionList = Arrays.asList(selections.split(",")); | |
207 | + queryWrapper.in("id",selectionList); | |
213 | 208 | } |
209 | + //Step.2 获取导出数据 | |
210 | + List<${entityName}> ${entityName?uncap_first}List = ${entityName?uncap_first}Service.list(queryWrapper); | |
214 | 211 | |
215 | 212 | // Step.3 组装pageList |
216 | 213 | List<${entityName}Page> pageList = new ArrayList<${entityName}Page>(); |
... | ... |
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/entity/${entityName}.javai
1 | +<#include "/common/utils.ftl"> | |
1 | 2 | package ${bussiPackage}.${entityPackage}.entity; |
2 | 3 | |
3 | 4 | import java.io.Serializable; |
... | ... | @@ -31,9 +32,9 @@ public class ${entityName} implements Serializable { |
31 | 32 | <#-- 生成字典Code --> |
32 | 33 | <#assign list_field_dictCode=""> |
33 | 34 | <#if po.classType='sel_user'> |
34 | - <#assign list_field_dictCode=', dictTable = "sys_user", dicText = "realname", dicCode = "username"'> | |
35 | + <#assign list_field_dictCode=', dictTable = "sys_user", dicText = "${camelToDashed(po.extendParams.text?default(\"realname\")?trim)}", dicCode = "${camelToDashed(po.extendParams.store?default(\"username\")?trim)}"'> | |
35 | 36 | <#elseif po.classType='sel_depart'> |
36 | - <#assign list_field_dictCode=', dictTable = "sys_depart", dicText = "depart_name", dicCode = "id"'> | |
37 | + <#assign list_field_dictCode=', dictTable = "sys_depart", dicText = "${camelToDashed(po.extendParams.text?default(\"depart_name\")?trim)}", dicCode = "${camelToDashed(po.extendParams.store?default(\"id\")?trim)}"'> | |
37 | 38 | <#elseif po.classType=='list' || po.classType=='list_multi' || po.classType=='sel_search' || po.classType=='radio' || po.classType=='checkbox'> |
38 | 39 | <#if po.dictTable?default("")?trim?length gt 1> |
39 | 40 | <#assign list_field_dictCode=', dictTable = "${po.dictTable}", dicText = "${po.dictText}", dicCode = "${po.dictField}"'> |
... | ... |
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/entity/[1-n]Entity.javai
1 | +<#include "/common/utils.ftl"> | |
1 | 2 | <#list subTables as subTab> |
2 | 3 | #segment#${subTab.entityName}.java |
3 | 4 | package ${bussiPackage}.${entityPackage}.entity; |
... | ... | @@ -33,9 +34,9 @@ public class ${subTab.entityName} implements Serializable { |
33 | 34 | <#-- 生成字典Code --> |
34 | 35 | <#assign list_field_dictCode=""> |
35 | 36 | <#if po.classType='sel_user'> |
36 | - <#assign list_field_dictCode=', dictTable = "sys_user", dicText = "realname", dicCode = "username"'> | |
37 | + <#assign list_field_dictCode=', dictTable = "sys_user", dicText = "${camelToDashed(po.extendParams.text?default(\"realname\")?trim)}", dicCode = "${camelToDashed(po.extendParams.store?default(\"username\")?trim)}"'> | |
37 | 38 | <#elseif po.classType='sel_depart'> |
38 | - <#assign list_field_dictCode=', dictTable = "sys_depart", dicText = "depart_name", dicCode = "id"'> | |
39 | + <#assign list_field_dictCode=', dictTable = "sys_depart", dicText = "${camelToDashed(po.extendParams.text?default(\"depart_name\")?trim)}", dicCode = "${camelToDashed(po.extendParams.store?default(\"id\")?trim)}"'> | |
39 | 40 | <#elseif po.classType=='list' || po.classType=='list_multi' || po.classType=='sel_search' || po.classType=='radio' || po.classType=='checkbox'> |
40 | 41 | <#if po.dictTable?default("")?trim?length gt 1> |
41 | 42 | <#assign list_field_dictCode=', dictTable = "${po.dictTable}", dicText = "${po.dictText}", dicCode = "${po.dictField}"'> |
... | ... |
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue/${entityName}_menu_insert.sql
0 → 100644
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/${entityName}Form.vuei
... | ... | @@ -41,7 +41,7 @@ |
41 | 41 | @input="popupCallback" |
42 | 42 | <#if po.readonly=='Y'>disabled</#if>/> |
43 | 43 | <#elseif po.classType =='sel_depart'> |
44 | - <j-select-depart v-model="model.${po.fieldName}" multi <#if po.readonly=='Y'>disabled</#if>/> | |
44 | + <j-select-depart v-model="model.${po.fieldName}" :multi="${po.extendParams.multi?default('true')}"<#if po.extendParams.store?default("")?trim?length gt 0> store="${po.extendParams.store}"</#if><#if po.extendParams.text?default("")?trim?length gt 0> text="${po.extendParams.text}"</#if> <#if po.readonly=='Y'>disabled</#if> /> | |
45 | 45 | <#elseif po.classType =='switch'> |
46 | 46 | <j-switch v-model="model.${po.fieldName}" <#if po.dictField!= 'is_open'>:options="${po.dictField}"</#if> <#if po.readonly=='Y'>disabled</#if>></j-switch> |
47 | 47 | <#elseif po.classType =='pca'> |
... | ... | @@ -51,7 +51,7 @@ |
51 | 51 | <#elseif po.classType =='password'> |
52 | 52 | <a-input-password v-model="model.${po.fieldName}" placeholder="请输入${po.filedComment}" <#if po.readonly=='Y'>disabled</#if>/> |
53 | 53 | <#elseif po.classType =='sel_user'> |
54 | - <j-select-user-by-dep v-model="model.${po.fieldName}" <#if po.readonly=='Y'>disabled</#if>/> | |
54 | + <j-select-user-by-dep v-model="model.${po.fieldName}" :multi="${po.extendParams.multi?default('true')}"<#if po.extendParams.store?default("")?trim?length gt 0> store="${po.extendParams.store}"</#if><#if po.extendParams.text?default("")?trim?length gt 0> text="${po.extendParams.text}"</#if> <#if po.readonly=='Y'>disabled</#if>/> | |
55 | 55 | <#elseif po.classType =='textarea'> |
56 | 56 | <a-textarea v-decorator="[${autoStringSuffix(po)}${autoWriteRules(po)}]" rows="4" placeholder="请输入${po.filedComment}" <#if po.readonly=='Y'>disabled</#if>/> |
57 | 57 | <#elseif po.classType=='list' || po.classType=='radio'> |
... | ... |
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/[1-n]Form.vuei
... | ... | @@ -36,9 +36,9 @@ |
36 | 36 | <#elseif po.classType =='switch'> |
37 | 37 | <j-switch v-model="model.${po.fieldName}" <#if po.dictField!= 'is_open'>:options="${po.dictField}"</#if>></j-switch> |
38 | 38 | <#elseif po.classType =='sel_depart'> |
39 | - <j-select-depart v-model="model.${po.fieldName}" /> | |
39 | + <j-select-depart v-model="model.${po.fieldName}" :multi="${po.extendParams.multi?default('true')}"<#if po.extendParams.store?default("")?trim?length gt 0> store="${po.extendParams.store}"</#if><#if po.extendParams.text?default("")?trim?length gt 0> text="${po.extendParams.text}"</#if> <#if po.readonly=='Y'>disabled</#if> /> | |
40 | 40 | <#elseif po.classType =='sel_user'> |
41 | - <j-select-user-by-dep v-model="model.${po.fieldName}" /> | |
41 | + <j-select-user-by-dep v-model="model.${po.fieldName}" :multi="${po.extendParams.multi?default('true')}"<#if po.extendParams.store?default("")?trim?length gt 0> store="${po.extendParams.store}"</#if><#if po.extendParams.text?default("")?trim?length gt 0> text="${po.extendParams.text}"</#if> <#if po.readonly=='Y'>disabled</#if>/> | |
42 | 42 | <#elseif po.classType =='textarea'> |
43 | 43 | <a-textarea v-model="model.${autoStringSuffixForModel(po)}" rows="4" placeholder="请输入${po.filedComment}"/> |
44 | 44 | <#elseif po.classType=='list' || po.classType=='radio'> |
... | ... |
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}List.vuei
... | ... | @@ -60,6 +60,10 @@ |
60 | 60 | <template #htmlSlot="{text}"> |
61 | 61 | <div v-html="text"></div> |
62 | 62 | </template> |
63 | + <!--省市区字段回显插槽--> | |
64 | + <template #pcaSlot="{text}"> | |
65 | + {{ getAreaTextByCode(text) }} | |
66 | + </template> | |
63 | 67 | <template #fileSlot="{text}"> |
64 | 68 | <span v-if="!text" style="font-size: 12px;font-style: italic;">无文件</span> |
65 | 69 | <a-button v-else :ghost="true" type="primary" preIcon="ant-design:download-outlined" size="small" @click="downloadFile(text)">下载</a-button> |
... | ... | @@ -81,6 +85,10 @@ |
81 | 85 | </#list> |
82 | 86 | import {columns, searchFormSchema} from './${entityName}.data'; |
83 | 87 | import {list, deleteOne, batchDelete, getImportUrl,getExportUrl} from './${entityName}.api'; |
88 | + import {downloadFile} from '/@/utils/common/renderUtils'; | |
89 | + <#if list_need_pca> | |
90 | + import { getAreaTextByCode } from '/@/components/Form/src/utils/Area'; | |
91 | + </#if> | |
84 | 92 | <#if list_need_category> |
85 | 93 | import { loadCategoryData } from '/@/api/common/api' |
86 | 94 | import { getAuthCache, setAuthCache } from '/@/utils/auth'; |
... | ... | @@ -102,6 +110,17 @@ |
102 | 110 | schemas: searchFormSchema, |
103 | 111 | autoSubmitOnEnter:true, |
104 | 112 | showAdvancedButton:true, |
113 | + fieldMapToNumber: [ | |
114 | + <#list columns as po> | |
115 | + <#if po.isQuery=='Y'> | |
116 | + <#if po.queryMode!='single'> | |
117 | + <#if po.fieldDbType=='int' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'> | |
118 | + ['${po.fieldName}', ['${po.fieldName}_begin', '${po.fieldName}_end']], | |
119 | + </#if> | |
120 | + </#if> | |
121 | + </#if> | |
122 | + </#list> | |
123 | + ], | |
105 | 124 | fieldMapToTime: [ |
106 | 125 | <#list columns as po> |
107 | 126 | <#if po.isQuery=='Y'> |
... | ... | @@ -116,9 +135,10 @@ |
116 | 135 | </#list> |
117 | 136 | ], |
118 | 137 | }, |
119 | - actionColumn: { | |
138 | + actionColumn: { | |
120 | 139 | width: 120, |
121 | - }, | |
140 | + fixed:'right' | |
141 | + }, | |
122 | 142 | }, |
123 | 143 | exportConfig: { |
124 | 144 | name:"${tableVo.ftlDescription}", |
... | ... |
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__data.tsi
1 | +<#include "/common/utils.ftl"> | |
1 | 2 | import {BasicColumn} from '/@/components/Table'; |
2 | 3 | import {FormSchema} from '/@/components/Table'; |
3 | 4 | import { rules} from '/@/utils/helper/validator'; |
... | ... | @@ -25,7 +26,7 @@ export const columns: BasicColumn[] = [ |
25 | 26 | slots: { customRender: 'htmlSlot' }, |
26 | 27 | <#elseif po.classType=='pca'> |
27 | 28 | dataIndex: '${po.fieldName}', |
28 | - slots: { customRender: 'pcaSlot' },//TODO 未翻译 | |
29 | + slots: { customRender: 'pcaSlot' }, | |
29 | 30 | <#elseif po.classType=='file'> |
30 | 31 | dataIndex: '${po.fieldName}', |
31 | 32 | slots: { customRender: 'fileSlot' }, |
... | ... | @@ -57,7 +58,7 @@ export const columns: BasicColumn[] = [ |
57 | 58 | return render.renderCategoryTree(text,'${po.dictField?default("")}') |
58 | 59 | }, |
59 | 60 | <#else> |
60 | - customRender: (text, record) => (text ? record['${po.dictText}'] : '') | |
61 | + customRender: ({text, record}) => (text ? record['${po.dictText}'] : '') | |
61 | 62 | </#if> |
62 | 63 | <#else> |
63 | 64 | dataIndex: '${po.fieldName}' |
... | ... | @@ -84,7 +85,7 @@ export const searchFormSchema: FormSchema[] = [ |
84 | 85 | <#if po.queryMode=='single'> |
85 | 86 | { |
86 | 87 | label: "${po.filedComment}", |
87 | - field: "${po.fieldName}", | |
88 | + field: ${autoStringSuffix(po)}, | |
88 | 89 | <#if po.classType=='sel_search'> |
89 | 90 | component: 'JSearchSelect', |
90 | 91 | componentProps:{ |
... | ... | @@ -95,16 +96,22 @@ export const searchFormSchema: FormSchema[] = [ |
95 | 96 | <#elseif po.classType=='switch'> |
96 | 97 | component: 'JSwitch', |
97 | 98 | componentProps:{ |
99 | + query:true, | |
98 | 100 | <#if po.dictField != 'is_open'> |
99 | - options:"${po.dictField}" | |
101 | + options:${po.dictField} | |
100 | 102 | </#if> |
101 | 103 | }, |
102 | 104 | <#elseif po.classType=='sel_depart'> |
103 | 105 | component: 'JSelectDept', |
104 | 106 | <#elseif po.classType=='list_multi'> |
105 | - component: 'JMultiSelectTag',//暂无该组件 | |
106 | - componentProps:{ | |
107 | - dictCode:"query_field_dictCode?default("")" | |
107 | + component: 'JSelectMultiple', | |
108 | + componentProps:{ | |
109 | + <#if po.dictTable?default("")?trim?length gt 1> | |
110 | + dictCode:"${po.dictTable},${po.dictText},${po.dictField}", | |
111 | + <#elseif po.dictField?default("")?trim?length gt 1> | |
112 | + dictCode:"${po.dictField}", | |
113 | + </#if> | |
114 | + triggerChange: true | |
108 | 115 | }, |
109 | 116 | <#elseif po.classType=='cat_tree'> |
110 | 117 | component: 'JCategorySelect', |
... | ... | @@ -121,16 +128,7 @@ export const searchFormSchema: FormSchema[] = [ |
121 | 128 | <#elseif po.classType=='pca'> |
122 | 129 | component: 'JAreaLinkage', |
123 | 130 | <#elseif po.classType=='popup'> |
124 | - component: 'JPopup', | |
125 | - componentProps: ({ formActionType }) => { | |
126 | - const {setFieldsValue} = formActionType; | |
127 | - return{ | |
128 | - setFieldsValue:setFieldsValue, | |
129 | - code:"${po.dictTable}", | |
130 | - fieldConfig:"${po.dictField}", | |
131 | - multi:${po.extendParams.popupMulti?c}, | |
132 | - } | |
133 | - }, | |
131 | + <#include "/common/form/vue3popup.ftl"> | |
134 | 132 | <#elseif po.classType=='list' || po.classType=='radio' || po.classType=='checkbox'> |
135 | 133 | <#-- ---------------------------下拉或是单选 判断数据字典是表字典还是普通字典------------------------------- --> |
136 | 134 | component: 'JDictSelectTag', |
... | ... | @@ -157,6 +155,8 @@ export const searchFormSchema: FormSchema[] = [ |
157 | 155 | componentProps: { |
158 | 156 | showTime:true |
159 | 157 | }, |
158 | +<#elseif po.fieldDbType=='int' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'> | |
159 | + component: 'JRangeNumber', | |
160 | 160 | <#else> |
161 | 161 | component: 'Input', //TODO 范围查询 |
162 | 162 | </#if> |
... | ... | @@ -189,28 +189,23 @@ export const formSchema: FormSchema[] = [ |
189 | 189 | </#if> |
190 | 190 | { |
191 | 191 | label: '${po.filedComment}', |
192 | - field: '${po.fieldName}', | |
192 | + field: ${autoStringSuffix(po)}, | |
193 | 193 | <#if po.classType =='date'> |
194 | 194 | component: 'DatePicker', |
195 | - <#elseif po.fieldType =='datetime'> | |
195 | + <#elseif po.classType =='datetime'> | |
196 | 196 | component: 'DatePicker', |
197 | 197 | componentProps: { |
198 | - showTime:true | |
198 | + showTime:true, | |
199 | + valueFormat: 'YYYY-MM-DD HH:mm:ss' | |
199 | 200 | }, |
200 | - <#elseif po.fieldType =='time'> | |
201 | + <#elseif po.classType =='time'> | |
201 | 202 | component: 'TimePicker', |
203 | + componentProps: { | |
204 | + valueFormat: 'HH:mm:ss' | |
205 | + }, | |
202 | 206 | <#elseif po.classType =='popup'> |
203 | - component: 'JPopup', | |
204 | - componentProps: ({ formActionType }) => { | |
205 | - const {setFieldsValue} = formActionType; | |
206 | - return{ | |
207 | - setFieldsValue:setFieldsValue, | |
208 | - code:"${po.dictTable}", | |
209 | - fieldConfig:${po.dictField}, | |
210 | - multi:${po.extendParams.popupMulti?c}, | |
211 | - } | |
212 | - }, | |
213 | - <#elseif po.classType =='sel_depart'> | |
207 | + <#include "/common/form/vue3popup.ftl"> | |
208 | + <#elseif po.classType =='sel_depart'> | |
214 | 209 | component: 'JSelectDept', |
215 | 210 | <#elseif po.classType =='switch'> |
216 | 211 | component: 'JSwitch', |
... | ... | @@ -231,14 +226,14 @@ export const formSchema: FormSchema[] = [ |
231 | 226 | labelKey:'realname', |
232 | 227 | }, |
233 | 228 | <#elseif po.classType =='textarea'> |
234 | - component: 'InputTextArea',//TODO 注意string转换问题 | |
229 | + component: 'InputTextArea', | |
235 | 230 | <#elseif po.classType=='list' || po.classType=='radio'> |
236 | 231 | component: 'JDictSelectTag', |
237 | 232 | componentProps:{ |
238 | 233 | dictCode:"${form_field_dictCode}" |
239 | 234 | }, |
240 | 235 | <#elseif po.classType=='list_multi' || po.classType=='checkbox'> |
241 | - component: 'JMultiSelectTag',//TODO 暂无该组件 | |
236 | + component: 'JSelectMultiple', | |
242 | 237 | componentProps:{ |
243 | 238 | dictCode:"${form_field_dictCode}" |
244 | 239 | }, |
... | ... | @@ -273,7 +268,7 @@ export const formSchema: FormSchema[] = [ |
273 | 268 | </#if> |
274 | 269 | }, |
275 | 270 | <#elseif po.classType=='umeditor'> |
276 | - component: 'JCodeEditor', //TODO String后缀暂未添加 | |
271 | + component: 'JEditor', | |
277 | 272 | <#elseif po.classType == 'sel_tree'> |
278 | 273 | component: 'JTreeSelect', |
279 | 274 | componentProps:{ |
... | ... | @@ -305,16 +300,16 @@ export const formSchema: FormSchema[] = [ |
305 | 300 | </#if> |
306 | 301 | <#-- 唯一校验 --> |
307 | 302 | <#if fieldValidType == 'only'> |
308 | - {...rules.duplicateCheckRule(<#if sub?default("")?trim?length gt 1>'${sub.tableName}'<#else>'${tableName}'</#if>, '${po.fieldDbName}',model,schema,true)[0]}, | |
303 | + {...rules.duplicateCheckRule(<#if sub?default("")?trim?length gt 1>'${sub.tableName}'<#else>'${tableName}'</#if>, '${po.fieldDbName}',model,schema)[0]}, | |
309 | 304 | <#-- 6到16位数字 --> |
310 | 305 | <#elseif fieldValidType == 'n6-16'> |
311 | 306 | { pattern: /^\d{6,16}$/, message: '请输入6到16位数字!'}, |
312 | 307 | <#-- 6到16位任意字符 --> |
313 | 308 | <#elseif fieldValidType == '*6-16'> |
314 | 309 | { pattern: /^.{6,16}$/, message: '请输入6到16位任意字符!'}, |
315 | - <#-- 6到18位字符串 --> | |
310 | + <#-- 6到18位字母 --> | |
316 | 311 | <#elseif fieldValidType == 's6-18'> |
317 | - { pattern: /^.{6,18}$/, message: '请输入6到18位任意字符!'}, | |
312 | + { pattern:/^[a-z|A-Z]{6,18}$/, message: '请输入6到18位字母!'}, | |
318 | 313 | <#-- 网址 --> |
319 | 314 | <#elseif fieldValidType == 'url'> |
320 | 315 | { pattern: /^((ht|f)tps?):\/\/[\w\-]+(\.[\w\-]+)+([\w\-.,@?^=%&:\/~+#]*[\w\-@?^=%&\/~+#])?$/, message: '请输入正确的网址!'}, |
... | ... | @@ -390,7 +385,7 @@ export const ${sub.entityName?uncap_first}Columns: BasicColumn[] = [ |
390 | 385 | slots: { customRender: 'htmlSlot' }, |
391 | 386 | <#elseif po.classType=='pca'> |
392 | 387 | dataIndex: '${po.fieldName}', |
393 | - slots: { customRender: 'pcaSlot' },//TODO 未翻译 | |
388 | + slots: { customRender: 'pcaSlot' }, | |
394 | 389 | <#elseif po.classType=='file'> |
395 | 390 | dataIndex: '${po.fieldName}', |
396 | 391 | slots: { customRender: 'fileSlot' }, |
... | ... | @@ -422,7 +417,7 @@ export const ${sub.entityName?uncap_first}Columns: BasicColumn[] = [ |
422 | 417 | return render.renderCategoryTree(text,'${po.dictField?default("")}') |
423 | 418 | }, |
424 | 419 | <#else> |
425 | - customRender: (text, record) => (text ? record['${po.dictText}'] : '') | |
420 | + customRender: ({text, record}) => (text ? record['${po.dictText}'] : '') | |
426 | 421 | </#if> |
427 | 422 | <#else> |
428 | 423 | dataIndex: '${po.fieldName}' |
... | ... | @@ -436,10 +431,14 @@ export const ${sub.entityName?uncap_first}FormSchema: FormSchema[] = [ |
436 | 431 | <#assign form_cat_tree = false> |
437 | 432 | <#assign form_cat_back = ""> |
438 | 433 | <#assign bpm_flag=false> |
434 | +<#assign sub_id_exists=false> | |
439 | 435 | <#list sub.colums as po><#rt/> |
440 | 436 | <#if po.fieldDbName=='bpm_status'> |
441 | 437 | <#assign bpm_flag=true> |
442 | 438 | </#if> |
439 | +<#if po.fieldDbName=='id'> | |
440 | + <#assign sub_id_exists=true> | |
441 | +</#if> | |
443 | 442 | <#if po.isShow =='Y'> |
444 | 443 | <#assign form_field_dictCode=""> |
445 | 444 | <#if po.dictTable?default("")?trim?length gt 1 && po.dictText?default("")?trim?length gt 1 && po.dictField?default("")?trim?length gt 1> |
... | ... | @@ -449,27 +448,22 @@ export const ${sub.entityName?uncap_first}FormSchema: FormSchema[] = [ |
449 | 448 | </#if> |
450 | 449 | { |
451 | 450 | label: '${po.filedComment}', |
452 | - field: '${po.fieldName}', | |
451 | + field: ${autoStringSuffix(po)}, | |
453 | 452 | <#if po.classType =='date'> |
454 | 453 | component: 'DatePicker', |
455 | - <#elseif po.fieldType =='datetime'> | |
454 | + <#elseif po.classType =='datetime'> | |
456 | 455 | component: 'DatePicker', |
457 | 456 | componentProps: { |
458 | - showTime:true | |
457 | + showTime:true, | |
458 | + valueFormat: 'YYYY-MM-DD HH:mm:ss' | |
459 | 459 | }, |
460 | - <#elseif po.fieldType =='time'> | |
460 | + <#elseif po.classType =='time'> | |
461 | 461 | component: 'TimePicker', |
462 | + componentProps: { | |
463 | + valueFormat: 'HH:mm:ss' | |
464 | + }, | |
462 | 465 | <#elseif po.classType =='popup'> |
463 | - component: 'JPopup', | |
464 | - componentProps: ({ formActionType }) => { | |
465 | - const {setFieldsValue} = formActionType; | |
466 | - return{ | |
467 | - setFieldsValue:setFieldsValue, | |
468 | - code:"${po.dictTable}", | |
469 | - fieldConfig:${po.dictField}, | |
470 | - multi:${po.extendParams.popupMulti?c}, | |
471 | - } | |
472 | - }, | |
466 | + <#include "/common/form/vue3popup.ftl"> | |
473 | 467 | <#elseif po.classType =='sel_depart'> |
474 | 468 | component: 'JSelectDept', |
475 | 469 | <#elseif po.classType =='switch'> |
... | ... | @@ -491,14 +485,14 @@ export const ${sub.entityName?uncap_first}FormSchema: FormSchema[] = [ |
491 | 485 | labelKey:'realname', |
492 | 486 | }, |
493 | 487 | <#elseif po.classType =='textarea'> |
494 | - component: 'InputTextArea',//TODO 注意string转换问题 | |
488 | + component: 'InputTextArea', | |
495 | 489 | <#elseif po.classType=='list' || po.classType=='radio'> |
496 | 490 | component: 'JDictSelectTag', |
497 | 491 | componentProps:{ |
498 | 492 | dictCode:"${form_field_dictCode}" |
499 | 493 | }, |
500 | 494 | <#elseif po.classType=='list_multi' || po.classType=='checkbox'> |
501 | - component: 'JMultiSelectTag',//TODO 暂无该组件 | |
495 | + component: 'JSelectMultiple', | |
502 | 496 | componentProps:{ |
503 | 497 | dictCode:"${form_field_dictCode}" |
504 | 498 | }, |
... | ... | @@ -533,7 +527,7 @@ export const ${sub.entityName?uncap_first}FormSchema: FormSchema[] = [ |
533 | 527 | </#if> |
534 | 528 | }, |
535 | 529 | <#elseif po.classType=='umeditor'> |
536 | - component: 'JCodeEditor', //TODO String后缀暂未添加 | |
530 | + component: 'JEditor', | |
537 | 531 | <#elseif po.classType == 'sel_tree'> |
538 | 532 | component: 'JTreeSelect', |
539 | 533 | componentProps:{ |
... | ... | @@ -565,16 +559,16 @@ export const ${sub.entityName?uncap_first}FormSchema: FormSchema[] = [ |
565 | 559 | </#if> |
566 | 560 | <#-- 唯一校验 --> |
567 | 561 | <#if fieldValidType == 'only'> |
568 | - {...rules.duplicateCheckRule(<#if sub?default("")?trim?length gt 1>'${sub.tableName}'<#else>'${tableName}'</#if>, '${po.fieldDbName}',model,schema,true)[0]}, | |
562 | + {...rules.duplicateCheckRule(<#if sub?default("")?trim?length gt 1>'${sub.tableName}'<#else>'${tableName}'</#if>, '${po.fieldDbName}',model,schema)[0]}, | |
569 | 563 | <#-- 6到16位数字 --> |
570 | 564 | <#elseif fieldValidType == 'n6-16'> |
571 | 565 | { pattern: /^\d{6,16}$/, message: '请输入6到16位数字!'}, |
572 | 566 | <#-- 6到16位任意字符 --> |
573 | 567 | <#elseif fieldValidType == '*6-16'> |
574 | 568 | { pattern: /^.{6,16}$/, message: '请输入6到16位任意字符!'}, |
575 | - <#-- 6到18位字符串 --> | |
569 | + <#-- 6到18位字母 --> | |
576 | 570 | <#elseif fieldValidType == 's6-18'> |
577 | - { pattern: /^.{6,18}$/, message: '请输入6到18位任意字符!'}, | |
571 | + { pattern: /^[a-z|A-Z]{6,18}$/, message: '请输入6到18位字母!'}, | |
578 | 572 | <#-- 网址 --> |
579 | 573 | <#elseif fieldValidType == 'url'> |
580 | 574 | { pattern: /^((ht|f)tps?):\/\/[\w\-]+(\.[\w\-]+)+([\w\-.,@?^=%&:\/~+#]*[\w\-@?^=%&\/~+#])?$/, message: '请输入正确的网址!'}, |
... | ... | @@ -616,6 +610,14 @@ export const ${sub.entityName?uncap_first}FormSchema: FormSchema[] = [ |
616 | 610 | }, |
617 | 611 | </#if> |
618 | 612 | </#list> |
613 | +<#if sub_id_exists == false> | |
614 | + { | |
615 | + label: '', | |
616 | + field: 'id', | |
617 | + component: 'Input', | |
618 | + show: false | |
619 | + }, | |
620 | +</#if> | |
619 | 621 | ]; |
620 | 622 | </#if> |
621 | 623 | </#list> |
... | ... | @@ -642,12 +644,20 @@ export const ${sub.entityName?uncap_first}JVxeColumns: JVxeColumn[] = [ |
642 | 644 | <#if col.readonly=='Y'> |
643 | 645 | disabled:true, |
644 | 646 | </#if> |
647 | +<#elseif col.classType =='time'> | |
648 | + type: JVxeTypes.time, | |
649 | + <#if col.readonly=='Y'> | |
650 | + disabled:true, | |
651 | + </#if> | |
645 | 652 | <#elseif col.classType =='textarea'> |
646 | 653 | type: JVxeTypes.textarea, |
647 | 654 | <#if col.readonly=='Y'> |
648 | 655 | disabled:true, |
649 | 656 | </#if> |
650 | -<#elseif "int,decimal,double,"?contains(col.classType)> | |
657 | +<#-- update-begin-author:taoyan date:20220523 for: VUEN-1084 【vue3】online表单测试发现的新问题 20、一对多列字段类型生成的不对,数字或者金额类型 --> | |
658 | +<#-- elseif "int,decimal,double,"?contains(col.classType) --> | |
659 | +<#elseif col.fieldDbType=='int' || col.fieldDbType=='double' || col.fieldDbType=='BigDecimal'> | |
660 | +<#-- update-end-author:taoyan date:20220523 for: VUEN-1084 【vue3】online表单测试发现的新问题 20、一对多列字段类型生成的不对,数字或者金额类型 --> | |
651 | 661 | type: JVxeTypes.inputNumber, |
652 | 662 | <#if col.readonly=='Y'> |
653 | 663 | disabled:true, |
... | ... | @@ -684,6 +694,16 @@ export const ${sub.entityName?uncap_first}JVxeColumns: JVxeColumn[] = [ |
684 | 694 | <#if col.readonly=='Y'> |
685 | 695 | disabled:true, |
686 | 696 | </#if> |
697 | +<#elseif col.classType =='sel_depart'> | |
698 | + type: JVxeTypes.departSelect, | |
699 | + <#if col.readonly=='Y'> | |
700 | + disabled:true, | |
701 | + </#if> | |
702 | +<#elseif col.classType =='sel_user'> | |
703 | + type: JVxeTypes.userSelect, | |
704 | + <#if col.readonly=='Y'> | |
705 | + disabled:true, | |
706 | + </#if> | |
687 | 707 | <#elseif col.classType =='image'> |
688 | 708 | type: JVxeTypes.image, |
689 | 709 | token:true, |
... | ... | @@ -707,9 +727,9 @@ export const ${sub.entityName?uncap_first}JVxeColumns: JVxeColumn[] = [ |
707 | 727 | <#elseif col.classType =='switch'> |
708 | 728 | type: JVxeTypes.checkbox, |
709 | 729 | <#if col.dictField == 'is_open'> |
710 | - customValue: ['Y', 'N'], | |
730 | + customValue: ['Y', 'N'], | |
711 | 731 | <#else> |
712 | - customValue: ${col.dictField}, | |
732 | + customValue: ${col.dictField}, | |
713 | 733 | </#if> |
714 | 734 | <#if col.readonly=='Y'> |
715 | 735 | disabled:true, |
... | ... | @@ -720,18 +740,11 @@ export const ${sub.entityName?uncap_first}JVxeColumns: JVxeColumn[] = [ |
720 | 740 | <#else> |
721 | 741 | <#assign popupBackFields = "${col.dictText}"> |
722 | 742 | </#if> |
723 | - type: JVxeTypes.popup, | |
724 | - popupCode:"${col.dictTable}", | |
725 | - field:"${col.dictField}", | |
726 | - orgFields:"${col.dictField}", | |
727 | - destFields:"${Format.underlineToHump(col.dictText)}", | |
728 | - <#if col.readonly=='Y'> | |
729 | - disabled:true, | |
730 | - </#if> | |
743 | + <#include "/common/form/vue3Jvxepopup.ftl"> | |
731 | 744 | <#else> |
732 | - type: JVxeTypes.input, | |
745 | + type: JVxeTypes.input, | |
733 | 746 | <#if col.readonly=='Y'> |
734 | - disabled:true, | |
747 | + disabled:true, | |
735 | 748 | </#if> |
736 | 749 | </#if> |
737 | 750 | <#if col.classType =='list_multi' || col.classType =='checkbox'> |
... | ... | @@ -754,18 +767,7 @@ export const ${sub.entityName?uncap_first}JVxeColumns: JVxeColumn[] = [ |
754 | 767 | defaultValue:'', |
755 | 768 | </#if> |
756 | 769 | <#-- 子表的校验 --> |
757 | -<#assign subFieldValidType = col.fieldValidType!''> | |
758 | -<#-- 非空校验 --> | |
759 | -<#if col.nullable == 'N' || subFieldValidType == '*'> | |
760 | - validateRules: [{ required: true, message: '${'$'}{title}不能为空' }], | |
761 | -<#-- 其他情况下,只要有值就被认为是正则校验 --> | |
762 | -<#elseif subFieldValidType?length gt 0> | |
763 | -<#assign subMessage = '格式不正确'> | |
764 | -<#if subFieldValidType == 'only' > | |
765 | - <#assign subMessage = '不能重复'> | |
766 | -</#if> | |
767 | - validateRules: [{ pattern: "${subFieldValidType}", message: "${'$'}{title}${subMessage}" }], | |
768 | -</#if> | |
770 | + <#include "/common/validatorRulesTemplate/sub-vue3.ftl"> | |
769 | 771 | }, |
770 | 772 | </#if> |
771 | 773 | </#if> |
... | ... |
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}_menu_insert.sql
0 → 100644
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue3/components/${entityName}Modal.vuei
1 | +<#include "/common/utils.ftl"> | |
1 | 2 | <template> |
2 | - <BasicModal v-bind="$attrs" @register="registerModal" :title="title" @ok="handleSubmit"> | |
3 | + <BasicModal v-bind="$attrs" @register="registerModal" destroyOnClose :title="title" :width="${getModalWidth(tableVo.fieldRowNum?default(1))}" @ok="handleSubmit"> | |
3 | 4 | <BasicForm @register="registerForm" ref="formRef"/> |
4 | 5 | <!-- 子表单区域 --> |
5 | 6 | <a-tabs v-model:activeKey="activeKey" @change="handleChangeTabs"> |
... | ... | @@ -7,7 +8,7 @@ |
7 | 8 | <#assign refKey = sub.entityName?uncap_first/> |
8 | 9 | <#if sub.foreignRelationType =='1'> |
9 | 10 | <a-tab-pane tab="${sub.ftlDescription}" key="${refKey}" :forceRender="true"> |
10 | - <${sub.entityName}Form ref="${sub.entityName?uncap_first}Form"></${sub.entityName}Form> | |
11 | + <${sub.entityName}Form ref="${sub.entityName?uncap_first}Form" :disabled="formDisabled"></${sub.entityName}Form> | |
11 | 12 | </a-tab-pane> |
12 | 13 | |
13 | 14 | <#else> |
... | ... | @@ -19,7 +20,8 @@ |
19 | 20 | :loading="${sub.entityName?uncap_first}Table.loading" |
20 | 21 | :columns="${sub.entityName?uncap_first}Table.columns" |
21 | 22 | :dataSource="${sub.entityName?uncap_first}Table.dataSource" |
22 | - :maxHeight="300" | |
23 | + :height="340" | |
24 | + :disabled="formDisabled" | |
23 | 25 | :rowNumber="true" |
24 | 26 | :rowSelection="true" |
25 | 27 | :toolbar="true" |
... | ... | @@ -48,6 +50,7 @@ |
48 | 50 | // Emits声明 |
49 | 51 | const emit = defineEmits(['register','success']); |
50 | 52 | const isUpdate = ref(true); |
53 | + const formDisabled = ref(false); | |
51 | 54 | const refKeys = ref([<#list subTables as sub>'${sub.entityName?uncap_first}', </#list>]); |
52 | 55 | <#assign hasOne2Many = false> |
53 | 56 | <#assign hasOne2One = false> |
... | ... | @@ -77,6 +80,7 @@ |
77 | 80 | labelWidth: 150, |
78 | 81 | schemas: formSchema, |
79 | 82 | showActionButtonGroup: false, |
83 | + baseColProps: {span: ${getFormSpan(tableVo.fieldRowNum?default(1))}} | |
80 | 84 | }); |
81 | 85 | //表单赋值 |
82 | 86 | const [registerModal, {setModalProps, closeModal}] = useModalInner(async (data) => { |
... | ... | @@ -84,6 +88,7 @@ |
84 | 88 | await reset(); |
85 | 89 | setModalProps({confirmLoading: false,showCancelBtn:data?.showFooter,showOkBtn:data?.showFooter}); |
86 | 90 | isUpdate.value = !!data?.isUpdate; |
91 | + formDisabled.value = !data?.showFooter; | |
87 | 92 | if (unref(isUpdate)) { |
88 | 93 | //表单赋值 |
89 | 94 | await setFieldsValue({ |
... | ... | @@ -176,5 +181,12 @@ |
176 | 181 | </script> |
177 | 182 | |
178 | 183 | <style lang="less" scoped> |
184 | + /** 时间和数字输入框样式 */ | |
185 | + :deep(.ant-input-number){ | |
186 | + width: 100% | |
187 | + } | |
179 | 188 | |
189 | + :deep(.ant-calendar-picker){ | |
190 | + width: 100% | |
191 | + } | |
180 | 192 | </style> |
181 | 193 | \ No newline at end of file |
... | ... |
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue3/components/[1-n]Form.vuei
1 | +<#include "/common/utils.ftl"> | |
1 | 2 | <#list subTables as sub> |
2 | 3 | <#if sub.foreignRelationType=='1'> |
3 | 4 | #segment#${sub.entityName}Form.vue |
... | ... | @@ -15,11 +16,18 @@ |
15 | 16 | name:"${sub.entityName}Form", |
16 | 17 | components: {BasicForm}, |
17 | 18 | emits:['register'], |
18 | - setup(_,{emit}) { | |
19 | - const [registerForm, {resetFields, setFieldsValue,getFieldsValue,validate}] = useForm({ | |
19 | + props:{ | |
20 | + disabled: { | |
21 | + type: Boolean, | |
22 | + default: false | |
23 | + } | |
24 | + }, | |
25 | + setup(props,{emit}) { | |
26 | + const [registerForm, {setProps, resetFields, setFieldsValue,getFieldsValue,validate}] = useForm({ | |
20 | 27 | labelWidth: 150, |
21 | 28 | schemas: ${sub.entityName?uncap_first}FormSchema, |
22 | 29 | showActionButtonGroup: false, |
30 | + baseColProps: {span: ${getFormSpan(tableVo.fieldRowNum?default(1))}} | |
23 | 31 | }); |
24 | 32 | /** |
25 | 33 | *初始化加载数据 |
... | ... | @@ -30,13 +38,22 @@ |
30 | 38 | res.success && setFieldsValue({...res.result.records[0]}); |
31 | 39 | }) |
32 | 40 | } |
41 | + setProps({disabled: props.disabled}) | |
33 | 42 | } |
34 | - /** | |
35 | - *获取表单数据 | |
36 | - */ | |
43 | + | |
44 | + /** | |
45 | + *获取表单数据 | |
46 | + */ | |
37 | 47 | function getFormData(){ |
38 | - return [getFieldsValue()]; | |
48 | + let formData = getFieldsValue(); | |
49 | + Object.keys(formData).map(k=>{ | |
50 | + if(formData[k] instanceof Array){ | |
51 | + formData[k] = formData[k].join(',') | |
52 | + } | |
53 | + }); | |
54 | + return [formData]; | |
39 | 55 | } |
56 | + | |
40 | 57 | /** |
41 | 58 | *表单校验 |
42 | 59 | */ |
... | ... |
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai
... | ... | @@ -205,17 +205,14 @@ public class ${entityName}Controller { |
205 | 205 | QueryWrapper<${entityName}> queryWrapper = QueryGenerator.initQueryWrapper(${entityName?uncap_first}, request.getParameterMap()); |
206 | 206 | LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); |
207 | 207 | |
208 | - //Step.2 获取导出数据 | |
209 | - List<${entityName}> queryList = ${entityName?uncap_first}Service.list(queryWrapper); | |
210 | - // 过滤选中数据 | |
208 | + //配置选中数据查询条件 | |
211 | 209 | String selections = request.getParameter("selections"); |
212 | - List<${entityName}> ${entityName?uncap_first}List = new ArrayList<${entityName}>(); | |
213 | - if(oConvertUtils.isEmpty(selections)) { | |
214 | - ${entityName?uncap_first}List = queryList; | |
215 | - }else { | |
216 | - List<String> selectionList = Arrays.asList(selections.split(",")); | |
217 | - ${entityName?uncap_first}List = queryList.stream().filter(item -> selectionList.contains(item.getId())).collect(Collectors.toList()); | |
210 | + if(oConvertUtils.isNotEmpty(selections)) { | |
211 | + List<String> selectionList = Arrays.asList(selections.split(",")); | |
212 | + queryWrapper.in("id",selectionList); | |
218 | 213 | } |
214 | + //Step.2 获取导出数据 | |
215 | + List<${entityName}> ${entityName?uncap_first}List = ${entityName?uncap_first}Service.list(queryWrapper); | |
219 | 216 | |
220 | 217 | // Step.3 组装pageList |
221 | 218 | List<${entityName}Page> pageList = new ArrayList<${entityName}Page>(); |
... | ... |
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/entity/${entityName}.javai
1 | +<#include "/common/utils.ftl"> | |
1 | 2 | package ${bussiPackage}.${entityPackage}.entity; |
2 | 3 | |
3 | 4 | import java.io.Serializable; |
... | ... | @@ -31,9 +32,9 @@ public class ${entityName} implements Serializable { |
31 | 32 | <#-- 生成字典Code --> |
32 | 33 | <#assign list_field_dictCode=""> |
33 | 34 | <#if po.classType='sel_user'> |
34 | - <#assign list_field_dictCode=', dictTable = "sys_user", dicText = "realname", dicCode = "username"'> | |
35 | + <#assign list_field_dictCode=', dictTable = "sys_user", dicText = "${camelToDashed(po.extendParams.text?default(\"realname\")?trim)}", dicCode = "${camelToDashed(po.extendParams.store?default(\"username\")?trim)}"'> | |
35 | 36 | <#elseif po.classType='sel_depart'> |
36 | - <#assign list_field_dictCode=', dictTable = "sys_depart", dicText = "depart_name", dicCode = "id"'> | |
37 | + <#assign list_field_dictCode=', dictTable = "sys_depart", dicText = "${camelToDashed(po.extendParams.text?default(\"depart_name\")?trim)}", dicCode = "${camelToDashed(po.extendParams.store?default(\"id\")?trim)}"'> | |
37 | 38 | <#elseif po.classType=='list' || po.classType=='list_multi' || po.classType=='sel_search' || po.classType=='radio' || po.classType=='checkbox'> |
38 | 39 | <#if po.dictTable?default("")?trim?length gt 1> |
39 | 40 | <#assign list_field_dictCode=', dictTable = "${po.dictTable}", dicText = "${po.dictText}", dicCode = "${po.dictField}"'> |
... | ... |
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/entity/[1-n]Entity.javai
1 | +<#include "/common/utils.ftl"> | |
1 | 2 | <#list subTables as subTab> |
2 | 3 | #segment#${subTab.entityName}.java |
3 | 4 | package ${bussiPackage}.${entityPackage}.entity; |
... | ... | @@ -32,9 +33,9 @@ public class ${subTab.entityName} implements Serializable { |
32 | 33 | <#-- 生成字典Code --> |
33 | 34 | <#assign list_field_dictCode=""> |
34 | 35 | <#if po.classType='sel_user'> |
35 | - <#assign list_field_dictCode=', dictTable = "sys_user", dicText = "realname", dicCode = "username"'> | |
36 | + <#assign list_field_dictCode=', dictTable = "sys_user", dicText = "${camelToDashed(po.extendParams.text?default(\"realname\")?trim)}", dicCode = "${camelToDashed(po.extendParams.store?default(\"username\")?trim)}"'> | |
36 | 37 | <#elseif po.classType='sel_depart'> |
37 | - <#assign list_field_dictCode=', dictTable = "sys_depart", dicText = "depart_name", dicCode = "id"'> | |
38 | + <#assign list_field_dictCode=', dictTable = "sys_depart", dicText = "${camelToDashed(po.extendParams.text?default(\"depart_name\")?trim)}", dicCode = "${camelToDashed(po.extendParams.store?default(\"id\")?trim)}"'> | |
38 | 39 | <#elseif po.classType=='list' || po.classType=='list_multi' || po.classType=='sel_search' || po.classType=='radio' || po.classType=='checkbox'> |
39 | 40 | <#if po.dictTable?default("")?trim?length gt 1> |
40 | 41 | <#assign list_field_dictCode=', dictTable = "${po.dictTable}", dicText = "${po.dictText}", dicCode = "${po.dictField}"'> |
... | ... |
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue/${entityName}_menu_insert.sql
0 → 100644
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/${entityName}Form.vuei
... | ... | @@ -48,7 +48,7 @@ |
48 | 48 | @input="popupCallback" |
49 | 49 | <#if po.readonly=='Y'>disabled</#if>/> |
50 | 50 | <#elseif po.classType =='sel_depart'> |
51 | - <j-select-depart v-model="model.${po.fieldName}" multi <#if po.readonly=='Y'>disabled</#if>/> | |
51 | + <j-select-depart v-model="model.${po.fieldName}" :multi="${po.extendParams.multi?default('true')}"<#if po.extendParams.store?default("")?trim?length gt 0> store="${po.extendParams.store}"</#if><#if po.extendParams.text?default("")?trim?length gt 0> text="${po.extendParams.text}"</#if> <#if po.readonly=='Y'>disabled</#if> /> | |
52 | 52 | <#elseif po.classType =='switch'> |
53 | 53 | <j-switch v-model="model.${po.fieldName}" <#if po.dictField != 'is_open'>:options="${po.dictField}"</#if> <#if po.readonly=='Y'>disabled</#if>></j-switch> |
54 | 54 | <#elseif po.classType =='pca'> |
... | ... | @@ -58,7 +58,7 @@ |
58 | 58 | <#elseif po.classType =='password'> |
59 | 59 | <a-input-password v-model="model.${po.fieldName}" placeholder="请输入${po.filedComment}" <#if po.readonly=='Y'>disabled</#if>/> |
60 | 60 | <#elseif po.classType =='sel_user'> |
61 | - <j-select-user-by-dep v-model="model.${po.fieldName}" <#if po.readonly=='Y'>disabled</#if>/> | |
61 | + <j-select-user-by-dep v-model="model.${po.fieldName}" :multi="${po.extendParams.multi?default('true')}"<#if po.extendParams.store?default("")?trim?length gt 0> store="${po.extendParams.store}"</#if><#if po.extendParams.text?default("")?trim?length gt 0> text="${po.extendParams.text}"</#if> <#if po.readonly=='Y'>disabled</#if>/> | |
62 | 62 | <#elseif po.classType =='textarea'> |
63 | 63 | <a-textarea v-model="model.${autoStringSuffixForModel(po)}" rows="4" placeholder="请输入${po.filedComment}" <#if po.readonly=='Y'>disabled</#if>/> |
64 | 64 | <#elseif po.classType=='list' || po.classType=='radio'> |
... | ... |
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/[1-n]Form.vuei
... | ... | @@ -44,7 +44,7 @@ |
44 | 44 | :multi="${po.extendParams.popupMulti?c}" |
45 | 45 | @input="popupCallback"/> |
46 | 46 | <#elseif po.classType =='sel_depart'> |
47 | - <j-select-depart v-model="model.${po.fieldName}" multi/> | |
47 | + <j-select-depart v-model="model.${po.fieldName}" :multi="${po.extendParams.multi?default('true')}"<#if po.extendParams.store?default("")?trim?length gt 0> store="${po.extendParams.store}"</#if><#if po.extendParams.text?default("")?trim?length gt 0> text="${po.extendParams.text}"</#if> <#if po.readonly=='Y'>disabled</#if> /> | |
48 | 48 | <#elseif po.classType =='switch'> |
49 | 49 | <j-switch v-model="model.${po.fieldName}" <#if po.dictField!= 'is_open'>:options="${po.dictField}"</#if>></j-switch> |
50 | 50 | <#elseif po.classType =='pca'> |
... | ... | @@ -54,7 +54,7 @@ |
54 | 54 | <#elseif po.classType =='password'> |
55 | 55 | <a-input-password v-model="model.${po.fieldName}" placeholder="请输入${po.filedComment}"/> |
56 | 56 | <#elseif po.classType =='sel_user'> |
57 | - <j-select-user-by-dep v-model="model.${po.fieldName}"/> | |
57 | + <j-select-user-by-dep v-model="model.${po.fieldName}" :multi="${po.extendParams.multi?default('true')}"<#if po.extendParams.store?default("")?trim?length gt 0> store="${po.extendParams.store}"</#if><#if po.extendParams.text?default("")?trim?length gt 0> text="${po.extendParams.text}"</#if> <#if po.readonly=='Y'>disabled</#if>/> | |
58 | 58 | <#elseif po.classType =='textarea'> |
59 | 59 | <a-textarea v-model="model.${autoStringSuffixForModel(po)}" rows="4" placeholder="请输入${po.filedComment}"/> |
60 | 60 | <#elseif po.classType=='list' || po.classType=='radio'> |
... | ... |
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}List.vuei
... | ... | @@ -46,6 +46,10 @@ |
46 | 46 | <template #htmlSlot="{text}"> |
47 | 47 | <div v-html="text"></div> |
48 | 48 | </template> |
49 | + <!--省市区字段回显插槽--> | |
50 | + <template #pcaSlot="{text}"> | |
51 | + {{ getAreaTextByCode(text) }} | |
52 | + </template> | |
49 | 53 | <template #fileSlot="{text}"> |
50 | 54 | <span v-if="!text" style="font-size: 12px;font-style: italic;">无文件</span> |
51 | 55 | <a-button v-else :ghost="true" type="primary" preIcon="ant-design:download-outlined" size="small" @click="downloadFile(text)">下载</a-button> |
... | ... | @@ -64,6 +68,10 @@ |
64 | 68 | import ${entityName}Modal from './components/${entityName}Modal.vue' |
65 | 69 | import {columns, searchFormSchema} from './${entityName}.data'; |
66 | 70 | import {list, deleteOne, batchDelete, getImportUrl,getExportUrl} from './${entityName}.api'; |
71 | + import {downloadFile} from '/@/utils/common/renderUtils'; | |
72 | +<#if list_need_pca> | |
73 | + import { getAreaTextByCode } from '/@/components/Form/src/utils/Area'; | |
74 | +</#if> | |
67 | 75 | <#if list_need_category> |
68 | 76 | import { loadCategoryData } from '/@/api/common/api' |
69 | 77 | import { getAuthCache, setAuthCache } from '/@/utils/auth'; |
... | ... | @@ -84,6 +92,17 @@ |
84 | 92 | schemas: searchFormSchema, |
85 | 93 | autoSubmitOnEnter:true, |
86 | 94 | showAdvancedButton:true, |
95 | + fieldMapToNumber: [ | |
96 | + <#list columns as po> | |
97 | + <#if po.isQuery=='Y'> | |
98 | + <#if po.queryMode!='single'> | |
99 | + <#if po.fieldDbType=='int' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'> | |
100 | + ['${po.fieldName}', ['${po.fieldName}_begin', '${po.fieldName}_end']], | |
101 | + </#if> | |
102 | + </#if> | |
103 | + </#if> | |
104 | + </#list> | |
105 | + ], | |
87 | 106 | fieldMapToTime: [ |
88 | 107 | <#list columns as po> |
89 | 108 | <#if po.isQuery=='Y'> |
... | ... | @@ -98,9 +117,10 @@ |
98 | 117 | </#list> |
99 | 118 | ], |
100 | 119 | }, |
101 | - actionColumn: { | |
120 | + actionColumn: { | |
102 | 121 | width: 120, |
103 | - }, | |
122 | + fixed:'right' | |
123 | + }, | |
104 | 124 | }, |
105 | 125 | exportConfig: { |
106 | 126 | name:"${tableVo.ftlDescription}", |
... | ... |
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__data.tsi
1 | +<#include "/common/utils.ftl"> | |
1 | 2 | import {BasicColumn} from '/@/components/Table'; |
2 | 3 | import {FormSchema} from '/@/components/Table'; |
3 | 4 | import { rules} from '/@/utils/helper/validator'; |
... | ... | @@ -25,7 +26,7 @@ export const columns: BasicColumn[] = [ |
25 | 26 | slots: { customRender: 'htmlSlot' }, |
26 | 27 | <#elseif po.classType=='pca'> |
27 | 28 | dataIndex: '${po.fieldName}', |
28 | - slots: { customRender: 'pcaSlot' },//TODO 未翻译 | |
29 | + slots: { customRender: 'pcaSlot' }, | |
29 | 30 | <#elseif po.classType=='file'> |
30 | 31 | dataIndex: '${po.fieldName}', |
31 | 32 | slots: { customRender: 'fileSlot' }, |
... | ... | @@ -57,7 +58,7 @@ export const columns: BasicColumn[] = [ |
57 | 58 | return render.renderCategoryTree(text,'${po.dictField?default("")}') |
58 | 59 | }, |
59 | 60 | <#else> |
60 | - customRender: (text, record) => (text ? record['${po.dictText}'] : '') | |
61 | + customRender: ({text, record}) => (text ? record['${po.dictText}'] : '') | |
61 | 62 | </#if> |
62 | 63 | <#else> |
63 | 64 | dataIndex: '${po.fieldName}' |
... | ... | @@ -95,16 +96,22 @@ export const searchFormSchema: FormSchema[] = [ |
95 | 96 | <#elseif po.classType=='switch'> |
96 | 97 | component: 'JSwitch', |
97 | 98 | componentProps:{ |
99 | + query:true, | |
98 | 100 | <#if po.dictField != 'is_open'> |
99 | - options:"${po.dictField}" | |
101 | + options:${po.dictField} | |
100 | 102 | </#if> |
101 | 103 | }, |
102 | 104 | <#elseif po.classType=='sel_depart'> |
103 | 105 | component: 'JSelectDept', |
104 | 106 | <#elseif po.classType=='list_multi'> |
105 | - component: 'JMultiSelectTag',//暂无该组件 | |
107 | + component: 'JSelectMultiple', | |
106 | 108 | componentProps:{ |
107 | - dictCode:"query_field_dictCode?default("")" | |
109 | + <#if po.dictTable?default("")?trim?length gt 1> | |
110 | + dictCode:"${po.dictTable},${po.dictText},${po.dictField}", | |
111 | + <#elseif po.dictField?default("")?trim?length gt 1> | |
112 | + dictCode:"${po.dictField}", | |
113 | + </#if> | |
114 | + triggerChange: true | |
108 | 115 | }, |
109 | 116 | <#elseif po.classType=='cat_tree'> |
110 | 117 | component: 'JCategorySelect', |
... | ... | @@ -121,16 +128,7 @@ export const searchFormSchema: FormSchema[] = [ |
121 | 128 | <#elseif po.classType=='pca'> |
122 | 129 | component: 'JAreaLinkage', |
123 | 130 | <#elseif po.classType=='popup'> |
124 | - component: 'JPopup', | |
125 | - componentProps: ({ formActionType }) => { | |
126 | - const {setFieldsValue} = formActionType; | |
127 | - return{ | |
128 | - setFieldsValue:setFieldsValue, | |
129 | - code:"${po.dictTable}", | |
130 | - fieldConfig:"${po.dictField}", | |
131 | - multi:${po.extendParams.popupMulti?c}, | |
132 | - } | |
133 | - }, | |
131 | + <#include "/common/form/vue3popup.ftl"> | |
134 | 132 | <#elseif po.classType=='list' || po.classType=='radio' || po.classType=='checkbox'> |
135 | 133 | <#-- ---------------------------下拉或是单选 判断数据字典是表字典还是普通字典------------------------------- --> |
136 | 134 | component: 'JDictSelectTag', |
... | ... | @@ -157,6 +155,8 @@ export const searchFormSchema: FormSchema[] = [ |
157 | 155 | componentProps: { |
158 | 156 | showTime:true |
159 | 157 | }, |
158 | +<#elseif po.fieldDbType=='int' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'> | |
159 | + component: 'JRangeNumber', | |
160 | 160 | <#else> |
161 | 161 | component: 'Input', //TODO 范围查询 |
162 | 162 | </#if> |
... | ... | @@ -189,27 +189,22 @@ export const formSchema: FormSchema[] = [ |
189 | 189 | </#if> |
190 | 190 | { |
191 | 191 | label: '${po.filedComment}', |
192 | - field: '${po.fieldName}', | |
192 | + field: ${autoStringSuffix(po)}, | |
193 | 193 | <#if po.classType =='date'> |
194 | 194 | component: 'DatePicker', |
195 | - <#elseif po.fieldType =='datetime'> | |
195 | + <#elseif po.classType =='datetime'> | |
196 | 196 | component: 'DatePicker', |
197 | 197 | componentProps: { |
198 | - showTime:true | |
198 | + showTime:true, | |
199 | + valueFormat: 'YYYY-MM-DD HH:mm:ss' | |
199 | 200 | }, |
200 | - <#elseif po.fieldType =='time'> | |
201 | + <#elseif po.classType =='time'> | |
201 | 202 | component: 'TimePicker', |
203 | + componentProps: { | |
204 | + valueFormat: 'HH:mm:ss' | |
205 | + }, | |
202 | 206 | <#elseif po.classType =='popup'> |
203 | - component: 'JPopup', | |
204 | - componentProps: ({ formActionType }) => { | |
205 | - const {setFieldsValue} = formActionType; | |
206 | - return{ | |
207 | - setFieldsValue:setFieldsValue, | |
208 | - code:"${po.dictTable}", | |
209 | - fieldConfig:${po.dictField}, | |
210 | - multi:${po.extendParams.popupMulti?c}, | |
211 | - } | |
212 | - }, | |
207 | + <#include "/common/form/vue3popup.ftl"> | |
213 | 208 | <#elseif po.classType =='sel_depart'> |
214 | 209 | component: 'JSelectDept', |
215 | 210 | <#elseif po.classType =='switch'> |
... | ... | @@ -231,14 +226,14 @@ export const formSchema: FormSchema[] = [ |
231 | 226 | labelKey:'realname', |
232 | 227 | }, |
233 | 228 | <#elseif po.classType =='textarea'> |
234 | - component: 'InputTextArea',//TODO 注意string转换问题 | |
229 | + component: 'InputTextArea', | |
235 | 230 | <#elseif po.classType=='list' || po.classType=='radio'> |
236 | 231 | component: 'JDictSelectTag', |
237 | 232 | componentProps:{ |
238 | 233 | dictCode:"${form_field_dictCode}" |
239 | 234 | }, |
240 | 235 | <#elseif po.classType=='list_multi' || po.classType=='checkbox'> |
241 | - component: 'JMultiSelectTag',//TODO 暂无该组件 | |
236 | + component: 'JSelectMultiple', | |
242 | 237 | componentProps:{ |
243 | 238 | dictCode:"${form_field_dictCode}" |
244 | 239 | }, |
... | ... | @@ -273,7 +268,7 @@ export const formSchema: FormSchema[] = [ |
273 | 268 | </#if> |
274 | 269 | }, |
275 | 270 | <#elseif po.classType=='umeditor'> |
276 | - component: 'JCodeEditor', //TODO String后缀暂未添加 | |
271 | + component: 'JEditor', | |
277 | 272 | <#elseif po.classType == 'sel_tree'> |
278 | 273 | component: 'JTreeSelect', |
279 | 274 | componentProps:{ |
... | ... | @@ -305,16 +300,16 @@ export const formSchema: FormSchema[] = [ |
305 | 300 | </#if> |
306 | 301 | <#-- 唯一校验 --> |
307 | 302 | <#if fieldValidType == 'only'> |
308 | - {...rules.duplicateCheckRule(<#if sub?default("")?trim?length gt 1>'${sub.tableName}'<#else>'${tableName}'</#if>, '${po.fieldDbName}',model,schema,true)[0]}, | |
303 | + {...rules.duplicateCheckRule(<#if sub?default("")?trim?length gt 1>'${sub.tableName}'<#else>'${tableName}'</#if>, '${po.fieldDbName}',model,schema)[0]}, | |
309 | 304 | <#-- 6到16位数字 --> |
310 | 305 | <#elseif fieldValidType == 'n6-16'> |
311 | 306 | { pattern: /^\d{6,16}$/, message: '请输入6到16位数字!'}, |
312 | 307 | <#-- 6到16位任意字符 --> |
313 | 308 | <#elseif fieldValidType == '*6-16'> |
314 | 309 | { pattern: /^.{6,16}$/, message: '请输入6到16位任意字符!'}, |
315 | - <#-- 6到18位字符串 --> | |
310 | + <#-- 6到18位字母 --> | |
316 | 311 | <#elseif fieldValidType == 's6-18'> |
317 | - { pattern: /^.{6,18}$/, message: '请输入6到18位任意字符!'}, | |
312 | + { pattern: /^[a-z|A-Z]{6,18}$/, message: '请输入6到18位字母!'}, | |
318 | 313 | <#-- 网址 --> |
319 | 314 | <#elseif fieldValidType == 'url'> |
320 | 315 | { pattern: /^((ht|f)tps?):\/\/[\w\-]+(\.[\w\-]+)+([\w\-.,@?^=%&:\/~+#]*[\w\-@?^=%&\/~+#])?$/, message: '请输入正确的网址!'}, |
... | ... | @@ -373,10 +368,14 @@ export const ${sub.entityName?uncap_first}FormSchema: FormSchema[] = [ |
373 | 368 | <#assign form_cat_tree = false> |
374 | 369 | <#assign form_cat_back = ""> |
375 | 370 | <#assign bpm_flag=false> |
371 | +<#assign sub_id_exists=false> | |
376 | 372 | <#list sub.colums as po><#rt/> |
377 | 373 | <#if po.fieldDbName=='bpm_status'> |
378 | 374 | <#assign bpm_flag=true> |
379 | 375 | </#if> |
376 | +<#if po.fieldDbName=='id'> | |
377 | + <#assign sub_id_exists=true> | |
378 | +</#if> | |
380 | 379 | <#if po.isShow =='Y'> |
381 | 380 | <#assign form_field_dictCode=""> |
382 | 381 | <#if po.dictTable?default("")?trim?length gt 1 && po.dictText?default("")?trim?length gt 1 && po.dictField?default("")?trim?length gt 1> |
... | ... | @@ -386,27 +385,22 @@ export const ${sub.entityName?uncap_first}FormSchema: FormSchema[] = [ |
386 | 385 | </#if> |
387 | 386 | { |
388 | 387 | label: '${po.filedComment}', |
389 | - field: '${po.fieldName}', | |
388 | + field: ${autoStringSuffix(po)}, | |
390 | 389 | <#if po.classType =='date'> |
391 | 390 | component: 'DatePicker', |
392 | - <#elseif po.fieldType =='datetime'> | |
391 | + <#elseif po.classType =='datetime'> | |
393 | 392 | component: 'DatePicker', |
394 | 393 | componentProps: { |
395 | - showTime:true | |
394 | + showTime:true, | |
395 | + valueFormat: 'YYYY-MM-DD HH:mm:ss' | |
396 | 396 | }, |
397 | - <#elseif po.fieldType =='time'> | |
397 | + <#elseif po.classType =='time'> | |
398 | 398 | component: 'TimePicker', |
399 | + componentProps: { | |
400 | + valueFormat: 'HH:mm:ss' | |
401 | + }, | |
399 | 402 | <#elseif po.classType =='popup'> |
400 | - component: 'JPopup', | |
401 | - componentProps: ({ formActionType }) => { | |
402 | - const {setFieldsValue} = formActionType; | |
403 | - return{ | |
404 | - setFieldsValue:setFieldsValue, | |
405 | - code:"${po.dictTable}", | |
406 | - fieldConfig:${po.dictField}, | |
407 | - multi:${po.extendParams.popupMulti?c}, | |
408 | - } | |
409 | - }, | |
403 | + <#include "/common/form/vue3popup.ftl"> | |
410 | 404 | <#elseif po.classType =='sel_depart'> |
411 | 405 | component: 'JSelectDept', |
412 | 406 | <#elseif po.classType =='switch'> |
... | ... | @@ -428,14 +422,14 @@ export const ${sub.entityName?uncap_first}FormSchema: FormSchema[] = [ |
428 | 422 | labelKey:'realname', |
429 | 423 | }, |
430 | 424 | <#elseif po.classType =='textarea'> |
431 | - component: 'InputTextArea',//TODO 注意string转换问题 | |
425 | + component: 'InputTextArea', | |
432 | 426 | <#elseif po.classType=='list' || po.classType=='radio'> |
433 | 427 | component: 'JDictSelectTag', |
434 | 428 | componentProps:{ |
435 | 429 | dictCode:"${form_field_dictCode}" |
436 | 430 | }, |
437 | 431 | <#elseif po.classType=='list_multi' || po.classType=='checkbox'> |
438 | - component: 'JMultiSelectTag',//TODO 暂无该组件 | |
432 | + component: 'JSelectMultiple', | |
439 | 433 | componentProps:{ |
440 | 434 | dictCode:"${form_field_dictCode}" |
441 | 435 | } |
... | ... | @@ -470,7 +464,7 @@ export const ${sub.entityName?uncap_first}FormSchema: FormSchema[] = [ |
470 | 464 | </#if> |
471 | 465 | }, |
472 | 466 | <#elseif po.classType=='umeditor'> |
473 | - component: 'JCodeEditor', //TODO String后缀暂未添加 | |
467 | + component: 'JEditor', | |
474 | 468 | <#elseif po.classType == 'sel_tree'> |
475 | 469 | component: 'JTreeSelect', |
476 | 470 | componentProps:{ |
... | ... | @@ -502,16 +496,16 @@ export const ${sub.entityName?uncap_first}FormSchema: FormSchema[] = [ |
502 | 496 | </#if> |
503 | 497 | <#-- 唯一校验 --> |
504 | 498 | <#if fieldValidType == 'only'> |
505 | - {...rules.duplicateCheckRule(<#if sub?default("")?trim?length gt 1>'${sub.tableName}'<#else>'${tableName}'</#if>, '${po.fieldDbName}',model,schema,true)[0]}, | |
499 | + {...rules.duplicateCheckRule(<#if sub?default("")?trim?length gt 1>'${sub.tableName}'<#else>'${tableName}'</#if>, '${po.fieldDbName}',model,schema)[0]}, | |
506 | 500 | <#-- 6到16位数字 --> |
507 | 501 | <#elseif fieldValidType == 'n6-16'> |
508 | 502 | { pattern: /^\d{6,16}$/, message: '请输入6到16位数字!'}, |
509 | 503 | <#-- 6到16位任意字符 --> |
510 | 504 | <#elseif fieldValidType == '*6-16'> |
511 | 505 | { pattern: /^.{6,16}$/, message: '请输入6到16位任意字符!'}, |
512 | - <#-- 6到18位字符串 --> | |
506 | + <#-- 6到18位字母 --> | |
513 | 507 | <#elseif fieldValidType == 's6-18'> |
514 | - { pattern: /^.{6,18}$/, message: '请输入6到18位任意字符!'}, | |
508 | + { pattern: /^[a-z|A-Z]{6,18}$/, message: '请输入6到18位字母!'}, | |
515 | 509 | <#-- 网址 --> |
516 | 510 | <#elseif fieldValidType == 'url'> |
517 | 511 | { pattern: /^((ht|f)tps?):\/\/[\w\-]+(\.[\w\-]+)+([\w\-.,@?^=%&:\/~+#]*[\w\-@?^=%&\/~+#])?$/, message: '请输入正确的网址!'}, |
... | ... | @@ -553,6 +547,14 @@ export const ${sub.entityName?uncap_first}FormSchema: FormSchema[] = [ |
553 | 547 | }, |
554 | 548 | </#if> |
555 | 549 | </#list> |
550 | +<#if sub_id_exists == false> | |
551 | + { | |
552 | + label: '', | |
553 | + field: 'id', | |
554 | + component: 'Input', | |
555 | + show: false | |
556 | + }, | |
557 | +</#if> | |
556 | 558 | ]; |
557 | 559 | </#if> |
558 | 560 | </#list> |
... | ... | @@ -579,12 +581,20 @@ export const ${sub.entityName?uncap_first}Columns: JVxeColumn[] = [ |
579 | 581 | <#if col.readonly=='Y'> |
580 | 582 | disabled:true, |
581 | 583 | </#if> |
584 | +<#elseif col.classType =='time'> | |
585 | + type: JVxeTypes.time, | |
586 | + <#if col.readonly=='Y'> | |
587 | + disabled:true, | |
588 | + </#if> | |
582 | 589 | <#elseif col.classType =='textarea'> |
583 | 590 | type: JVxeTypes.textarea, |
584 | 591 | <#if col.readonly=='Y'> |
585 | 592 | disabled:true, |
586 | 593 | </#if> |
587 | -<#elseif "int,decimal,double,"?contains(col.classType)> | |
594 | +<#-- update-begin-author:taoyan date:20220523 for: VUEN-1084 【vue3】online表单测试发现的新问题 20、一对多列字段类型生成的不对,数字或者金额类型 --> | |
595 | +<#-- elseif "int,decimal,double,"?contains(col.classType) --> | |
596 | +<#elseif col.fieldDbType=='int' || col.fieldDbType=='double' || col.fieldDbType=='BigDecimal'> | |
597 | +<#-- update-end-author:taoyan date:20220523 for: VUEN-1084 【vue3】online表单测试发现的新问题 20、一对多列字段类型生成的不对,数字或者金额类型 --> | |
588 | 598 | type: JVxeTypes.inputNumber, |
589 | 599 | <#if col.readonly=='Y'> |
590 | 600 | disabled:true, |
... | ... | @@ -621,6 +631,16 @@ export const ${sub.entityName?uncap_first}Columns: JVxeColumn[] = [ |
621 | 631 | <#if col.readonly=='Y'> |
622 | 632 | disabled:true, |
623 | 633 | </#if> |
634 | +<#elseif col.classType =='sel_depart'> | |
635 | + type: JVxeTypes.departSelect, | |
636 | + <#if col.readonly=='Y'> | |
637 | + disabled:true, | |
638 | + </#if> | |
639 | +<#elseif col.classType =='sel_user'> | |
640 | + type: JVxeTypes.userSelect, | |
641 | + <#if col.readonly=='Y'> | |
642 | + disabled:true, | |
643 | + </#if> | |
624 | 644 | <#elseif col.classType =='image'> |
625 | 645 | type: JVxeTypes.image, |
626 | 646 | token:true, |
... | ... | @@ -644,9 +664,9 @@ export const ${sub.entityName?uncap_first}Columns: JVxeColumn[] = [ |
644 | 664 | <#elseif col.classType =='switch'> |
645 | 665 | type: JVxeTypes.checkbox, |
646 | 666 | <#if col.dictField == 'is_open'> |
647 | - customValue: ['Y', 'N'], | |
667 | + customValue: ['Y', 'N'], | |
648 | 668 | <#else> |
649 | - customValue: ${col.dictField}, | |
669 | + customValue: ${col.dictField}, | |
650 | 670 | </#if> |
651 | 671 | <#if col.readonly=='Y'> |
652 | 672 | disabled:true, |
... | ... | @@ -657,18 +677,11 @@ export const ${sub.entityName?uncap_first}Columns: JVxeColumn[] = [ |
657 | 677 | <#else> |
658 | 678 | <#assign popupBackFields = "${col.dictText}"> |
659 | 679 | </#if> |
660 | - type: JVxeTypes.popup, | |
661 | - popupCode:"${col.dictTable}", | |
662 | - field:"${col.dictField}", | |
663 | - orgFields:"${col.dictField}", | |
664 | - destFields:"${Format.underlineToHump(col.dictText)}", | |
665 | - <#if col.readonly=='Y'> | |
666 | - disabled:true, | |
667 | - </#if> | |
680 | + <#include "/common/form/vue3Jvxepopup.ftl"> | |
668 | 681 | <#else> |
669 | - type: JVxeTypes.input, | |
682 | + type: JVxeTypes.input, | |
670 | 683 | <#if col.readonly=='Y'> |
671 | - disabled:true, | |
684 | + disabled:true, | |
672 | 685 | </#if> |
673 | 686 | </#if> |
674 | 687 | <#if col.classType =='list_multi' || col.classType =='checkbox'> |
... | ... | @@ -691,18 +704,7 @@ export const ${sub.entityName?uncap_first}Columns: JVxeColumn[] = [ |
691 | 704 | defaultValue:'', |
692 | 705 | </#if> |
693 | 706 | <#-- 子表的校验 --> |
694 | -<#assign subFieldValidType = col.fieldValidType!''> | |
695 | -<#-- 非空校验 --> | |
696 | -<#if col.nullable == 'N' || subFieldValidType == '*'> | |
697 | - validateRules: [{ required: true, message: '${'$'}{title}不能为空' }], | |
698 | -<#-- 其他情况下,只要有值就被认为是正则校验 --> | |
699 | -<#elseif subFieldValidType?length gt 0> | |
700 | -<#assign subMessage = '格式不正确'> | |
701 | -<#if subFieldValidType == 'only' > | |
702 | - <#assign subMessage = '不能重复'> | |
703 | -</#if> | |
704 | - validateRules: [{ pattern: "${subFieldValidType}", message: "${'$'}{title}${subMessage}" }], | |
705 | -</#if> | |
707 | + <#include "/common/validatorRulesTemplate/sub-vue3.ftl"> | |
706 | 708 | }, |
707 | 709 | </#if> |
708 | 710 | </#if> |
... | ... |
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}_menu_insert.sql
0 → 100644
1 | +<#include "/common/sql/menu_insert.ftl"> | |
... | ... |
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3/components/${entityName}Modal.vuei
1 | +<#include "/common/utils.ftl"> | |
1 | 2 | <template> |
2 | - <BasicModal v-bind="$attrs" @register="registerModal" :title="title" @ok="handleSubmit"> | |
3 | + <BasicModal v-bind="$attrs" @register="registerModal" destroyOnClose :title="title" :width="${getModalWidth(tableVo.fieldRowNum?default(1))}" @ok="handleSubmit"> | |
3 | 4 | <BasicForm @register="registerForm" ref="formRef"/> |
4 | 5 | <!-- 子表单区域 --> |
5 | 6 | <a-tabs v-model:activeKey="activeKey" @change="handleChangeTabs"> |
... | ... | @@ -7,7 +8,7 @@ |
7 | 8 | <#assign refKey = sub.entityName?uncap_first/> |
8 | 9 | <#if sub.foreignRelationType =='1'> |
9 | 10 | <a-tab-pane tab="${sub.ftlDescription}" key="${refKey}" :forceRender="true"> |
10 | - <${sub.entityName}Form ref="${sub.entityName?uncap_first}Form"></${sub.entityName}Form> | |
11 | + <${sub.entityName}Form ref="${sub.entityName?uncap_first}Form" :disabled="formDisabled"></${sub.entityName}Form> | |
11 | 12 | </a-tab-pane> |
12 | 13 | |
13 | 14 | <#else> |
... | ... | @@ -19,9 +20,10 @@ |
19 | 20 | :loading="${sub.entityName?uncap_first}Table.loading" |
20 | 21 | :columns="${sub.entityName?uncap_first}Table.columns" |
21 | 22 | :dataSource="${sub.entityName?uncap_first}Table.dataSource" |
22 | - :maxHeight="300" | |
23 | + :height="340" | |
23 | 24 | :rowNumber="true" |
24 | 25 | :rowSelection="true" |
26 | + :disabled="formDisabled" | |
25 | 27 | :toolbar="true" |
26 | 28 | /> |
27 | 29 | </a-tab-pane> |
... | ... | @@ -48,6 +50,7 @@ |
48 | 50 | // Emits声明 |
49 | 51 | const emit = defineEmits(['register','success']); |
50 | 52 | const isUpdate = ref(true); |
53 | + const formDisabled = ref(false); | |
51 | 54 | const refKeys = ref([<#list subTables as sub>'${sub.entityName?uncap_first}', </#list>]); |
52 | 55 | <#assign hasOne2Many = false> |
53 | 56 | <#assign hasOne2One = false> |
... | ... | @@ -77,6 +80,7 @@ |
77 | 80 | labelWidth: 150, |
78 | 81 | schemas: formSchema, |
79 | 82 | showActionButtonGroup: false, |
83 | + baseColProps: {span: ${getFormSpan(tableVo.fieldRowNum?default(1))}} | |
80 | 84 | }); |
81 | 85 | //表单赋值 |
82 | 86 | const [registerModal, {setModalProps, closeModal}] = useModalInner(async (data) => { |
... | ... | @@ -84,6 +88,7 @@ |
84 | 88 | await reset(); |
85 | 89 | setModalProps({confirmLoading: false,showCancelBtn:data?.showFooter,showOkBtn:data?.showFooter}); |
86 | 90 | isUpdate.value = !!data?.isUpdate; |
91 | + formDisabled.value = !data?.showFooter; | |
87 | 92 | if (unref(isUpdate)) { |
88 | 93 | //表单赋值 |
89 | 94 | await setFieldsValue({ |
... | ... | @@ -176,5 +181,12 @@ |
176 | 181 | </script> |
177 | 182 | |
178 | 183 | <style lang="less" scoped> |
184 | + /** 时间和数字输入框样式 */ | |
185 | + :deep(.ant-input-number){ | |
186 | + width: 100% | |
187 | + } | |
179 | 188 | |
189 | + :deep(.ant-calendar-picker){ | |
190 | + width: 100% | |
191 | + } | |
180 | 192 | </style> |
181 | 193 | \ No newline at end of file |
... | ... |
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3/components/[1-n]Form.vuei
1 | +<#include "/common/utils.ftl"> | |
1 | 2 | <#list subTables as sub> |
2 | 3 | <#if sub.foreignRelationType=='1'> |
3 | 4 | #segment#${sub.entityName}Form.vue |
... | ... | @@ -15,11 +16,18 @@ |
15 | 16 | name:"${sub.entityName}Form", |
16 | 17 | components: {BasicForm}, |
17 | 18 | emits:['register'], |
18 | - setup(_,{emit}) { | |
19 | - const [registerForm, {resetFields, setFieldsValue,getFieldsValue,validate}] = useForm({ | |
19 | + props:{ | |
20 | + disabled: { | |
21 | + type: Boolean, | |
22 | + default: false | |
23 | + } | |
24 | + }, | |
25 | + setup(props,{emit}) { | |
26 | + const [registerForm, {setProps, resetFields, setFieldsValue,getFieldsValue,validate}] = useForm({ | |
20 | 27 | labelWidth: 150, |
21 | 28 | schemas: ${sub.entityName?uncap_first}FormSchema, |
22 | 29 | showActionButtonGroup: false, |
30 | + baseColProps: {span: ${getFormSpan(tableVo.fieldRowNum?default(1))}} | |
23 | 31 | }); |
24 | 32 | /** |
25 | 33 | *初始化加载数据 |
... | ... | @@ -30,12 +38,19 @@ |
30 | 38 | res.success && setFieldsValue({...res.result[0]}); |
31 | 39 | }) |
32 | 40 | } |
41 | + setProps({disabled: props.disabled}) | |
33 | 42 | } |
34 | 43 | /** |
35 | 44 | *获取表单数据 |
36 | 45 | */ |
37 | 46 | function getFormData(){ |
38 | - return [getFieldsValue()]; | |
47 | + let formData = getFieldsValue(); | |
48 | + Object.keys(formData).map(k=>{ | |
49 | + if(formData[k] instanceof Array){ | |
50 | + formData[k] = formData[k].join(',') | |
51 | + } | |
52 | + }); | |
53 | + return [formData]; | |
39 | 54 | } |
40 | 55 | /** |
41 | 56 | *表单校验 |
... | ... |
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}List.vuei
0 → 100644
1 | +<template> | |
2 | + <div> | |
3 | + <#assign query_field_no=0> | |
4 | + <#assign need_category = false> | |
5 | + <#assign need_pca = false> | |
6 | + <#assign need_search = false> | |
7 | + <#assign need_dept_user = false> | |
8 | + <#assign need_switch = false> | |
9 | + <#assign need_dept = false> | |
10 | + <#assign need_multi = false> | |
11 | + <#assign need_popup = false> | |
12 | + <#assign need_select_tag = false> | |
13 | + <#assign need_select_tree = false> | |
14 | + <#assign need_time = false> | |
15 | + <#assign bpm_flag=false> | |
16 | + <#assign need_markdown = false> | |
17 | + <#assign need_upload = false> | |
18 | + <#assign need_image_upload = false> | |
19 | + <#assign need_editor = false> | |
20 | + <#assign need_checkbox = false> | |
21 | + <!--查询区域--> | |
22 | + <div class="jeecg-basic-table-form-container"> | |
23 | + <a-form @keyup.enter.native="reload" :model="queryParam" :label-col="labelCol" :wrapper-col="wrapperCol"> | |
24 | + <a-row :gutter="24"> | |
25 | + <#-- 开始循环 --> | |
26 | + <#list columns as po> | |
27 | + <#if po.fieldDbName=='bpm_status'> | |
28 | + <#assign bpm_flag=true> | |
29 | + </#if> | |
30 | + <#if po.classType=='cat_tree' && po.dictText?default("")?trim?length == 0> | |
31 | + <#assign need_category=true> | |
32 | + </#if> | |
33 | + <#if po.classType=='pca'> | |
34 | + <#assign need_pca=true> | |
35 | + </#if> | |
36 | + <#if po.classType=='sel_search'> | |
37 | + <#assign need_search = true> | |
38 | + </#if> | |
39 | + <#if po.classType=='sel_user'> | |
40 | + <#assign need_dept_user = true> | |
41 | + </#if> | |
42 | + <#if po.classType=='sel_depart'> | |
43 | + <#assign need_dept = true> | |
44 | + </#if> | |
45 | + <#if po.classType=='switch'> | |
46 | + <#assign need_switch = true> | |
47 | + </#if> | |
48 | + <#if po.classType=='list_multi'> | |
49 | + <#assign need_multi = true> | |
50 | + </#if> | |
51 | + <#if po.classType=='popup'> | |
52 | + <#assign need_popup = true> | |
53 | + </#if> | |
54 | + <#if po.classType=='sel_tree'> | |
55 | + <#assign need_select_tree = true> | |
56 | + </#if> | |
57 | + <#if po.classType=='time'> | |
58 | + <#assign need_time = true> | |
59 | + </#if> | |
60 | + <#include "/common/form/native/vue3NativeSearch.ftl"> | |
61 | + </#list> | |
62 | + <#if query_field_no gt 2> | |
63 | + </template> | |
64 | +</#if> | |
65 | +<#if query_flag> | |
66 | + <a-col :xl="6" :lg="7" :md="8" :sm="24"> | |
67 | + <span style="float: left; overflow: hidden" class="table-page-search-submitButtons"> | |
68 | + <a-col :lg="6"> | |
69 | + <a-button type="primary" preIcon="ant-design:search-outlined" @click="reload">查询</a-button> | |
70 | + <a-button preIcon="ant-design:reload-outlined" @click="searchReset" style="margin-left: 8px">重置</a-button> | |
71 | + <a @click="toggleSearchStatus = !toggleSearchStatus" style="margin-left: 8px"> | |
72 | + {{ toggleSearchStatus ? '收起' : '展开' }} | |
73 | + <Icon :icon="toggleSearchStatus ? 'ant-design:up-outlined' : 'ant-design:down-outlined'" /> | |
74 | + </a> | |
75 | + </a-col> | |
76 | + </span> | |
77 | + </a-col> | |
78 | +</#if> | |
79 | + </a-row> | |
80 | + </a-form> | |
81 | + </div> | |
82 | +<#-- 结束循环 --> | |
83 | + <!--引用表格--> | |
84 | + <BasicTable @register="registerTable" :rowSelection="rowSelection"> | |
85 | + <!--插槽:table标题--> | |
86 | + <template #tableTitle> | |
87 | + <a-button type="primary" @click="handleAdd" preIcon="ant-design:plus-outlined"> 新增</a-button> | |
88 | + <a-button type="primary" preIcon="ant-design:export-outlined" @click="onExportXls"> 导出</a-button> | |
89 | + <j-upload-button type="primary" preIcon="ant-design:import-outlined" @click="onImportXls">导入</j-upload-button> | |
90 | + <a-dropdown v-if="selectedRowKeys.length > 0"> | |
91 | + <template #overlay> | |
92 | + <a-menu> | |
93 | + <a-menu-item key="1" @click="batchHandleDelete"> | |
94 | + <Icon icon="ant-design:delete-outlined"></Icon> | |
95 | + 删除 | |
96 | + </a-menu-item> | |
97 | + </a-menu> | |
98 | + </template> | |
99 | + <a-button>批量操作 | |
100 | + <Icon icon="mdi:chevron-down"></Icon> | |
101 | + </a-button> | |
102 | + </a-dropdown> | |
103 | + </template> | |
104 | + <!--操作栏--> | |
105 | + <template #action="{ record }"> | |
106 | + <TableAction :actions="getTableAction(record)" :dropDownActions="getDropDownAction(record)"/> | |
107 | + </template> | |
108 | + <!--字段回显插槽--> | |
109 | + <template #htmlSlot="{text}"> | |
110 | + <div v-html="text"></div> | |
111 | + </template> | |
112 | + <!--省市区字段回显插槽--> | |
113 | + <template #pcaSlot="{text}"> | |
114 | + {{ getAreaTextByCode(text) }} | |
115 | + </template> | |
116 | + <template #fileSlot="{text}"> | |
117 | + <span v-if="!text" style="font-size: 12px;font-style: italic;">无文件</span> | |
118 | + <a-button v-else :ghost="true" type="primary" preIcon="ant-design:download-outlined" size="small" @click="downloadFile(text)">下载</a-button> | |
119 | + </template> | |
120 | + </BasicTable> | |
121 | + <!-- 表单区域 --> | |
122 | + <${entityName}Modal @register="registerModal" @success="handleSuccess"></${entityName}Modal> | |
123 | + </div> | |
124 | +</template> | |
125 | + | |
126 | +<script lang="ts" name="${entityPackage}-${entityName?uncap_first}" setup> | |
127 | + import {ref, reactive, computed, unref} from 'vue'; | |
128 | + import {BasicTable, useTable, TableAction} from '/@/components/Table'; | |
129 | + import { useListPage } from '/@/hooks/system/useListPage' | |
130 | + import {useModal} from '/@/components/Modal'; | |
131 | + import ${entityName}Modal from './components/${entityName}Modal.vue' | |
132 | + import {columns, searchFormSchema} from './${entityName}.data'; | |
133 | + import {list, deleteOne, batchDelete, getImportUrl,getExportUrl} from './${entityName}.api'; | |
134 | + import {downloadFile} from '/@/utils/common/renderUtils'; | |
135 | + <#include "/common/form/native/vue3NativeImport.ftl"> | |
136 | +<#if need_pca> | |
137 | + import { getAreaTextByCode } from '/@/components/Form/src/utils/Area'; | |
138 | +</#if> | |
139 | + <#if need_category> | |
140 | + import { loadCategoryData } from '/@/api/common/api' | |
141 | + import { getAuthCache, setAuthCache } from '/@/utils/auth'; | |
142 | + import { DB_DICT_DATA_KEY } from '/@/enums/cacheEnum'; | |
143 | + </#if> | |
144 | + const checkedKeys = ref<Array<string | number>>([]); | |
145 | + //注册model | |
146 | + const [registerModal, {openModal}] = useModal(); | |
147 | + //注册table数据 | |
148 | + const { prefixCls,tableContext,onExportXls,onImportXls } = useListPage({ | |
149 | + tableProps:{ | |
150 | + title: '${tableVo.ftlDescription}', | |
151 | + api: list, | |
152 | + columns, | |
153 | + canResize:false, | |
154 | + useSearchForm: false, | |
155 | + actionColumn: { | |
156 | + width: 120, | |
157 | + fixed:'right' | |
158 | + }, | |
159 | + beforeFetch: (params) => { | |
160 | + return Object.assign(params, queryParam.value); | |
161 | + }, | |
162 | + }, | |
163 | + exportConfig: { | |
164 | + name:"${tableVo.ftlDescription}", | |
165 | + url: getExportUrl, | |
166 | + }, | |
167 | + importConfig: { | |
168 | + url: getImportUrl, | |
169 | + success: handleSuccess | |
170 | + }, | |
171 | + }) | |
172 | + | |
173 | + const [registerTable, {reload},{ rowSelection, selectedRowKeys }] = tableContext | |
174 | + | |
175 | + /** | |
176 | + * 新增事件 | |
177 | + */ | |
178 | + function handleAdd() { | |
179 | + openModal(true, { | |
180 | + isUpdate: false, | |
181 | + showFooter: true, | |
182 | + }); | |
183 | + } | |
184 | + /** | |
185 | + * 编辑事件 | |
186 | + */ | |
187 | + function handleEdit(record: Recordable) { | |
188 | + openModal(true, { | |
189 | + record, | |
190 | + isUpdate: true, | |
191 | + showFooter: true, | |
192 | + }); | |
193 | + } | |
194 | + /** | |
195 | + * 详情 | |
196 | + */ | |
197 | + function handleDetail(record: Recordable) { | |
198 | + openModal(true, { | |
199 | + record, | |
200 | + isUpdate: true, | |
201 | + showFooter: false, | |
202 | + }); | |
203 | + } | |
204 | + /** | |
205 | + * 删除事件 | |
206 | + */ | |
207 | + async function handleDelete(record) { | |
208 | + await deleteOne({id: record.id}, handleSuccess); | |
209 | + } | |
210 | + /** | |
211 | + * 批量删除事件 | |
212 | + */ | |
213 | + async function batchHandleDelete() { | |
214 | + await batchDelete({ids: selectedRowKeys.value},handleSuccess); | |
215 | + } | |
216 | + /** | |
217 | + * 成功回调 | |
218 | + */ | |
219 | + function handleSuccess() { | |
220 | + (selectedRowKeys.value = []) && reload(); | |
221 | + } | |
222 | + /** | |
223 | + * 操作栏 | |
224 | + */ | |
225 | + function getTableAction(record){ | |
226 | + return [ | |
227 | + { | |
228 | + label: '编辑', | |
229 | + onClick: handleEdit.bind(null, record), | |
230 | + } | |
231 | + ] | |
232 | + } | |
233 | + /** | |
234 | + * 下拉操作栏 | |
235 | + */ | |
236 | + function getDropDownAction(record){ | |
237 | + return [ | |
238 | + { | |
239 | + label: '详情', | |
240 | + onClick: handleDetail.bind(null, record), | |
241 | + }, { | |
242 | + label: '删除', | |
243 | + popConfirm: { | |
244 | + title: '是否确认删除', | |
245 | + confirm: handleDelete.bind(null, record), | |
246 | + } | |
247 | + } | |
248 | + ] | |
249 | + } | |
250 | + <#if need_category> | |
251 | + /** | |
252 | + * form点击事件 | |
253 | + * @param value | |
254 | + */ | |
255 | + function handleFormChange(key, value) { | |
256 | + queryParam.value[key] = value; | |
257 | + } | |
258 | + /** | |
259 | + * 初始化字典配置 | |
260 | + */ | |
261 | + function initDictConfig(){ | |
262 | + <#list columns as po> | |
263 | + <#if (po.isQuery=='Y' || po.isShowList=='Y') && po.classType!='popup'> | |
264 | + <#if po.classType=='cat_tree' && need_category==true> | |
265 | + loadCategoryData({code:'${po.dictField?default("")}'}).then((res) => { | |
266 | + if (res) { | |
267 | + let allDictDate = getAuthCache(DB_DICT_DATA_KEY); | |
268 | + if(!allDictDate['${po.dictField?default("")}']){ | |
269 | + Object.assign(allDictDate,{'${po.dictField?default("")}':res}) | |
270 | + } | |
271 | + setAuthCache(DB_DICT_DATA_KEY,allDictDate) | |
272 | + } | |
273 | + }) | |
274 | + </#if> | |
275 | + </#if> | |
276 | + </#list> | |
277 | + } | |
278 | + initDictConfig(); | |
279 | + </#if> | |
280 | + | |
281 | + /* ----------------------以下为原生查询需要添加的-------------------------- */ | |
282 | + const queryParam = ref<any>({}); | |
283 | + const toggleSearchStatus = ref<boolean>(false); | |
284 | + const labelCol = reactive({ | |
285 | + xs: { span: 24 }, | |
286 | + sm: { span: 7 }, | |
287 | + }); | |
288 | + const wrapperCol = reactive({ | |
289 | + xs: { span: 24 }, | |
290 | + sm: { span: 16 }, | |
291 | + }); | |
292 | + /** | |
293 | + * 重置 | |
294 | + */ | |
295 | + function searchReset() { | |
296 | + queryParam.value = {}; | |
297 | + selectedRowKeys.value = []; | |
298 | + //刷新数据 | |
299 | + reload(); | |
300 | + } | |
301 | + <#if need_popup> | |
302 | + /** | |
303 | + * popup组件值改变事件 | |
304 | + */ | |
305 | + function setFieldsValue(map) { | |
306 | + Object.keys(map).map((key) => { | |
307 | + queryParam.value[key] = map[key]; | |
308 | + }); | |
309 | + } | |
310 | + </#if> | |
311 | + | |
312 | + <#if need_pca> | |
313 | + /** | |
314 | + * 省市区点击事件 | |
315 | + * @param key | |
316 | + * @param value | |
317 | + */ | |
318 | + function handleAreaChange(key, value) { | |
319 | + queryParam.value[key] = value.join(','); | |
320 | + } | |
321 | + </#if> | |
322 | +</script> | |
323 | +<style lang="less" scoped> | |
324 | + .jeecg-basic-table-form-container { | |
325 | + .table-page-search-submitButtons { | |
326 | + display: block; | |
327 | + margin-bottom: 24px; | |
328 | + white-space: nowrap; | |
329 | + } | |
330 | + .query-group-cust{ | |
331 | + width: calc(50% - 15px); | |
332 | + min-width: 100px !important; | |
333 | + } | |
334 | + .query-group-split-cust{ | |
335 | + width: 30px; | |
336 | + display: inline-block; | |
337 | + text-align: center | |
338 | + } | |
339 | + } | |
340 | +</style> | |
0 | 341 | \ No newline at end of file |
... | ... |
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}__api.tsi
0 → 100644
1 | +import {defHttp} from '/@/utils/http/axios'; | |
2 | +import {Modal} from 'ant-design-vue'; | |
3 | + | |
4 | +enum Api { | |
5 | + list = '/${entityPackage}/${entityName?uncap_first}/list', | |
6 | + save='/${entityPackage}/${entityName?uncap_first}/add', | |
7 | + edit='/${entityPackage}/${entityName?uncap_first}/edit', | |
8 | + deleteOne = '/${entityPackage}/${entityName?uncap_first}/delete', | |
9 | + deleteBatch = '/${entityPackage}/${entityName?uncap_first}/deleteBatch', | |
10 | + importExcel = '/${entityPackage}/${entityName?uncap_first}/importExcel', | |
11 | + exportXls = '/${entityPackage}/${entityName?uncap_first}/exportXls', | |
12 | + queryDataById = '/${entityPackage}/${entityName?uncap_first}/queryById', | |
13 | +<#list subTables as sub><#rt/> | |
14 | + ${sub.entityName?uncap_first}List = '/${entityPackage}/${entityName?uncap_first}/query${sub.entityName}ByMainId', | |
15 | +</#list> | |
16 | +} | |
17 | +/** | |
18 | + * 导出api | |
19 | + * @param params | |
20 | + */ | |
21 | +export const getExportUrl = Api.exportXls; | |
22 | + | |
23 | +/** | |
24 | + * 导入api | |
25 | + */ | |
26 | +export const getImportUrl = Api.importExcel; | |
27 | + | |
28 | +<#list subTables as sub><#rt/> | |
29 | +/** | |
30 | + * 查询子表数据 | |
31 | + * @param params | |
32 | + */ | |
33 | +export const query${sub.entityName}ListByMainId = (id) => defHttp.get({url: Api.${sub.entityName?uncap_first}List, params:{ id }}); | |
34 | +</#list> | |
35 | + | |
36 | +/** | |
37 | + * 列表接口 | |
38 | + * @param params | |
39 | + */ | |
40 | +export const list = (params) => | |
41 | + defHttp.get({url: Api.list, params}); | |
42 | + | |
43 | +/** | |
44 | + * 删除单个 | |
45 | + */ | |
46 | +export const deleteOne = (params,handleSuccess) => { | |
47 | + return defHttp.delete({url: Api.deleteOne, params}, {joinParamsToUrl: true}).then(() => { | |
48 | + handleSuccess(); | |
49 | + }); | |
50 | +} | |
51 | +/** | |
52 | + * 批量删除 | |
53 | + * @param params | |
54 | + */ | |
55 | +export const batchDelete = (params, handleSuccess) => { | |
56 | + Modal.confirm({ | |
57 | + title: '确认删除', | |
58 | + content: '是否删除选中数据', | |
59 | + okText: '确认', | |
60 | + cancelText: '取消', | |
61 | + onOk: () => { | |
62 | + return defHttp.delete({url: Api.deleteBatch, data: params}, {joinParamsToUrl: true}).then(() => { | |
63 | + handleSuccess(); | |
64 | + }); | |
65 | + } | |
66 | + }); | |
67 | +} | |
68 | +/** | |
69 | + * 保存或者更新 | |
70 | + * @param params | |
71 | + */ | |
72 | +export const saveOrUpdate = (params, isUpdate) => { | |
73 | + let url = isUpdate ? Api.edit : Api.save; | |
74 | + return defHttp.post({url: url, params}); | |
75 | +} | |
76 | + | |
77 | +/** | |
78 | +* 根据id查询数据 | |
79 | +* @param params | |
80 | +*/ | |
81 | +export const queryDataById = (id) => defHttp.get({url: Api.queryDataById, params:{ id }}); | |
82 | + | |
... | ... |
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}__data.tsi
0 → 100644
1 | +<#include "/common/utils.ftl"> | |
2 | +import {BasicColumn} from '/@/components/Table'; | |
3 | +import {FormSchema} from '/@/components/Table'; | |
4 | +import { rules} from '/@/utils/helper/validator'; | |
5 | +import { render } from '/@/utils/common/renderUtils'; | |
6 | +import {JVxeTypes,JVxeColumn} from '/@/components/jeecg/JVxeTable/types' | |
7 | +//列表数据 | |
8 | +export const columns: BasicColumn[] = [ | |
9 | + <#list columns as po> | |
10 | + <#if po.isShowList =='Y' && po.fieldName !='id'> | |
11 | + { | |
12 | + title: '${po.filedComment}', | |
13 | + align:"center", | |
14 | + <#if po.sort=='Y'> | |
15 | + sorter: true, | |
16 | + </#if> | |
17 | + <#if po.classType=='date'> | |
18 | + dataIndex: '${po.fieldName}', | |
19 | + customRender:({text}) =>{ | |
20 | + return !text?"":(text.length>10?text.substr(0,10):text) | |
21 | + }, | |
22 | + <#elseif po.fieldDbType=='Blob'> | |
23 | + dataIndex: '${po.fieldName}String' | |
24 | + <#elseif po.classType=='umeditor'> | |
25 | + dataIndex: '${po.fieldName}', | |
26 | + slots: { customRender: 'htmlSlot' }, | |
27 | + <#elseif po.classType=='pca'> | |
28 | + dataIndex: '${po.fieldName}', | |
29 | + slots: { customRender: 'pcaSlot' }, | |
30 | + <#elseif po.classType=='file'> | |
31 | + dataIndex: '${po.fieldName}', | |
32 | + slots: { customRender: 'fileSlot' }, | |
33 | + <#elseif po.classType=='image'> | |
34 | + dataIndex: '${po.fieldName}', | |
35 | + customRender:render.renderImage, | |
36 | + <#elseif po.classType=='switch'> | |
37 | + dataIndex: '${po.fieldName}', | |
38 | +<#assign switch_extend_arr=['Y','N']> | |
39 | +<#if po.dictField?default("")?contains("[")> | |
40 | +<#assign switch_extend_arr=po.dictField?eval> | |
41 | +</#if> | |
42 | +<#list switch_extend_arr as a> | |
43 | +<#if a_index == 0> | |
44 | +<#assign switch_extend_arr1=a> | |
45 | +<#else> | |
46 | +<#assign switch_extend_arr2=a> | |
47 | +</#if> | |
48 | +</#list> | |
49 | + customRender:({text}) => { | |
50 | + return render.renderSwitch(text, [{text:'是',value:'${switch_extend_arr1}'},{text:'否',value:'${switch_extend_arr2}'}]) | |
51 | + }, | |
52 | + <#elseif po.classType == 'sel_tree' || po.classType=='list' || po.classType=='list_multi' || po.classType=='sel_search' || po.classType=='radio' || po.classType=='checkbox' || po.classType=='sel_depart' || po.classType=='sel_user'> | |
53 | + dataIndex: '${po.fieldName}_dictText' | |
54 | + <#elseif po.classType=='cat_tree'> | |
55 | + dataIndex: '${po.fieldName}', | |
56 | + <#if po.dictText?default("")?trim?length == 0> | |
57 | + customRender:({text}) => { | |
58 | + return render.renderCategoryTree(text,'${po.dictField?default("")}') | |
59 | + }, | |
60 | + <#else> | |
61 | + customRender: ({text, record}) => (text ? record['${po.dictText}'] : '') | |
62 | + </#if> | |
63 | + <#else> | |
64 | + dataIndex: '${po.fieldName}' | |
65 | + </#if> | |
66 | + }, | |
67 | + </#if> | |
68 | + </#list> | |
69 | +]; | |
70 | +//查询数据 | |
71 | +export const searchFormSchema: FormSchema[] = [ | |
72 | +<#-- 开始循环 --> | |
73 | +<#list columns as po> | |
74 | +<#if po.fieldDbName=='bpm_status'> | |
75 | + <#assign bpm_flag=true> | |
76 | +</#if> | |
77 | +<#if po.isQuery=='Y'> | |
78 | +<#assign query_flag=true> | |
79 | + <#assign query_field_dictCode=""> | |
80 | + <#if po.dictTable?default("")?trim?length gt 1> | |
81 | + <#assign query_field_dictCode="${po.dictTable},${po.dictText},${po.dictField}"> | |
82 | + <#elseif po.dictField?default("")?trim?length gt 1> | |
83 | + <#assign query_field_dictCode="${po.dictField}"> | |
84 | + </#if> | |
85 | +<#if po.queryMode=='single'> | |
86 | + { | |
87 | + label: "${po.filedComment}", | |
88 | + field: "${po.fieldName}", | |
89 | +<#if po.classType=='sel_search'> | |
90 | + component: 'JSearchSelect', | |
91 | + componentProps:{ | |
92 | + dict:"${po.dictTable},${po.dictText},${po.dictField}" | |
93 | + }, | |
94 | +<#elseif po.classType=='sel_user'> | |
95 | + component: 'JSelectUserByDept', | |
96 | +<#elseif po.classType=='switch'> | |
97 | + component: 'JSwitch', | |
98 | + componentProps:{ | |
99 | + <#if po.dictField != 'is_open'> | |
100 | + options:"${po.dictField}" | |
101 | + </#if> | |
102 | + }, | |
103 | + <#elseif po.classType=='sel_depart'> | |
104 | + component: 'JSelectDept', | |
105 | + <#elseif po.classType=='list_multi'> | |
106 | + component: 'JSelectMultiple', | |
107 | + componentProps:{ | |
108 | + <#if po.dictTable?default("")?trim?length gt 1> | |
109 | + dictCode:"${po.dictTable},${po.dictText},${po.dictField}", | |
110 | + <#elseif po.dictField?default("")?trim?length gt 1> | |
111 | + dictCode:"${po.dictField}", | |
112 | + </#if> | |
113 | + triggerChange: true | |
114 | + }, | |
115 | + <#elseif po.classType=='cat_tree'> | |
116 | + component: 'JCategorySelect', | |
117 | + componentProps:{ | |
118 | + pcode:"${po.dictField?default("")}",//back和事件未添加,暂时有问题 | |
119 | + }, | |
120 | +<#elseif po.classType=='date'> | |
121 | + component: 'DatePicker', | |
122 | +<#elseif po.classType=='datetime'> | |
123 | + component: 'DatePicker', | |
124 | + componentProps: { | |
125 | + showTime:true | |
126 | + }, | |
127 | +<#elseif po.classType=='pca'> | |
128 | + component: 'JAreaLinkage', | |
129 | +<#elseif po.classType=='popup'> | |
130 | + <#include "/common/form/vue3popup.ftl"> | |
131 | +<#elseif po.classType=='list' || po.classType=='radio' || po.classType=='checkbox'> | |
132 | +<#-- ---------------------------下拉或是单选 判断数据字典是表字典还是普通字典------------------------------- --> | |
133 | + component: 'JDictSelectTag', | |
134 | + componentProps:{ | |
135 | + <#if po.dictTable?default("")?trim?length gt 1> | |
136 | + dictCode:"${po.dictTable},${po.dictText},${po.dictField}" | |
137 | + <#elseif po.dictField?default("")?trim?length gt 1> | |
138 | + dictCode:"${po.dictField}" | |
139 | + </#if> | |
140 | + }, | |
141 | +<#else> | |
142 | + component: 'Input', | |
143 | +</#if> | |
144 | + colProps: {span: 6}, | |
145 | + }, | |
146 | +<#else> | |
147 | + { | |
148 | + label: "${po.filedComment}", | |
149 | + field: "${po.fieldName}", | |
150 | +<#if po.classType=='date'> | |
151 | + component: 'RangePicker', | |
152 | +<#elseif po.classType=='datetime'> | |
153 | + component: 'RangePicker', | |
154 | + componentProps: { | |
155 | + showTime:true | |
156 | + }, | |
157 | +<#elseif po.fieldDbType=='int' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'> | |
158 | + component: 'JRangeNumber', | |
159 | +<#else> | |
160 | + component: 'Input', //TODO 范围查询 | |
161 | +</#if> | |
162 | + colProps: {span: 6}, | |
163 | + }, | |
164 | +</#if> | |
165 | +</#if> | |
166 | +</#list> | |
167 | +<#-- 结束循环 --> | |
168 | +]; | |
169 | +//表单数据 | |
170 | +export const formSchema: FormSchema[] = [ | |
171 | +<#assign form_cat_tree = false> | |
172 | +<#assign form_cat_back = ""> | |
173 | +<#assign bpm_flag=false> | |
174 | +<#assign id_exists = false> | |
175 | +<#list columns as po><#rt/> | |
176 | +<#if po.fieldDbName=='bpm_status'> | |
177 | + <#assign bpm_flag=true> | |
178 | +</#if> | |
179 | +<#if po.fieldDbName == 'id'> | |
180 | + <#assign id_exists = true> | |
181 | +</#if> | |
182 | +<#if po.isShow =='Y'> | |
183 | +<#assign form_field_dictCode=""> | |
184 | + <#if po.dictTable?default("")?trim?length gt 1 && po.dictText?default("")?trim?length gt 1 && po.dictField?default("")?trim?length gt 1> | |
185 | + <#assign form_field_dictCode="${po.dictTable},${po.dictText},${po.dictField}"> | |
186 | + <#elseif po.dictField?default("")?trim?length gt 1> | |
187 | + <#assign form_field_dictCode="${po.dictField}"> | |
188 | + </#if> | |
189 | + { | |
190 | + label: '${po.filedComment}', | |
191 | + field: ${autoStringSuffix(po)}, | |
192 | + <#if po.classType =='date'> | |
193 | + component: 'DatePicker', | |
194 | + <#elseif po.classType =='datetime'> | |
195 | + component: 'DatePicker', | |
196 | + componentProps: { | |
197 | + showTime:true, | |
198 | + valueFormat: 'YYYY-MM-DD HH:mm:ss' | |
199 | + }, | |
200 | + <#elseif po.classType =='time'> | |
201 | + component: 'TimePicker', | |
202 | + componentProps: { | |
203 | + valueFormat: 'HH:mm:ss' | |
204 | + }, | |
205 | + <#elseif po.classType =='popup'> | |
206 | + <#include "/common/form/vue3popup.ftl"> | |
207 | + <#elseif po.classType =='sel_depart'> | |
208 | + component: 'JSelectDept', | |
209 | + <#elseif po.classType =='switch'> | |
210 | + component: 'JSwitch', | |
211 | + componentProps:{ | |
212 | + <#if po.dictField != 'is_open'> | |
213 | + options:${po.dictField} | |
214 | + </#if> | |
215 | + }, | |
216 | + <#elseif po.classType =='pca'> | |
217 | + component: 'JAreaLinkage', | |
218 | + <#elseif po.classType =='markdown'> | |
219 | + component: 'JMarkdownEditor',//注意string转换问题 | |
220 | + <#elseif po.classType =='password'> | |
221 | + component: 'InputPassword', | |
222 | + <#elseif po.classType =='sel_user'> | |
223 | + component: 'JSelectUserByDept', | |
224 | + componentProps:{ | |
225 | + labelKey:'realname', | |
226 | + }, | |
227 | + <#elseif po.classType =='textarea'> | |
228 | + component: 'InputTextArea', | |
229 | + <#elseif po.classType=='list' || po.classType=='radio'> | |
230 | + component: 'JDictSelectTag', | |
231 | + componentProps:{ | |
232 | + dictCode:"${form_field_dictCode}" | |
233 | + }, | |
234 | + <#elseif po.classType=='list_multi' || po.classType=='checkbox'> | |
235 | + component: 'JSelectMultiple', | |
236 | + componentProps:{ | |
237 | + dictCode:"${form_field_dictCode}" | |
238 | + }, | |
239 | + <#elseif po.classType=='sel_search'> | |
240 | + component: 'JSearchSelect', | |
241 | + componentProps:{ | |
242 | + dict:"${form_field_dictCode}" | |
243 | + }, | |
244 | +<#elseif po.classType=='cat_tree'> | |
245 | + <#assign form_cat_tree = true> | |
246 | + component: 'JCategorySelect', | |
247 | + componentProps:{ | |
248 | + pcode:"${po.dictField?default("")}", //TODO back和事件未添加,暂时有问题 | |
249 | + }, | |
250 | + <#if po.dictText?default("")?trim?length gt 1> | |
251 | + <#assign form_cat_back = "${po.dictText}"> | |
252 | + </#if> | |
253 | + <#elseif po.fieldDbType=='int' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'> | |
254 | + component: 'InputNumber', | |
255 | + <#elseif po.classType=='file'> | |
256 | + component: 'JUpload', | |
257 | + componentProps:{ | |
258 | + <#if po.uploadnum??> | |
259 | + maxCount:${po.uploadnum} | |
260 | + </#if> | |
261 | + }, | |
262 | + <#elseif po.classType=='image'> | |
263 | + component: 'JImageUpload', | |
264 | + componentProps:{ | |
265 | + <#if po.uploadnum??> | |
266 | + fileMax:${po.uploadnum} | |
267 | + </#if> | |
268 | + }, | |
269 | + <#elseif po.classType=='umeditor'> | |
270 | + component: 'JEditor', | |
271 | + <#elseif po.classType == 'sel_tree'> | |
272 | + component: 'JTreeSelect', | |
273 | + componentProps:{ | |
274 | + <#if po.dictText??> | |
275 | + <#if po.dictText?split(',')[2]?? && po.dictText?split(',')[0]??> | |
276 | + dict:"${po.dictTable},${po.dictText?split(',')[2]},${po.dictText?split(',')[0]}", | |
277 | + <#elseif po.dictText?split(',')[1]??> | |
278 | + pidField:"${po.dictText?split(',')[1]}", | |
279 | + <#elseif po.dictText?split(',')[3]??> | |
280 | + hasChildField:"${po.dictText?split(',')[3]}", | |
281 | + </#if> | |
282 | + </#if> | |
283 | + pidValue:"${po.dictField}", | |
284 | + }, | |
285 | + <#else> | |
286 | + component: 'Input', | |
287 | + </#if> | |
288 | + <#include "/common/utils.ftl"> | |
289 | + <#if po.isShow == 'Y' && poHasCheck(po)> | |
290 | + dynamicRules: ({model,schema}) => { | |
291 | + <#if po.fieldName != 'id'> | |
292 | + <#assign fieldValidType = po.fieldValidType!''> | |
293 | + return [ | |
294 | + <#-- 非空校验 --> | |
295 | + <#if po.nullable == 'N' || fieldValidType == '*'> | |
296 | + { required: true, message: '请输入${po.filedComment}!'}, | |
297 | + <#elseif fieldValidType!=''> | |
298 | + { required: false}, | |
299 | + </#if> | |
300 | + <#-- 唯一校验 --> | |
301 | + <#if fieldValidType == 'only'> | |
302 | + {...rules.duplicateCheckRule(<#if sub?default("")?trim?length gt 1>'${sub.tableName}'<#else>'${tableName}'</#if>, '${po.fieldDbName}',model,schema)[0]}, | |
303 | + <#-- 6到16位数字 --> | |
304 | + <#elseif fieldValidType == 'n6-16'> | |
305 | + { pattern: /^\d{6,16}$/, message: '请输入6到16位数字!'}, | |
306 | + <#-- 6到16位任意字符 --> | |
307 | + <#elseif fieldValidType == '*6-16'> | |
308 | + { pattern: /^.{6,16}$/, message: '请输入6到16位任意字符!'}, | |
309 | + <#-- 6到18位字符串 --> | |
310 | + <#elseif fieldValidType == 's6-18'> | |
311 | + { pattern: /^.{6,18}$/, message: '请输入6到18位任意字符!'}, | |
312 | + <#-- 网址 --> | |
313 | + <#elseif fieldValidType == 'url'> | |
314 | + { pattern: /^((ht|f)tps?):\/\/[\w\-]+(\.[\w\-]+)+([\w\-.,@?^=%&:\/~+#]*[\w\-@?^=%&\/~+#])?$/, message: '请输入正确的网址!'}, | |
315 | + <#-- 电子邮件 --> | |
316 | + <#elseif fieldValidType == 'e'> | |
317 | + { pattern: /^([\w]+\.*)([\w]+)@[\w]+\.\w{3}(\.\w{2}|)$/, message: '请输入正确的电子邮件!'}, | |
318 | + <#-- 手机号码 --> | |
319 | + <#elseif fieldValidType == 'm'> | |
320 | + { pattern: /^1[3456789]\d{9}$/, message: '请输入正确的手机号码!'}, | |
321 | + <#-- 邮政编码 --> | |
322 | + <#elseif fieldValidType == 'p'> | |
323 | + { pattern: /^[1-9]\d{5}$/, message: '请输入正确的邮政编码!'}, | |
324 | + <#-- 字母 --> | |
325 | + <#elseif fieldValidType == 's'> | |
326 | + { pattern: /^[A-Z|a-z]+$/, message: '请输入字母!'}, | |
327 | + <#-- 数字 --> | |
328 | + <#elseif fieldValidType == 'n'> | |
329 | + { pattern: /^-?\d+\.?\d*$/, message: '请输入数字!'}, | |
330 | + <#-- 整数 --> | |
331 | + <#elseif fieldValidType == 'z'> | |
332 | + { pattern: /^-?\d+$/, message: '请输入整数!'}, | |
333 | + <#-- 金额 --> | |
334 | + <#elseif fieldValidType == 'money'> | |
335 | + { pattern: /^(([1-9][0-9]*)|([0]\.\d{0,2}|[1-9][0-9]*\.\d{0,2}))$/, message: '请输入正确的金额!'}, | |
336 | + <#-- 正则校验 --> | |
337 | + <#elseif fieldValidType != '' && fieldValidType != '*'> | |
338 | + { pattern: '${fieldValidType}', message: '不符合校验规则!'}, | |
339 | + <#-- 无校验 --> | |
340 | + <#else> | |
341 | + <#t> | |
342 | + </#if> | |
343 | + ]; | |
344 | + </#if> | |
345 | + }, | |
346 | + </#if> | |
347 | + <#if po.readonly=='Y'> | |
348 | + dynamicDisabled:true | |
349 | + </#if> | |
350 | + }, | |
351 | +</#if> | |
352 | +</#list> | |
353 | +<#if id_exists == false> | |
354 | + // TODO 主键隐藏字段,目前写死为ID | |
355 | + { | |
356 | + label: '', | |
357 | + field: 'id', | |
358 | + component: 'Input', | |
359 | + show: false | |
360 | + }, | |
361 | +</#if> | |
362 | +]; | |
363 | +//子表单数据 | |
364 | +<#list subTables as sub> | |
365 | +<#if sub.foreignRelationType =='1'> | |
366 | +export const ${sub.entityName?uncap_first}FormSchema: FormSchema[] = [ | |
367 | +<#assign form_cat_tree = false> | |
368 | +<#assign form_cat_back = ""> | |
369 | +<#assign bpm_flag=false> | |
370 | +<#assign sub_id_exists=false> | |
371 | +<#list sub.colums as po><#rt/> | |
372 | +<#if po.fieldDbName=='bpm_status'> | |
373 | + <#assign bpm_flag=true> | |
374 | +</#if> | |
375 | +<#if po.fieldDbName=='id'> | |
376 | + <#assign sub_id_exists=true> | |
377 | +</#if> | |
378 | +<#if po.isShow =='Y'> | |
379 | +<#assign form_field_dictCode=""> | |
380 | + <#if po.dictTable?default("")?trim?length gt 1 && po.dictText?default("")?trim?length gt 1 && po.dictField?default("")?trim?length gt 1> | |
381 | + <#assign form_field_dictCode="${po.dictTable},${po.dictText},${po.dictField}"> | |
382 | + <#elseif po.dictField?default("")?trim?length gt 1> | |
383 | + <#assign form_field_dictCode="${po.dictField}"> | |
384 | + </#if> | |
385 | + { | |
386 | + label: '${po.filedComment}', | |
387 | + field: ${autoStringSuffix(po)}, | |
388 | + <#if po.classType =='date'> | |
389 | + component: 'DatePicker', | |
390 | + <#elseif po.classType =='datetime'> | |
391 | + component: 'DatePicker', | |
392 | + componentProps: { | |
393 | + showTime:true, | |
394 | + valueFormat: 'YYYY-MM-DD HH:mm:ss' | |
395 | + }, | |
396 | + <#elseif po.classType =='time'> | |
397 | + component: 'TimePicker', | |
398 | + componentProps: { | |
399 | + valueFormat: 'HH:mm:ss' | |
400 | + }, | |
401 | + <#elseif po.classType =='popup'> | |
402 | + <#include "/common/form/vue3popup.ftl"> | |
403 | + <#elseif po.classType =='sel_depart'> | |
404 | + component: 'JSelectDept', | |
405 | + <#elseif po.classType =='switch'> | |
406 | + component: 'JSwitch', | |
407 | + componentProps:{ | |
408 | + <#if po.dictField != 'is_open'> | |
409 | + options:${po.dictField} | |
410 | + </#if> | |
411 | + }, | |
412 | + <#elseif po.classType =='pca'> | |
413 | + component: 'JAreaLinkage', | |
414 | + <#elseif po.classType =='markdown'> | |
415 | + component: 'JMarkdownEditor',//注意string转换问题 | |
416 | + <#elseif po.classType =='password'> | |
417 | + component: 'InputPassword', | |
418 | + <#elseif po.classType =='sel_user'> | |
419 | + component: 'JSelectUserByDept', | |
420 | + componentProps:{ | |
421 | + labelKey:'realname', | |
422 | + }, | |
423 | + <#elseif po.classType =='textarea'> | |
424 | + component: 'InputTextArea', | |
425 | + <#elseif po.classType=='list' || po.classType=='radio'> | |
426 | + component: 'JDictSelectTag', | |
427 | + componentProps:{ | |
428 | + dictCode:"${form_field_dictCode}" | |
429 | + }, | |
430 | + <#elseif po.classType=='list_multi' || po.classType=='checkbox'> | |
431 | + component: 'JSelectMultiple', | |
432 | + componentProps:{ | |
433 | + dictCode:"${form_field_dictCode}" | |
434 | + } | |
435 | + <#elseif po.classType=='sel_search'> | |
436 | + component: 'JSearchSelect', | |
437 | + componentProps:{ | |
438 | + dict:"${form_field_dictCode}" | |
439 | + }, | |
440 | +<#elseif po.classType=='cat_tree'> | |
441 | + <#assign form_cat_tree = true> | |
442 | + component: 'JCategorySelect', | |
443 | + componentProps:{ | |
444 | + pcode:"${po.dictField?default("")}", //TODO back和事件未添加,暂时有问题 | |
445 | + }, | |
446 | + <#if po.dictText?default("")?trim?length gt 1> | |
447 | + <#assign form_cat_back = "${po.dictText}"> | |
448 | + </#if> | |
449 | + <#elseif po.fieldDbType=='int' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'> | |
450 | + component: 'InputNumber', | |
451 | + <#elseif po.classType=='file'> | |
452 | + component: 'JUpload', | |
453 | + componentProps:{ | |
454 | + <#if po.uploadnum??> | |
455 | + maxCount:${po.uploadnum} | |
456 | + </#if> | |
457 | + }, | |
458 | + <#elseif po.classType=='image'> | |
459 | + component: 'JImageUpload', | |
460 | + componentProps:{ | |
461 | + <#if po.uploadnum??> | |
462 | + fileMax:${po.uploadnum} | |
463 | + </#if> | |
464 | + }, | |
465 | + <#elseif po.classType=='umeditor'> | |
466 | + component: 'JEditor', | |
467 | + <#elseif po.classType == 'sel_tree'> | |
468 | + component: 'JTreeSelect', | |
469 | + componentProps:{ | |
470 | + <#if po.dictText??> | |
471 | + <#if po.dictText?split(',')[2]?? && po.dictText?split(',')[0]??> | |
472 | + dict:"${po.dictTable},${po.dictText?split(',')[2]},${po.dictText?split(',')[0]}", | |
473 | + <#elseif po.dictText?split(',')[1]??> | |
474 | + pidField:"${po.dictText?split(',')[1]}", | |
475 | + <#elseif po.dictText?split(',')[3]??> | |
476 | + hasChildField:"${po.dictText?split(',')[3]}", | |
477 | + </#if> | |
478 | + </#if> | |
479 | + pidValue:"${po.dictField}", | |
480 | + }, | |
481 | + <#else> | |
482 | + component: 'Input', | |
483 | + </#if> | |
484 | + <#include "/common/utils.ftl"> | |
485 | + <#if po.isShow == 'Y' && poHasCheck(po)> | |
486 | + dynamicRules: ({model,schema}) => { | |
487 | + <#if po.fieldName != 'id'> | |
488 | + <#assign fieldValidType = po.fieldValidType!''> | |
489 | + return [ | |
490 | + <#-- 非空校验 --> | |
491 | + <#if po.nullable == 'N' || fieldValidType == '*'> | |
492 | + { required: true, message: '请输入${po.filedComment}!'}, | |
493 | + <#elseif fieldValidType!=''> | |
494 | + { required: false}, | |
495 | + </#if> | |
496 | + <#-- 唯一校验 --> | |
497 | + <#if fieldValidType == 'only'> | |
498 | + {...rules.duplicateCheckRule(<#if sub?default("")?trim?length gt 1>'${sub.tableName}'<#else>'${tableName}'</#if>, '${po.fieldDbName}',model,schema)[0]}, | |
499 | + <#-- 6到16位数字 --> | |
500 | + <#elseif fieldValidType == 'n6-16'> | |
501 | + { pattern: /^\d{6,16}$/, message: '请输入6到16位数字!'}, | |
502 | + <#-- 6到16位任意字符 --> | |
503 | + <#elseif fieldValidType == '*6-16'> | |
504 | + { pattern: /^.{6,16}$/, message: '请输入6到16位任意字符!'}, | |
505 | + <#-- 6到18位字符串 --> | |
506 | + <#elseif fieldValidType == 's6-18'> | |
507 | + { pattern: /^.{6,18}$/, message: '请输入6到18位任意字符!'}, | |
508 | + <#-- 网址 --> | |
509 | + <#elseif fieldValidType == 'url'> | |
510 | + { pattern: /^((ht|f)tps?):\/\/[\w\-]+(\.[\w\-]+)+([\w\-.,@?^=%&:\/~+#]*[\w\-@?^=%&\/~+#])?$/, message: '请输入正确的网址!'}, | |
511 | + <#-- 电子邮件 --> | |
512 | + <#elseif fieldValidType == 'e'> | |
513 | + { pattern: /^([\w]+\.*)([\w]+)@[\w]+\.\w{3}(\.\w{2}|)$/, message: '请输入正确的电子邮件!'}, | |
514 | + <#-- 手机号码 --> | |
515 | + <#elseif fieldValidType == 'm'> | |
516 | + { pattern: /^1[3456789]\d{9}$/, message: '请输入正确的手机号码!'}, | |
517 | + <#-- 邮政编码 --> | |
518 | + <#elseif fieldValidType == 'p'> | |
519 | + { pattern: /^[1-9]\d{5}$/, message: '请输入正确的邮政编码!'}, | |
520 | + <#-- 字母 --> | |
521 | + <#elseif fieldValidType == 's'> | |
522 | + { pattern: /^[A-Z|a-z]+$/, message: '请输入字母!'}, | |
523 | + <#-- 数字 --> | |
524 | + <#elseif fieldValidType == 'n'> | |
525 | + { pattern: /^-?\d+\.?\d*$/, message: '请输入数字!'}, | |
526 | + <#-- 整数 --> | |
527 | + <#elseif fieldValidType == 'z'> | |
528 | + { pattern: /^-?\d+$/, message: '请输入整数!'}, | |
529 | + <#-- 金额 --> | |
530 | + <#elseif fieldValidType == 'money'> | |
531 | + { pattern: /^(([1-9][0-9]*)|([0]\.\d{0,2}|[1-9][0-9]*\.\d{0,2}))$/, message: '请输入正确的金额!'}, | |
532 | + <#-- 正则校验 --> | |
533 | + <#elseif fieldValidType != '' && fieldValidType != '*'> | |
534 | + { pattern: '${fieldValidType}', message: '不符合校验规则!'}, | |
535 | + <#-- 无校验 --> | |
536 | + <#else> | |
537 | + <#t> | |
538 | + </#if> | |
539 | + ]; | |
540 | + </#if> | |
541 | + }, | |
542 | + </#if> | |
543 | + <#if po.readonly=='Y'> | |
544 | + dynamicDisabled:true | |
545 | + </#if> | |
546 | + }, | |
547 | +</#if> | |
548 | +</#list> | |
549 | +<#if sub_id_exists == false> | |
550 | + { | |
551 | + label: '', | |
552 | + field: 'id', | |
553 | + component: 'Input', | |
554 | + show: false | |
555 | + }, | |
556 | +</#if> | |
557 | +]; | |
558 | +</#if> | |
559 | +</#list> | |
560 | +//子表表格配置 | |
561 | +<#list subTables as sub> | |
562 | +<#if sub.foreignRelationType =='0'> | |
563 | +export const ${sub.entityName?uncap_first}Columns: JVxeColumn[] = [ | |
564 | +<#assign popupBackFields = ""> | |
565 | + | |
566 | +<#-- 循环子表的列 开始 --> | |
567 | +<#list sub.colums as col><#rt/> | |
568 | +<#if col.isShow =='Y'> | |
569 | +<#if col.filedComment !='外键' > | |
570 | + { | |
571 | + title: '${col.filedComment}', | |
572 | + key: '${autoStringSuffixForModel(col)}', | |
573 | +<#if col.classType =='date'> | |
574 | + type: JVxeTypes.date, | |
575 | + <#if col.readonly=='Y'> | |
576 | + disabled:true, | |
577 | + </#if> | |
578 | +<#elseif col.classType =='datetime'> | |
579 | + type: JVxeTypes.datetime, | |
580 | + <#if col.readonly=='Y'> | |
581 | + disabled:true, | |
582 | + </#if> | |
583 | +<#elseif col.classType =='time'> | |
584 | + type: JVxeTypes.time, | |
585 | + <#if col.readonly=='Y'> | |
586 | + disabled:true, | |
587 | + </#if> | |
588 | +<#elseif col.classType =='textarea'> | |
589 | + type: JVxeTypes.textarea, | |
590 | + <#if col.readonly=='Y'> | |
591 | + disabled:true, | |
592 | + </#if> | |
593 | +<#-- update-begin-author:taoyan date:20220523 for: VUEN-1084 【vue3】online表单测试发现的新问题 20、一对多列字段类型生成的不对,数字或者金额类型 --> | |
594 | +<#-- elseif "int,decimal,double,"?contains(col.classType) --> | |
595 | +<#elseif col.fieldDbType=='int' || col.fieldDbType=='double' || col.fieldDbType=='BigDecimal'> | |
596 | +<#-- update-end-author:taoyan date:20220523 for: VUEN-1084 【vue3】online表单测试发现的新问题 20、一对多列字段类型生成的不对,数字或者金额类型 --> | |
597 | + type: JVxeTypes.inputNumber, | |
598 | + <#if col.readonly=='Y'> | |
599 | + disabled:true, | |
600 | + </#if> | |
601 | +<#elseif col.classType =='list' || col.classType =='radio'> | |
602 | + type: JVxeTypes.select, | |
603 | + options:[], | |
604 | + <#if col.dictTable?default("")?trim?length gt 1> | |
605 | + dictCode:"${col.dictTable},${col.dictText},${col.dictField}", | |
606 | + <#else> | |
607 | + dictCode:"${col.dictField}", | |
608 | + </#if> | |
609 | + <#if col.readonly=='Y'> | |
610 | + disabled:true, | |
611 | + </#if> | |
612 | +<#elseif col.classType =='list_multi' || col.classType =='checkbox'> | |
613 | + type: JVxeTypes.selectMultiple, | |
614 | + options:[], | |
615 | + <#if col.dictTable?default("")?trim?length gt 1> | |
616 | + dictCode:"${col.dictTable},${col.dictText},${col.dictField}", | |
617 | + <#else> | |
618 | + dictCode:"${col.dictField}", | |
619 | + </#if> | |
620 | + <#if col.readonly=='Y'> | |
621 | + disabled:true, | |
622 | + </#if> | |
623 | +<#elseif col.classType =='sel_search'> | |
624 | + type: JVxeTypes.selectSearch, | |
625 | + <#if col.dictTable?default("")?trim?length gt 1> | |
626 | + dictCode:"${col.dictTable},${col.dictText},${col.dictField}", | |
627 | + <#else> | |
628 | + dictCode:"${col.dictField}", | |
629 | + </#if> | |
630 | + <#if col.readonly=='Y'> | |
631 | + disabled:true, | |
632 | + </#if> | |
633 | +<#elseif col.classType =='sel_depart'> | |
634 | + type: JVxeTypes.departSelect, | |
635 | + <#if col.readonly=='Y'> | |
636 | + disabled:true, | |
637 | + </#if> | |
638 | +<#elseif col.classType =='sel_user'> | |
639 | + type: JVxeTypes.userSelect, | |
640 | + <#if col.readonly=='Y'> | |
641 | + disabled:true, | |
642 | + </#if> | |
643 | +<#elseif col.classType =='image'> | |
644 | + type: JVxeTypes.image, | |
645 | + token:true, | |
646 | + responseName:"message", | |
647 | + <#if col.readonly=='Y'> | |
648 | + disabled:true, | |
649 | + </#if> | |
650 | + <#if col.uploadnum??> | |
651 | + number: ${col.uploadnum}, | |
652 | + </#if> | |
653 | +<#elseif col.classType =='file'> | |
654 | + type: JVxeTypes.file, | |
655 | + token:true, | |
656 | + responseName:"message", | |
657 | + <#if col.readonly=='Y'> | |
658 | + disabled:true, | |
659 | + </#if> | |
660 | + <#if col.uploadnum??> | |
661 | + number: ${col.uploadnum}, | |
662 | + </#if> | |
663 | +<#elseif col.classType =='switch'> | |
664 | + type: JVxeTypes.checkbox, | |
665 | + <#if col.dictField == 'is_open'> | |
666 | + customValue: ['Y', 'N'], | |
667 | + <#else> | |
668 | + customValue: ${col.dictField}, | |
669 | + </#if> | |
670 | + <#if col.readonly=='Y'> | |
671 | + disabled:true, | |
672 | + </#if> | |
673 | +<#elseif col.classType =='popup'> | |
674 | +<#if popupBackFields?length gt 0> | |
675 | + <#assign popupBackFields = "${popupBackFields}"+","+"${col.dictText}"> | |
676 | +<#else> | |
677 | + <#assign popupBackFields = "${col.dictText}"> | |
678 | +</#if> | |
679 | + <#include "/common/form/vue3Jvxepopup.ftl"> | |
680 | +<#else> | |
681 | + type: JVxeTypes.input, | |
682 | + <#if col.readonly=='Y'> | |
683 | + disabled:true, | |
684 | + </#if> | |
685 | +</#if> | |
686 | +<#if col.classType =='list_multi' || col.classType =='checkbox'> | |
687 | + width:"250px", | |
688 | +<#else> | |
689 | + width:"200px", | |
690 | +</#if> | |
691 | +<#if col.classType =='file'> | |
692 | + placeholder: '请选择文件', | |
693 | +<#else> | |
694 | + placeholder: '请输入${'$'}{title}', | |
695 | +</#if> | |
696 | +<#if col.defaultVal??> | |
697 | +<#if col.fieldDbType=="BigDecimal" || col.fieldDbType=="double" || col.fieldDbType=="int"> | |
698 | + defaultValue:${col.defaultVal}, | |
699 | + <#else> | |
700 | + defaultValue:"${col.defaultVal}", | |
701 | +</#if> | |
702 | +<#else> | |
703 | + defaultValue:'', | |
704 | +</#if> | |
705 | +<#-- 子表的校验 --> | |
706 | + <#include "/common/validatorRulesTemplate/sub-vue3.ftl"> | |
707 | + }, | |
708 | +</#if> | |
709 | +</#if> | |
710 | +</#list> | |
711 | +<#-- 循环子表的列 结束 --> | |
712 | + ] | |
713 | +</#if> | |
714 | +</#list> | |
0 | 715 | \ No newline at end of file |
... | ... |
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/${entityName}_menu_insert.sql
0 → 100644
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/components/${entityName}Form.vuei
0 → 100644
1 | +<#include "/common/utils.ftl"> | |
2 | +<#assign need_category = false> | |
3 | +<#assign bpm_flag=false> | |
4 | +<#assign need_pca = false> | |
5 | +<#assign need_search = false> | |
6 | +<#assign need_dept_user = false> | |
7 | +<#assign need_switch = false> | |
8 | +<#assign need_dept = false> | |
9 | +<#assign need_multi = false> | |
10 | +<#assign need_popup = false> | |
11 | +<#assign need_select_tag = false> | |
12 | +<#assign need_select_tree = false> | |
13 | +<#assign need_time = false> | |
14 | +<#assign need_markdown = false> | |
15 | +<#assign need_upload = false> | |
16 | +<#assign need_image_upload = false> | |
17 | +<#assign need_editor = false> | |
18 | +<#assign need_checkbox = false> | |
19 | +<#assign form_span = 24> | |
20 | +<#if tableVo.fieldRowNum==2> | |
21 | + <#assign form_span = 12> | |
22 | +<#elseif tableVo.fieldRowNum==3> | |
23 | + <#assign form_span = 8> | |
24 | +<#elseif tableVo.fieldRowNum==4> | |
25 | + <#assign form_span = 6> | |
26 | +</#if> | |
27 | +<#assign hasOne2manyTable = false> | |
28 | +<#assign subTabActiveKey = ''> | |
29 | +<#assign subMainFieldMap={}> | |
30 | +<#assign subTableColumnsKey=[]> | |
31 | +<#assign hasOnlyValidate = false> | |
32 | +<template> | |
33 | + <a-spin :spinning="loading"> | |
34 | + <a-form v-bind="formItemLayout"> | |
35 | + <a-row> | |
36 | + <#list columns as po> | |
37 | + <#if po.isShow == 'Y' && po.fieldValidType?default("") == 'only'> | |
38 | + <#assign hasOnlyValidate = true> | |
39 | + </#if> | |
40 | + <#if po.fieldDbName=='bpm_status'> | |
41 | + <#assign bpm_flag=true> | |
42 | + </#if> | |
43 | +<#include "/common/form/native/vue3NativeForm.ftl"> | |
44 | + </#list> | |
45 | + </a-row> | |
46 | + </a-form> | |
47 | + | |
48 | + <!-- 子表单区域 --> | |
49 | + <a-tabs v-model:activeKey="activeKey"> | |
50 | +<#list subTables as sub><#rt/> | |
51 | + <a-tab-pane tab="${sub.ftlDescription}" key="${sub.entityName?uncap_first}" :forceRender="true"> | |
52 | + <#if sub.foreignRelationType =='1'> | |
53 | + <${Format.humpToShortbar(sub.entityName)}-form ref="${sub.entityName?uncap_first}FormRef" :disabled="formDisabled"></${Format.humpToShortbar(sub.entityName)}-form> | |
54 | + <#else> | |
55 | + <j-vxe-table | |
56 | + :keep-source="true" | |
57 | + ref="${sub.entityName?uncap_first}TableRef" | |
58 | + :loading="${sub.entityName?uncap_first}Table.loading" | |
59 | + :columns="${sub.entityName?uncap_first}Table.columns" | |
60 | + :dataSource="${sub.entityName?uncap_first}Table.dataSource" | |
61 | + :maxHeight="300" | |
62 | + :disabled="formDisabled" | |
63 | + :rowNumber="true" | |
64 | + :rowSelection="true" | |
65 | + :toolbar="true"/> | |
66 | + </#if> | |
67 | + </a-tab-pane> | |
68 | +</#list> | |
69 | + </a-tabs> | |
70 | + </a-spin> | |
71 | +</template> | |
72 | + | |
73 | +<script lang="ts"> | |
74 | + import { defineComponent, ref, reactive, computed, toRaw } from 'vue'; | |
75 | + import { useValidateAntFormAndTable } from '/@/hooks/system/useJvxeMethods'; | |
76 | + import { <#list subTables as sub><#if sub.foreignRelationType =='0'>query${sub.entityName}ListByMainId, </#if></#list>queryDataById, saveOrUpdate } from '../${entityName}.api'; | |
77 | + <#list subTables as sub> | |
78 | + <#if sub.foreignRelationType =='1'> | |
79 | + import ${sub.entityName}Form from './${sub.entityName}Form.vue' | |
80 | + <#else> | |
81 | + <#assign hasOne2manyTable = true> | |
82 | + <#assign subTableColumnsKey += ['${sub.entityName?uncap_first}Columns']> | |
83 | + </#if> | |
84 | + <#if sub?? && (sub.foreignMainKeys)??> | |
85 | + <#list sub.foreignMainKeys as key> | |
86 | + <#assign subMainFieldMap += {"${sub.entityName}": "${dashedToCamel(key)}"}> | |
87 | + </#list> | |
88 | + </#if> | |
89 | + </#list> | |
90 | + <#if hasOne2manyTable == true> | |
91 | + import { JVxeTable } from '/@/components/jeecg/JVxeTable'; | |
92 | + import {<#list subTableColumnsKey as columnsKey><#if columnsKey_index gt 0>, </#if>${columnsKey}</#list>} from '../${entityName}.data'; | |
93 | + </#if> | |
94 | + <#include "/common/form/native/vue3NativeImport.ftl"> | |
95 | + <#if hasOnlyValidate == true> | |
96 | + import { duplicateValidate } from '/@/utils/helper/validator' | |
97 | + </#if> | |
98 | + import { Form } from 'ant-design-vue'; | |
99 | + const useForm = Form.useForm; | |
100 | + | |
101 | + export default defineComponent({ | |
102 | + name: "${entityName}Form", | |
103 | + components:{ | |
104 | + <#include "/common/form/native/vue3NativeComponents.ftl"> | |
105 | + <#if hasOne2manyTable == true> | |
106 | + JVxeTable, | |
107 | + </#if> | |
108 | +<#list subTables as sub> | |
109 | + <#if sub.foreignRelationType =='1'> | |
110 | + ${sub.entityName}Form, | |
111 | + </#if> | |
112 | +</#list> | |
113 | + }, | |
114 | + props:{ | |
115 | + disabled:{ | |
116 | + type: Boolean, | |
117 | + default: false | |
118 | + } | |
119 | + }, | |
120 | + emits:['success'], | |
121 | + setup(props, {emit}) { | |
122 | + const loading = ref(false); | |
123 | + <#list subTables as sub> | |
124 | + <#if sub_index == 0> | |
125 | + <#assign subTabActiveKey = '${sub.entityName?uncap_first}'> | |
126 | + </#if> | |
127 | + <#if sub.foreignRelationType =='1'> | |
128 | + const ${sub.entityName?uncap_first}FormRef = ref(); | |
129 | + <#else> | |
130 | + const ${sub.entityName?uncap_first}TableRef = ref(); | |
131 | + const ${sub.entityName?uncap_first}Table = reactive<Record<string, any>>({ | |
132 | + loading: false, | |
133 | + columns: ${sub.entityName?uncap_first}Columns, | |
134 | + dataSource: [] | |
135 | + }); | |
136 | + </#if> | |
137 | + </#list> | |
138 | + const activeKey = ref('${subTabActiveKey}'); | |
139 | + const formData = reactive<Record<string, any>>({ | |
140 | + <#list columns as po> | |
141 | + <#if po.isShow == 'Y'> | |
142 | + ${po.fieldName}: '', | |
143 | + </#if> | |
144 | + </#list> | |
145 | + }); | |
146 | + | |
147 | + //表单验证 | |
148 | + const validatorRules = reactive({ | |
149 | + <#list columns as po> | |
150 | + <#if po.isShow == 'Y' && poHasCheck(po)> | |
151 | + ${po.fieldName}: [<#include "/common/validatorRulesTemplate/native/vue3CoreNative.ftl">], | |
152 | + </#if> | |
153 | + </#list> | |
154 | + }); | |
155 | + const {resetFields, validate, validateInfos} = useForm(formData, validatorRules, {immediate: true}); | |
156 | + const dbData = {}; | |
157 | + const formItemLayout = { | |
158 | + labelCol: {xs: {span: 24}, sm: {span: 5}}, | |
159 | + wrapperCol: {xs: {span: 24}, sm: {span: 16}}, | |
160 | + }; | |
161 | + | |
162 | + const formDisabled = computed(() => { | |
163 | + return props.disabled; | |
164 | + }); | |
165 | + | |
166 | + function add() { | |
167 | + resetFields(); | |
168 | + <#list subTables as sub> | |
169 | + <#if sub.foreignRelationType =='1'> | |
170 | + ${sub.entityName?uncap_first}FormRef.value.initFormData(); | |
171 | + <#else> | |
172 | + ${sub.entityName?uncap_first}Table.dataSource = []; | |
173 | + </#if> | |
174 | + </#list> | |
175 | + } | |
176 | + | |
177 | + async function edit(row) { | |
178 | + //主表数据 | |
179 | + await queryMainData(row.id); | |
180 | + //子表数据 | |
181 | + <#list subTables as sub> | |
182 | + <#if sub.foreignRelationType =='1'> | |
183 | + await ${sub.entityName?uncap_first}FormRef.value.initFormData(row['${subMainFieldMap[sub.entityName]}']); | |
184 | + <#else> | |
185 | + const ${sub.entityName?uncap_first}DataList = await query${sub.entityName}ListByMainId(row['${subMainFieldMap[sub.entityName]}']); | |
186 | + ${sub.entityName?uncap_first}Table.dataSource = [...${sub.entityName?uncap_first}DataList]; | |
187 | + </#if> | |
188 | + </#list> | |
189 | + } | |
190 | + | |
191 | + async function queryMainData(id) { | |
192 | + const row = await queryDataById(id); | |
193 | + Object.keys(row).map(k => { | |
194 | + formData[k] = row[k]; | |
195 | + }); | |
196 | + } | |
197 | + | |
198 | + const {getSubFormAndTableData, transformData} = useValidateAntFormAndTable(activeKey, { | |
199 | + <#list subTables as sub> | |
200 | + <#if sub.foreignRelationType =='1'> | |
201 | + '${sub.entityName?uncap_first}': ${sub.entityName?uncap_first}FormRef, | |
202 | + <#else> | |
203 | + '${sub.entityName?uncap_first}': ${sub.entityName?uncap_first}TableRef, | |
204 | + </#if> | |
205 | + </#list> | |
206 | + }); | |
207 | + | |
208 | + async function getFormData() { | |
209 | + await validate(); | |
210 | + return transformData(toRaw(formData)) | |
211 | + } | |
212 | + | |
213 | + async function submitForm() { | |
214 | + const mainData = await getFormData(); | |
215 | + const subData = await getSubFormAndTableData(); | |
216 | + const values = Object.assign({}, dbData, mainData, subData); | |
217 | + console.log('表单提交数据', values) | |
218 | + const isUpdate = values.id ? true : false | |
219 | + await saveOrUpdate(values, isUpdate); | |
220 | + //关闭弹窗 | |
221 | + emit('success'); | |
222 | + } | |
223 | + | |
224 | + function setFieldsValue(values) { | |
225 | + if(values){ | |
226 | + Object.keys(values).map(k=>{ | |
227 | + formData[k] = values[k]; | |
228 | + }); | |
229 | + } | |
230 | + } | |
231 | + | |
232 | + <#list columns as po> | |
233 | + <#if po.isShow == 'Y' && po.fieldValidType?default("") == 'only'> | |
234 | + async function ${po.fieldName}Duplicatevalidate(_r, value) { | |
235 | + return duplicateValidate('${tableName}', '${po.fieldDbName}', value, formData.id || '') | |
236 | + } | |
237 | + </#if> | |
238 | + </#list> | |
239 | + | |
240 | + return { | |
241 | + <#list subTables as sub> | |
242 | + <#if sub.foreignRelationType =='1'> | |
243 | + ${sub.entityName?uncap_first}FormRef, | |
244 | + <#else> | |
245 | + ${sub.entityName?uncap_first}TableRef, | |
246 | + ${sub.entityName?uncap_first}Table, | |
247 | + </#if> | |
248 | + </#list> | |
249 | + validatorRules, | |
250 | + validateInfos, | |
251 | + activeKey, | |
252 | + loading, | |
253 | + formData, | |
254 | + setFieldsValue, | |
255 | + formItemLayout, | |
256 | + formDisabled, | |
257 | + getFormData, | |
258 | + submitForm, | |
259 | + add, | |
260 | + edit | |
261 | + } | |
262 | + } | |
263 | + }); | |
264 | +</script> | |
0 | 265 | \ No newline at end of file |
... | ... |
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/components/${entityName}Modal.vuei
0 → 100644
1 | +<#include "/common/utils.ftl"> | |
2 | +<template> | |
3 | + <BasicModal v-bind="$attrs" @register="registerModal" :title="title" :width="${getModalWidth(tableVo.fieldRowNum?default(1))}" @ok="handleSubmit"> | |
4 | + <${Format.humpToShortbar(entityName)}-form ref="formComponent" :disabled="formDisabled" @success="submitSuccess"></${Format.humpToShortbar(entityName)}-form> | |
5 | + </BasicModal> | |
6 | +</template> | |
7 | + | |
8 | +<script lang="ts"> | |
9 | + import { ref, unref } from 'vue'; | |
10 | + import { BasicModal, useModalInner } from '/@/components/Modal'; | |
11 | + import ${entityName}Form from './${entityName}Form.vue'; | |
12 | + | |
13 | + export default { | |
14 | + name: "TestCgMainVxeModal", | |
15 | + components:{ | |
16 | + BasicModal, | |
17 | + ${entityName}Form | |
18 | + }, | |
19 | + emits:['register','success'], | |
20 | + setup(_p, {emit}){ | |
21 | + const formComponent = ref() | |
22 | + const isUpdate = ref(true); | |
23 | + const formDisabled = ref(false); | |
24 | + const title = ref('') | |
25 | + | |
26 | + //表单赋值 | |
27 | + const [registerModal, {setModalProps, closeModal}] = useModalInner(async (data) => { | |
28 | + setModalProps({confirmLoading: false,showCancelBtn:data?.showFooter,showOkBtn:data?.showFooter}); | |
29 | + isUpdate.value = !!data?.isUpdate; | |
30 | + title.value = data?.isUpdate?'编辑':'新增' | |
31 | + formDisabled.value = !data?.showFooter; | |
32 | + if (unref(isUpdate)) { | |
33 | + console.log('data', data) | |
34 | + formComponent.value.edit(data.record) | |
35 | + }else{ | |
36 | + formComponent.value.add() | |
37 | + } | |
38 | + }); | |
39 | + | |
40 | + function handleSubmit() { | |
41 | + formComponent.value.submitForm(); | |
42 | + } | |
43 | + | |
44 | + function submitSuccess(){ | |
45 | + emit('success'); | |
46 | + closeModal(); | |
47 | + } | |
48 | + | |
49 | + return { | |
50 | + registerModal, | |
51 | + title, | |
52 | + formComponent, | |
53 | + formDisabled, | |
54 | + handleSubmit, | |
55 | + submitSuccess | |
56 | + } | |
57 | + } | |
58 | + } | |
59 | +</script> | |
60 | +<style lang="less" scoped> | |
61 | + /** 时间和数字输入框样式 */ | |
62 | + :deep(.ant-input-number){ | |
63 | + width: 100% | |
64 | + } | |
65 | + | |
66 | + :deep(.ant-calendar-picker){ | |
67 | + width: 100% | |
68 | + } | |
69 | +</style> | |
0 | 70 | \ No newline at end of file |
... | ... |
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/jvxe/onetomany/java/${bussiPackage}/${entityPackage}/vue3Native/components/[1-n]Form.vuei
0 → 100644
1 | +<#include "/common/utils.ftl"> | |
2 | +<#list subTables as sub> | |
3 | +<#if sub.foreignRelationType=='1'> | |
4 | +#segment#${sub.entityName}Form.vue | |
5 | +<#include "/common/utils.ftl"> | |
6 | +<#assign need_category = false> | |
7 | +<#assign bpm_flag=false> | |
8 | +<#assign need_pca = false> | |
9 | +<#assign need_search = false> | |
10 | +<#assign need_dept_user = false> | |
11 | +<#assign need_switch = false> | |
12 | +<#assign need_dept = false> | |
13 | +<#assign need_multi = false> | |
14 | +<#assign need_popup = false> | |
15 | +<#assign need_select_tag = false> | |
16 | +<#assign need_select_tree = false> | |
17 | +<#assign need_time = false> | |
18 | +<#assign need_markdown = false> | |
19 | +<#assign need_upload = false> | |
20 | +<#assign need_image_upload = false> | |
21 | +<#assign need_editor = false> | |
22 | +<#assign need_checkbox = false> | |
23 | +<#assign form_span = 24> | |
24 | +<#if tableVo.fieldRowNum==2> | |
25 | + <#assign form_span = 12> | |
26 | +<#elseif tableVo.fieldRowNum==3> | |
27 | + <#assign form_span = 8> | |
28 | +<#elseif tableVo.fieldRowNum==4> | |
29 | + <#assign form_span = 6> | |
30 | +</#if> | |
31 | + <#assign hasOnlyValidate = false> | |
32 | +<template> | |
33 | + <a-spin :spinning="loading"> | |
34 | + <a-form v-bind="formItemLayout"> | |
35 | + <a-row> | |
36 | + <#list sub.colums as po> | |
37 | + <#if po.isShow == 'Y' && po.fieldValidType?default("") == 'only'> | |
38 | + <#assign hasOnlyValidate = true> | |
39 | + </#if> | |
40 | + <#if po.fieldDbName=='bpm_status'> | |
41 | + <#assign bpm_flag=true> | |
42 | + </#if> | |
43 | + <#include "/common/form/native/vue3NativeForm.ftl"> | |
44 | + </#list> | |
45 | + </a-row> | |
46 | + </a-form> | |
47 | + </a-spin> | |
48 | +</template> | |
49 | + | |
50 | +<script lang="ts"> | |
51 | + import { defineComponent, ref, reactive, toRaw } from 'vue'; | |
52 | + import { query${sub.entityName}ListByMainId } from '../${entityName}.api'; | |
53 | +<#include "/common/form/native/vue3NativeImport.ftl"> | |
54 | +<#if hasOnlyValidate == true> | |
55 | + import { duplicateValidate } from '/@/utils/helper/validator' | |
56 | +</#if> | |
57 | + import { useMessage } from '/@/hooks/web/useMessage'; | |
58 | + import { Form } from 'ant-design-vue'; | |
59 | + const useForm = Form.useForm; | |
60 | + | |
61 | + export default defineComponent({ | |
62 | + name: '${sub.entityName}Form', | |
63 | + components:{ | |
64 | + <#include "/common/form/native/vue3NativeComponents.ftl"> | |
65 | + }, | |
66 | + props:{ | |
67 | + disabled:{ | |
68 | + type: Boolean, | |
69 | + default: false | |
70 | + } | |
71 | + }, | |
72 | + setup(){ | |
73 | + const { createMessage } = useMessage(); | |
74 | + const isForm = true; | |
75 | + const loading = ref(false); | |
76 | + const formData = reactive<Record<string, any>>({ | |
77 | + <#list sub.colums as po> | |
78 | + <#if po.isShow == 'Y'> | |
79 | + ${po.fieldName}: '', | |
80 | + </#if> | |
81 | + </#list> | |
82 | + }); | |
83 | + //表单验证 | |
84 | + const validatorRules = reactive({ | |
85 | + <#list sub.colums as po> | |
86 | + <#if po.isShow == 'Y' && poHasCheck(po)> | |
87 | + ${po.fieldName}: [<#include "/common/validatorRulesTemplate/native/vue3CoreNative.ftl">], | |
88 | + </#if> | |
89 | + </#list> | |
90 | + }) | |
91 | + const { resetFields, validate, validateInfos } = useForm(formData, validatorRules, {immediate: true}); | |
92 | + const formItemLayout = { | |
93 | + labelCol: { xs: { span: 24 }, sm: { span: 5 } }, | |
94 | + wrapperCol: { xs: { span: 24 }, sm: { span: 16 } }, | |
95 | + }; | |
96 | + | |
97 | + async function initFormData(mainId) { | |
98 | + resetFields(); | |
99 | + if(mainId){ | |
100 | + let list = await query${sub.entityName}ListByMainId(mainId); | |
101 | + if(list && list.length>0){ | |
102 | + let temp = list[0]; | |
103 | + Object.keys(temp).map(k=>{ | |
104 | + formData[k] = temp[k]; | |
105 | + }) | |
106 | + } | |
107 | + } | |
108 | + } | |
109 | + | |
110 | + async function getFormData() { | |
111 | + await validate(); | |
112 | + let subFormData = toRaw(formData); | |
113 | + if(Object.keys(subFormData).length>0){ | |
114 | + return subFormData | |
115 | + } | |
116 | + return false; | |
117 | + } | |
118 | + | |
119 | + function setFieldsValue(values) { | |
120 | + if(values){ | |
121 | + Object.keys(values).map(k=>{ | |
122 | + formData[k] = values[k]; | |
123 | + }); | |
124 | + } | |
125 | + } | |
126 | + | |
127 | + <#list sub.colums as po> | |
128 | + <#if po.isShow == 'Y' && po.fieldValidType?default("") == 'only'> | |
129 | + async function ${po.fieldName}Duplicatevalidate(_r, value) { | |
130 | + return duplicateValidate('${sub.tableName}', '${po.fieldDbName}', value, formData.id || '') | |
131 | + } | |
132 | + </#if> | |
133 | + </#list> | |
134 | + | |
135 | + return { | |
136 | + loading, | |
137 | + formData, | |
138 | + formItemLayout, | |
139 | + initFormData, | |
140 | + getFormData, | |
141 | + setFieldsValue, | |
142 | + isForm, | |
143 | + validateInfos | |
144 | + } | |
145 | + } | |
146 | + }); | |
147 | +</script> | |
148 | +</#if> | |
149 | +</#list> | |
... | ... |
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai
... | ... | @@ -196,17 +196,14 @@ public class ${entityName}Controller { |
196 | 196 | QueryWrapper<${entityName}> queryWrapper = QueryGenerator.initQueryWrapper(${entityName?uncap_first}, request.getParameterMap()); |
197 | 197 | LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); |
198 | 198 | |
199 | - //Step.2 获取导出数据 | |
200 | - List<${entityName}> queryList = ${entityName?uncap_first}Service.list(queryWrapper); | |
201 | - // 过滤选中数据 | |
202 | - String selections = request.getParameter("selections"); | |
203 | - List<${entityName}> ${entityName?uncap_first}List = new ArrayList<${entityName}>(); | |
204 | - if(oConvertUtils.isEmpty(selections)) { | |
205 | - ${entityName?uncap_first}List = queryList; | |
206 | - }else { | |
207 | - List<String> selectionList = Arrays.asList(selections.split(",")); | |
208 | - ${entityName?uncap_first}List = queryList.stream().filter(item -> selectionList.contains(item.getId())).collect(Collectors.toList()); | |
209 | - } | |
199 | + //配置选中数据查询条件 | |
200 | + String selections = request.getParameter("selections"); | |
201 | + if(oConvertUtils.isNotEmpty(selections)) { | |
202 | + List<String> selectionList = Arrays.asList(selections.split(",")); | |
203 | + queryWrapper.in("id",selectionList); | |
204 | + } | |
205 | + //Step.2 获取导出数据 | |
206 | + List<${entityName}> ${entityName?uncap_first}List = ${entityName?uncap_first}Service.list(queryWrapper); | |
210 | 207 | |
211 | 208 | // Step.3 组装pageList |
212 | 209 | List<${entityName}Page> pageList = new ArrayList<${entityName}Page>(); |
... | ... |
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/entity/${entityName}.javai
1 | +<#include "/common/utils.ftl"> | |
1 | 2 | package ${bussiPackage}.${entityPackage}.entity; |
2 | 3 | |
3 | 4 | import java.io.Serializable; |
... | ... | @@ -31,9 +32,9 @@ public class ${entityName} implements Serializable { |
31 | 32 | <#-- 生成字典Code --> |
32 | 33 | <#assign list_field_dictCode=""> |
33 | 34 | <#if po.classType='sel_user'> |
34 | - <#assign list_field_dictCode=', dictTable = "sys_user", dicText = "realname", dicCode = "username"'> | |
35 | + <#assign list_field_dictCode=', dictTable = "sys_user", dicText = "${camelToDashed(po.extendParams.text?default(\"realname\")?trim)}", dicCode = "${camelToDashed(po.extendParams.store?default(\"username\")?trim)}"'> | |
35 | 36 | <#elseif po.classType='sel_depart'> |
36 | - <#assign list_field_dictCode=', dictTable = "sys_depart", dicText = "depart_name", dicCode = "id"'> | |
37 | + <#assign list_field_dictCode=', dictTable = "sys_depart", dicText = "${camelToDashed(po.extendParams.text?default(\"depart_name\")?trim)}", dicCode = "${camelToDashed(po.extendParams.store?default(\"id\")?trim)}"'> | |
37 | 38 | <#elseif po.classType=='list' || po.classType=='list_multi' || po.classType=='sel_search' || po.classType=='radio' || po.classType=='checkbox'> |
38 | 39 | <#if po.dictTable?default("")?trim?length gt 1> |
39 | 40 | <#assign list_field_dictCode=', dictTable = "${po.dictTable}", dicText = "${po.dictText}", dicCode = "${po.dictField}"'> |
... | ... |
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/entity/[1-n]Entity.javai
1 | +<#include "/common/utils.ftl"> | |
1 | 2 | <#list subTables as subTab> |
2 | 3 | #segment#${subTab.entityName}.java |
3 | 4 | package ${bussiPackage}.${entityPackage}.entity; |
... | ... | @@ -32,9 +33,9 @@ public class ${subTab.entityName} implements Serializable { |
32 | 33 | <#-- 生成字典Code --> |
33 | 34 | <#assign list_field_dictCode=""> |
34 | 35 | <#if po.classType='sel_user'> |
35 | - <#assign list_field_dictCode=', dictTable = "sys_user", dicText = "realname", dicCode = "username"'> | |
36 | + <#assign list_field_dictCode=', dictTable = "sys_user", dicText = "${camelToDashed(po.extendParams.text?default(\"realname\")?trim)}", dicCode = "${camelToDashed(po.extendParams.store?default(\"username\")?trim)}"'> | |
36 | 37 | <#elseif po.classType='sel_depart'> |
37 | - <#assign list_field_dictCode=', dictTable = "sys_depart", dicText = "depart_name", dicCode = "id"'> | |
38 | + <#assign list_field_dictCode=', dictTable = "sys_depart", dicText = "${camelToDashed(po.extendParams.text?default(\"depart_name\")?trim)}", dicCode = "${camelToDashed(po.extendParams.store?default(\"id\")?trim)}"'> | |
38 | 39 | <#elseif po.classType=='list' || po.classType=='list_multi' || po.classType=='sel_search' || po.classType=='radio' || po.classType=='checkbox'> |
39 | 40 | <#if po.dictTable?default("")?trim?length gt 1> |
40 | 41 | <#assign list_field_dictCode=', dictTable = "${po.dictTable}", dicText = "${po.dictText}", dicCode = "${po.dictField}"'> |
... | ... |
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue/${entityName}_menu_insert.sql
0 → 100644
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/${entityName}Form.vuei
... | ... | @@ -39,7 +39,7 @@ |
39 | 39 | @input="popupCallback" |
40 | 40 | <#if po.readonly=='Y'>disabled</#if>/> |
41 | 41 | <#elseif po.classType =='sel_depart'> |
42 | - <j-select-depart v-model="model.${po.fieldName}" multi <#if po.readonly=='Y'>disabled</#if>/> | |
42 | + <j-select-depart v-model="model.${po.fieldName}" :multi="${po.extendParams.multi?default('true')}"<#if po.extendParams.store?default("")?trim?length gt 0> store="${po.extendParams.store}"</#if><#if po.extendParams.text?default("")?trim?length gt 0> text="${po.extendParams.text}"</#if> <#if po.readonly=='Y'>disabled</#if> /> | |
43 | 43 | <#elseif po.classType =='switch'> |
44 | 44 | <j-switch v-model="model.${po.fieldName}" <#if po.dictField!= 'is_open'>:options="${po.dictField}"</#if> <#if po.readonly=='Y'>disabled</#if>></j-switch> |
45 | 45 | <#elseif po.classType =='pca'> |
... | ... | @@ -49,7 +49,7 @@ |
49 | 49 | <#elseif po.classType =='password'> |
50 | 50 | <a-input-password v-model="model.${po.fieldName}" placeholder="请输入${po.filedComment}" <#if po.readonly=='Y'>disabled</#if>/> |
51 | 51 | <#elseif po.classType =='sel_user'> |
52 | - <j-select-user-by-dep v-model="model.${po.fieldName}" <#if po.readonly=='Y'>disabled</#if>/> | |
52 | + <j-select-user-by-dep v-model="model.${po.fieldName}" :multi="${po.extendParams.multi?default('true')}"<#if po.extendParams.store?default("")?trim?length gt 0> store="${po.extendParams.store}"</#if><#if po.extendParams.text?default("")?trim?length gt 0> text="${po.extendParams.text}"</#if> <#if po.readonly=='Y'>disabled</#if>/> | |
53 | 53 | <#elseif po.classType =='textarea'> |
54 | 54 | <a-textarea v-model="model.${autoStringSuffixForModel(po)}" rows="4" placeholder="请输入${po.filedComment}" <#if po.readonly=='Y'>disabled</#if>/> |
55 | 55 | <#elseif po.classType=='list' || po.classType=='radio'> |
... | ... |
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue/modules/[1-n]Form.vuei
... | ... | @@ -44,7 +44,7 @@ |
44 | 44 | :multi="${po.extendParams.popupMulti?c}" |
45 | 45 | @input="popupCallback"/> |
46 | 46 | <#elseif po.classType =='sel_depart'> |
47 | - <j-select-depart v-model="model.${po.fieldName}" multi/> | |
47 | + <j-select-depart v-model="model.${po.fieldName}" :multi="${po.extendParams.multi?default('true')}"<#if po.extendParams.store?default("")?trim?length gt 0> store="${po.extendParams.store}"</#if><#if po.extendParams.text?default("")?trim?length gt 0> text="${po.extendParams.text}"</#if> <#if po.readonly=='Y'>disabled</#if> /> | |
48 | 48 | <#elseif po.classType =='switch'> |
49 | 49 | <j-switch v-model="model.${po.fieldName}" <#if po.dictField!= 'is_open'>:options="${po.dictField}"</#if>></j-switch> |
50 | 50 | <#elseif po.classType =='pca'> |
... | ... | @@ -54,7 +54,7 @@ |
54 | 54 | <#elseif po.classType =='password'> |
55 | 55 | <a-input-password v-model="model.${po.fieldName}" placeholder="请输入${po.filedComment}"/> |
56 | 56 | <#elseif po.classType =='sel_user'> |
57 | - <j-select-user-by-dep v-model="model.${po.fieldName}"/> | |
57 | + <j-select-user-by-dep v-model="model.${po.fieldName}" :multi="${po.extendParams.multi?default('true')}"<#if po.extendParams.store?default("")?trim?length gt 0> store="${po.extendParams.store}"</#if><#if po.extendParams.text?default("")?trim?length gt 0> text="${po.extendParams.text}"</#if> <#if po.readonly=='Y'>disabled</#if>/> | |
58 | 58 | <#elseif po.classType =='textarea'> |
59 | 59 | <a-textarea v-model="model.${autoStringSuffixForModel(po)}" rows="4" placeholder="请输入${po.filedComment}"/> |
60 | 60 | <#elseif po.classType=='list' || po.classType=='radio'> |
... | ... |
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}List.vuei
... | ... | @@ -46,6 +46,10 @@ |
46 | 46 | <template #htmlSlot="{text}"> |
47 | 47 | <div v-html="text"></div> |
48 | 48 | </template> |
49 | + <!--省市区字段回显插槽--> | |
50 | + <template #pcaSlot="{text}"> | |
51 | + {{ getAreaTextByCode(text) }} | |
52 | + </template> | |
49 | 53 | <template #fileSlot="{text}"> |
50 | 54 | <span v-if="!text" style="font-size: 12px;font-style: italic;">无文件</span> |
51 | 55 | <a-button v-else :ghost="true" type="primary" preIcon="ant-design:download-outlined" size="small" @click="downloadFile(text)">下载</a-button> |
... | ... | @@ -64,6 +68,10 @@ |
64 | 68 | import ${entityName}Modal from './components/${entityName}Modal.vue' |
65 | 69 | import {columns, searchFormSchema} from './${entityName}.data'; |
66 | 70 | import {list, deleteOne, batchDelete, getImportUrl,getExportUrl} from './${entityName}.api'; |
71 | + import {downloadFile} from '/@/utils/common/renderUtils'; | |
72 | +<#if list_need_pca> | |
73 | + import { getAreaTextByCode } from '/@/components/Form/src/utils/Area'; | |
74 | +</#if> | |
67 | 75 | <#if list_need_category> |
68 | 76 | import { loadCategoryData } from '/@/api/common/api' |
69 | 77 | import { getAuthCache, setAuthCache } from '/@/utils/auth'; |
... | ... | @@ -84,6 +92,17 @@ |
84 | 92 | schemas: searchFormSchema, |
85 | 93 | autoSubmitOnEnter:true, |
86 | 94 | showAdvancedButton:true, |
95 | + fieldMapToNumber: [ | |
96 | + <#list columns as po> | |
97 | + <#if po.isQuery=='Y'> | |
98 | + <#if po.queryMode!='single'> | |
99 | + <#if po.fieldDbType=='int' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'> | |
100 | + ['${po.fieldName}', ['${po.fieldName}_begin', '${po.fieldName}_end']], | |
101 | + </#if> | |
102 | + </#if> | |
103 | + </#if> | |
104 | + </#list> | |
105 | + ], | |
87 | 106 | fieldMapToTime: [ |
88 | 107 | <#list columns as po> |
89 | 108 | <#if po.isQuery=='Y'> |
... | ... | @@ -98,9 +117,10 @@ |
98 | 117 | </#list> |
99 | 118 | ], |
100 | 119 | }, |
101 | - actionColumn: { | |
120 | + actionColumn: { | |
102 | 121 | width: 120, |
103 | - }, | |
122 | + fixed:'right' | |
123 | + }, | |
104 | 124 | }, |
105 | 125 | exportConfig: { |
106 | 126 | name:"${tableVo.ftlDescription}", |
... | ... |
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__data.tsi
1 | +<#include "/common/utils.ftl"> | |
1 | 2 | import {BasicColumn} from '/@/components/Table'; |
2 | 3 | import {FormSchema} from '/@/components/Table'; |
3 | 4 | import { rules} from '/@/utils/helper/validator'; |
... | ... | @@ -25,7 +26,7 @@ export const columns: BasicColumn[] = [ |
25 | 26 | slots: { customRender: 'htmlSlot' }, |
26 | 27 | <#elseif po.classType=='pca'> |
27 | 28 | dataIndex: '${po.fieldName}', |
28 | - slots: { customRender: 'pcaSlot' },//TODO 未翻译 | |
29 | + slots: { customRender: 'pcaSlot' }, | |
29 | 30 | <#elseif po.classType=='file'> |
30 | 31 | dataIndex: '${po.fieldName}', |
31 | 32 | slots: { customRender: 'fileSlot' }, |
... | ... | @@ -57,7 +58,7 @@ export const columns: BasicColumn[] = [ |
57 | 58 | return render.renderCategoryTree(text,'${po.dictField?default("")}') |
58 | 59 | }, |
59 | 60 | <#else> |
60 | - customRender: (text, record) => (text ? record['${po.dictText}'] : '') | |
61 | + customRender: ({text, record}) => (text ? record['${po.dictText}'] : '') | |
61 | 62 | </#if> |
62 | 63 | <#else> |
63 | 64 | dataIndex: '${po.fieldName}' |
... | ... | @@ -95,16 +96,22 @@ export const searchFormSchema: FormSchema[] = [ |
95 | 96 | <#elseif po.classType=='switch'> |
96 | 97 | component: 'JSwitch', |
97 | 98 | componentProps:{ |
99 | + query:true, | |
98 | 100 | <#if po.dictField != 'is_open'> |
99 | - options:"${po.dictField}" | |
101 | + options:${po.dictField} | |
100 | 102 | </#if> |
101 | 103 | }, |
102 | 104 | <#elseif po.classType=='sel_depart'> |
103 | 105 | component: 'JSelectDept', |
104 | 106 | <#elseif po.classType=='list_multi'> |
105 | - component: 'JMultiSelectTag',//暂无该组件 | |
107 | + component: 'JSelectMultiple', | |
106 | 108 | componentProps:{ |
107 | - dictCode:"query_field_dictCode?default("")" | |
109 | + <#if po.dictTable?default("")?trim?length gt 1> | |
110 | + dictCode:"${po.dictTable},${po.dictText},${po.dictField}", | |
111 | + <#elseif po.dictField?default("")?trim?length gt 1> | |
112 | + dictCode:"${po.dictField}", | |
113 | + </#if> | |
114 | + triggerChange: true | |
108 | 115 | }, |
109 | 116 | <#elseif po.classType=='cat_tree'> |
110 | 117 | component: 'JCategorySelect', |
... | ... | @@ -121,16 +128,7 @@ export const searchFormSchema: FormSchema[] = [ |
121 | 128 | <#elseif po.classType=='pca'> |
122 | 129 | component: 'JAreaLinkage', |
123 | 130 | <#elseif po.classType=='popup'> |
124 | - component: 'JPopup', | |
125 | - componentProps: ({ formActionType }) => { | |
126 | - const {setFieldsValue} = formActionType; | |
127 | - return{ | |
128 | - setFieldsValue:setFieldsValue, | |
129 | - code:"${po.dictTable}", | |
130 | - fieldConfig:"${po.dictField}", | |
131 | - multi:${po.extendParams.popupMulti?c}, | |
132 | - } | |
133 | - }, | |
131 | + <#include "/common/form/vue3popup.ftl"> | |
134 | 132 | <#elseif po.classType=='list' || po.classType=='radio' || po.classType=='checkbox'> |
135 | 133 | <#-- ---------------------------下拉或是单选 判断数据字典是表字典还是普通字典------------------------------- --> |
136 | 134 | component: 'JDictSelectTag', |
... | ... | @@ -157,6 +155,8 @@ export const searchFormSchema: FormSchema[] = [ |
157 | 155 | componentProps: { |
158 | 156 | showTime:true |
159 | 157 | }, |
158 | +<#elseif po.fieldDbType=='int' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'> | |
159 | + component: 'JRangeNumber', | |
160 | 160 | <#else> |
161 | 161 | component: 'Input', //TODO 范围查询 |
162 | 162 | </#if> |
... | ... | @@ -189,27 +189,19 @@ export const formSchema: FormSchema[] = [ |
189 | 189 | </#if> |
190 | 190 | { |
191 | 191 | label: '${po.filedComment}', |
192 | - field: '${po.fieldName}', | |
192 | + field: ${autoStringSuffix(po)}, | |
193 | 193 | <#if po.classType =='date'> |
194 | 194 | component: 'DatePicker', |
195 | - <#elseif po.fieldType =='datetime'> | |
195 | + <#elseif po.classType =='datetime'> | |
196 | 196 | component: 'DatePicker', |
197 | 197 | componentProps: { |
198 | - showTime:true | |
198 | + showTime:true, | |
199 | + valueFormat: 'YYYY-MM-DD HH:mm:ss' | |
199 | 200 | }, |
200 | - <#elseif po.fieldType =='time'> | |
201 | + <#elseif po.classType =='time'> | |
201 | 202 | component: 'TimePicker', |
202 | 203 | <#elseif po.classType =='popup'> |
203 | - component: 'JPopup', | |
204 | - componentProps: ({ formActionType }) => { | |
205 | - const {setFieldsValue} = formActionType; | |
206 | - return{ | |
207 | - setFieldsValue:setFieldsValue, | |
208 | - code:"${po.dictTable}", | |
209 | - fieldConfig:${po.dictField}, | |
210 | - multi:${po.extendParams.popupMulti?c}, | |
211 | - } | |
212 | - }, | |
204 | + <#include "/common/form/vue3popup.ftl"> | |
213 | 205 | <#elseif po.classType =='sel_depart'> |
214 | 206 | component: 'JSelectDept', |
215 | 207 | <#elseif po.classType =='switch'> |
... | ... | @@ -231,14 +223,14 @@ export const formSchema: FormSchema[] = [ |
231 | 223 | labelKey:'realname', |
232 | 224 | }, |
233 | 225 | <#elseif po.classType =='textarea'> |
234 | - component: 'InputTextArea',//TODO 注意string转换问题 | |
226 | + component: 'InputTextArea', | |
235 | 227 | <#elseif po.classType=='list' || po.classType=='radio'> |
236 | 228 | component: 'JDictSelectTag', |
237 | 229 | componentProps:{ |
238 | 230 | dictCode:"${form_field_dictCode}" |
239 | 231 | }, |
240 | 232 | <#elseif po.classType=='list_multi' || po.classType=='checkbox'> |
241 | - component: 'JMultiSelectTag',//TODO 暂无该组件 | |
233 | + component: 'JSelectMultiple', | |
242 | 234 | componentProps:{ |
243 | 235 | dictCode:"${form_field_dictCode}" |
244 | 236 | }, |
... | ... | @@ -273,7 +265,7 @@ export const formSchema: FormSchema[] = [ |
273 | 265 | </#if> |
274 | 266 | }, |
275 | 267 | <#elseif po.classType=='umeditor'> |
276 | - component: 'JCodeEditor', //TODO String后缀暂未添加 | |
268 | + component: 'JEditor', | |
277 | 269 | <#elseif po.classType == 'sel_tree'> |
278 | 270 | component: 'JTreeSelect', |
279 | 271 | componentProps:{ |
... | ... | @@ -305,16 +297,16 @@ export const formSchema: FormSchema[] = [ |
305 | 297 | </#if> |
306 | 298 | <#-- 唯一校验 --> |
307 | 299 | <#if fieldValidType == 'only'> |
308 | - {...rules.duplicateCheckRule(<#if sub?default("")?trim?length gt 1>'${sub.tableName}'<#else>'${tableName}'</#if>, '${po.fieldDbName}',model,schema,true)[0]}, | |
300 | + {...rules.duplicateCheckRule(<#if sub?default("")?trim?length gt 1>'${sub.tableName}'<#else>'${tableName}'</#if>, '${po.fieldDbName}',model,schema)[0]}, | |
309 | 301 | <#-- 6到16位数字 --> |
310 | 302 | <#elseif fieldValidType == 'n6-16'> |
311 | 303 | { pattern: /^\d{6,16}$/, message: '请输入6到16位数字!'}, |
312 | 304 | <#-- 6到16位任意字符 --> |
313 | 305 | <#elseif fieldValidType == '*6-16'> |
314 | 306 | { pattern: /^.{6,16}$/, message: '请输入6到16位任意字符!'}, |
315 | - <#-- 6到18位字符串 --> | |
307 | + <#-- 6到18位字母 --> | |
316 | 308 | <#elseif fieldValidType == 's6-18'> |
317 | - { pattern: /^.{6,18}$/, message: '请输入6到18位任意字符!'}, | |
309 | + { pattern: /^[a-z|A-Z]{6,18}$/, message: '请输入6到18位字母!'}, | |
318 | 310 | <#-- 网址 --> |
319 | 311 | <#elseif fieldValidType == 'url'> |
320 | 312 | { pattern: /^((ht|f)tps?):\/\/[\w\-]+(\.[\w\-]+)+([\w\-.,@?^=%&:\/~+#]*[\w\-@?^=%&\/~+#])?$/, message: '请输入正确的网址!'}, |
... | ... | @@ -373,10 +365,14 @@ export const ${sub.entityName?uncap_first}FormSchema: FormSchema[] = [ |
373 | 365 | <#assign form_cat_tree = false> |
374 | 366 | <#assign form_cat_back = ""> |
375 | 367 | <#assign bpm_flag=false> |
368 | +<#assign sub_id_exists = false> | |
376 | 369 | <#list sub.colums as po><#rt/> |
377 | 370 | <#if po.fieldDbName=='bpm_status'> |
378 | 371 | <#assign bpm_flag=true> |
379 | 372 | </#if> |
373 | +<#if po.fieldDbName == 'id'> | |
374 | + <#assign sub_id_exists = true> | |
375 | +</#if> | |
380 | 376 | <#if po.isShow =='Y'> |
381 | 377 | <#assign form_field_dictCode=""> |
382 | 378 | <#if po.dictTable?default("")?trim?length gt 1 && po.dictText?default("")?trim?length gt 1 && po.dictField?default("")?trim?length gt 1> |
... | ... | @@ -386,27 +382,19 @@ export const ${sub.entityName?uncap_first}FormSchema: FormSchema[] = [ |
386 | 382 | </#if> |
387 | 383 | { |
388 | 384 | label: '${po.filedComment}', |
389 | - field: '${po.fieldName}', | |
385 | + field: ${autoStringSuffix(po)}, | |
390 | 386 | <#if po.classType =='date'> |
391 | 387 | component: 'DatePicker', |
392 | - <#elseif po.fieldType =='datetime'> | |
388 | + <#elseif po.classType =='datetime'> | |
393 | 389 | component: 'DatePicker', |
394 | 390 | componentProps: { |
395 | - showTime:true | |
391 | + showTime:true, | |
392 | + valueFormat: 'YYYY-MM-DD HH:mm:ss' | |
396 | 393 | }, |
397 | - <#elseif po.fieldType =='time'> | |
394 | + <#elseif po.classType =='time'> | |
398 | 395 | component: 'TimePicker', |
399 | 396 | <#elseif po.classType =='popup'> |
400 | - component: 'JPopup', | |
401 | - componentProps: ({ formActionType }) => { | |
402 | - const {setFieldsValue} = formActionType; | |
403 | - return{ | |
404 | - setFieldsValue:setFieldsValue, | |
405 | - code:"${po.dictTable}", | |
406 | - fieldConfig:${po.dictField}, | |
407 | - multi:${po.extendParams.popupMulti?c}, | |
408 | - } | |
409 | - }, | |
397 | + <#include "/common/form/vue3popup.ftl"> | |
410 | 398 | <#elseif po.classType =='sel_depart'> |
411 | 399 | component: 'JSelectDept', |
412 | 400 | <#elseif po.classType =='switch'> |
... | ... | @@ -428,14 +416,14 @@ export const ${sub.entityName?uncap_first}FormSchema: FormSchema[] = [ |
428 | 416 | labelKey:'realname', |
429 | 417 | }, |
430 | 418 | <#elseif po.classType =='textarea'> |
431 | - component: 'InputTextArea',//TODO 注意string转换问题 | |
419 | + component: 'InputTextArea', | |
432 | 420 | <#elseif po.classType=='list' || po.classType=='radio'> |
433 | 421 | component: 'JDictSelectTag', |
434 | 422 | componentProps:{ |
435 | 423 | dictCode:"${form_field_dictCode}" |
436 | 424 | }, |
437 | 425 | <#elseif po.classType=='list_multi' || po.classType=='checkbox'> |
438 | - component: 'JMultiSelectTag',//TODO 暂无该组件 | |
426 | + component: 'JSelectMultiple', | |
439 | 427 | componentProps:{ |
440 | 428 | dictCode:"${form_field_dictCode}" |
441 | 429 | }, |
... | ... | @@ -470,7 +458,7 @@ export const ${sub.entityName?uncap_first}FormSchema: FormSchema[] = [ |
470 | 458 | </#if> |
471 | 459 | }, |
472 | 460 | <#elseif po.classType=='umeditor'> |
473 | - component: 'JCodeEditor', //TODO String后缀暂未添加 | |
461 | + component: 'JEditor', | |
474 | 462 | <#elseif po.classType == 'sel_tree'> |
475 | 463 | component: 'JTreeSelect', |
476 | 464 | componentProps:{ |
... | ... | @@ -502,16 +490,16 @@ export const ${sub.entityName?uncap_first}FormSchema: FormSchema[] = [ |
502 | 490 | </#if> |
503 | 491 | <#-- 唯一校验 --> |
504 | 492 | <#if fieldValidType == 'only'> |
505 | - {...rules.duplicateCheckRule(<#if sub?default("")?trim?length gt 1>'${sub.tableName}'<#else>'${tableName}'</#if>, '${po.fieldDbName}',model,schema,true)[0]}, | |
493 | + {...rules.duplicateCheckRule(<#if sub?default("")?trim?length gt 1>'${sub.tableName}'<#else>'${tableName}'</#if>, '${po.fieldDbName}',model,schema)[0]}, | |
506 | 494 | <#-- 6到16位数字 --> |
507 | 495 | <#elseif fieldValidType == 'n6-16'> |
508 | 496 | { pattern: /^\d{6,16}$/, message: '请输入6到16位数字!'}, |
509 | 497 | <#-- 6到16位任意字符 --> |
510 | 498 | <#elseif fieldValidType == '*6-16'> |
511 | 499 | { pattern: /^.{6,16}$/, message: '请输入6到16位任意字符!'}, |
512 | - <#-- 6到18位字符串 --> | |
500 | + <#-- 6到18位字母 --> | |
513 | 501 | <#elseif fieldValidType == 's6-18'> |
514 | - { pattern: /^.{6,18}$/, message: '请输入6到18位任意字符!'}, | |
502 | + { pattern: /^[a-z|A-Z]{6,18}$/, message: '请输入6到18位字母!'}, | |
515 | 503 | <#-- 网址 --> |
516 | 504 | <#elseif fieldValidType == 'url'> |
517 | 505 | { pattern: /^((ht|f)tps?):\/\/[\w\-]+(\.[\w\-]+)+([\w\-.,@?^=%&:\/~+#]*[\w\-@?^=%&\/~+#])?$/, message: '请输入正确的网址!'}, |
... | ... | @@ -553,6 +541,14 @@ export const ${sub.entityName?uncap_first}FormSchema: FormSchema[] = [ |
553 | 541 | }, |
554 | 542 | </#if> |
555 | 543 | </#list> |
544 | +<#if sub_id_exists == false> | |
545 | + { | |
546 | + label: '', | |
547 | + field: 'id', | |
548 | + component: 'Input', | |
549 | + show: false | |
550 | + }, | |
551 | +</#if> | |
556 | 552 | ]; |
557 | 553 | </#if> |
558 | 554 | </#list> |
... | ... | @@ -579,12 +575,20 @@ export const ${sub.entityName?uncap_first}Columns: JVxeColumn[] = [ |
579 | 575 | <#if col.readonly=='Y'> |
580 | 576 | disabled:true, |
581 | 577 | </#if> |
578 | +<#elseif col.classType =='time'> | |
579 | + type: JVxeTypes.time, | |
580 | + <#if col.readonly=='Y'> | |
581 | + disabled:true, | |
582 | + </#if> | |
582 | 583 | <#elseif col.classType =='textarea'> |
583 | 584 | type: JVxeTypes.textarea, |
584 | 585 | <#if col.readonly=='Y'> |
585 | 586 | disabled:true, |
586 | 587 | </#if> |
587 | -<#elseif "int,decimal,double,"?contains(col.classType)> | |
588 | +<#-- update-begin-author:taoyan date:20220523 for: VUEN-1084 【vue3】online表单测试发现的新问题 20、一对多列字段类型生成的不对,数字或者金额类型 --> | |
589 | +<#-- elseif "int,decimal,double,"?contains(col.classType) --> | |
590 | +<#elseif col.fieldDbType=='int' || col.fieldDbType=='double' || col.fieldDbType=='BigDecimal'> | |
591 | +<#-- update-end-author:taoyan date:20220523 for: VUEN-1084 【vue3】online表单测试发现的新问题 20、一对多列字段类型生成的不对,数字或者金额类型 --> | |
588 | 592 | type: JVxeTypes.inputNumber, |
589 | 593 | <#if col.readonly=='Y'> |
590 | 594 | disabled:true, |
... | ... | @@ -621,6 +625,16 @@ export const ${sub.entityName?uncap_first}Columns: JVxeColumn[] = [ |
621 | 625 | <#if col.readonly=='Y'> |
622 | 626 | disabled:true, |
623 | 627 | </#if> |
628 | +<#elseif col.classType =='sel_depart'> | |
629 | + type: JVxeTypes.departSelect, | |
630 | + <#if col.readonly=='Y'> | |
631 | + disabled:true, | |
632 | + </#if> | |
633 | +<#elseif col.classType =='sel_user'> | |
634 | + type: JVxeTypes.userSelect, | |
635 | + <#if col.readonly=='Y'> | |
636 | + disabled:true, | |
637 | + </#if> | |
624 | 638 | <#elseif col.classType =='image'> |
625 | 639 | type: JVxeTypes.image, |
626 | 640 | token:true, |
... | ... | @@ -644,9 +658,9 @@ export const ${sub.entityName?uncap_first}Columns: JVxeColumn[] = [ |
644 | 658 | <#elseif col.classType =='switch'> |
645 | 659 | type: JVxeTypes.checkbox, |
646 | 660 | <#if col.dictField == 'is_open'> |
647 | - customValue: ['Y', 'N'], | |
661 | + customValue: ['Y', 'N'], | |
648 | 662 | <#else> |
649 | - customValue: ${col.dictField}, | |
663 | + customValue: ${col.dictField}, | |
650 | 664 | </#if> |
651 | 665 | <#if col.readonly=='Y'> |
652 | 666 | disabled:true, |
... | ... | @@ -657,14 +671,7 @@ export const ${sub.entityName?uncap_first}Columns: JVxeColumn[] = [ |
657 | 671 | <#else> |
658 | 672 | <#assign popupBackFields = "${col.dictText}"> |
659 | 673 | </#if> |
660 | - type: JVxeTypes.popup, | |
661 | - popupCode:"${col.dictTable}", | |
662 | - field:"${col.dictField}", | |
663 | - orgFields:"${col.dictField}", | |
664 | - destFields:"${Format.underlineToHump(col.dictText)}", | |
665 | - <#if col.readonly=='Y'> | |
666 | - disabled:true, | |
667 | - </#if> | |
674 | + <#include "/common/form/vue3Jvxepopup.ftl"> | |
668 | 675 | <#else> |
669 | 676 | type: JVxeTypes.input, |
670 | 677 | <#if col.readonly=='Y'> |
... | ... | @@ -691,18 +698,7 @@ export const ${sub.entityName?uncap_first}Columns: JVxeColumn[] = [ |
691 | 698 | defaultValue:'', |
692 | 699 | </#if> |
693 | 700 | <#-- 子表的校验 --> |
694 | -<#assign subFieldValidType = col.fieldValidType!''> | |
695 | -<#-- 非空校验 --> | |
696 | -<#if col.nullable == 'N' || subFieldValidType == '*'> | |
697 | - validateRules: [{ required: true, message: '${'$'}{title}不能为空' }], | |
698 | -<#-- 其他情况下,只要有值就被认为是正则校验 --> | |
699 | -<#elseif subFieldValidType?length gt 0> | |
700 | -<#assign subMessage = '格式不正确'> | |
701 | -<#if subFieldValidType == 'only' > | |
702 | - <#assign subMessage = '不能重复'> | |
703 | -</#if> | |
704 | - validateRules: [{ pattern: "${subFieldValidType}", message: "${'$'}{title}${subMessage}" }], | |
705 | -</#if> | |
701 | + <#include "/common/validatorRulesTemplate/sub-vue3.ftl"> | |
706 | 702 | }, |
707 | 703 | </#if> |
708 | 704 | </#if> |
... | ... |
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}_menu_insert.sql
0 → 100644
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue3/components/${entityName}Modal.vuei
1 | +<#include "/common/utils.ftl"> | |
1 | 2 | <template> |
2 | - <BasicModal v-bind="$attrs" @register="registerModal" :title="title" @ok="handleSubmit"> | |
3 | + <BasicModal ref="modalRef" destroyOnClose wrapClassName="j-cgform-tab-modal" v-bind="$attrs" @register="registerModal" :width="${getModalWidth(tableVo.fieldRowNum?default(1))}" @ok="handleSubmit"> | |
3 | 4 | <!-- 子表单区域 --> |
4 | 5 | <a-tabs v-model:activeKey="activeKey" @change="handleChangeTabs"> |
5 | 6 | <!--主表区域 --> |
6 | - <a-tab-pane tab="${tableVo.ftlDescription}" :key="refKeys[0]" :forceRender="true"> | |
7 | + <a-tab-pane tab="${tableVo.ftlDescription}" :key="refKeys[0]" :forceRender="true" :style="tabsStyle"> | |
7 | 8 | <BasicForm @register="registerForm" ref="formRef"/> |
8 | 9 | </a-tab-pane> |
9 | 10 | <!--子表单区域 --> |
10 | 11 | <#list subTables as sub><#rt/> |
11 | 12 | <#assign refKey = sub.entityName?uncap_first/> |
12 | 13 | <#if sub.foreignRelationType =='1'> |
13 | - <a-tab-pane tab="${sub.ftlDescription}" key="${refKey}" :forceRender="true"> | |
14 | - <${sub.entityName}Form ref="${sub.entityName?uncap_first}Form"></${sub.entityName}Form> | |
14 | + <a-tab-pane tab="${sub.ftlDescription}" key="${refKey}" :forceRender="true" :style="tabsStyle"> | |
15 | + <${sub.entityName}Form ref="${sub.entityName?uncap_first}Form" :disabled="formDisabled"></${sub.entityName}Form> | |
15 | 16 | </a-tab-pane> |
16 | 17 | |
17 | 18 | <#else> |
18 | - <a-tab-pane tab="${sub.ftlDescription}" key="${refKey}" :forceRender="true"> | |
19 | + <a-tab-pane tab="${sub.ftlDescription}" key="${refKey}" :forceRender="true" :style="tabsStyle"> | |
19 | 20 | <JVxeTable |
20 | 21 | keep-source |
21 | 22 | resizable |
... | ... | @@ -23,7 +24,8 @@ |
23 | 24 | :loading="${sub.entityName?uncap_first}Table.loading" |
24 | 25 | :columns="${sub.entityName?uncap_first}Table.columns" |
25 | 26 | :dataSource="${sub.entityName?uncap_first}Table.dataSource" |
26 | - :maxHeight="300" | |
27 | + :height="340" | |
28 | + :disabled="formDisabled" | |
27 | 29 | :rowNumber="true" |
28 | 30 | :rowSelection="true" |
29 | 31 | :toolbar="true" |
... | ... | @@ -52,6 +54,8 @@ |
52 | 54 | // Emits声明 |
53 | 55 | const emit = defineEmits(['register','success']); |
54 | 56 | const isUpdate = ref(true); |
57 | + const formDisabled = ref(false); | |
58 | + const modalRef = ref(); | |
55 | 59 | const refKeys = ref(['${tableVo.entityName?uncap_first}',<#list subTables as sub>'${sub.entityName?uncap_first}', </#list>]); |
56 | 60 | <#assign hasOne2Many = false> |
57 | 61 | <#assign hasOne2One = false> |
... | ... | @@ -81,6 +85,7 @@ |
81 | 85 | labelWidth: 150, |
82 | 86 | schemas: formSchema, |
83 | 87 | showActionButtonGroup: false, |
88 | + baseColProps: {span: ${getFormSpan(tableVo.fieldRowNum?default(1))}} | |
84 | 89 | }); |
85 | 90 | //表单赋值 |
86 | 91 | const [registerModal, {setModalProps, closeModal}] = useModalInner(async (data) => { |
... | ... | @@ -88,6 +93,7 @@ |
88 | 93 | await reset(); |
89 | 94 | setModalProps({confirmLoading: false,showCancelBtn:data?.showFooter,showOkBtn:data?.showFooter}); |
90 | 95 | isUpdate.value = !!data?.isUpdate; |
96 | + formDisabled.value = !data?.showFooter; | |
91 | 97 | if (unref(isUpdate)) { |
92 | 98 | //表单赋值 |
93 | 99 | await setFieldsValue({ |
... | ... | @@ -109,9 +115,21 @@ |
109 | 115 | }); |
110 | 116 | //方法配置 |
111 | 117 | const [handleChangeTabs,handleSubmit,requestSubTableData,formRef] = useJvxeMethod(requestAddOrEdit,classifyIntoFormData,tableRefs,activeKey,refKeys<#if hasOne2One==true>,validateSubForm</#if>); |
112 | - | |
113 | - //设置标题 | |
114 | - const title = computed(() => (!unref(isUpdate) ? '新增' : '编辑')); | |
118 | + // 弹窗tabs滚动区域的高度 | |
119 | + const tabsStyle = computed(() => { | |
120 | + let height: Nullable<string> = null | |
121 | + let minHeight = '100px' | |
122 | + let maxHeight: Nullable<string> = '500px' | |
123 | + // 弹窗wrapper | |
124 | + let modalWrapperRef = modalRef.value?.modalWrapperRef | |
125 | + if (modalWrapperRef) { | |
126 | + if (modalWrapperRef.fullScreen) { | |
127 | + height = 'calc(' + modalWrapperRef.spinStyle.height + ' - 50px)'; | |
128 | + maxHeight = null | |
129 | + } | |
130 | + } | |
131 | + return {height, minHeight, maxHeight} | |
132 | + }) | |
115 | 133 | |
116 | 134 | async function reset(){ |
117 | 135 | await resetFields(); |
... | ... | @@ -180,5 +198,38 @@ |
180 | 198 | </script> |
181 | 199 | |
182 | 200 | <style lang="less" scoped> |
201 | +/** 时间和数字输入框样式 */ | |
202 | + :deep(.ant-input-number){ | |
203 | + width: 100% | |
204 | + } | |
205 | + | |
206 | + :deep(.ant-calendar-picker){ | |
207 | + width: 100% | |
208 | + } | |
209 | +</style> | |
210 | + | |
211 | +<style lang="less"> | |
212 | +// Online表单Tab风格专属样式 | |
213 | +.j-cgform-tab-modal { | |
214 | + .ant-modal-header { | |
215 | + padding-top: 8px; | |
216 | + padding-bottom: 8px; | |
217 | + border-bottom: none !important; | |
218 | + } | |
219 | + | |
220 | + .ant-modal .ant-modal-body > .scrollbar, | |
221 | + .ant-tabs-nav .ant-tabs-tab { | |
222 | + padding-top: 0; | |
223 | + } | |
224 | + | |
225 | + .ant-tabs-top-bar { | |
226 | + width: calc(100% - 55px); | |
227 | + position: relative; | |
228 | + left: -14px; | |
229 | + } | |
183 | 230 | |
231 | + .ant-tabs .ant-tabs-top-content > .ant-tabs-tabpane { | |
232 | + overflow: hidden auto; | |
233 | + } | |
234 | +} | |
184 | 235 | </style> |
185 | 236 | \ No newline at end of file |
... | ... |
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/tab/onetomany/java/${bussiPackage}/${entityPackage}/vue3/components/[1-n]Form.vuei
1 | +<#include "/common/utils.ftl"> | |
1 | 2 | <#list subTables as sub> |
2 | 3 | <#if sub.foreignRelationType=='1'> |
3 | 4 | #segment#${sub.entityName}Form.vue |
... | ... | @@ -15,11 +16,18 @@ |
15 | 16 | name:"${sub.entityName}Form", |
16 | 17 | components: {BasicForm}, |
17 | 18 | emits:['register'], |
18 | - setup(_,{emit}) { | |
19 | - const [registerForm, {resetFields, setFieldsValue,getFieldsValue,validate}] = useForm({ | |
19 | + props:{ | |
20 | + disabled: { | |
21 | + type: Boolean, | |
22 | + default: false | |
23 | + } | |
24 | + }, | |
25 | + setup(props,{emit}) { | |
26 | + const [registerForm, {setProps, resetFields, setFieldsValue,getFieldsValue,validate}] = useForm({ | |
20 | 27 | labelWidth: 150, |
21 | 28 | schemas: ${sub.entityName?uncap_first}FormSchema, |
22 | 29 | showActionButtonGroup: false, |
30 | + baseColProps: {span: ${getFormSpan(tableVo.fieldRowNum?default(1))}} | |
23 | 31 | }); |
24 | 32 | /** |
25 | 33 | *初始化加载数据 |
... | ... | @@ -30,12 +38,19 @@ |
30 | 38 | res.success && setFieldsValue({...res.result[0]}); |
31 | 39 | }) |
32 | 40 | } |
41 | + setProps({disabled: props.disabled}) | |
33 | 42 | } |
34 | 43 | /** |
35 | 44 | *获取表单数据 |
36 | 45 | */ |
37 | 46 | function getFormData(){ |
38 | - return [getFieldsValue()]; | |
47 | + let formData = getFieldsValue(); | |
48 | + Object.keys(formData).map(k=>{ | |
49 | + if(formData[k] instanceof Array){ | |
50 | + formData[k] = formData[k].join(',') | |
51 | + } | |
52 | + }); | |
53 | + return [formData]; | |
39 | 54 | } |
40 | 55 | /** |
41 | 56 | *表单校验 |
... | ... |
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template/onetomany/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__data.tsi
... | ... | @@ -78,11 +78,11 @@ export const ${sub.entityName?uncap_first}Columns: JVxeColumn[] = [ |
78 | 78 | { |
79 | 79 | title: '${col.filedComment}', |
80 | 80 | key: '${col.fieldName}', |
81 | -<#if col.classType =='date'> | |
81 | +<#if col.fieldType =='date'> | |
82 | 82 | type: JVxeTypes.date, |
83 | -<#elseif col.classType =='datetime'> | |
83 | +<#elseif col.fieldType =='datetime'> | |
84 | 84 | type: JVxeTypes.datetime, |
85 | -<#elseif "int,decimal,double,"?contains(col.classType)> | |
85 | +<#elseif "int,decimal,double,"?contains(col.fieldType)> | |
86 | 86 | type: JVxeTypes.inputNumber, |
87 | 87 | <#else> |
88 | 88 | type: JVxeTypes.input, |
... | ... |
jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template/onetomany2/java/${bussiPackage}/${entityPackage}/vue3/${entityName}__data.tsi
... | ... | @@ -103,7 +103,11 @@ export const ${sub.entityName?uncap_first}FormSchema: FormSchema[] = [ |
103 | 103 | <#if po.fieldType =='date'> |
104 | 104 | component: 'DatePicker', |
105 | 105 | <#elseif po.fieldType =='datetime'> |
106 | - component: 'TimePicker', | |
106 | + component: 'DatePicker', | |
107 | + componentProps: { | |
108 | + showTime: true, | |
109 | + valueFormat: 'YYYY-MM-DD hh:mm:ss', | |
110 | + }, | |
107 | 111 | <#elseif "int,decimal,double,"?contains(po.fieldType)> |
108 | 112 | component: 'InputNumber', |
109 | 113 | <#else> |
... | ... |