【代码生成器专项优化】

代码生成没有生成前端权限指令v-auth
代码生成支持新组件JPopupDict字典
查询条件范围控件更换美观的效果: 日期范围、数字范围、金额范围等
用户和部门组件,生成代码的时候需要根据Online存储字段和显示字段配置来
原生表单校验不通过,未滚到未通过校验的字段
非原生表单校验不通过,未滚到未通过校验的字段
详情页面触发了校验修复
ERP风格子表操作列没有浮动
页面控件类型为下拉框时,生成的前端vue代码冗余","
代码生成 int类型字段的查询条件,没有渲染成数值输入框
无论是原生erp还是非原生,不选中主表的时候,直接导出子表,发现导出了所有数据
一对多erp,也改成点击行就选中
一对Tab风格样式美化
pull/7021/head
JEECG 2024-07-13 18:08:34 +08:00
parent 0148a0b45e
commit 819555e612
43 changed files with 973 additions and 204 deletions

View File

@ -13,6 +13,9 @@
<#if need_popup>
JPopup,
</#if>
<#if need_popup_dict>
JPopupDict,
</#if>
<#if need_category>
JCategorySelect,
</#if>

View File

@ -9,7 +9,7 @@
<#assign form_field_dictCode="${po.dictField}">
</#if>
<a-col :span="${form_span}">
<a-form-item label="${po.filedComment}" v-bind="validateInfos.${autoStringSuffixForModel(po)}">
<a-form-item label="${po.filedComment}" v-bind="validateInfos.${autoStringSuffixForModel(po)}" id="${formEntityName}-${autoStringSuffixForModel(po)}" name="${autoStringSuffixForModel(po)}">
<#if po.classType =='date'>
<a-date-picker placeholder="请选择${po.filedComment}" <#if po.extendParams?exists && po.extendParams.picker?exists>picker="${po.extendParams.picker}"</#if> v-model:value="formData.${po.fieldName}" value-format="YYYY-MM-DD" style="width: 100%" <#if po.readonly=='Y'>disabled</#if> allow-clear />
<#elseif po.classType =='datetime'>
@ -33,9 +33,18 @@
:multi="${po.extendParams.popupMulti?c}"
:setFieldsValue="setFieldsValue"
<#if po.readonly=='Y'>disabled</#if><#rt> allow-clear />
<#elseif po.classType =='popup_dict'>
<#assign need_popup_dict = true>
<#assign sourceFields = po.dictField?default("")?trim?split(",")/>
<#assign targetFields = po.dictText?default("")?trim?split(",")/>
<j-popup-dict
placeholder="请选择${po.filedComment}"
v-model:value="formData.${po.fieldName}"
dictCode="${po.dictTable},${po.dictText},${po.dictField}"
:multi="${po.extendParams.popupMulti?c}" <#if po.readonly=='Y'>disabled</#if> />
<#elseif po.classType =='sel_depart'>
<#assign need_dept = true>
<j-select-dept v-model:value="formData.${po.fieldName}" :multiple="${po.extendParams.multi?default('true')}" checkStrictly <#if po.readonly=='Y'>disabled</#if> allow-clear />
<j-select-dept v-model:value="formData.${po.fieldName}" <#if po.extendParams?exists && po.extendParams.text?exists>labelKey="${po.extendParams.text}"</#if> <#if po.extendParams?exists && po.extendParams.store?exists>rowKey="${po.extendParams.store}"</#if> <#if po.readonly=='Y'>disabled</#if> :multiple="${po.extendParams.multi?default('true')}" checkStrictly <#if po.readonly=='Y'>disabled</#if> allow-clear />
<#elseif po.classType =='switch'>
<#assign need_switch = true>
<j-switch v-model:value="formData.${po.fieldName}" <#if po.dictField != 'is_open'>:options="${po.dictField}"</#if> <#if po.readonly=='Y'>disabled</#if>></j-switch>
@ -50,7 +59,7 @@
<#elseif po.classType =='sel_user'>
<#assign need_dept_user = true>
<#-- update-begin---author:chenrui ---date:20240102 for[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- -->
<j-select-user v-model:value="formData.${po.fieldName}" <#if po.readonly=='Y'>disabled</#if> allow-clear />
<j-select-user v-model:value="formData.${po.fieldName}" <#if po.extendParams?exists && po.extendParams.text?exists>labelKey="${po.extendParams.text}"</#if> <#if po.extendParams?exists && po.extendParams.store?exists>rowKey="${po.extendParams.store}"</#if> <#if po.readonly=='Y'>disabled</#if> allow-clear />
<#-- update-end---author:chenrui ---date:20240102 for[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- -->
<#elseif po.classType =='textarea'>
<a-textarea v-model:value="formData.${autoStringSuffixForModel(po)}" :rows="4" placeholder="请输入${po.filedComment}" <#if po.readonly=='Y'>disabled</#if>/>

View File

@ -13,6 +13,9 @@
<#if need_popup>
import JPopup from '/@/components/Form/src/jeecg/components/JPopup.vue';
</#if>
<#if need_popup_dict>
import JPopupDict from '/@/components/Form/src/jeecg/components/JPopupDict.vue';
</#if>
<#if need_category>
import JCategorySelect from '/@/components/Form/src/jeecg/components/JCategorySelect.vue';
</#if>
@ -47,4 +50,7 @@
</#if>
<#if need_checkbox>
import JCheckbox from "/@/components/Form/src/jeecg/components/JCheckbox.vue";
</#if>
<#if need_range_number>
import JRangeNumber from "/@/components/Form/src/jeecg/components/JRangeNumber.vue";
</#if>

View File

@ -56,66 +56,41 @@
<#if query_field_no gt 1> </#if>]"
<#if query_field_no gt 1> </#if>:multi="${po.extendParams.popupMulti?c}"
<#if query_field_no gt 1> </#if>:setFieldsValue="setFieldsValue" allow-clear />
<#elseif po.classType=='popup_dict'>
<#if query_field_no gt 1> </#if><j-popup-dict
<#if query_field_no gt 1> </#if>placeholder="请选择${po.filedComment}"
<#if query_field_no gt 1> </#if>v-model:value="queryParam.${po.fieldName}"
<#if query_field_no gt 1> </#if>dictCode="${po.dictTable},${po.dictText},${po.dictField}"
<#if query_field_no gt 1> </#if>:multi="${po.extendParams.popupMulti?c}"
<#if query_field_no gt 1> </#if><#if po.readonly=='Y'>disabled</#if> />
<#elseif po.classType=='list' || po.classType=='radio' || po.classType=='checkbox'>
<#-- ---------------------------下拉或是单选 判断数据字典是表字典还是普通字典------------------------------- -->
<#if po.dictTable?default("")?trim?length gt 1>
<#-- ---------------------------下拉或是单选 判断数据字典是表字典还是普通字典------------------------------- -->
<#if po.dictTable?default("")?trim?length gt 1>
<#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}" allow-clear />
<#elseif po.dictField?default("")?trim?length gt 1>
<#elseif po.dictField?default("")?trim?length gt 1>
<#if query_field_no gt 1> </#if><j-dict-select-tag placeholder="请选择${po.filedComment}" v-model:value="queryParam.${po.fieldName}" dictCode="${po.dictField}" allow-clear />
<#else>
<#else>
<#if query_field_no gt 1> </#if><a-input placeholder="请输入${po.filedComment}" v-model:value="queryParam.${po.fieldName}" allow-clear ></a-input>
</#if>
</#if>
<#elseif po.fieldDbType=='int' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal'>
<#if query_field_no gt 1> </#if><a-input-number placeholder="请输入${po.filedComment}" v-model:value="queryParam.${po.fieldName}"></a-input-number>
<#else>
<#else>
<#if query_field_no gt 1> </#if><a-input placeholder="请输入${po.filedComment}" v-model:value="queryParam.${autoStringSuffixForModel(po)}" allow-clear ></a-input>
</#if>
</#if>
<#if query_field_no gt 1> </#if></a-form-item>
<#if query_field_no gt 1> </#if></a-col>
<#else>
<#if query_field_no gt 1> </#if><a-col :lg="6">
<#if query_field_no gt 1> </#if><a-form-item>
<#if query_field_no gt 1> </#if><template #label><span title="${po.filedComment}"><#if po.filedComment?default("")?trim?length gt 4>${po.filedComment?substring(0,4)}<#else>${po.filedComment}</#if></span></template>
<#if query_field_no gt 1> </#if><a-form-item name="${autoStringSuffixForModel(po)}">
<#if query_field_no gt 1> </#if><template #label><span title="${po.filedComment}"><#if po.filedComment?default("")?trim?length gt 4>${po.filedComment?substring(0,4)}<#else>${po.filedComment}</#if></span></template>
<#if po.classType=='date'>
<#if query_field_no gt 1> </#if><div style="display: flex">
<#if query_field_no gt 1> </#if><a-form-item name="${po.fieldName}_begin" style="margin-bottom: 0;">
<#if query_field_no gt 1> </#if><a-date-picker value-format="YYYY-MM-DD" placeholder="请选择开始日期" <#if po.extendParams?exists && po.extendParams.picker?exists>picker="${po.extendParams.picker}"</#if> v-model:value="queryParam.${po.fieldName}_begin" class="query-group-cust" allow-clear />
<#if query_field_no gt 1> </#if></a-form-item>
<#if query_field_no gt 1> </#if><span class="query-group-split-cust">~</span>
<#if query_field_no gt 1> </#if><a-form-item name="${po.fieldName}_end" style="margin-bottom: 0;">
<#if query_field_no gt 1> </#if><a-date-picker value-format="YYYY-MM-DD" placeholder="请选择结束日期" <#if po.extendParams?exists && po.extendParams.picker?exists>picker="${po.extendParams.picker}"</#if> v-model:value="queryParam.${po.fieldName}_end" class="query-group-cust" allow-clear />
<#if query_field_no gt 1> </#if></a-form-item>
<#if query_field_no gt 1> </#if></div>
<#if query_field_no gt 1> </#if><a-range-picker value-format="YYYY-MM-DD" <#if po.extendParams?exists && po.extendParams.picker?exists>picker="${po.extendParams.picker}"</#if> v-model:value="queryParam.${po.fieldName}" class="query-group-cust"/>
<#elseif po.classType=='time'>
<#if query_field_no gt 1> </#if><div style="display: flex">
<#if query_field_no gt 1> </#if><a-form-item name="${po.fieldName}_begin" style="margin-bottom: 0;">
<#if query_field_no gt 1> </#if><time-picker value-format="HH:mm:ss" placeholder="请选择开始时间" v-model:value="queryParam.${po.fieldName}_begin" class="query-group-cust" allow-clear />
<#if query_field_no gt 1> </#if></a-form-item>
<#if query_field_no gt 1> </#if><span class="query-group-split-cust">~</span>
<#if query_field_no gt 1> </#if><a-form-item name="${po.fieldName}_end" style="margin-bottom: 0;">
<#if query_field_no gt 1> </#if><time-picker value-format="HH:mm:ss" placeholder="请选择结束日期" v-model:value="queryParam.${po.fieldName}_end" class="query-group-cust" allow-clear />
<#if query_field_no gt 1> </#if></a-form-item>
<#if query_field_no gt 1> </#if></div>
<#if query_field_no gt 1> </#if><a-time-range-picker value-format="HH:mm:ss" v-model:value="queryParam.${po.fieldName}" class="query-group-cust" />
<#elseif po.classType=='datetime'>
<#if query_field_no gt 1> </#if><div style="display: flex">
<#if query_field_no gt 1> </#if><a-form-item name="${po.fieldName}_begin" style="margin-bottom: 0;">
<#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" allow-clear />
<#if query_field_no gt 1> </#if></a-form-item>
<#if query_field_no gt 1> </#if><span class="query-group-split-cust">~</span>
<#if query_field_no gt 1> </#if><a-form-item name="${po.fieldName}_end" style="margin-bottom: 0;">
<#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" allow-clear />
<#if query_field_no gt 1> </#if></a-form-item>
<#if query_field_no gt 1> </#if></div>
<#if query_field_no gt 1> </#if><a-range-picker showTime value-format="YYYY-MM-DD HH:mm:ss" v-model:value="queryParam.${po.fieldName}" class="query-group-cust"/>
<#else>
<#if query_field_no gt 1> </#if><div style="display: flex">
<#if query_field_no gt 1> </#if><a-form-item name="${po.fieldName}_begin" style="margin-bottom: 0;">
<#if query_field_no gt 1> </#if><a-input placeholder="请输入最小值" v-model:value="queryParam.${po.fieldName}_begin" class="query-group-cust" allow-clear ></a-input>
<#if query_field_no gt 1> </#if></a-form-item>
<#if query_field_no gt 1> </#if><span class="query-group-left query-group-split-cust">~</span>
<#if query_field_no gt 1> </#if><a-form-item name="${po.fieldName}_end" style="margin-bottom: 0;">
<#if query_field_no gt 1> </#if><a-input placeholder="请输入最大值" v-model:value="queryParam.${po.fieldName}_end" class="query-group-cust" allow-clear ></a-input>
<#if query_field_no gt 1> </#if></a-form-item>
<#if query_field_no gt 1> </#if></div>
<#if query_field_no gt 1> </#if><JRangeNumber v-model:value="queryParam.${po.fieldName}" class="query-group-cust"></JRangeNumber>
</#if>
<#if query_field_no gt 1> </#if></a-form-item>
<#if query_field_no gt 1> </#if></a-col>

