Commit 7e5256dcd7c88166813492507e9bf7001d893092
1 parent
650f048b
代码生成器升级
1.支持插入菜单sql生成 2.vue3模板大升级 3.提供vue3原生表单模板生成
Showing
98 changed files
with
5297 additions
and
526 deletions
Too many changes to show.
To preserve performance only 68 of 98 files are displayed.
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>(); |
... | ... |