View File

@ -149,6 +149,8 @@
<#-- update-begin---author:chenrui ---date:20231228 for:fix 带条件字典存在单引号导致js编译错误---------- -->
<#elseif po.dictField?default("")?trim?length gt 1>
<#assign dictCode="dictCode: '${po.dictField}'">
<#else>
<#assign dictCode="dictCode: ''">
</#if>
<#if po.classType=='list' || po.classType=='list_multi' || po.classType=='sel_search' || po.classType=='checkbox' || po.classType=='radio'>
@ -229,4 +231,19 @@
</#if>
</#if>
<#return flag>
</#function>
<#-- vue3 native 获取范围字段 -->
<#function getRangeField(columns) >
<#assign rangeField = "">
<#list columns as po>
<#if po.isQuery=='Y'>
<#if po.queryMode!='single'>
<#if po.fieldDbType=='int' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal' || po.classType=='time' || po.classType=='date' || po.classType=='datetime'>
<#assign rangeField = rangeField + "${po.fieldName},">
</#if>
</#if>
</#if>
</#list>
<#return rangeField>
</#function>

View File

@ -21,9 +21,9 @@
<BasicTable @register="registerTable" :rowSelection="rowSelection">
<!--插槽:table标题-->
<template #tableTitle>
<a-button type="primary" @click="handleAdd" preIcon="ant-design:plus-outlined"> 新增</a-button>
<a-button type="primary" preIcon="ant-design:export-outlined" @click="onExportXls"> 导出</a-button>
<j-upload-button type="primary" preIcon="ant-design:import-outlined" @click="onImportXls">导入</j-upload-button>
<a-button type="primary" v-auth="'${entityPackage}:${tableName}:add'" @click="handleAdd" preIcon="ant-design:plus-outlined"> 新增</a-button>
<a-button type="primary" v-auth="'${entityPackage}:${tableName}:exportXls'" preIcon="ant-design:export-outlined" @click="onExportXls"> 导出</a-button>
<j-upload-button type="primary" v-auth="'${entityPackage}:${tableName}:importExcel'" preIcon="ant-design:import-outlined" @click="onImportXls">导入</j-upload-button>
<a-dropdown v-if="selectedRowKeys.length > 0">
<template #overlay>
<a-menu>
@ -33,7 +33,7 @@
</a-menu-item>
</a-menu>
</template>
<a-button>批量操作
<a-button v-auth="'${entityPackage}:${tableName}:deleteBatch'">批量操作
<Icon icon="mdi:chevron-down"></Icon>
</a-button>
</a-dropdown>
@ -229,6 +229,7 @@
{
label: '编辑',
onClick: handleEdit.bind(null, record),
auth: '${entityPackage}:${tableName}:edit'
}
]
}
@ -247,7 +248,8 @@
title: '是否确认删除',
confirm: handleDelete.bind(null, record),
placement: 'topLeft',
}
},
auth: '${entityPackage}:${tableName}:delete'
}
];
if(record.bpmStatus == '1'){
@ -272,7 +274,8 @@
title: '是否确认删除',
confirm: handleDelete.bind(null, record),
placement: 'topLeft',
}
},
auth: '${entityPackage}:${tableName}:delete'
}
]
</#if>
@ -318,6 +321,6 @@
</#if>
</script>
<style scoped>
<style lang="less" scoped>
<#include "/common/form/vue3SearchStyle.ftl">
</style>

View File

@ -57,7 +57,7 @@ export const columns: BasicColumn[] = [
customRender:({text}) => {
return render.renderSwitch(text, [{text:'是',value:'${switch_extend_arr1}'},{text:'否',value:'${switch_extend_arr2}'}])
},
<#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'>
<#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' || po.classType=='popup_dict'>
dataIndex: '${po.fieldName}_dictText'
<#elseif po.classType=='cat_tree'>
dataIndex: '${po.fieldName}',
@ -104,6 +104,14 @@ export const searchFormSchema: FormSchema[] = [
<#elseif po.classType=='sel_user'>
<#-- update-begin---author:chenrui ---date:20240102 for[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- -->
component: 'JSelectUser',
componentProps:{
<#if po.extendParams?exists && po.extendParams.text?exists>
labelKey: '${po.extendParams.text}',
</#if>
<#if po.extendParams?exists && po.extendParams.store?exists>
rowKey: '${po.extendParams.store}',
</#if>
},
<#-- update-end---author:chenrui ---date:20240102 for[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- -->
<#elseif po.classType=='switch'>
component: 'JSwitch',
@ -115,6 +123,14 @@ export const searchFormSchema: FormSchema[] = [
},
<#elseif po.classType=='sel_depart'>
component: 'JSelectDept',
componentProps:{
<#if po.extendParams?exists && po.extendParams.text?exists>
labelKey: '${po.extendParams.text}',
</#if>
<#if po.extendParams?exists && po.extendParams.store?exists>
rowKey: '${po.extendParams.store}',
</#if>
},
<#elseif po.classType=='list_multi'>
component: 'JSelectMultiple',
componentProps:{
@ -156,6 +172,13 @@ export const searchFormSchema: FormSchema[] = [
},
<#elseif po.classType=='popup'>
<#include "/common/form/vue3popup.ftl">
<#elseif po.classType=='popup_dict'>
component: 'JPopupDict',
componentProps: {
placeholder: '请选择${po.filedComment}',
dictCode: '${po.dictTable},${po.dictText},${po.dictField}',
multi: ${po.extendParams.popupMulti?c}
},
<#elseif po.classType=='list' || po.classType=='radio' || po.classType=='checkbox'>
<#-- ---------------------------下拉或是单选 判断数据字典是表字典还是普通字典------------------------------- -->
component: 'JDictSelectTag',
@ -276,8 +299,23 @@ export const formSchema: FormSchema[] = [
},
<#elseif po.classType =='popup'>
<#include "/common/form/vue3popup.ftl">
<#elseif po.classType=='popup_dict'>
component: 'JPopupDict',
componentProps: {
placeholder: '请选择${po.filedComment}',
dictCode: '${po.dictTable},${po.dictText},${po.dictField}',
multi: ${po.extendParams.popupMulti?c}
},
<#elseif po.classType =='sel_depart'>
component: 'JSelectDept',
componentProps:{
<#if po.extendParams?exists && po.extendParams.text?exists>
labelKey: '${po.extendParams.text}',
</#if>
<#if po.extendParams?exists && po.extendParams.store?exists>
rowKey: '${po.extendParams.store}',
</#if>
},
<#elseif po.classType =='switch'>
component: 'JSwitch',
componentProps:{
@ -299,8 +337,13 @@ export const formSchema: FormSchema[] = [
component: 'JSelectUser',
<#-- update-end---author:chenrui ---date:20240102 for[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- -->
componentProps:{
labelKey:'realname',
},
<#if po.extendParams?exists && po.extendParams.text?exists>
labelKey: '${po.extendParams.text}',
</#if>
<#if po.extendParams?exists && po.extendParams.store?exists>
rowKey: '${po.extendParams.store}',
</#if>
},
<#elseif po.classType =='textarea'>
component: 'InputTextArea',
<#elseif po.classType=='list'>

View File

@ -1,7 +1,7 @@
<#include "/common/utils.ftl">
<template>
<BasicModal v-bind="$attrs" @register="registerModal" destroyOnClose :title="title" :width="${getModalWidth(tableVo.fieldRowNum?default(1))}" @ok="handleSubmit">
<BasicForm @register="registerForm"/>
<BasicForm @register="registerForm" name="${entityName}Form" />
</BasicModal>
</template>
@ -16,7 +16,7 @@
const isUpdate = ref(true);
const isDetail = ref(false);
//表单配置
const [registerForm, {setProps,resetFields, setFieldsValue, validate}] = useForm({
const [registerForm, { setProps,resetFields, setFieldsValue, validate, scrollToField }] = useForm({
//labelWidth: 150,
schemas: formSchema,
showActionButtonGroup: false,
@ -51,6 +51,14 @@
closeModal();
//刷新列表
emit('success');
} catch ({ errorFields }) {
if (errorFields) {
const firstField = errorFields[0];
if (firstField) {
scrollToField(firstField.name, { behavior: 'smooth', block: 'center' });
}
}
return Promise.reject(errorFields);
} finally {
setModalProps({confirmLoading: false});
}

View File

@ -1,3 +1,4 @@
<#include "/common/utils.ftl">
<template>
<div class="p-2">
<#assign query_field_no=0>
@ -9,6 +10,7 @@
<#assign need_dept = false>
<#assign need_multi = false>
<#assign need_popup = false>
<#assign need_popup_dict = false>
<#assign need_select_tag = false>
<#assign need_select_tree = false>
<#assign need_time = false>
@ -18,6 +20,8 @@
<#assign need_image_upload = false>
<#assign need_editor = false>
<#assign need_checkbox = false>
<#assign need_range_number = false>
<#assign is_range = false>
<#assign query_flag = false>
<!--查询区域-->
<div class="jeecg-basic-table-form-container">
@ -52,11 +56,20 @@
<#if po.classType=='popup'>
<#assign need_popup = true>
</#if>
<#if po.classType=='popup_dict'>
<#assign need_popup_dict = true>
</#if>
<#if po.classType=='sel_tree'>
<#assign need_select_tree = true>
</#if>
<#if po.classType=='time'>
<#assign need_time = true>
</#if>
<#if po.queryMode!='single' && (po.fieldDbType=='int' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal')>
<#assign need_range_number = true>
</#if>
<#if po.queryMode!='single'>
<#assign is_range = true>
</#if>
<#include "/common/form/native/vue3NativeSearch.ftl">
</#list>
@ -85,9 +98,9 @@
<BasicTable @register="registerTable" :rowSelection="rowSelection">
<!--插槽:table标题-->
<template #tableTitle>
<a-button type="primary" @click="handleAdd" preIcon="ant-design:plus-outlined"> 新增</a-button>
<a-button type="primary" preIcon="ant-design:export-outlined" @click="onExportXls"> 导出</a-button>
<j-upload-button type="primary" preIcon="ant-design:import-outlined" @click="onImportXls">导入</j-upload-button>
<a-button type="primary" v-auth="'${entityPackage}:${tableName}:add'" @click="handleAdd" preIcon="ant-design:plus-outlined"> 新增</a-button>
<a-button type="primary" v-auth="'${entityPackage}:${tableName}:exportXls'" preIcon="ant-design:export-outlined" @click="onExportXls"> 导出</a-button>
<j-upload-button type="primary" v-auth="'${entityPackage}:${tableName}:importExcel'" preIcon="ant-design:import-outlined" @click="onImportXls">导入</j-upload-button>
<a-dropdown v-if="selectedRowKeys.length > 0">
<template #overlay>
<a-menu>
@ -97,7 +110,7 @@
</a-menu-item>
</a-menu>
</template>
<a-button>批量操作
<a-button v-auth="'${entityPackage}:${tableName}:deleteBatch'">批量操作
<Icon icon="mdi:chevron-down"></Icon>
</a-button>
</a-dropdown>
@ -158,6 +171,9 @@
<#if bpm_flag==true>
import { startProcess } from '/@/api/common/api';
</#if>
<#if is_range>
import { cloneDeep } from "lodash-es";
</#if>
const formRef = ref();
const queryParam = reactive<any>({});
@ -176,8 +192,13 @@
width: 120,
fixed: 'right',
},
beforeFetch: (params) => {
beforeFetch: async (params) => {
<#if is_range>
let rangerQuery = await setRangeQuery();
return Object.assign(params, rangerQuery);
<#else>
return Object.assign(params, queryParam);
</#if>
},
},
exportConfig: {
@ -270,6 +291,7 @@
{
label: '编辑',
onClick: handleEdit.bind(null, record),
auth: '${entityPackage}:${tableName}:edit'
},
];
}
@ -289,7 +311,8 @@
title: '是否确认删除',
confirm: handleDelete.bind(null, record),
placement: 'topLeft',
}
},
auth: '${entityPackage}:${tableName}:delete'
}
];
if(record.bpmStatus == '1'){
@ -314,7 +337,8 @@
title: '是否确认删除',
confirm: handleDelete.bind(null, record),
placement: 'topLeft',
}
},
auth: '${entityPackage}:${tableName}:delete'
}
]
</#if>
@ -407,6 +431,32 @@
}
initDictConfig();
</#if>
<#if is_range>
let rangeField = '${getRangeField(columns)}'
/**
* 设置范围查询条件
*/
async function setRangeQuery(){
let queryParamClone = cloneDeep(queryParam);
if (rangeField) {
let fieldsValue = rangeField.split(',');
fieldsValue.forEach(item => {
if (queryParamClone[item]) {
let range = queryParamClone[item];
queryParamClone[item+'_begin'] = range[0];
queryParamClone[item+'_end'] = range[1];
delete queryParamClone[item];
} else {
queryParamClone[item+'_begin'] = '';
queryParamClone[item+'_end'] = '';
}
})
}
return queryParamClone;
}
</#if>
</script>
<style lang="less" scoped>

View File

@ -57,7 +57,7 @@ export const columns: BasicColumn[] = [
customRender:({text}) => {
return render.renderSwitch(text, [{text:'是',value:'${switch_extend_arr1}'},{text:'否',value:'${switch_extend_arr2}'}]);
},
<#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'>
<#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' || po.classType=='popup_dict'>
dataIndex: '${po.fieldName}_dictText'
<#elseif po.classType=='cat_tree'>
dataIndex: '${po.fieldName}',

View File

@ -3,7 +3,7 @@
<a-spin :spinning="confirmLoading">
<JFormContainer :disabled="disabled">
<template #detail>
<a-form ref="formRef" class="antd-modal-form" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-form ref="formRef" class="antd-modal-form" :labelCol="labelCol" :wrapperCol="wrapperCol" name="${entityName}Form">
<a-row>
<#assign need_category = false>
<#assign bpm_flag=false>
@ -14,6 +14,7 @@
<#assign need_dept = false>
<#assign need_multi = false>
<#assign need_popup = false>
<#assign need_popup_dict = false>
<#assign need_select_tag = false>
<#assign need_select_tree = false>
<#assign need_time = false>
@ -23,6 +24,7 @@
<#assign need_editor = false>
<#assign need_checkbox = false>
<#assign hasOnlyValidate = false>
<#assign need_range_number = false>
<#assign form_span = 24>
<#if tableVo.fieldRowNum==2>
<#assign form_span = 12>
@ -38,6 +40,7 @@
<#if po.isShow == 'Y' && po.fieldValidType?default("") == 'only'>
<#assign hasOnlyValidate = true>
</#if>
<#assign formEntityName>${entityName}Form</#assign>
<#include "/common/form/native/vue3NativeForm.ftl">
</#list>
<#if bpm_flag>
@ -64,7 +67,10 @@
<#if hasOnlyValidate == true>
import { duplicateValidate } from '/@/utils/helper/validator'
</#if>
<#if bpm_flag>
import { usePermission } from '/@/hooks/web/usePermission';
const { isDisabledAuth, hasPermission, initBpmFormData } = usePermission();
</#if>
const props = defineProps({
formDisabled: { type: Boolean, default: false },
formData: { type: Object, default: () => ({})},
@ -101,6 +107,7 @@
<#if bpm_flag>
onMounted(()=>{
initBpmFormData(props.formData);
initFormData();
});
//渲染流程表单数据
@ -152,8 +159,18 @@
* 提交数据
*/
async function submitForm() {
// 触发表单验证
await validate();
try {
// 触发表单验证
await validate();
} catch ({ errorFields }) {
if (errorFields) {
const firstField = errorFields[0];
if (firstField) {
formRef.value.scrollToField(firstField.name, { behavior: 'smooth', block: 'center' });
}
}
return Promise.reject(errorFields);
}
confirmLoading.value = true;
const isUpdate = ref<boolean>(false);
//时间格式化

View File

@ -26,9 +26,9 @@
<BasicTable @register="registerTable" :rowSelection="rowSelection" :expandedRowKeys="expandedRowKeys" @expand="handleExpand" @fetch-success="onFetchSuccess">
<!--插槽:table标题-->
<template #tableTitle>
<a-button type="primary" @click="handleCreate" preIcon="ant-design:plus-outlined"> 新增</a-button>
<a-button type="primary" preIcon="ant-design:export-outlined" @click="onExportXls"> 导出</a-button>
<j-upload-button type="primary" preIcon="ant-design:import-outlined" @click="onImportXls">导入</j-upload-button>
<a-button type="primary" v-auth="'${entityPackage}:${tableName}:add'" @click="handleCreate" preIcon="ant-design:plus-outlined"> 新增</a-button>
<a-button type="primary" v-auth="'${entityPackage}:${tableName}:exportXls'" preIcon="ant-design:export-outlined" @click="onExportXls"> 导出</a-button>
<j-upload-button type="primary" v-auth="'${entityPackage}:${tableName}:importExcel'" preIcon="ant-design:import-outlined" @click="onImportXls">导入</j-upload-button>
<a-dropdown v-if="selectedRowKeys.length > 0">
<template #overlay>
@ -39,7 +39,7 @@
</a-menu-item>
</a-menu>
</template>
<a-button>批量操作
<a-button v-auth="'${entityPackage}:${tableName}:deleteBatch'">批量操作
<Icon icon="ant-design:down-outlined"></Icon>
</a-button>
</a-dropdown>
@ -371,6 +371,7 @@
{
label: '编辑',
onClick: handleEdit.bind(null, record),
auth: '${entityPackage}:${tableName}:edit'
},
{
label: '添加下级',
@ -392,9 +393,9 @@
popConfirm: {
title: '是否确认删除',
confirm: handleDelete.bind(null, record),
placement: 'topLeft',
}
}
placement: 'topLeft'
},
auth: '${entityPackage}:${tableName}:delete'
];
if(record.bpmStatus == '1' || !record.bpmStatus){
dropDownAction.push({
@ -417,8 +418,9 @@
popConfirm: {
title: '确定删除吗?',
confirm: handleDelete.bind(null, record),
placement: 'topLeft',
}
placement: 'topLeft'
},
auth: '${entityPackage}:${tableName}:delete'
}
]
</#if>
@ -442,6 +444,6 @@
</script>
<style scoped>
<style lang="less" scoped>
<#include "/common/form/vue3SearchStyle.ftl">
</style>

View File

@ -61,7 +61,7 @@ export const columns: BasicColumn[] = [
customRender:({text}) => {
return render.renderSwitch(text, [{text:'是',value:'${switch_extend_arr1}'},{text:'否',value:'${switch_extend_arr2}'}])
},
<#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'>
<#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' || po.classType=='popup_dict'>
dataIndex: '${po.fieldName}_dictText'
<#elseif po.classType=='cat_tree'>
dataIndex: '${po.fieldName}',
@ -109,6 +109,14 @@ export const searchFormSchema: FormSchema[] = [
<#-- update-begin---author:chenrui ---date:20240102 for[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- -->
component: 'JSelectUser',
<#-- update-end---author:chenrui ---date:20240102 for[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- -->
componentProps:{
<#if po.extendParams?exists && po.extendParams.text?exists>
labelKey: '${po.extendParams.text}',
</#if>
<#if po.extendParams?exists && po.extendParams.store?exists>
rowKey: '${po.extendParams.store}',
</#if>
},
<#elseif po.classType=='switch'>
component: 'JSwitch',
componentProps:{
@ -118,6 +126,14 @@ export const searchFormSchema: FormSchema[] = [
},
<#elseif po.classType=='sel_depart'>
component: 'JSelectDept',
componentProps:{
<#if po.extendParams?exists && po.extendParams.text?exists>
labelKey: '${po.extendParams.text}',
</#if>
<#if po.extendParams?exists && po.extendParams.store?exists>
rowKey: '${po.extendParams.store}',
</#if>
},
<#elseif po.classType=='list_multi'>
component: 'JSelectMultiple',
componentProps:{
@ -159,6 +175,13 @@ export const searchFormSchema: FormSchema[] = [
},
<#elseif po.classType=='popup'>
<#include "/common/form/vue3popup.ftl">
<#elseif po.classType=='popup_dict'>
component: 'JPopupDict',
componentProps: {
placeholder: '请选择${po.filedComment}',
dictCode: '${po.dictTable},${po.dictText},${po.dictField}',
multi: ${po.extendParams.popupMulti?c}
},
<#elseif po.classType == 'sel_tree'>
component: 'JTreeSelect',
componentProps:{
@ -294,8 +317,23 @@ export const formSchema: FormSchema[] = [
},
<#elseif po.classType =='popup'>
<#include "/common/form/vue3popup.ftl">
<#elseif po.classType=='popup_dict'>
component: 'JPopupDict',
componentProps: {
placeholder: '请选择${po.filedComment}',
dictCode: '${po.dictTable},${po.dictText},${po.dictField}',
multi: ${po.extendParams.popupMulti?c}
},
<#elseif po.classType =='sel_depart'>
component: 'JSelectDept',
componentProps:{
<#if po.extendParams?exists && po.extendParams.text?exists>
labelKey: '${po.extendParams.text}',
</#if>
<#if po.extendParams?exists && po.extendParams.store?exists>
rowKey: '${po.extendParams.store}',
</#if>
},
<#elseif po.classType =='switch'>
component: 'JSwitch',
componentProps:{
@ -317,8 +355,13 @@ export const formSchema: FormSchema[] = [
component: 'JSelectUser',
<#-- update-end---author:chenrui ---date:20240102 for[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- -->
componentProps:{
labelKey:'realname',
},
<#if po.extendParams?exists && po.extendParams.text?exists>
labelKey: '${po.extendParams.text}',
</#if>
<#if po.extendParams?exists && po.extendParams.store?exists>
rowKey: '${po.extendParams.store}',
</#if>
},
<#elseif po.classType =='textarea'>
component: 'InputTextArea',
<#elseif po.classType=='list'>

View File

@ -11,7 +11,7 @@
</#list>
<template>
<BasicModal v-bind="$attrs" @register="registerModal" destroyOnClose :width="${getModalWidth(tableVo.fieldRowNum?default(1))}" :title="getTitle" @ok="handleSubmit">
<BasicForm @register="registerForm"/>
<BasicForm @register="registerForm" name="${entityName}Form" />
</BasicModal>
</template>
<script lang="ts" setup>
@ -29,7 +29,7 @@
// 当前编辑的数据
let model:Nullable<Recordable> = null;
//表单配置
const [registerForm, {setProps,resetFields, setFieldsValue, validate, updateSchema}] = useForm({
const [registerForm, { setProps,resetFields, setFieldsValue, validate, updateSchema, scrollToField }] = useForm({
schemas: formSchema,
showActionButtonGroup: false,
baseColProps: {span: ${getFormSpan(tableVo.fieldRowNum?default(1))}},
@ -103,6 +103,14 @@
// 是否更改了父级节点
changeParent: model != null && (model['${pidFieldName}'] != values['${pidFieldName}']),
});
} catch ({ errorFields }) {
if (errorFields) {
const firstField = errorFields[0];
if (firstField) {
scrollToField(firstField.name, { behavior: 'smooth', block: 'center' });
}
}
return Promise.reject(errorFields);
} finally {
setModalProps({confirmLoading: false});
}

View File

@ -20,6 +20,7 @@
<#assign need_dept = false>
<#assign need_multi = false>
<#assign need_popup = false>
<#assign need_popup_dict = false>
<#assign need_select_tag = false>
<#assign need_select_tree = false>
<#assign need_time = false>
@ -29,6 +30,8 @@
<#assign need_image_upload = false>
<#assign need_editor = false>
<#assign need_checkbox = false>
<#assign need_range_number = false>
<#assign is_range = false>
<#assign query_flag = false>
<!--查询区域-->
<div class="jeecg-basic-table-form-container">
@ -63,11 +66,20 @@
<#if po.classType=='popup'>
<#assign need_popup = true>
</#if>
<#if po.classType=='popup_dict'>
<#assign need_popup_dict = true>
</#if>
<#if po.classType=='sel_tree'>
<#assign need_select_tree = true>
</#if>
<#if po.classType=='time'>
<#assign need_time = true>
</#if>
<#if po.queryMode!='single' && (po.fieldDbType=='int' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal')>
<#assign need_range_number = true>
</#if>
<#if po.queryMode!='single'>
<#assign is_range = true>
</#if>
<#include "/common/form/native/vue3NativeSearch.ftl">
</#list>
@ -96,7 +108,7 @@
<BasicTable @register="registerTable" :rowSelection="rowSelection" :expandedRowKeys="expandedRowKeys" @expand="handleExpand" @fetch-success="onFetchSuccess">
<!--插槽:table标题-->
<template #tableTitle>
<a-button type="primary" @click="handleAdd" preIcon="ant-design:plus-outlined"> 新增</a-button>
<a-button type="primary" v-auth="'${entityPackage}:${tableName}:add'" @click="handleAdd" preIcon="ant-design:plus-outlined"> 新增</a-button>
<a-dropdown v-if="selectedRowKeys.length > 0">
<template #overlay>
<a-menu>
@ -106,7 +118,7 @@
</a-menu-item>
</a-menu>
</template>
<a-button
<a-button v-auth="'${entityPackage}:${tableName}:deleteBatch'"
>批量操作
<Icon icon="ant-design:down-outlined"></Icon>
</a-button>
@ -164,6 +176,9 @@
</#if>
<#if need_pca>
import { getAreaTextByCode } from '/@/components/Form/src/utils/Area';
</#if>
<#if is_range>
import { cloneDeep } from "lodash-es";
</#if>
<#if bpm_flag==true>
import { startProcess } from '/@/api/common/api';
@ -186,8 +201,13 @@
width: 120,
fixed: 'right',
},
beforeFetch: (params) => {
beforeFetch: async (params) => {
<#if is_range>
let rangerQuery = await setRangeQuery();
return Object.assign(params, rangerQuery);
<#else>
return Object.assign(params, queryParam.value);
</#if>
},
},
exportConfig: {
@ -419,6 +439,7 @@
{
label: '编辑',
onClick: handleEdit.bind(null, record),
auth: '${entityPackage}:${tableName}:edit'
}
];
}
@ -443,8 +464,9 @@
popConfirm: {
title: '确定删除吗?',
confirm: handleDelete.bind(null, record),
placement: 'topLeft',
placement: 'topLeft'
},
auth: '${entityPackage}:${tableName}:delete'
},
];
if(record.bpmStatus == '1' || !record.bpmStatus){
@ -475,6 +497,7 @@
confirm: handleDelete.bind(null, record),
placement: 'topLeft',
},
auth: '${entityPackage}:${tableName}:delete'
},
];
</#if>
@ -569,6 +592,32 @@
}
initDictConfig();
</#if>
<#if is_range>
let rangeField = '${getRangeField(columns)}'
/**
* 设置范围查询条件
*/
async function setRangeQuery(){
let queryParamClone = cloneDeep(queryParam.value);
if (rangeField) {
let fieldsValue = rangeField.split(',');
fieldsValue.forEach(item => {
if (queryParamClone[item]) {
let range = queryParamClone[item];
queryParamClone[item+'_begin'] = range[0];
queryParamClone[item+'_end'] = range[1];
delete queryParamClone[item];
} else {
queryParamClone[item+'_begin'] = '';
queryParamClone[item+'_end'] = '';
}
})
}
return queryParamClone;
}
</#if>
</script>
<style lang="less" scoped>

View File

@ -61,7 +61,7 @@ export const columns: BasicColumn[] = [
customRender:({text}) => {
return render.renderSwitch(text, [{text:'是',value:'${switch_extend_arr1}'},{text:'否',value:'${switch_extend_arr2}'}]);
},
<#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'>
<#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' || po.classType=='popup_dict'>
dataIndex: '${po.fieldName}_dictText'
<#elseif po.classType=='cat_tree'>
dataIndex: '${po.fieldName}',

View File

@ -3,7 +3,7 @@
<a-spin :spinning="confirmLoading">
<JFormContainer :disabled="disabled">
<template #detail>
<a-form ref="formRef" class="antd-modal-form" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-form ref="formRef" class="antd-modal-form" :labelCol="labelCol" :wrapperCol="wrapperCol" name="${entityName}Form">
<a-row>
<#assign need_category = false>
<#assign bpm_flag=false>
@ -14,6 +14,7 @@
<#assign need_dept = false>
<#assign need_multi = false>
<#assign need_popup = false>
<#assign need_popup_dict = false>
<#assign need_select_tag = false>
<#assign need_select_tree = false>
<#assign need_time = false>
@ -22,6 +23,7 @@
<#assign need_image_upload = false>
<#assign need_editor = false>
<#assign need_checkbox = false>
<#assign need_range_number = false>
<#assign pidFieldName = "">
<#assign hasOnlyValidate = false>
<#assign form_span = 24>
@ -56,6 +58,7 @@
</a-form-item>
</a-col>
</#if>
<#assign formEntityName>${entityName}Form</#assign>
<#include "/common/form/native/vue3NativeForm.ftl">
</#list>
<#if bpm_flag>
@ -82,7 +85,10 @@
<#if hasOnlyValidate == true>
import { duplicateValidate } from '/@/utils/helper/validator'
</#if>
<#if bpm_flag>
import { usePermission } from '/@/hooks/web/usePermission';
const { isDisabledAuth, hasPermission, initBpmFormData } = usePermission();
</#if>
const useForm = Form.useForm;
const formRef = ref();
const isUpdate = ref(true);
@ -124,6 +130,7 @@
<#if bpm_flag>
onMounted(()=>{
initBpmFormData(props.formData);
initFormData();
});
//渲染流程表单数据
@ -196,8 +203,18 @@
* 提交数据
*/
async function submitForm() {
// 触发表单验证
await validate();
try {
// 触发表单验证
await validate();
} catch ({ errorFields }) {
if (errorFields) {
const firstField = errorFields[0];
if (firstField) {
formRef.value.scrollToField(firstField.name, { behavior: 'smooth', block: 'center' });
}
}
return Promise.reject(errorFields);
}
confirmLoading.value = true;
const isUpdate = ref<boolean>(false);
//时间格式化

View File

@ -22,9 +22,9 @@
<BasicTable @register="registerTable" :rowSelection="rowSelection">
<!--插槽:table标题-->
<template #tableTitle>
<a-button type="primary" @click="handleAdd" preIcon="ant-design:plus-outlined"> 新增</a-button>
<a-button type="primary" preIcon="ant-design:export-outlined" @click="onExportXls"> 导出</a-button>
<j-upload-button type="primary" preIcon="ant-design:import-outlined" @click="onImportXls">导入</j-upload-button>
<a-button type="primary" v-auth="'${entityPackage}:${tableName}:add'" @click="handleAdd" preIcon="ant-design:plus-outlined"> 新增</a-button>
<a-button type="primary" v-auth="'${entityPackage}:${tableName}:exportXls'" preIcon="ant-design:export-outlined" @click="onExportXls"> 导出</a-button>
<j-upload-button type="primary" v-auth="'${entityPackage}:${tableName}:importExcel'" preIcon="ant-design:import-outlined" @click="onImportXls">导入</j-upload-button>
<a-dropdown v-if="selectedRowKeys.length > 0">
<template #overlay>
<a-menu>
@ -34,7 +34,7 @@
</a-menu-item>
</a-menu>
</template>
<a-button>批量操作
<a-button v-auth="'${entityPackage}:${tableName}:deleteBatch'">批量操作
<Icon icon="mdi:chevron-down"></Icon>
</a-button>
</a-dropdown>
@ -251,6 +251,7 @@
{
label: '编辑',
onClick: handleEdit.bind(null, record),
auth: '${entityPackage}:${tableName}:edit'
}
]
}
@ -285,8 +286,9 @@
popConfirm: {
title: '是否确认删除',
confirm: handleDelete.bind(null, record),
placement: 'topLeft',
}
placement: 'topLeft'
},
auth: '${entityPackage}:${tableName}:delete'
}
];
if(record.bpmStatus == '1'){
@ -309,8 +311,9 @@
popConfirm: {
title: '是否确认删除',
confirm: handleDelete.bind(null, record),
placement: 'topLeft',
}
placement: 'topLeft'
},
auth: '${entityPackage}:${tableName}:delete'
}
]
</#if>

View File

@ -57,7 +57,7 @@ export const columns: BasicColumn[] = [
customRender:({text}) => {
return render.renderSwitch(text, [{text:'是',value:'${switch_extend_arr1}'},{text:'否',value:'${switch_extend_arr2}'}])
},
<#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'>
<#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' || po.classType=='popup_dict'>
dataIndex: '${po.fieldName}_dictText'
<#elseif po.classType=='cat_tree'>
dataIndex: '${po.fieldName}',
@ -102,6 +102,14 @@ export const searchFormSchema: FormSchema[] = [
<#-- update-begin---author:chenrui ---date:20240102 for[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- -->
component: 'JSelectUser',
<#-- update-end---author:chenrui ---date:20240102 for[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- -->
componentProps:{
<#if po.extendParams?exists && po.extendParams.text?exists>
labelKey: '${po.extendParams.text}',
</#if>
<#if po.extendParams?exists && po.extendParams.store?exists>
rowKey: '${po.extendParams.store}',
</#if>
},
<#elseif po.classType=='switch'>
component: 'JSwitch',
componentProps:{
@ -112,6 +120,14 @@ export const searchFormSchema: FormSchema[] = [
},
<#elseif po.classType=='sel_depart'>
component: 'JSelectDept',
componentProps:{
<#if po.extendParams?exists && po.extendParams.text?exists>
labelKey: '${po.extendParams.text}',
</#if>
<#if po.extendParams?exists && po.extendParams.store?exists>
rowKey: '${po.extendParams.store}',
</#if>
},
<#elseif po.classType=='list_multi'>
component: 'JSelectMultiple',
componentProps:{
@ -148,6 +164,13 @@ export const searchFormSchema: FormSchema[] = [
},
<#elseif po.classType=='popup'>
<#include "/common/form/vue3popup.ftl">
<#elseif po.classType=='popup_dict'>
component: 'JPopupDict',
componentProps: {
placeholder: '请选择${po.filedComment}',
dictCode: '${po.dictTable},${po.dictText},${po.dictField}',
multi: ${po.extendParams.popupMulti?c}
},
<#elseif po.classType=='list' || po.classType=='radio' || po.classType=='checkbox'>
<#-- ---------------------------下拉或是单选 判断数据字典是表字典还是普通字典------------------------------- -->
component: 'JDictSelectTag',
@ -269,8 +292,23 @@ export const formSchema: FormSchema[] = [
},
<#elseif po.classType =='popup'>
<#include "/common/form/vue3popup.ftl">
<#elseif po.classType=='popup_dict'>
component: 'JPopupDict',
componentProps: {
placeholder: '请选择${po.filedComment}',
dictCode: '${po.dictTable},${po.dictText},${po.dictField}',
multi: ${po.extendParams.popupMulti?c}
},
<#elseif po.classType =='sel_depart'>
component: 'JSelectDept',
componentProps:{
<#if po.extendParams?exists && po.extendParams.text?exists>
labelKey: '${po.extendParams.text}',
</#if>
<#if po.extendParams?exists && po.extendParams.store?exists>
rowKey: '${po.extendParams.store}',
</#if>
},
<#elseif po.classType =='switch'>
component: 'JSwitch',
componentProps:{
@ -292,7 +330,14 @@ export const formSchema: FormSchema[] = [
component: 'JSelectUser',
<#-- update-end---author:chenrui ---date:20240102 for[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- -->
componentProps:{
labelKey:'realname',
<#if po.extendParams?exists && po.extendParams.text?exists>
labelKey: '${po.extendParams.text}',
<#else>
labelKey:'realname',
</#if>
<#if po.extendParams?exists && po.extendParams.store?exists>
rowKey: '${po.extendParams.store}',
</#if>
},
<#elseif po.classType =='textarea'>
component: 'InputTextArea',//TODO 注意string转换问题
@ -575,8 +620,23 @@ export const ${sub.entityName?uncap_first}FormSchema: FormSchema[] = [
},
<#elseif po.classType =='popup'>
<#include "/common/form/vue3popup.ftl">
<#elseif po.classType=='popup_dict'>
component: 'JPopupDict',
componentProps: {
placeholder: '请选择${po.filedComment}',
dictCode: '${po.dictTable},${po.dictText},${po.dictField}',
multi: ${po.extendParams.popupMulti?c}
},
<#elseif po.classType =='sel_depart'>
component: 'JSelectDept',
componentProps:{
<#if po.extendParams?exists && po.extendParams.text?exists>
labelKey: '${po.extendParams.text}',
</#if>
<#if po.extendParams?exists && po.extendParams.store?exists>
rowKey: '${po.extendParams.store}',
</#if>
},
<#elseif po.classType =='switch'>
component: 'JSwitch',
componentProps:{
@ -597,9 +657,16 @@ export const ${sub.entityName?uncap_first}FormSchema: FormSchema[] = [
<#-- update-begin---author:chenrui ---date:20240102 for[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- -->
component: 'JSelectUser',
<#-- update-end---author:chenrui ---date:20240102 for[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- -->
componentProps:{
labelKey:'realname',
},
componentProps:{
<#if po.extendParams?exists && po.extendParams.text?exists>
labelKey: '${po.extendParams.text}',
<#else>
labelKey:'realname',
</#if>
<#if po.extendParams?exists && po.extendParams.store?exists>
rowKey: '${po.extendParams.store}',
</#if>
},
<#elseif po.classType =='textarea'>
component: 'InputTextArea',
<#elseif po.classType=='list' || po.classType=='radio'>

View File

@ -79,6 +79,7 @@
useSearchForm: false,
actionColumn: {
width: 180,
fixed:'right'
},
pagination:{
current: 1,

View File

@ -1,7 +1,7 @@
<#include "/common/utils.ftl">
<template>
<BasicModal v-bind="$attrs" @register="registerModal" destroyOnClose :title="title" :width="${getModalWidth(tableVo.fieldRowNum?default(1))}" @ok="handleSubmit">
<BasicForm @register="registerForm"/>
<BasicForm @register="registerForm" name="${entityName}Form" />
</BasicModal>
</template>
@ -16,7 +16,7 @@
const isUpdate = ref(true);
const isDetail = ref(false);
//表单配置
const [registerForm, {setProps,resetFields, setFieldsValue, validate}] = useForm({
const [registerForm, { setProps,resetFields, setFieldsValue, validate, scrollToField }] = useForm({
//labelWidth: 150,
schemas: formSchema,
showActionButtonGroup: false,
@ -51,6 +51,14 @@
closeModal();
//刷新列表
emit('success');
} catch ({ errorFields }) {
if (errorFields) {
const firstField = errorFields[0];
if (firstField) {
scrollToField(firstField.name, { behavior: 'smooth', block: 'center' });
}
}
return Promise.reject(errorFields);
} finally {
setModalProps({confirmLoading: false});
}

View File

@ -3,7 +3,7 @@
#segment#${sub.entityName}Modal.vue
<template>
<BasicModal v-bind="$attrs" @register="registerModal" destroyOnClose :title="title" :width="${getModalWidth(tableVo.fieldRowNum?default(1))}" @ok="handleSubmit">
<BasicForm @register="registerForm"/>
<BasicForm @register="registerForm" name="${sub.entityName}Form" />
</BasicModal>
</template>
@ -21,7 +21,7 @@
const isUpdate = ref(true);
const isDetail = ref(false);
//表单配置
const [registerForm, {setProps,resetFields, setFieldsValue, validate}] = useForm({
const [registerForm, { setProps,resetFields, setFieldsValue, validate, scrollToField }] = useForm({
//labelWidth: 150,
schemas: ${sub.entityName?uncap_first}FormSchema,
showActionButtonGroup: false,
@ -61,6 +61,13 @@
closeModal();
//刷新列表
emit('success');
} catch ({ errorFields }) {
if (errorFields) {
const firstField = errorFields[0];
if (firstField) {
scrollToField(firstField.name, { behavior: 'smooth', block: 'center' });
}
}
} finally {
setModalProps({confirmLoading: false});
}

View File

@ -10,6 +10,7 @@
<#assign need_dept = false>
<#assign need_multi = false>
<#assign need_popup = false>
<#assign need_popup_dict = false>
<#assign need_select_tag = false>
<#assign need_select_tree = false>
<#assign need_time = false>
@ -20,6 +21,8 @@
<#assign need_editor = false>
<#assign need_checkbox = false>
<#assign query_flag = false>
<#assign need_range_number = false>
<#assign is_range = false>
<!--查询区域-->
<div class="jeecg-basic-table-form-container">
<a-form ref="formRef" @keyup.enter.native="reload" :model="queryParam" :label-col="labelCol" :wrapper-col="wrapperCol">
@ -56,12 +59,21 @@
<#if po.classType=='popup'>
<#assign need_popup = true>
</#if>
<#if po.classType=='popup_dict'>
<#assign need_popup_dict = true>
</#if>
<#if po.classType=='sel_tree'>
<#assign need_select_tree = true>
</#if>
<#if po.classType=='time'>
<#assign need_time = true>
</#if>
<#if po.queryMode!='single' && (po.fieldDbType=='int' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal')>
<#assign need_range_number = true>
</#if>
<#if po.queryMode!='single'>
<#assign is_range = true>
</#if>
<#include "/common/form/native/vue3NativeSearch.ftl">
</#list>
<#if query_field_no gt 2>
@ -90,9 +102,9 @@
<BasicTable @register="registerTable" :rowSelection="rowSelection">
<!--插槽:table标题-->
<template #tableTitle>
<a-button type="primary" @click="handleAdd" preIcon="ant-design:plus-outlined"> 新增</a-button>
<a-button type="primary" preIcon="ant-design:export-outlined" @click="onExportXls"> 导出</a-button>
<j-upload-button type="primary" preIcon="ant-design:import-outlined" @click="onImportXls">导入</j-upload-button>
<a-button type="primary" v-auth="'${entityPackage}:${tableName}:add'" @click="handleAdd" preIcon="ant-design:plus-outlined"> 新增</a-button>
<a-button type="primary" v-auth="'${entityPackage}:${tableName}:exportXls'" preIcon="ant-design:export-outlined" @click="onExportXls"> 导出</a-button>
<j-upload-button type="primary" v-auth="'${entityPackage}:${tableName}:importExcel'" preIcon="ant-design:import-outlined" @click="onImportXls">导入</j-upload-button>
<a-dropdown v-if="selectedRowKeys.length > 0">
<template #overlay>
<a-menu>
@ -102,7 +114,7 @@
</a-menu-item>
</a-menu>
</template>
<a-button
<a-button v-auth="'${entityPackage}:${tableName}:deleteBatch'"
>批量操作
<Icon icon="mdi:chevron-down"></Icon>
</a-button>
@ -160,7 +172,7 @@
import { BasicTable, useTable, TableAction } from '/@/components/Table';
import { useListPage } from '/@/hooks/system/useListPage'
import ${entityName}Modal from './components/${entityName}Modal.vue'
import { columns, searchFormSchema, superQuerySchema } from './${entityName}.data';
import { columns, superQuerySchema } from './${entityName}.data';
import { list, deleteOne, batchDelete, getImportUrl,getExportUrl } from './${entityName}.api';
import { downloadFile } from '/@/utils/common/renderUtils';
<#include "/common/form/native/vue3NativeImport.ftl">
@ -179,7 +191,9 @@
import ${sub.entityName}List from './${sub.entityName}List.vue'
</#list>
import { useUserStore } from '/@/store/modules/user';
<#if is_range>
import { cloneDeep } from "lodash-es";
</#if>
const formRef = ref();
const queryParam = reactive<any>({});
const checkedKeys = ref<Array<string | number>>([]);
@ -199,8 +213,13 @@
width: 120,
fixed:'right'
},
beforeFetch: (params) => {
beforeFetch: async (params) => {
<#if is_range>
let rangerQuery = await setRangeQuery();
return Object.assign(params, rangerQuery);
<#else>
return Object.assign(params, queryParam);
</#if>
},
pagination: {
current: 1,
@ -292,6 +311,7 @@
{
label: '编辑',
onClick: handleEdit.bind(null, record),
auth: '${entityPackage}:${tableName}:edit'
},
];
}
@ -310,8 +330,9 @@
popConfirm: {
title: '是否确认删除',
confirm: handleDelete.bind(null, record),
placement: 'topLeft',
}
placement: 'topLeft'
},
auth: '${entityPackage}:${tableName}:delete'
}
];
if(record.bpmStatus == '1' || !record.bpmStatus){
@ -336,8 +357,9 @@
popConfirm: {
title: '是否确认删除',
confirm: handleDelete.bind(null, record),
placement: 'topLeft',
placement: 'topLeft'
},
auth: '${entityPackage}:${tableName}:delete'
},
];
</#if>
@ -436,6 +458,32 @@
}
}
</#if>
<#if is_range>
let rangeField = '${getRangeField(columns)}'
/**
* 设置范围查询条件
*/
async function setRangeQuery(){
let queryParamClone = cloneDeep(queryParam);
if (rangeField) {
let fieldsValue = rangeField.split(',');
fieldsValue.forEach(item => {
if (queryParamClone[item]) {
let range = queryParamClone[item];
queryParamClone[item+'_begin'] = range[0];
queryParamClone[item+'_end'] = range[1];
delete queryParamClone[item];
} else {
queryParamClone[item+'_begin'] = '';
queryParamClone[item+'_end'] = '';
}
})
}
return queryParamClone;
}
</#if>
</script>
<style lang="less" scoped>
<#include "/common/form/native/vueNativeSearchStyle.ftl">

View File

@ -57,7 +57,7 @@ export const columns: BasicColumn[] = [
customRender:({text}) => {
return render.renderSwitch(text, [{text:'是',value:'${switch_extend_arr1}'},{text:'否',value:'${switch_extend_arr2}'}])
},
<#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'>
<#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' || po.classType=='popup_dict'>
dataIndex: '${po.fieldName}_dictText'
<#elseif po.classType=='cat_tree'>
dataIndex: '${po.fieldName}',
@ -121,7 +121,7 @@ export const ${sub.entityName?uncap_first}Columns: BasicColumn[] = [
customRender:({text}) => {
return render.renderSwitch(text, [{text:'是',value:'${switch_extend_arr1}'},{text:'否',value:'${switch_extend_arr2}'}])
},
<#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'>
<#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' || po.classType=='popup_dict'>
dataIndex: '${po.fieldName}_dictText'
<#elseif po.classType=='cat_tree'>
dataIndex: '${po.fieldName}',

View File

@ -87,6 +87,7 @@
useSearchForm: false,
actionColumn: {
width: 180,
fixed:'right'
},
beforeFetch: (params) => {
return Object.assign(params, queryParam);

View File

@ -3,7 +3,7 @@
<a-spin :spinning="confirmLoading">
<JFormContainer :disabled="disabled">
<template #detail>
<a-form ref="formRef" class="antd-modal-form" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-form ref="formRef" class="antd-modal-form" :labelCol="labelCol" :wrapperCol="wrapperCol" name="${entityName}Form">
<a-row>
<#assign need_category = false>
<#assign bpm_flag=false>
@ -14,6 +14,7 @@
<#assign need_dept = false>
<#assign need_multi = false>
<#assign need_popup = false>
<#assign need_popup_dict = false>
<#assign need_select_tag = false>
<#assign need_select_tree = false>
<#assign need_time = false>
@ -23,6 +24,7 @@
<#assign need_editor = false>
<#assign need_checkbox = false>
<#assign hasOnlyValidate = false>
<#assign need_range_number = false>
<#assign form_span = 24>
<#if tableVo.fieldRowNum==2>
<#assign form_span = 12>
@ -38,6 +40,7 @@
<#if po.isShow == 'Y' && po.fieldValidType?default("") == 'only'>
<#assign hasOnlyValidate = true>
</#if>
<#assign formEntityName>${entityName}Form</#assign>
<#include "/common/form/native/vue3NativeForm.ftl">
</#list>
<#if bpm_flag>
@ -151,8 +154,18 @@
* 提交数据
*/
async function submitForm() {
// 触发表单验证
await validate();
try {
// 触发表单验证
await validate();
} catch ({ errorFields }) {
if (errorFields) {
const firstField = errorFields[0];
if (firstField) {
formRef.value.scrollToField(firstField.name, { behavior: 'smooth', block: 'center' });
}
}
return Promise.reject(errorFields);
}
confirmLoading.value = true;
const isUpdate = ref<boolean>(false);
//时间格式化

View File

@ -10,6 +10,7 @@
<#assign need_dept = false>
<#assign need_multi = false>
<#assign need_popup = false>
<#assign need_popup_dict = false>
<#assign need_select_tag = false>
<#assign need_select_tree = false>
<#assign need_time = false>
@ -18,6 +19,7 @@
<#assign need_image_upload = false>
<#assign need_editor = false>
<#assign need_checkbox = false>
<#assign need_range_number = false>
<#assign form_span = 24>
<#if tableVo.fieldRowNum==2>
<#assign form_span = 12>
@ -31,7 +33,7 @@
<a-spin :spinning="confirmLoading">
<JFormContainer :disabled="disabled">
<template #detail>
<a-form class="antd-modal-form" v-bind="formItemLayout" ref="formRef">
<a-form class="antd-modal-form" v-bind="formItemLayout" ref="formRef" name="${sub.entityName}Form">
<a-row>
<#list sub.colums as po>
<#if po.isShow == 'Y' && po.fieldValidType?default("") == 'only'>
@ -40,6 +42,7 @@
<#if po.fieldDbName=='bpm_status'>
<#assign bpm_flag=true>
</#if>
<#assign formEntityName>${sub.entityName}</#assign>
<#include "/common/form/native/vue3NativeForm.ftl">
</#list>
</a-row>
@ -121,7 +124,18 @@
*/
async function submitForm() {
// 触发表单验证
await validate();
try {
// 触发表单验证
await validate();
} catch ({ errorFields }) {
if (errorFields) {
const firstField = errorFields[0];
if (firstField) {
formRef.value.scrollToField(firstField.name, { behavior: 'smooth', block: 'center' });
}
}
return Promise.reject(errorFields);
}
confirmLoading.value = true;
const isUpdate = ref<boolean>(false);
//时间格式化

View File

@ -35,9 +35,9 @@
<!-- 内嵌table区域 end -->
<!--插槽:table标题-->
<template #tableTitle>
<a-button type="primary" @click="handleAdd" preIcon="ant-design:plus-outlined"> 新增</a-button>
<a-button type="primary" preIcon="ant-design:export-outlined" @click="onExportXls"> 导出</a-button>
<j-upload-button type="primary" preIcon="ant-design:import-outlined" @click="onImportXls">导入</j-upload-button>
<a-button type="primary" v-auth="'${entityPackage}:${tableName}:add'" @click="handleAdd" preIcon="ant-design:plus-outlined"> 新增</a-button>
<a-button type="primary" v-auth="'${entityPackage}:${tableName}:exportXls'" preIcon="ant-design:export-outlined" @click="onExportXls"> 导出</a-button>
<j-upload-button type="primary" v-auth="'${entityPackage}:${tableName}:importExcel'" preIcon="ant-design:import-outlined" @click="onImportXls">导入</j-upload-button>
<a-dropdown v-if="selectedRowKeys.length > 0">
<template #overlay>
<a-menu>
@ -47,7 +47,7 @@
</a-menu-item>
</a-menu>
</template>
<a-button>批量操作
<a-button v-auth="'${entityPackage}:${tableName}:deleteBatch'">批量操作
<Icon icon="mdi:chevron-down"></Icon>
</a-button>
</a-dropdown>
@ -257,6 +257,7 @@
{
label: '编辑',
onClick: handleEdit.bind(null, record),
auth: '${entityPackage}:${tableName}:edit'
}
]
}
@ -291,8 +292,9 @@
popConfirm: {
title: '是否确认删除',
confirm: handleDelete.bind(null, record),
placement: 'topLeft',
}
placement: 'topLeft'
},
auth: '${entityPackage}:${tableName}:delete'
}
];
if(record.bpmStatus == '1' || !record.bpmStatus){
@ -316,8 +318,9 @@
popConfirm: {
title: '是否确认删除',
confirm: handleDelete.bind(null, record),
placement: 'topLeft',
}
placement: 'topLeft'
},
auth: '${entityPackage}:${tableName}:delete'
}
]
</#if>
@ -347,6 +350,6 @@
</#if>
</script>
<style scoped>
<style lang="less" scoped>
<#include "/common/form/vue3SearchStyle.ftl">
</style>

View File

@ -58,7 +58,7 @@ export const columns: BasicColumn[] = [
customRender:({text}) => {
return render.renderSwitch(text, [{text:'是',value:'${switch_extend_arr1}'},{text:'否',value:'${switch_extend_arr2}'}])
},
<#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'>
<#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' || po.classType=='popup_dict'>
dataIndex: '${po.fieldName}_dictText'
<#elseif po.classType=='cat_tree'>
dataIndex: '${po.fieldName}',
@ -106,6 +106,14 @@ export const searchFormSchema: FormSchema[] = [
<#-- update-begin---author:chenrui ---date:20240102 for[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- -->
component: 'JSelectUser',
<#-- update-end---author:chenrui ---date:20240102 for[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- -->
componentProps:{
<#if po.extendParams?exists && po.extendParams.text?exists>
labelKey: '${po.extendParams.text}',
</#if>
<#if po.extendParams?exists && po.extendParams.store?exists>
rowKey: '${po.extendParams.store}',
</#if>
},
<#elseif po.classType=='switch'>
component: 'JSwitch',
componentProps:{
@ -116,6 +124,14 @@ export const searchFormSchema: FormSchema[] = [
},
<#elseif po.classType=='sel_depart'>
component: 'JSelectDept',
componentProps:{
<#if po.extendParams?exists && po.extendParams.text?exists>
labelKey: '${po.extendParams.text}',
</#if>
<#if po.extendParams?exists && po.extendParams.store?exists>
rowKey: '${po.extendParams.store}',
</#if>
},
<#elseif po.classType=='list_multi'>
component: 'JSelectMultiple',
componentProps:{
@ -152,6 +168,13 @@ export const searchFormSchema: FormSchema[] = [
},
<#elseif po.classType=='popup'>
<#include "/common/form/vue3popup.ftl">
<#elseif po.classType=='popup_dict'>
component: 'JPopupDict',
componentProps: {
placeholder: '请选择${po.filedComment}',
dictCode: '${po.dictTable},${po.dictText},${po.dictField}',
multi: ${po.extendParams.popupMulti?c}
},
<#elseif po.classType=='list' || po.classType=='radio' || po.classType=='checkbox'>
<#-- ---------------------------下拉或是单选 判断数据字典是表字典还是普通字典------------------------------- -->
component: 'JDictSelectTag',
@ -272,8 +295,23 @@ export const formSchema: FormSchema[] = [
},
<#elseif po.classType =='popup'>
<#include "/common/form/vue3popup.ftl">
<#elseif po.classType=='popup_dict'>
component: 'JPopupDict',
componentProps: {
placeholder: '请选择${po.filedComment}',
dictCode: '${po.dictTable},${po.dictText},${po.dictField}',
multi: ${po.extendParams.popupMulti?c}
},
<#elseif po.classType =='sel_depart'>
component: 'JSelectDept',
componentProps:{
<#if po.extendParams?exists && po.extendParams.text?exists>
labelKey: '${po.extendParams.text}',
</#if>
<#if po.extendParams?exists && po.extendParams.store?exists>
rowKey: '${po.extendParams.store}',
</#if>
},
<#elseif po.classType =='switch'>
component: 'JSwitch',
componentProps:{
@ -294,8 +332,13 @@ export const formSchema: FormSchema[] = [
<#-- update-begin---author:chenrui ---date:20240102 for[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- -->
component: 'JSelectUser',
<#-- update-end---author:chenrui ---date:20240102 for[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- -->
componentProps:{
labelKey:'realname',
componentProps:{
<#if po.extendParams?exists && po.extendParams.text?exists>
labelKey: '${po.extendParams.text}',
</#if>
<#if po.extendParams?exists && po.extendParams.store?exists>
rowKey: '${po.extendParams.store}',
</#if>
},
<#elseif po.classType =='textarea'>
component: 'InputTextArea',
@ -494,7 +537,7 @@ export const ${sub.entityName?uncap_first}Columns: BasicColumn[] = [
customRender:({text}) => {
return render.renderSwitch(text, [{text:'是',value:'${switch_extend_arr1}'},{text:'否',value:'${switch_extend_arr2}'}])
},
<#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'>
<#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' || po.classType=='popup_dict'>
dataIndex: '${po.fieldName}_dictText'
<#elseif po.classType=='cat_tree'>
dataIndex: '${po.fieldName}',
@ -565,8 +608,23 @@ export const ${sub.entityName?uncap_first}FormSchema: FormSchema[] = [
},
<#elseif po.classType =='popup'>
<#include "/common/form/vue3popup.ftl">
<#elseif po.classType=='popup_dict'>
component: 'JPopupDict',
componentProps: {
placeholder: '请选择${po.filedComment}',
dictCode: '${po.dictTable},${po.dictText},${po.dictField}',
multi: ${po.extendParams.popupMulti?c}
},
<#elseif po.classType =='sel_depart'>
component: 'JSelectDept',
componentProps:{
<#if po.extendParams?exists && po.extendParams.text?exists>
labelKey: '${po.extendParams.text}',
</#if>
<#if po.extendParams?exists && po.extendParams.store?exists>
rowKey: '${po.extendParams.store}',
</#if>
},
<#elseif po.classType =='switch'>
component: 'JSwitch',
componentProps:{
@ -587,8 +645,13 @@ export const ${sub.entityName?uncap_first}FormSchema: FormSchema[] = [
<#-- update-begin---author:chenrui ---date:20240102 for[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- -->
component: 'JSelectUser',
<#-- update-end---author:chenrui ---date:20240102 for[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- -->
componentProps:{
labelKey:'realname',
componentProps:{
<#if po.extendParams?exists && po.extendParams.text?exists>
labelKey: '${po.extendParams.text}',
</#if>
<#if po.extendParams?exists && po.extendParams.store?exists>
rowKey: '${po.extendParams.store}',
</#if>
},
<#elseif po.classType =='textarea'>
component: 'InputTextArea',
@ -822,11 +885,27 @@ export const ${sub.entityName?uncap_first}JVxeColumns: JVxeColumn[] = [
</#if>
<#elseif col.classType =='sel_depart'>
type: JVxeTypes.departSelect,
props:{
<#if col.extendParams?exists && col.extendParams.text?exists>
labelKey: '${col.extendParams.text}',
</#if>
<#if col.extendParams?exists && col.extendParams.store?exists>
rowKey: '${col.extendParams.store}',
</#if>
},
<#if col.readonly=='Y'>
disabled:true,
</#if>
<#elseif col.classType =='sel_user'>
type: JVxeTypes.userSelect,
props:{
<#if col.extendParams?exists && col.extendParams.text?exists>
labelKey: '${col.extendParams.text}',
</#if>
<#if col.extendParams?exists && col.extendParams.store?exists>
rowKey: '${col.extendParams.store}',
</#if>
},
<#if col.readonly=='Y'>
disabled:true,
</#if>

View File

@ -1,7 +1,7 @@
<#include "/common/utils.ftl">
<template>
<BasicModal v-bind="$attrs" @register="registerModal" destroyOnClose :title="title" :width="${getModalWidth(tableVo.fieldRowNum?default(1))}" @ok="handleSubmit">
<BasicForm @register="registerForm" ref="formRef"/>
<BasicForm @register="registerForm" ref="formRef" name="${entityName}Form" />
<!-- 子表单区域 -->
<a-tabs v-model:activeKey="activeKey" animated @change="handleChangeTabs">
<#list subTables as sub><#rt/>
@ -157,6 +157,12 @@
if (e.error === VALIDATE_FAILED) {
// 如果有未通过表单验证的子表就自动跳转到它所在的tab
activeKey.value = e.index == null ? unref(activeKey) : refKeys.value[e.index]
if (e.errorFields) {
const firstField = e.errorFields[0];
if (firstField) {
e.scrollToField(firstField.name, { behavior: 'smooth', block: 'center' });
}
}
} else {
console.error(e)
}

View File

@ -3,7 +3,7 @@
<#if sub.foreignRelationType=='1'>
#segment#${sub.entityName}Form.vue
<template>
<BasicForm @register="registerForm"/>
<BasicForm @register="registerForm" name="${sub.entityName}Form" class="basic-modal-form" />
</template>
<script lang="ts">
import {defineComponent} from 'vue';
@ -23,7 +23,7 @@
}
},
setup(props,{emit}) {
const [registerForm, {setProps, resetFields, setFieldsValue,getFieldsValue,validate}] = useForm({
const [registerForm, { setProps, resetFields, setFieldsValue, getFieldsValue, validate, scrollToField }] = useForm({
//labelWidth: 150,
schemas: ${sub.entityName?uncap_first}FormSchema,
showActionButtonGroup: false,
@ -62,8 +62,8 @@
// 验证子表表单
validate().then(()=>{
return resolve()
}).catch(()=> {
return reject({ error: VALIDATE_FAILED ,index})
}).catch(({ errorFields })=> {
return reject({ error: VALIDATE_FAILED ,index, errorFields: errorFields, scrollToField: scrollToField })
})
})
}
@ -77,5 +77,11 @@
}
})
</script>
<style lang="less" scoped>
.basic-modal-form {
overflow: auto;
height: 340px;
}
</style>
</#if>
</#list>

View File

@ -21,9 +21,9 @@
<BasicTable @register="registerTable" :rowSelection="rowSelection">
<!--插槽:table标题-->
<template #tableTitle>
<a-button type="primary" @click="handleAdd" preIcon="ant-design:plus-outlined"> 新增</a-button>
<a-button type="primary" preIcon="ant-design:export-outlined" @click="onExportXls"> 导出</a-button>
<j-upload-button type="primary" preIcon="ant-design:import-outlined" @click="onImportXls">导入</j-upload-button>
<a-button type="primary" v-auth="'${entityPackage}:${tableName}:add'" @click="handleAdd" preIcon="ant-design:plus-outlined"> 新增</a-button>
<a-button type="primary" v-auth="'${entityPackage}:${tableName}:exportXls'" preIcon="ant-design:export-outlined" @click="onExportXls"> 导出</a-button>
<j-upload-button type="primary" v-auth="'${entityPackage}:${tableName}:importExcel'" preIcon="ant-design:import-outlined" @click="onImportXls">导入</j-upload-button>
<a-dropdown v-if="selectedRowKeys.length > 0">
<template #overlay>
<a-menu>
@ -33,7 +33,7 @@
</a-menu-item>
</a-menu>
</template>
<a-button>批量操作
<a-button v-auth="'${entityPackage}:${tableName}:deleteBatch'">批量操作
<Icon icon="mdi:chevron-down"></Icon>
</a-button>
</a-dropdown>
@ -230,6 +230,7 @@
{
label: '编辑',
onClick: handleEdit.bind(null, record),
auth: '${entityPackage}:${tableName}:edit'
}
]
}
@ -264,8 +265,9 @@
popConfirm: {
title: '是否确认删除',
confirm: handleDelete.bind(null, record),
placement: 'topLeft',
}
placement: 'topLeft'
},
auth: '${entityPackage}:${tableName}:delete'
}
];
if(record.bpmStatus == '1' || !record.bpmStatus){
@ -289,8 +291,9 @@
popConfirm: {
title: '是否确认删除',
confirm: handleDelete.bind(null, record),
placement: 'topLeft',
}
placement: 'topLeft'
},
auth: '${entityPackage}:${tableName}:delete'
}
]
</#if>
@ -320,6 +323,6 @@
</#if>
</script>
<style scoped>
<style lang="less" scoped>
<#include "/common/form/vue3SearchStyle.ftl">
</style>

View File

@ -58,7 +58,7 @@ export const columns: BasicColumn[] = [
customRender:({text}) => {
return render.renderSwitch(text, [{text:'是',value:'${switch_extend_arr1}'},{text:'否',value:'${switch_extend_arr2}'}])
},
<#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'>
<#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' || po.classType=='popup_dict'>
dataIndex: '${po.fieldName}_dictText'
<#elseif po.classType=='cat_tree'>
dataIndex: '${po.fieldName}',
@ -106,6 +106,14 @@ export const searchFormSchema: FormSchema[] = [
<#-- update-begin---author:chenrui ---date:20240102 for[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- -->
component: 'JSelectUser',
<#-- update-end---author:chenrui ---date:20240102 for[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- -->
componentProps:{
<#if po.extendParams?exists && po.extendParams.text?exists>
labelKey: '${po.extendParams.text}',
</#if>
<#if po.extendParams?exists && po.extendParams.store?exists>
rowKey: '${po.extendParams.store}',
</#if>
},
<#elseif po.classType=='switch'>
component: 'JSwitch',
componentProps:{
@ -116,6 +124,14 @@ export const searchFormSchema: FormSchema[] = [
},
<#elseif po.classType=='sel_depart'>
component: 'JSelectDept',
componentProps:{
<#if po.extendParams?exists && po.extendParams.text?exists>
labelKey: '${po.extendParams.text}',
</#if>
<#if po.extendParams?exists && po.extendParams.store?exists>
rowKey: '${po.extendParams.store}',
</#if>
},
<#elseif po.classType=='list_multi'>
component: 'JSelectMultiple',
componentProps:{
@ -152,6 +168,13 @@ export const searchFormSchema: FormSchema[] = [
},
<#elseif po.classType=='popup'>
<#include "/common/form/vue3popup.ftl">
<#elseif po.classType=='popup_dict'>
component: 'JPopupDict',
componentProps: {
placeholder: '请选择${po.filedComment}',
dictCode: '${po.dictTable},${po.dictText},${po.dictField}',
multi: ${po.extendParams.popupMulti?c}
},
<#elseif po.classType=='list' || po.classType=='radio' || po.classType=='checkbox'>
<#-- ---------------------------下拉或是单选 判断数据字典是表字典还是普通字典------------------------------- -->
component: 'JDictSelectTag',
@ -272,8 +295,23 @@ export const formSchema: FormSchema[] = [
},
<#elseif po.classType =='popup'>
<#include "/common/form/vue3popup.ftl">
<#elseif po.classType=='popup_dict'>
component: 'JPopupDict',
componentProps: {
placeholder: '请选择${po.filedComment}',
dictCode: '${po.dictTable},${po.dictText},${po.dictField}',
multi: ${po.extendParams.popupMulti?c}
},
<#elseif po.classType =='sel_depart'>
component: 'JSelectDept',
componentProps:{
<#if po.extendParams?exists && po.extendParams.text?exists>
labelKey: '${po.extendParams.text}',
</#if>
<#if po.extendParams?exists && po.extendParams.store?exists>
rowKey: '${po.extendParams.store}',
</#if>
},
<#elseif po.classType =='switch'>
component: 'JSwitch',
componentProps:{
@ -294,8 +332,13 @@ export const formSchema: FormSchema[] = [
<#-- update-begin---author:chenrui ---date:20240102 for[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件------------- -->
component: 'JSelectUser',
<#-- update-end---author:chenrui ---date:20240102 for[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件------------- -->
componentProps:{
labelKey:'realname',
componentProps:{
<#if po.extendParams?exists && po.extendParams.text?exists>
labelKey: '${po.extendParams.text}',
</#if>
<#if po.extendParams?exists && po.extendParams.store?exists>
rowKey: '${po.extendParams.store}',
</#if>
},
<#elseif po.classType =='textarea'>
component: 'InputTextArea',
@ -505,6 +548,13 @@ export const ${sub.entityName?uncap_first}FormSchema: FormSchema[] = [
},
<#elseif po.classType =='popup'>
<#include "/common/form/vue3popup.ftl">
<#elseif po.classType=='popup_dict'>
component: 'JPopupDict',
componentProps: {
placeholder: '请选择${po.filedComment}',
dictCode: '${po.dictTable},${po.dictText},${po.dictField}',
multi: ${po.extendParams.popupMulti?c}
},
<#elseif po.classType =='sel_depart'>
component: 'JSelectDept',
<#elseif po.classType =='switch'>
@ -762,11 +812,27 @@ export const ${sub.entityName?uncap_first}Columns: JVxeColumn[] = [
</#if>
<#elseif col.classType =='sel_depart'>
type: JVxeTypes.departSelect,
props:{
<#if col.extendParams?exists && col.extendParams.text?exists>
labelKey: '${col.extendParams.text}',
</#if>
<#if col.extendParams?exists && col.extendParams.store?exists>
rowKey: '${col.extendParams.store}',
</#if>
},
<#if col.readonly=='Y'>
disabled:true,
</#if>
<#elseif col.classType =='sel_user'>
type: JVxeTypes.userSelect,
props:{
<#if col.extendParams?exists && col.extendParams.text?exists>
labelKey: '${col.extendParams.text}',
</#if>
<#if col.extendParams?exists && col.extendParams.store?exists>
rowKey: '${col.extendParams.store}',
</#if>
},
<#if col.readonly=='Y'>
disabled:true,
</#if>

View File

@ -1,7 +1,7 @@
<#include "/common/utils.ftl">
<template>
<BasicModal v-bind="$attrs" @register="registerModal" destroyOnClose :title="title" :width="${getModalWidth(tableVo.fieldRowNum?default(1))}" @ok="handleSubmit">
<BasicForm @register="registerForm" ref="formRef"/>
<BasicForm @register="registerForm" ref="formRef" name="${entityName}Form"/>
<!-- 子表单区域 -->
<a-tabs v-model:activeKey="activeKey" animated @change="handleChangeTabs">
<#list subTables as sub><#rt/>
@ -157,6 +157,12 @@
if (e.error === VALIDATE_FAILED) {
// 如果有未通过表单验证的子表就自动跳转到它所在的tab
activeKey.value = e.index == null ? unref(activeKey) : refKeys.value[e.index]
if (e.errorFields) {
const firstField = e.errorFields[0];
if (firstField) {
e.scrollToField(firstField.name, { behavior: 'smooth', block: 'center' });
}
}
} else {
console.error(e)
}

View File

@ -3,7 +3,7 @@
<#if sub.foreignRelationType=='1'>
#segment#${sub.entityName}Form.vue
<template>
<BasicForm @register="registerForm"/>
<BasicForm @register="registerForm" name="${sub.entityName}Form" class="basic-modal-form"/>
</template>
<script lang="ts">
import {defineComponent} from 'vue';
@ -23,7 +23,7 @@
}
},
setup(props,{emit}) {
const [registerForm, {setProps, resetFields, setFieldsValue,getFieldsValue,validate}] = useForm({
const [registerForm, { setProps, resetFields, setFieldsValue, getFieldsValue, validate, scrollToField }] = useForm({
//labelWidth: 150,
schemas: ${sub.entityName?uncap_first}FormSchema,
showActionButtonGroup: false,
@ -60,9 +60,9 @@
// 验证子表表单
validate().then(()=>{
return resolve()
}).catch(()=> {
return reject({ error: VALIDATE_FAILED ,index})
})
}).catch(({ errorFields }) => {
return reject({ error: VALIDATE_FAILED, index, errorFields: errorFields, scrollToField: scrollToField });
});
})
}
return {
@ -75,5 +75,11 @@
}
})
</script>
<style lang="less" scoped>
.basic-modal-form {
overflow: auto;
height: 340px;
}
</style>
</#if>
</#list>

View File

@ -10,6 +10,7 @@
<#assign need_dept = false>
<#assign need_multi = false>
<#assign need_popup = false>
<#assign need_popup_dict = false>
<#assign need_select_tag = false>
<#assign need_select_tree = false>
<#assign need_time = false>
@ -20,6 +21,8 @@
<#assign need_editor = false>
<#assign need_checkbox = false>
<#assign query_flag = false>
<#assign need_range_number = false>
<#assign is_range = false>
<!--查询区域-->
<div class="jeecg-basic-table-form-container">
<a-form ref="formRef" @keyup.enter.native="reload" :model="queryParam" :label-col="labelCol" :wrapper-col="wrapperCol">
@ -56,12 +59,21 @@
<#if po.classType=='popup'>
<#assign need_popup = true>
</#if>
<#if po.classType=='popup_dict'>
<#assign need_popup_dict = true>
</#if>
<#if po.classType=='sel_tree'>
<#assign need_select_tree = true>
</#if>
<#if po.classType=='time'>
<#assign need_time = true>
</#if>
<#if po.queryMode!='single' && (po.fieldDbType=='int' || po.fieldDbType=='double' || po.fieldDbType=='BigDecimal')>
<#assign need_range_number = true>
</#if>
<#if po.queryMode!='single'>
<#assign is_range = true>
</#if>
<#include "/common/form/native/vue3NativeSearch.ftl">
</#list>
<#if query_field_no gt 2>
@ -89,9 +101,9 @@
<BasicTable @register="registerTable" :rowSelection="rowSelection">
<!--插槽:table标题-->
<template #tableTitle>
<a-button type="primary" @click="handleAdd" preIcon="ant-design:plus-outlined"> 新增</a-button>
<a-button type="primary" preIcon="ant-design:export-outlined" @click="onExportXls"> 导出</a-button>
<j-upload-button type="primary" preIcon="ant-design:import-outlined" @click="onImportXls">导入</j-upload-button>
<a-button type="primary" v-auth="'${entityPackage}:${tableName}:add'" @click="handleAdd" preIcon="ant-design:plus-outlined"> 新增</a-button>
<a-button type="primary" v-auth="'${entityPackage}:${tableName}:exportXls'" preIcon="ant-design:export-outlined" @click="onExportXls"> 导出</a-button>
<j-upload-button type="primary" v-auth="'${entityPackage}:${tableName}:importExcel'" preIcon="ant-design:import-outlined" @click="onImportXls">导入</j-upload-button>
<a-dropdown v-if="selectedRowKeys.length > 0">
<template #overlay>
<a-menu>
@ -101,7 +113,7 @@
</a-menu-item>
</a-menu>
</template>
<a-button>批量操作
<a-button v-auth="'${entityPackage}:${tableName}:deleteBatch'">批量操作
<Icon icon="mdi:chevron-down"></Icon>
</a-button>
</a-dropdown>
@ -163,6 +175,9 @@
<#if bpm_flag==true>
import { startProcess } from '/@/api/common/api';
</#if>
<#if is_range>
import { cloneDeep } from "lodash-es";
</#if>
import { useUserStore } from '/@/store/modules/user';
const formRef = ref();
const queryParam = reactive<any>({});
@ -182,8 +197,13 @@
width: 120,
fixed:'right'
},
beforeFetch: (params) => {
beforeFetch: async (params) => {
<#if is_range>
let rangerQuery = await setRangeQuery();
return Object.assign(params, rangerQuery);
<#else>
return Object.assign(params, queryParam);
</#if>
},
},
exportConfig: {
@ -269,6 +289,7 @@
{
label: '编辑',
onClick: handleEdit.bind(null, record),
auth: '${entityPackage}:${tableName}:edit'
}
]
}
@ -285,8 +306,9 @@
label: '删除',
popConfirm: {
title: '是否确认删除',
confirm: handleDelete.bind(null, record),
}
confirm: handleDelete.bind(null, record)
},
auth: '${entityPackage}:${tableName}:delete'
}
];
if(record.bpmStatus == '1' || !record.bpmStatus){
@ -310,8 +332,9 @@
popConfirm: {
title: '是否确认删除',
confirm: handleDelete.bind(null, record),
placement: 'topLeft',
}
placement: 'topLeft'
},
auth: '${entityPackage}:${tableName}:delete'
}
]
</#if>
@ -407,6 +430,32 @@
}
}
</#if>
<#if is_range>
let rangeField = '${getRangeField(columns)}'
/**
* 设置范围查询条件
*/
async function setRangeQuery(){
let queryParamClone = cloneDeep(queryParam);
if (rangeField) {
let fieldsValue = rangeField.split(',');
fieldsValue.forEach(item => {
if (queryParamClone[item]) {
let range = queryParamClone[item];
queryParamClone[item+'_begin'] = range[0];
queryParamClone[item+'_end'] = range[1];
delete queryParamClone[item];
} else {
queryParamClone[item+'_begin'] = '';
queryParamClone[item+'_end'] = '';
}
})
}
return queryParamClone;
}
</#if>
</script>
<style lang="less" scoped>
<#include "/common/form/native/vueNativeSearchStyle.ftl">

View File

@ -58,7 +58,7 @@ export const columns: BasicColumn[] = [
customRender:({text}) => {
return render.renderSwitch(text, [{text:'是',value:'${switch_extend_arr1}'},{text:'否',value:'${switch_extend_arr2}'}])
},
<#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'>
<#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' || po.classType=='popup_dict'>
dataIndex: '${po.fieldName}_dictText'
<#elseif po.classType=='cat_tree'>
dataIndex: '${po.fieldName}',

View File

@ -8,6 +8,7 @@
<#assign need_dept = false>
<#assign need_multi = false>
<#assign need_popup = false>
<#assign need_popup_dict = false>
<#assign need_select_tag = false>
<#assign need_select_tree = false>
<#assign need_time = false>
@ -16,6 +17,7 @@
<#assign need_image_upload = false>
<#assign need_editor = false>
<#assign need_checkbox = false>
<#assign need_range_number = false>
<#assign form_span = 24>
<#if tableVo.fieldRowNum==2>
<#assign form_span = 12>
@ -33,7 +35,7 @@
<a-spin :spinning="loading">
<JFormContainer :disabled="disabled">
<template #detail>
<a-form v-bind="formItemLayout">
<a-form v-bind="formItemLayout" name="${entityName}Form" ref="formRef">
<a-row>
<#list columns as po>
<#if po.isShow == 'Y' && po.fieldValidType?default("") == 'only'>
@ -42,6 +44,7 @@
<#if po.fieldDbName=='bpm_status'>
<#assign bpm_flag=true>
</#if>
<#assign formEntityName>${entityName}Form</#assign>
<#include "/common/form/native/vue3NativeForm.ftl">
</#list>
</a-row>
@ -135,6 +138,7 @@
emits:['success'],
setup(props, {emit}) {
const loading = ref(false);
const formRef = ref();
<#list subTables as sub>
<#if sub_index == 0>
<#assign subTabActiveKey = '${sub.entityName?uncap_first}'>
@ -247,6 +251,7 @@
async function queryMainData(id) {
const row = await queryDataById(id);
resetFields();
const tmpData = {};
Object.keys(formData).forEach((key) => {
if(row.hasOwnProperty(key)){
@ -268,7 +273,18 @@
});
async function getFormData() {
await validate();
try {
// 触发表单验证
await validate();
} catch ({ errorFields }) {
if (errorFields) {
const firstField = errorFields[0];
if (firstField) {
formRef.value.scrollToField(firstField.name, { behavior: 'smooth', block: 'center' });
}
}
return Promise.reject(errorFields);
}
return transformData(toRaw(formData))
}
@ -332,7 +348,8 @@
getFormData,
submitForm,
add,
edit
edit,
formRef,
}
}
});

View File

@ -12,6 +12,7 @@
<#assign need_dept = false>
<#assign need_multi = false>
<#assign need_popup = false>
<#assign need_popup_dict = false>
<#assign need_select_tag = false>
<#assign need_select_tree = false>
<#assign need_time = false>
@ -20,6 +21,7 @@
<#assign need_image_upload = false>
<#assign need_editor = false>
<#assign need_checkbox = false>
<#assign need_range_number = false>
<#assign form_span = 24>
<#if tableVo.fieldRowNum==2>
<#assign form_span = 12>
@ -33,7 +35,7 @@
<a-spin :spinning="loading">
<JFormContainer :disabled="disabled">
<template #detail>
<a-form v-bind="formItemLayout">
<a-form v-bind="formItemLayout" name="${sub.entityName}Form" ref="formRef" class="antd-modal-form">
<a-row>
<#list sub.colums as po>
<#if po.isShow == 'Y' && po.fieldValidType?default("") == 'only'>
@ -42,6 +44,7 @@
<#if po.fieldDbName=='bpm_status'>
<#assign bpm_flag=true>
</#if>
<#assign formEntityName>${sub.entityName}Form</#assign>
<#include "/common/form/native/vue3NativeForm.ftl">
</#list>
</a-row>
@ -79,6 +82,7 @@
const { createMessage } = useMessage();
const isForm = true;
const loading = ref(false);
const formRef = ref();
const formData = reactive<Record<string, any>>({
id: '',
<#include "/common/init/native/vue3NativeSubInitValue.ftl">
@ -116,7 +120,18 @@
}
async function getFormData() {
await validate();
try {
// 触发表单验证
await validate();
} catch ({ errorFields }) {
if (errorFields) {
const firstField = errorFields[0];
if (firstField) {
formRef.value.scrollToField(firstField.name, { behavior: 'smooth', block: 'center' });
}
}
return Promise.reject(errorFields);
}
let subFormData = toRaw(formData);
if(Object.keys(subFormData).length>0){
return subFormData
@ -158,10 +173,17 @@
setFieldsValue,
handleFormChange,
isForm,
validateInfos
validateInfos,
formRef,
}
}
});
</script>
<style lang="less" scoped>
.antd-modal-form {
max-height: 340px;
overflow: auto;
}
</style>
</#if>
</#list>

View File

@ -21,9 +21,9 @@
<BasicTable @register="registerTable" :rowSelection="rowSelection">
<!--插槽:table标题-->
<template #tableTitle>
<a-button type="primary" @click="handleAdd" preIcon="ant-design:plus-outlined"> 新增</a-button>
<a-button type="primary" preIcon="ant-design:export-outlined" @click="onExportXls"> 导出</a-button>
<j-upload-button type="primary" preIcon="ant-design:import-outlined" @click="onImportXls">导入</j-upload-button>
<a-button type="primary" v-auth="'${entityPackage}:${tableName}:add'" @click="handleAdd" preIcon="ant-design:plus-outlined"> 新增</a-button>
<a-button type="primary" v-auth="'${entityPackage}:${tableName}:exportXls'" preIcon="ant-design:export-outlined" @click="onExportXls"> 导出</a-button>
<j-upload-button type="primary" v-auth="'${entityPackage}:${tableName}:importExcel'" preIcon="ant-design:import-outlined" @click="onImportXls">导入</j-upload-button>
<a-dropdown v-if="selectedRowKeys.length > 0">
<template #overlay>
<a-menu>
@ -33,7 +33,7 @@
</a-menu-item>
</a-menu>
</template>
<a-button>批量操作
<a-button v-auth="'${entityPackage}:${tableName}:deleteBatch'">批量操作
<Icon icon="mdi:chevron-down"></Icon>
</a-button>
</a-dropdown>
@ -229,6 +229,7 @@
{
label: '编辑',
onClick: handleEdit.bind(null, record),
auth: '${entityPackage}:${tableName}:edit'
}
]
}
@ -263,8 +264,9 @@
popConfirm: {
title: '是否确认删除',
confirm: handleDelete.bind(null, record),
placement: 'topLeft',
}
placement: 'topLeft'
},
auth: '${entityPackage}:${tableName}:delete'
}
];
if(record.bpmStatus == '1' || !record.bpmStatus){
@ -288,8 +290,9 @@
popConfirm: {
title: '是否确认删除',
confirm: handleDelete.bind(null, record),
placement: 'topLeft',
}
placement: 'topLeft'
},
auth: '${entityPackage}:${tableName}:delete'
}
]
</#if>
@ -319,6 +322,6 @@
</#if>
</script>
<style scoped>
<style lang="less" scoped>
<#include "/common/form/vue3SearchStyle.ftl">
</style>

View File

@ -58,7 +58,7 @@ export const columns: BasicColumn[] = [
customRender:({text}) => {
return render.renderSwitch(text, [{text:'是',value:'${switch_extend_arr1}'},{text:'否',value:'${switch_extend_arr2}'}])
},
<#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'>
<#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' || po.classType=='popup_dict'>
dataIndex: '${po.fieldName}_dictText'
<#elseif po.classType=='cat_tree'>
dataIndex: '${po.fieldName}',
@ -106,6 +106,14 @@ export const searchFormSchema: FormSchema[] = [
<#-- update-begin---author:chenrui ---date:20240102 for[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- -->
component: 'JSelectUser',
<#-- update-end---author:chenrui ---date:20240102 for[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- -->
componentProps:{
<#if po.extendParams?exists && po.extendParams.text?exists>
labelKey: '${po.extendParams.text}',
</#if>
<#if po.extendParams?exists && po.extendParams.store?exists>
rowKey: '${po.extendParams.store}',
</#if>
},
<#elseif po.classType=='switch'>
component: 'JSwitch',
componentProps:{
@ -116,6 +124,14 @@ export const searchFormSchema: FormSchema[] = [
},
<#elseif po.classType=='sel_depart'>
component: 'JSelectDept',
componentProps:{
<#if po.extendParams?exists && po.extendParams.text?exists>
labelKey: '${po.extendParams.text}',
</#if>
<#if po.extendParams?exists && po.extendParams.store?exists>
rowKey: '${po.extendParams.store}',
</#if>
},
<#elseif po.classType=='list_multi'>
component: 'JSelectMultiple',
componentProps:{
@ -152,6 +168,13 @@ export const searchFormSchema: FormSchema[] = [
},
<#elseif po.classType=='popup'>
<#include "/common/form/vue3popup.ftl">
<#elseif po.classType=='popup_dict'>
component: 'JPopupDict',
componentProps: {
placeholder: '请选择${po.filedComment}',
dictCode: '${po.dictTable},${po.dictText},${po.dictField}',
multi: ${po.extendParams.popupMulti?c}
},
<#elseif po.classType=='list' || po.classType=='radio' || po.classType=='checkbox'>
<#-- ---------------------------下拉或是单选 判断数据字典是表字典还是普通字典------------------------------- -->
component: 'JDictSelectTag',
@ -272,8 +295,23 @@ export const formSchema: FormSchema[] = [
},
<#elseif po.classType =='popup'>
<#include "/common/form/vue3popup.ftl">
<#elseif po.classType=='popup_dict'>
component: 'JPopupDict',
componentProps: {
placeholder: '请选择${po.filedComment}',
dictCode: '${po.dictTable},${po.dictText},${po.dictField}',
multi: ${po.extendParams.popupMulti?c}
},
<#elseif po.classType =='sel_depart'>
component: 'JSelectDept',
componentProps:{
<#if po.extendParams?exists && po.extendParams.text?exists>
labelKey: '${po.extendParams.text}',
</#if>
<#if po.extendParams?exists && po.extendParams.store?exists>
rowKey: '${po.extendParams.store}',
</#if>
},
<#elseif po.classType =='switch'>
component: 'JSwitch',
componentProps:{
@ -294,8 +332,13 @@ export const formSchema: FormSchema[] = [
<#-- update-begin---author:chenrui ---date:20240102 for[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- -->
component: 'JSelectUser',
<#-- update-end---author:chenrui ---date:20240102 for[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- -->
componentProps:{
labelKey:'realname',
componentProps:{
<#if po.extendParams?exists && po.extendParams.text?exists>
labelKey: '${po.extendParams.text}',
</#if>
<#if po.extendParams?exists && po.extendParams.store?exists>
rowKey: '${po.extendParams.store}',
</#if>
},
<#elseif po.classType =='textarea'>
component: 'InputTextArea',
@ -505,8 +548,23 @@ export const ${sub.entityName?uncap_first}FormSchema: FormSchema[] = [
},
<#elseif po.classType =='popup'>
<#include "/common/form/vue3popup.ftl">
<#elseif po.classType=='popup_dict'>
component: 'JPopupDict',
componentProps: {
placeholder: '请选择${po.filedComment}',
dictCode: '${po.dictTable},${po.dictText},${po.dictField}',
multi: ${po.extendParams.popupMulti?c}
},
<#elseif po.classType =='sel_depart'>
component: 'JSelectDept',
componentProps:{
<#if po.extendParams?exists && po.extendParams.text?exists>
labelKey: '${po.extendParams.text}',
</#if>
<#if po.extendParams?exists && po.extendParams.store?exists>
rowKey: '${po.extendParams.store}',
</#if>
},
<#elseif po.classType =='switch'>
component: 'JSwitch',
componentProps:{
@ -527,8 +585,13 @@ export const ${sub.entityName?uncap_first}FormSchema: FormSchema[] = [
<#-- update-begin---author:chenrui ---date:20240102 for[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- -->
component: 'JSelectUser',
<#-- update-end---author:chenrui ---date:20240102 for[issue/#5711]修复用户选择组件在生成代码后变成部门用户选择组件---------- -->
componentProps:{
labelKey:'realname',
componentProps:{
<#if po.extendParams?exists && po.extendParams.text?exists>
labelKey: '${po.extendParams.text}',
</#if>
<#if po.extendParams?exists && po.extendParams.store?exists>
rowKey: '${po.extendParams.store}',
</#if>
},
<#elseif po.classType =='textarea'>
component: 'InputTextArea',
@ -762,11 +825,27 @@ export const ${sub.entityName?uncap_first}Columns: JVxeColumn[] = [
</#if>
<#elseif col.classType =='sel_depart'>
type: JVxeTypes.departSelect,
props:{
<#if col.extendParams?exists && col.extendParams.text?exists>
labelKey: '${col.extendParams.text}',
</#if>
<#if col.extendParams?exists && col.extendParams.store?exists>
rowKey: '${col.extendParams.store}',
</#if>
},
<#if col.readonly=='Y'>
disabled:true,
</#if>
<#elseif col.classType =='sel_user'>
type: JVxeTypes.userSelect,
props:{
<#if col.extendParams?exists && col.extendParams.text?exists>
labelKey: '${col.extendParams.text}',
</#if>
<#if col.extendParams?exists && col.extendParams.store?exists>
rowKey: '${col.extendParams.store}',
</#if>
},
<#if col.readonly=='Y'>
disabled:true,
</#if>

View File

@ -17,7 +17,7 @@
<!--表单区域 -->
<div class="contentArea">
<!--主表区域 -->
<BasicForm @register="registerForm" ref="formRef" v-show="activeKey == refKeys[0]"/>
<BasicForm @register="registerForm" ref="formRef" v-show="activeKey == refKeys[0]" name="${entityName}Form"/>
<!--子表区域 -->
<#list subTables as sub><#rt/>
<#assign refKey = sub.entityName?uncap_first/>
@ -192,6 +192,12 @@
if (e.error === VALIDATE_FAILED) {
// 如果有未通过表单验证的子表就自动跳转到它所在的tab
activeKey.value = e.index == null ? unref(activeKey) : refKeys.value[e.index]
if (e.errorFields) {
const firstField = e.errorFields[0];
if (firstField) {
e.scrollToField(firstField.name, { behavior: 'smooth', block: 'center' });
}
}
} else {
console.error(e)
}

View File

@ -3,7 +3,7 @@
<#if sub.foreignRelationType=='1'>
#segment#${sub.entityName}Form.vue
<template>
<BasicForm @register="registerForm"/>
<BasicForm @register="registerForm" name="${sub.entityName}Form" class="basic-modal-form" />
</template>
<script lang="ts">
import {defineComponent} from 'vue';
@ -23,7 +23,7 @@
}
},
setup(props,{emit}) {
const [registerForm, {setProps, resetFields, setFieldsValue,getFieldsValue,validate}] = useForm({
const [registerForm, { setProps, resetFields, setFieldsValue, getFieldsValue, validate, scrollToField }] = useForm({
//labelWidth: 150,
schemas: ${sub.entityName?uncap_first}FormSchema,
showActionButtonGroup: false,
@ -60,9 +60,9 @@
// 验证子表表单
validate().then(()=>{
return resolve()
}).catch(()=> {
return reject({ error: VALIDATE_FAILED ,index})
})
}).catch(({ errorFields }) => {
return reject({ error: VALIDATE_FAILED , index, errorFields: errorFields, scrollToField: scrollToField });
});
})
}
return {
@ -75,5 +75,11 @@
}
})
</script>
<style lang="less" scoped>
.basic-modal-form {
overflow: auto;
height: 340px;
}
</style>
</#if>
</#list>