代码生成器模板优化,主要与内部版本同步

pull/4246/merge
zhangdaiscott 2022-11-07 13:41:28 +08:00
parent 97736e4b5d
commit 9745b7e3ee
21 changed files with 1141 additions and 46 deletions

View File

@ -4,7 +4,7 @@
<#assign id = '${.now?string["yyyyMMddhhmmSSsss"]}0'>
INSERT INTO sys_permission(id, parent_id, name, url, component, component_name, redirect, menu_type, perms, perms_type, sort_no, always_show, icon, is_route, is_leaf, keep_alive, hidden, hide_tab, description, status, del_flag, rule_flag, create_by, create_time, update_by, update_time, internal_or_external)
VALUES ('${id}', NULL, '${tableVo.ftlDescription}', '/${entityPackage}/${entityName?uncap_first}List', '${entityPackage}/${entityName}List', NULL, NULL, 0, NULL, '1', 1.00, 0, NULL, 1, 1, 0, 0, 0, NULL, '1', 0, 0, 'admin', '${.now?string["yyyy-MM-dd HH:mm:ss"]}', NULL, NULL, 0);
VALUES ('${id}', NULL, '${tableVo.ftlDescription}', '/${entityPackage}/${entityName?uncap_first}List', '${entityPackage}/${entityName}List', NULL, NULL, 0, NULL, '1', 0.00, 0, NULL, 1, 1, 0, 0, 0, NULL, '1', 0, 0, 'admin', '${.now?string["yyyy-MM-dd HH:mm:ss"]}', NULL, NULL, 0);
-- 权限控制sql
-- 新增

View File

@ -0,0 +1,71 @@
<#include "/common/utils.ftl">
<template>
<div style="height: 400px">
<BasicForm @register="registerForm"></BasicForm>
<div style="width: 100%;text-align: center" v-if="!formDisabled">
<a-button @click="submitForm" pre-icon="ant-design:check" type="primary">提 交</a-button>
</div>
</div>
</template>
<script lang="ts">
import {BasicForm, useForm} from '/@/components/Form/index';
import {computed, defineComponent} from 'vue';
import {defHttp} from '/@/utils/http/axios';
import { propTypes } from '/@/utils/propTypes';
import {getBpmFormSchema} from '../${entityName}.data';
import {saveOrUpdate} from '../${entityName}.api';
export default defineComponent({
name: "${entityName}Form",
components:{
BasicForm
},
props:{
formData: propTypes.object.def({}),
formBpm: propTypes.bool.def(true),
},
setup(props){
const [registerForm, { setFieldsValue, setProps, getFieldsValue }] = useForm({
labelWidth: 150,
schemas: getBpmFormSchema(props.formData),
showActionButtonGroup: false,
baseColProps: {span: 24}
});
const formDisabled = computed(()=>{
if(props.formData.disabled === false){
return false;
}
return true;
});
let formData = {};
const queryByIdUrl = '/${entityPackage}/${entityName?uncap_first}/queryById';
async function initFormData(){
let params = {id: props.formData.dataId};
const data = await defHttp.get({url: queryByIdUrl, params});
formData = {...data}
//设置表单的值
await setFieldsValue(formData);
//默认是禁用
await setProps({disabled: formDisabled.value})
}
async function submitForm() {
let data = getFieldsValue();
let params = Object.assign({}, formData, data);
console.log('表单数据', params)
await saveOrUpdate(params, true)
}
initFormData();
return {
registerForm,
formDisabled,
submitForm,
}
}
});
</script>

View File

@ -141,6 +141,9 @@
<#if need_pca>
import { getAreaTextByCode } from '/@/components/Form/src/utils/Area';
</#if>
<#if bpm_flag==true>
import { startProcess } from '/@/api/common/api';
</#if>
const queryParam = ref<any>({});
const toggleSearchStatus = ref<boolean>(false);
@ -241,19 +244,43 @@
* 下拉操作栏
*/
function getDropDownAction(record) {
return [
<#if bpm_flag==true>
let dropDownAction = [
{
label: '详情',
onClick: handleDetail.bind(null, record),
},
{
}, {
label: '删除',
popConfirm: {
title: '是否确认删除',
confirm: handleDelete.bind(null, record),
},
},
}
}
];
if(record.bpmStatus == '1'){
dropDownAction.push({
label: '发起流程',
popConfirm: {
title: '确认提交流程吗?',
confirm: handleProcess.bind(null, record),
}
})
}
return dropDownAction;
<#else>
return [
{
label: '详情',
onClick: handleDetail.bind(null, record),
}, {
label: '删除',
popConfirm: {
title: '是否确认删除',
confirm: handleDelete.bind(null, record),
}
}
]
</#if>
}
/**
@ -295,6 +322,22 @@
}
</#if>
<#if bpm_flag==true>
/**
* 提交流程
*/
async function handleProcess(record) {
let params = {
flowCode: 'dev_${tableName}_001',
id: record.id,
formUrl: '${entityPackage}/components/${entityName}Form',
formUrlMobile: ''
}
await startProcess(params);
handleSuccess();
}
</#if>
<#if need_category>
/**
* form点击事件

View File

@ -38,16 +38,20 @@
</#if>
<#include "/common/form/native/vue3NativeForm.ftl">
</#list>
<#if bpm_flag>
<a-col v-if="showFlowSubmitButton" :span="24" style="width: 100%;text-align: center;">
<a-button preIcon="ant-design:check-outlined" style="width: 126px" type="primary" @click="submitForm">提 交</a-button>
</a-col>
</#if>
</a-row>
</a-form>
</a-spin>
</template>
<script lang="ts" setup>
import { ref, reactive, defineExpose, nextTick, defineProps, computed } from 'vue';
import { ref, reactive, defineExpose, nextTick, defineProps, computed, onMounted } from 'vue';
import { defHttp } from '/@/utils/http/axios';
import { useMessage } from '/@/hooks/web/useMessage';
import moment from 'moment';
<#include "/common/form/native/vue3NativeImport.ftl">
import { getValueType } from '/@/utils';
import { saveOrUpdate } from '../${entityName}.api';
@ -57,7 +61,9 @@
</#if>
const props = defineProps({
disabled: { type: Boolean, default: false },
formDisabled: { type: Boolean, default: false },
formData: { type: Object, default: ()=>{} },
formBpm: { type: Boolean, default: true }
});
const formRef = ref();
const useForm = Form.useForm;
@ -85,6 +91,43 @@
<#include "/common/validatorRulesTemplate/native/vue3MainNative.ftl">
};
const { resetFields, validate, validateInfos } = useForm(formData, validatorRules, { immediate: true });
// 表单禁用
const disabled = computed(()=>{
if(props.formBpm === true){
if(props.formData.disabled === false){
return false;
}else{
return true;
}
}
return props.formDisabled;
});
<#if bpm_flag>
onMounted(()=>{
initFormData();
});
//渲染流程表单数据
const queryByIdUrl = '/${entityPackage}/${entityName?uncap_first}/queryById';
async function initFormData(){
if(props.formBpm === true){
let params = {id: props.formData.dataId};
const data = await defHttp.get({url: queryByIdUrl, params});
//设置表单的值
edit({...data});
}
}
// 是否显示提交按钮
const showFlowSubmitButton = computed(()=>{
if(props.formBpm === true){
if(props.formData.disabled === false){
return true
}
}
return false
});
</#if>
/**
* 新增

View File

@ -1,6 +1,6 @@
<template>
<a-modal :title="title" :width="width" :visible="visible" @ok="handleOk" :okButtonProps="{ class: { 'jee-hidden': disableSubmit } }" @cancel="handleCancel" cancelText="关闭">
<${entityName}Form ref="registerForm" @ok="submitCallback" :disabled="disableSubmit"></${entityName}Form>
<${entityName}Form ref="registerForm" @ok="submitCallback" :formDisabled="disableSubmit" :formBpm="false"></${entityName}Form>
</a-modal>
</template>

View File

@ -350,7 +350,7 @@
}
}
];
if(record.bpmStatus == '1'){
if(record.bpmStatus == '1' || !record.bpmStatus){
dropDownAction.push({
label: '发起流程',
popConfirm: {
@ -384,7 +384,7 @@
let params = {
flowCode: 'dev_${tableName}_001',
id: record.id,
formUrl: '${entityPackage}/modules/${entityName}Form',
formUrl: '${entityPackage}/components/${entityName}Form',
formUrlMobile: ''
}
await startProcess(params);

View File

@ -403,3 +403,13 @@ export const formSchema: FormSchema[] = [
},
</#if>
];
/**
* 流程表单调用这个方法获取formSchema
* @param param
*/
export function getBpmFormSchema(_formData): FormSchema[]{
// 默认和原始表单保持一致 如果流程中配置了权限数据这里需要单独处理formSchema
return formSchema;
}

View File

@ -0,0 +1,71 @@
<#include "/common/utils.ftl">
<template>
<div style="height: 400px">
<BasicForm @register="registerForm"></BasicForm>
<div style="width: 100%;text-align: center" v-if="!formDisabled">
<a-button @click="submitForm" pre-icon="ant-design:check" type="primary">提 交</a-button>
</div>
</div>
</template>
<script lang="ts">
import {BasicForm, useForm} from '/@/components/Form/index';
import {computed, defineComponent} from 'vue';
import {defHttp} from '/@/utils/http/axios';
import { propTypes } from '/@/utils/propTypes';
import {getBpmFormSchema} from '../${entityName}.data';
import {saveOrUpdateDict} from '../${entityName}.api';
export default defineComponent({
name: "${entityName}Form",
components:{
BasicForm
},
props:{
formData: propTypes.object.def({}),
formBpm: propTypes.bool.def(true),
},
setup(props){
const [registerForm, { setFieldsValue, setProps, getFieldsValue }] = useForm({
labelWidth: 150,
schemas: getBpmFormSchema(props.formData),
showActionButtonGroup: false,
baseColProps: {span: 24}
});
const formDisabled = computed(()=>{
if(props.formData.disabled === false){
return false;
}
return true;
});
let formData = {};
const queryByIdUrl = '/${entityPackage}/${entityName?uncap_first}/queryById';
async function initFormData(){
let params = {id: props.formData.dataId};
const data = await defHttp.get({url: queryByIdUrl, params});
formData = {...data}
//设置表单的值
await setFieldsValue(formData);
//默认是禁用
await setProps({disabled: formDisabled.value})
}
async function submitForm() {
let data = getFieldsValue();
let params = Object.assign({}, formData, data);
console.log('表单数据', params)
await saveOrUpdateDict(params, true)
}
initFormData();
return {
registerForm,
formDisabled,
submitForm,
}
}
});
</script>

View File

@ -150,6 +150,9 @@
<#if need_pca>
import { getAreaTextByCode } from '/@/components/Form/src/utils/Area';
</#if>
<#if bpm_flag==true>
import { startProcess } from '/@/api/common/api';
</#if>
const expandedRowKeys = ref([]);
const queryParam = ref<any>({});
@ -381,12 +384,14 @@
}
];
}
/**
* 下拉操作栏
*/
function getDropDownAction(record) {
return [
function getDropDownAction(record){
<#if bpm_flag==true>
let dropDownAction = [
{
label: '详情',
onClick: handleDetail.bind(null, record),
@ -394,7 +399,7 @@
{
label: '添加下级',
onClick: handleAddSub.bind(null, { pid: record.id }),
},
},
{
label: '删除',
popConfirm: {
@ -403,8 +408,54 @@
},
},
];
if(record.bpmStatus == '1' || !record.bpmStatus){
dropDownAction.push({
label: '发起流程',
popConfirm: {
title: '确认提交流程吗?',
confirm: handleProcess.bind(null, record),
}
})
}
return dropDownAction;
<#else>
return [
{
label: '详情',
onClick: handleDetail.bind(null, record),
},
{
label: '添加下级',
onClick: handleAddSub.bind(null, { pid: record.id }),
},
{
label: '删除',
popConfirm: {
title: '确定删除吗?',
confirm: handleDelete.bind(null, record),
},
},
];
</#if>
}
<#if bpm_flag==true>
/**
* 提交流程
*/
async function handleProcess(record) {
let params = {
flowCode: 'dev_${tableName}_001',
id: record.id,
formUrl: '${entityPackage}/components/${entityName}Form',
formUrlMobile: ''
}
await startProcess(params);
await reload();
}
</#if>
/**
* 查询
*/

View File

@ -56,16 +56,20 @@
</#if>
<#include "/common/form/native/vue3NativeForm.ftl">
</#list>
<#if bpm_flag>
<a-col v-if="showFlowSubmitButton" :span="24" style="width: 100%;text-align: center;">
<a-button preIcon="ant-design:check-outlined" style="width: 126px" type="primary" @click="submitForm">提 交</a-button>
</a-col>
</#if>
</a-row>
</a-form>
</a-spin>
</template>
<script lang="ts" setup>
import { ref, reactive, defineExpose, nextTick, unref, defineProps, computed } from 'vue';
import { ref, reactive, defineExpose, nextTick, unref, defineProps, computed, onMounted } from 'vue';
import { defHttp } from '/@/utils/http/axios';
import { useMessage } from '/@/hooks/web/useMessage';
import moment from 'moment';
<#include "/common/form/native/vue3NativeImport.ftl">
import { getValueType } from '/@/utils';
import {loadTreeData, saveOrUpdateDict} from '../${entityName}.api';
@ -106,8 +110,47 @@
};
const { resetFields, validate, validateInfos } = useForm(formData, validatorRules, { immediate: true });
const props = defineProps({
disabled: { type: Boolean, default: false },
formDisabled: { type: Boolean, default: false },
formData: { type: Object, default: ()=>{} },
formBpm: { type: Boolean, default: true }
});
// 表单禁用
const disabled = computed(()=>{
if(props.formBpm === true){
if(props.formData.disabled === false){
return false;
}else{
return true;
}
}
return props.formDisabled;
});
<#if bpm_flag>
onMounted(()=>{
initFormData();
});
//渲染流程表单数据
const queryByIdUrl = '/${entityPackage}/${entityName?uncap_first}/queryById';
async function initFormData(){
if(props.formBpm === true){
let params = {id: props.formData.dataId};
const data = await defHttp.get({url: queryByIdUrl, params});
//设置表单的值
edit({...data});
}
}
// 是否显示提交按钮
const showFlowSubmitButton = computed(()=>{
if(props.formBpm === true){
if(props.formData.disabled === false){
return true
}
}
return false
});
</#if>
/**
* 新增

View File

@ -1,6 +1,6 @@
<template>
<a-modal :title="title" :width="width" :visible="visible" @ok="handleOk" :okButtonProps="{ class: { 'jee-hidden': disableSubmit } }" @cancel="handleCancel" cancelText="关闭">
<${entityName}Form ref="registerForm" @ok="submitCallback" :disabled="disableSubmit"></${entityName}Form>
<${entityName}Form ref="registerForm" @ok="submitCallback" :formDisabled="disableSubmit" :formBpm="false"></${entityName}Form>
</a-modal>
</template>

View File

@ -230,7 +230,7 @@
let params = {
flowCode: 'dev_${tableName}_001',
id: record.id,
formUrl: '${entityPackage}/modules/${entityName}Form',
formUrl: '${entityPackage}/components/${entityName}Form',
formUrlMobile: ''
}
await startProcess(params);
@ -255,7 +255,7 @@
}
}
];
if(record.bpmStatus == '1'){
if(record.bpmStatus == '1' || !record.bpmStatus){
dropDownAction.push({
label: '发起流程',
popConfirm: {

View File

@ -794,4 +794,13 @@ export const ${sub.entityName?uncap_first}JVxeColumns: JVxeColumn[] = [
<#-- 循环子表的列 结束 -->
]
</#if>
</#list>
</#list>
/**
* 流程表单调用这个方法获取formSchema
* @param param
*/
export function getBpmFormSchema(_formData): FormSchema[]{
// 默认和原始表单保持一致 如果流程中配置了权限数据这里需要单独处理formSchema
return formSchema;
}

View File

@ -0,0 +1,208 @@
<#include "/common/utils.ftl">
<template>
<div>
<BasicForm @register="registerForm" ref="formRef"/>
<!-- 子表单区域 -->
<a-tabs v-model:activeKey="activeKey" @change="handleChangeTabs">
<#list subTables as sub><#rt/>
<#assign refKey = sub.entityName?uncap_first/>
<#if sub.foreignRelationType =='1'>
<a-tab-pane tab="${sub.ftlDescription}" key="${refKey}" :forceRender="true">
<${sub.entityName}Form ref="${sub.entityName?uncap_first}Form" :disabled="formDisabled"></${sub.entityName}Form>
</a-tab-pane>
<#else>
<a-tab-pane tab="${sub.ftlDescription}" key="${refKey}" :forceRender="true">
<JVxeTable
keep-source
resizable
ref="${refKey}"
:loading="${sub.entityName?uncap_first}Table.loading"
:columns="${sub.entityName?uncap_first}Table.columns"
:dataSource="${sub.entityName?uncap_first}Table.dataSource"
:height="340"
:disabled="formDisabled"
:rowNumber="true"
:rowSelection="true"
:toolbar="true"
/>
</a-tab-pane>
</#if>
</#list>
</a-tabs>
<div style="width: 100%;text-align: center;margin-top: 10px;" v-if="showFlowSubmitButton">
<a-button preIcon="ant-design:check-outlined" style="width: 126px" type="primary" @click="handleSubmit">提 交</a-button>
</div>
</div>
</template>
<script lang="ts" setup>
import { defHttp } from '/@/utils/http/axios';
import {ref, computed, unref,reactive, onMounted, defineProps } from 'vue';
import {BasicForm, useForm} from '/@/components/Form/index';
import { JVxeTable } from '/@/components/jeecg/JVxeTable'
import { useJvxeMethod } from '/@/hooks/system/useJvxeMethods.ts'
<#list subTables as sub>
<#if sub.foreignRelationType =='1'>
import ${sub.entityName}Form from './${sub.entityName}Form.vue'
</#if>
</#list>
import {formSchema<#list subTables as sub><#if sub.foreignRelationType =='0'>,${sub.entityName?uncap_first}JVxeColumns</#if></#list>} from '../${entityName}.data';
import {saveOrUpdate<#list subTables as sub>,query${sub.entityName}</#list>} from '../${entityName}.api';
import { VALIDATE_FAILED } from '/@/utils/common/vxeUtils'
const isUpdate = ref(true);
const refKeys = ref([<#list subTables as sub>'${sub.entityName?uncap_first}', </#list>]);
<#assign hasOne2Many = false>
<#assign hasOne2One = false>
const activeKey = ref('${subTables[0].entityName?uncap_first}');
<#list subTables as sub>
<#if sub.foreignRelationType =='0'>
<#assign hasOne2Many = true>
const ${sub.entityName?uncap_first} = ref();
</#if>
<#if sub.foreignRelationType =='1'>
<#assign hasOne2One = true>
const ${sub.entityName?uncap_first}Form = ref();
</#if>
</#list>
const tableRefs = {<#list subTables as sub><#if sub.foreignRelationType =='0'>${sub.entityName?uncap_first}, <#assign hasOne2Many = true></#if></#list>};
<#list subTables as sub>
<#if sub.foreignRelationType =='0'>
const ${sub.entityName?uncap_first}Table = reactive({
loading: false,
dataSource: [],
columns:${sub.entityName?uncap_first}JVxeColumns
})
</#if>
</#list>
const props = defineProps({
formData: { type: Object, default: ()=>{} },
formBpm: { type: Boolean, default: true }
});
const formDisabled = computed(()=>{
if(props.formBpm === true){
if(props.formData.disabled === false){
return false;
}
}
return true;
});
// 是否显示提交按钮
const showFlowSubmitButton = computed(()=>{
if(props.formBpm === true){
if(props.formData.disabled === false){
return true
}
}
return false
});
//表单配置
const [registerForm, {setProps,resetFields, setFieldsValue, validate}] = useForm({
labelWidth: 150,
schemas: formSchema,
showActionButtonGroup: false,
baseColProps: {span: ${getFormSpan(tableVo.fieldRowNum?default(1))}}
});
onMounted(()=>{
initFormData();
});
//渲染流程表单数据
const queryByIdUrl = '/${entityPackage}/${entityName?uncap_first}/queryById';
async function initFormData(){
if(props.formBpm === true){
await reset();
let params = {id: props.formData.dataId};
const data = await defHttp.get({url: queryByIdUrl, params});
//表单赋值
await setFieldsValue({
...data
});
<#list subTables as sub><#rt/>
<#if sub.foreignRelationType =='1'>
${sub.entityName?uncap_first}Form.value.initFormData(query${sub.entityName}, data.id)
</#if>
</#list>
<#list subTables as sub><#rt/>
<#if sub.foreignRelationType =='0'>
requestSubTableData(query${sub.entityName}, {id: data.id}, ${sub.entityName?uncap_first}Table)
</#if>
</#list>
// 隐藏底部时禁用整个表单
setProps({ disabled: formDisabled.value })
}
}
//方法配置
const [handleChangeTabs,handleSubmit,requestSubTableData,formRef] = useJvxeMethod(requestAddOrEdit,classifyIntoFormData,tableRefs,activeKey,refKeys<#if hasOne2One==true>,validateSubForm</#if>);
async function reset(){
await resetFields();
activeKey.value = '${subTables[0].entityName?uncap_first}';
<#list subTables as sub>
<#if sub.foreignRelationType =='0'>
${sub.entityName?uncap_first}Table.dataSource = [];
</#if>
<#if sub.foreignRelationType =='1'>
${sub.entityName?uncap_first}Form.value.resetFields();
</#if>
</#list>
}
function classifyIntoFormData(allValues) {
let main = Object.assign({}, allValues.formValue)
return {
...main, // 展开
<#assign subManyIndex = 0>
<#list subTables as sub><#rt/>
<#if sub.foreignRelationType =='0'>
${sub.entityName?uncap_first}List: allValues.tablesValue[${subManyIndex}].tableData,
<#assign subManyIndex = subManyIndex+1>
<#else>
${sub.entityName?uncap_first}List: ${sub.entityName?uncap_first}Form.value.getFormData(),
</#if>
</#list>
}
}
<#if hasOne2One==true>
//校验所有一对一子表表单
function validateSubForm(allValues){
return new Promise((resolve,reject)=>{
Promise.all([
<#list subTables as sub><#rt/>
<#if sub.foreignRelationType =='1'>
${sub.entityName?uncap_first}Form.value.validateForm(${sub_index}),
</#if>
</#list>
]).then(() => {
resolve(allValues)
}).catch(e => {
if (e.error === VALIDATE_FAILED) {
// 如果有未通过表单验证的子表就自动跳转到它所在的tab
activeKey.value = e.index == null ? unref(activeKey) : refKeys.value[e.index]
} else {
console.error(e)
}
})
})
}
</#if>
//表单提交事件
async function requestAddOrEdit(values) {
//提交表单
await saveOrUpdate(values, true);
}
</script>
<style lang="less" scoped>
/** 时间和数字输入框样式 */
:deep(.ant-input-number){
width: 100%
}
:deep(.ant-calendar-picker){
width: 100%
}
</style>

View File

@ -229,7 +229,7 @@
}
}
];
if(record.bpmStatus == '1'){
if(record.bpmStatus == '1' || !record.bpmStatus){
dropDownAction.push({
label: '发起流程',
popConfirm: {

View File

@ -0,0 +1,199 @@
<#include "/common/utils.ftl">
<template>
<div>
<BasicForm @register="registerForm" ref="formRef"/>
<!-- 子表单区域 -->
<a-tabs v-model:activeKey="activeKey" @change="handleChangeTabs">
<#list subTables as sub><#rt/>
<#assign refKey = sub.entityName?uncap_first/>
<#if sub.foreignRelationType =='1'>
<a-tab-pane tab="${sub.ftlDescription}" key="${refKey}" :forceRender="true">
<${sub.entityName}Form ref="${sub.entityName?uncap_first}Form" :disabled="formDisabled"></${sub.entityName}Form>
</a-tab-pane>
<#else>
<a-tab-pane tab="${sub.ftlDescription}" key="${refKey}" :forceRender="true">
<JVxeTable
keep-source
resizable
ref="${refKey}"
:loading="${sub.entityName?uncap_first}Table.loading"
:columns="${sub.entityName?uncap_first}Table.columns"
:dataSource="${sub.entityName?uncap_first}Table.dataSource"
:height="340"
:rowNumber="true"
:rowSelection="true"
:disabled="formDisabled"
:toolbar="true"
/>
</a-tab-pane>
</#if>
</#list>
</a-tabs>
<div style="width: 100%;text-align: center" v-if="!formDisabled">
<a-button @click="handleSubmit" pre-icon="ant-design:check" type="primary">提 交</a-button>
</div>
</div>
</template>
<script lang="ts">
import {BasicForm, useForm} from '/@/components/Form/index';
import { computed, defineComponent, reactive, ref, unref } from 'vue';
import {defHttp} from '/@/utils/http/axios';
import { propTypes } from '/@/utils/propTypes';
import { useJvxeMethod } from '/@/hooks/system/useJvxeMethods';
import { VALIDATE_FAILED } from '/@/utils/common/vxeUtils';
<#list subTables as sub>
<#if sub.foreignRelationType =='1'>
import ${sub.entityName}Form from './${sub.entityName}Form.vue'
</#if>
</#list>
import {getBpmFormSchema<#list subTables as sub><#if sub.foreignRelationType =='0'>,${sub.entityName?uncap_first}Columns</#if></#list>} from '../${entityName}.data';
import {saveOrUpdate<#list subTables as sub>,${sub.entityName?uncap_first}List</#list>} from '../${entityName}.api';
export default defineComponent({
name: "${entityName}Form",
components:{
BasicForm,
<#list subTables as sub>
<#if sub.foreignRelationType =='1'>
${sub.entityName}Form,
</#if>
</#list>
},
props:{
formData: propTypes.object.def({}),
formBpm: propTypes.bool.def(true),
},
setup(props){
const [registerForm, { setFieldsValue, setProps }] = useForm({
labelWidth: 150,
schemas: getBpmFormSchema(props.formData),
showActionButtonGroup: false,
baseColProps: {span: 24}
});
const formDisabled = computed(()=>{
if(props.formData.disabled === false){
return false;
}
return true;
});
<#assign hasOne2Many = false>
<#assign hasOne2One = false>
const refKeys = ref([<#list subTables as sub>'${sub.entityName?uncap_first}', </#list>]);
const activeKey = ref('${subTables[0].entityName?uncap_first}');
<#list subTables as sub>
<#if sub.foreignRelationType =='0'>
<#assign hasOne2Many = true>
const ${sub.entityName?uncap_first} = ref();
</#if>
<#if sub.foreignRelationType =='1'>
<#assign hasOne2One = true>
const ${sub.entityName?uncap_first}Form = ref();
</#if>
</#list>
const tableRefs = {<#list subTables as sub><#if sub.foreignRelationType =='0'>${sub.entityName?uncap_first}, <#assign hasOne2Many = true></#if></#list>};
<#list subTables as sub>
<#if sub.foreignRelationType =='0'>
const ${sub.entityName?uncap_first}Table = reactive({
loading: false,
dataSource: [],
columns:${sub.entityName?uncap_first}Columns
})
</#if>
</#list>
const [handleChangeTabs,handleSubmit,requestSubTableData,formRef] = useJvxeMethod(requestAddOrEdit,classifyIntoFormData,tableRefs,activeKey,refKeys,validateSubForm);
function classifyIntoFormData(allValues) {
let main = Object.assign({}, allValues.formValue)
return {
...main, // 展开
<#assign subManyIndex = 0>
<#list subTables as sub><#rt/>
<#if sub.foreignRelationType =='0'>
${sub.entityName?uncap_first}List: allValues.tablesValue[${subManyIndex}].tableData,
<#assign subManyIndex = subManyIndex+1>
<#else>
${sub.entityName?uncap_first}List: ${sub.entityName?uncap_first}Form.value.getFormData(),
</#if>
</#list>
}
}
<#if hasOne2One==true>
//校验所有一对一子表表单
function validateSubForm(allValues){
return new Promise((resolve, _reject)=>{
Promise.all([
<#list subTables as sub><#rt/>
<#if sub.foreignRelationType =='1'>
${sub.entityName?uncap_first}Form.value.validateForm(${sub_index}),
</#if>
</#list>
]).then(() => {
resolve(allValues)
}).catch(e => {
if (e.error === VALIDATE_FAILED) {
// 如果有未通过表单验证的子表就自动跳转到它所在的tab
activeKey.value = e.index == null ? unref(activeKey) : refKeys.value[e.index]
} else {
console.error(e)
}
})
})
}
</#if>
//表单提交事件
async function requestAddOrEdit(values) {
await saveOrUpdate(values, true);
}
const queryByIdUrl = '/${entityPackage}/${entityName?uncap_first}/queryById';
async function initFormData(){
let params = {id: props.formData.dataId};
const data = await defHttp.get({url: queryByIdUrl, params});
//设置表单的值
await setFieldsValue({...data});
<#list subTables as sub>
<#if sub.foreignRelationType =='0'>
requestSubTableData(${sub.entityName?uncap_first}List, {id: data.id}, ${sub.entityName?uncap_first}Table, ()=>{});
</#if>
<#if sub.foreignRelationType =='1'>
${sub.entityName?uncap_first}Form.value.initFormData(${sub.entityName?uncap_first}List, data.id);
</#if>
</#list>
//默认是禁用
await setProps({disabled: formDisabled.value})
}
initFormData();
return {
registerForm,
formDisabled,
formRef,
handleSubmit,
activeKey,
handleChangeTabs,
<#list subTables as sub>
<#if sub.foreignRelationType =='0'>
${sub.entityName?uncap_first},
</#if>
<#if sub.foreignRelationType =='1'>
${sub.entityName?uncap_first}Form,
</#if>
</#list>
<#list subTables as sub>
<#if sub.foreignRelationType =='0'>
${sub.entityName?uncap_first}Table,
</#if>
</#list>
}
}
});
</script>

View File

@ -145,6 +145,10 @@
import { getAuthCache, setAuthCache } from '/@/utils/auth';
import { DB_DICT_DATA_KEY } from '/@/enums/cacheEnum';
</#if>
<#if bpm_flag==true>
import { startProcess } from '/@/api/common/api';
</#if>
const checkedKeys = ref<Array<string | number>>([]);
//注册model
const [registerModal, {openModal}] = useModal();
@ -238,19 +242,61 @@
* 下拉操作栏
*/
function getDropDownAction(record){
return [
{
label: '详情',
onClick: handleDetail.bind(null, record),
}, {
label: '删除',
popConfirm: {
title: '是否确认删除',
confirm: handleDelete.bind(null, record),
}
<#if bpm_flag==true>
let dropDownAction = [
{
label: '详情',
onClick: handleDetail.bind(null, record),
}, {
label: '删除',
popConfirm: {
title: '是否确认删除',
confirm: handleDelete.bind(null, record),
}
]
}
];
if(record.bpmStatus == '1' || !record.bpmStatus){
dropDownAction.push({
label: '发起流程',
popConfirm: {
title: '确认提交流程吗?',
confirm: handleProcess.bind(null, record),
}
})
}
return dropDownAction;
<#else>
return [
{
label: '详情',
onClick: handleDetail.bind(null, record),
}, {
label: '删除',
popConfirm: {
title: '是否确认删除',
confirm: handleDelete.bind(null, record),
}
}
]
</#if>
}
<#if bpm_flag==true>
/**
* 提交流程
*/
async function handleProcess(record) {
let params = {
flowCode: 'dev_${tableName}_001',
id: record.id,
formUrl: '${entityPackage}/components/${entityName}Form',
formUrlMobile: ''
}
await startProcess(params);
handleSuccess();
}
</#if>
<#if need_category>
/**
* form点击事件

View File

@ -50,7 +50,7 @@
<#list subTables as sub><#rt/>
<a-tab-pane tab="${sub.ftlDescription}" key="${sub.entityName?uncap_first}" :forceRender="true">
<#if sub.foreignRelationType =='1'>
<${Format.humpToShortbar(sub.entityName)}-form ref="${sub.entityName?uncap_first}FormRef" :disabled="formDisabled"></${Format.humpToShortbar(sub.entityName)}-form>
<${Format.humpToShortbar(sub.entityName)}-form ref="${sub.entityName?uncap_first}FormRef" :disabled="disabled"></${Format.humpToShortbar(sub.entityName)}-form>
<#else>
<j-vxe-table
:keep-source="true"
@ -59,7 +59,7 @@
:columns="${sub.entityName?uncap_first}Table.columns"
:dataSource="${sub.entityName?uncap_first}Table.dataSource"
:maxHeight="300"
:disabled="formDisabled"
:disabled="disabled"
:rowNumber="true"
:rowSelection="true"
:toolbar="true"/>
@ -67,11 +67,17 @@
</a-tab-pane>
</#list>
</a-tabs>
<#if bpm_flag>
<div v-if="showFlowSubmitButton" :span="24" style="width: 100%;text-align: center;margin-top: 10px">
<a-button preIcon="ant-design:check-outlined" style="width: 126px" type="primary" @click="submitForm">提 交</a-button>
</div>
</#if>
</a-spin>
</template>
<script lang="ts">
import { defineComponent, ref, reactive, computed, toRaw } from 'vue';
import { defineComponent, ref, reactive, computed, toRaw, onMounted } from 'vue';
import { defHttp } from '/@/utils/http/axios';
import { useValidateAntFormAndTable } from '/@/hooks/system/useJvxeMethods';
import { <#list subTables as sub><#if sub.foreignRelationType =='0'>query${sub.entityName}ListByMainId, </#if></#list>queryDataById, saveOrUpdate } from '../${entityName}.api';
<#list subTables as sub>
@ -112,10 +118,12 @@
</#list>
},
props:{
disabled:{
formDisabled:{
type: Boolean,
default: false
}
},
formData: { type: Object, default: ()=>{} },
formBpm: { type: Boolean, default: true }
},
emits:['success'],
setup(props, {emit}) {
@ -160,10 +168,55 @@
wrapperCol: {xs: {span: 24}, sm: {span: 16}},
};
const formDisabled = computed(() => {
return props.disabled;
// 表单禁用
const disabled = computed(()=>{
if(props.formBpm === true){
if(props.formData.disabled === false){
return false;
}else{
return true;
}
}
return props.formDisabled;
});
<#if bpm_flag>
onMounted(()=>{
initFormData();
});
//渲染流程表单数据
const queryByIdUrl = '/${entityPackage}/${entityName?uncap_first}/queryById';
async function initFormData(){
if(props.formBpm === true){
let params = {id: props.formData.dataId};
const row = await defHttp.get({url: queryByIdUrl, params});
//设置表单的值
Object.keys(row).map(k => {
formData[k] = row[k];
});
//子表数据
<#list subTables as sub>
<#if sub.foreignRelationType =='1'>
await ${sub.entityName?uncap_first}FormRef.value.initFormData(row['${subMainFieldMap[sub.entityName]}']);
<#else>
const ${sub.entityName?uncap_first}DataList = await query${sub.entityName}ListByMainId(row['${subMainFieldMap[sub.entityName]}']);
${sub.entityName?uncap_first}Table.dataSource = [...${sub.entityName?uncap_first}DataList];
</#if>
</#list>
}
}
// 是否显示提交按钮
const showFlowSubmitButton = computed(()=>{
if(props.formBpm === true){
if(props.formData.disabled === false){
return true
}
}
return false
});
</#if>
function add() {
resetFields();
<#list subTables as sub>
@ -264,7 +317,10 @@
setFieldsValue,
handleFormChange,
formItemLayout,
formDisabled,
disabled,
<#if bpm_flag>
showFlowSubmitButton,
</#if>
getFormData,
submitForm,
add,

View File

@ -1,7 +1,7 @@
<#include "/common/utils.ftl">
<template>
<BasicModal v-bind="$attrs" @register="registerModal" :title="title" :width="${getModalWidth(tableVo.fieldRowNum?default(1))}" @ok="handleSubmit">
<${Format.humpToShortbar(entityName)}-form ref="formComponent" :disabled="formDisabled" @success="submitSuccess"></${Format.humpToShortbar(entityName)}-form>
<${Format.humpToShortbar(entityName)}-form ref="formComponent" :formDisabled="formDisabled" :formBpm="false" @success="submitSuccess"></${Format.humpToShortbar(entityName)}-form>
</BasicModal>
</template>

View File

@ -204,7 +204,7 @@
let params = {
flowCode: 'dev_${tableName}_001',
id: record.id,
formUrl: '${entityPackage}/modules/${entityName}Form',
formUrl: '${entityPackage}/components/${entityName}Form',
formUrlMobile: ''
}
await startProcess(params);
@ -229,7 +229,7 @@
}
}
];
if(record.bpmStatus == '1'){
if(record.bpmStatus == '1' || !record.bpmStatus){
dropDownAction.push({
label: '发起流程',
popConfirm: {

View File

@ -0,0 +1,245 @@
<#include "/common/utils.ftl">
<template>
<div>
<!-- 子表单区域 -->
<a-tabs v-model:activeKey="activeKey" @change="handleChangeTabs">
<!--主表区域 -->
<a-tab-pane tab="${tableVo.ftlDescription}" :key="refKeys[0]" :forceRender="true" :style="tabsStyle">
<BasicForm @register="registerForm" ref="formRef"/>
</a-tab-pane>
<!--子表单区域 -->
<#list subTables as sub><#rt/>
<#assign refKey = sub.entityName?uncap_first/>
<#if sub.foreignRelationType =='1'>
<a-tab-pane tab="${sub.ftlDescription}" key="${refKey}" :forceRender="true" :style="tabsStyle">
<${sub.entityName}Form ref="${sub.entityName?uncap_first}Form" :disabled="formDisabled"></${sub.entityName}Form>
</a-tab-pane>
<#else>
<a-tab-pane tab="${sub.ftlDescription}" key="${refKey}" :forceRender="true" :style="tabsStyle">
<JVxeTable
keep-source
resizable
ref="${refKey}"
:loading="${sub.entityName?uncap_first}Table.loading"
:columns="${sub.entityName?uncap_first}Table.columns"
:dataSource="${sub.entityName?uncap_first}Table.dataSource"
:height="340"
:disabled="formDisabled"
:rowNumber="true"
:rowSelection="true"
:toolbar="true"
/>
</a-tab-pane>
</#if>
</#list>
</a-tabs>
<div style="width: 100%;text-align: center;margin-top: 10px;" v-if="showFlowSubmitButton">
<a-button preIcon="ant-design:check-outlined" style="width: 126px" type="primary" @click="handleSubmit">提 交</a-button>
</div>
</div>
</template>
<script lang="ts" setup>
import { defHttp } from '/@/utils/http/axios';
import {ref, computed, unref,reactive, onMounted, defineProps } from 'vue';
import {BasicForm, useForm} from '/@/components/Form/index';
import { JVxeTable } from '/@/components/jeecg/JVxeTable'
import { useJvxeMethod } from '/@/hooks/system/useJvxeMethods.ts'
<#list subTables as sub>
<#if sub.foreignRelationType =='1'>
import ${sub.entityName}Form from './${sub.entityName}Form.vue'
</#if>
</#list>
import {formSchema<#list subTables as sub><#if sub.foreignRelationType =='0'>,${sub.entityName?uncap_first}Columns</#if></#list>} from '../${entityName}.data';
import {saveOrUpdate<#list subTables as sub>,${sub.entityName?uncap_first}List</#list>} from '../${entityName}.api';
import { VALIDATE_FAILED } from '/@/utils/common/vxeUtils'
const refKeys = ref(['${tableVo.entityName?uncap_first}',<#list subTables as sub>'${sub.entityName?uncap_first}', </#list>]);
<#assign hasOne2Many = false>
<#assign hasOne2One = false>
const activeKey = ref('${tableVo.entityName?uncap_first}');
<#list subTables as sub>
<#if sub.foreignRelationType =='0'>
<#assign hasOne2Many = true>
const ${sub.entityName?uncap_first} = ref();
</#if>
<#if sub.foreignRelationType =='1'>
<#assign hasOne2One = true>
const ${sub.entityName?uncap_first}Form = ref();
</#if>
</#list>
const tableRefs = {<#list subTables as sub><#if sub.foreignRelationType =='0'>${sub.entityName?uncap_first}, <#assign hasOne2Many = true></#if></#list>};
<#list subTables as sub>
<#if sub.foreignRelationType =='0'>
const ${sub.entityName?uncap_first}Table = reactive({
loading: false,
dataSource: [],
columns:${sub.entityName?uncap_first}Columns
})
</#if>
</#list>
const props = defineProps({
formData: { type: Object, default: ()=>{} },
formBpm: { type: Boolean, default: true }
});
const formDisabled = computed(()=>{
if(props.formBpm === true){
if(props.formData.disabled === false){
return false;
}
}
return true;
});
// 是否显示提交按钮
const showFlowSubmitButton = computed(()=>{
if(props.formBpm === true){
if(props.formData.disabled === false){
return true
}
}
return false
});
//表单配置
const [registerForm, {setProps,resetFields, setFieldsValue, validate}] = useForm({
labelWidth: 150,
schemas: formSchema,
showActionButtonGroup: false,
baseColProps: {span: ${getFormSpan(tableVo.fieldRowNum?default(1))}}
});
onMounted(()=>{
initFormData();
});
//渲染流程表单数据
const queryByIdUrl = '/${entityPackage}/${entityName?uncap_first}/queryById';
async function initFormData(){
if(props.formBpm === true){
await reset();
let params = {id: props.formData.dataId};
const data = await defHttp.get({url: queryByIdUrl, params});
//表单赋值
await setFieldsValue({
...data
});
<#list subTables as sub><#rt/>
<#if sub.foreignRelationType =='1'>
${sub.entityName?uncap_first}Form.value.initFormData(${sub.entityName?uncap_first}List, data.id)
</#if>
</#list>
<#list subTables as sub><#rt/>
<#if sub.foreignRelationType =='0'>
requestSubTableData(${sub.entityName?uncap_first}List, {id: data.id}, ${sub.entityName?uncap_first}Table)
</#if>
</#list>
// 隐藏底部时禁用整个表单
setProps({ disabled: formDisabled.value })
}
}
//方法配置
const [handleChangeTabs,handleSubmit,requestSubTableData,formRef] = useJvxeMethod(requestAddOrEdit,classifyIntoFormData,tableRefs,activeKey,refKeys<#if hasOne2One==true>,validateSubForm</#if>);
// 弹窗tabs滚动区域的高度
const tabsStyle = computed(() => {
let height: Nullable<string> = null
let minHeight = '100px'
let maxHeight: Nullable<string> = '500px'
// 弹窗wrapper
return {height, minHeight, maxHeight}
})
async function reset(){
await resetFields();
activeKey.value = '${tableVo.entityName?uncap_first}';
<#list subTables as sub>
<#if sub.foreignRelationType =='0'>
${sub.entityName?uncap_first}Table.dataSource = [];
</#if>
<#if sub.foreignRelationType =='1'>
${sub.entityName?uncap_first}Form.value.resetFields();
</#if>
</#list>
}
function classifyIntoFormData(allValues) {
let main = Object.assign({}, allValues.formValue)
return {
...main, // 展开
<#assign subManyIndex = 0>
<#list subTables as sub><#rt/>
<#if sub.foreignRelationType =='0'>
${sub.entityName?uncap_first}List: allValues.tablesValue[${subManyIndex}].tableData,
<#assign subManyIndex = subManyIndex+1>
<#else>
${sub.entityName?uncap_first}List: ${sub.entityName?uncap_first}Form.value.getFormData(),
</#if>
</#list>
}
}
<#if hasOne2One==true>
//校验所有一对一子表表单
function validateSubForm(allValues){
return new Promise((resolve,reject)=>{
Promise.all([
<#list subTables as sub><#rt/>
<#if sub.foreignRelationType =='1'>
${sub.entityName?uncap_first}Form.value.validateForm(${sub_index+1}),
</#if>
</#list>
]).then(() => {
resolve(allValues)
}).catch(e => {
if (e.error === VALIDATE_FAILED) {
// 如果有未通过表单验证的子表就自动跳转到它所在的tab
activeKey.value = e.index == null ? unref(activeKey) : refKeys.value[e.index]
} else {
console.error(e)
}
})
})
}
</#if>
//表单提交事件
async function requestAddOrEdit(values) {
//提交表单
await saveOrUpdate(values, true);
}
</script>
<style lang="less" scoped>
/** 时间和数字输入框样式 */
:deep(.ant-input-number){
width: 100%
}
:deep(.ant-calendar-picker){
width: 100%
}
</style>
<style lang="less">
// Online表单Tab风格专属样式
.j-cgform-tab-modal {
.ant-modal-header {
padding-top: 8px;
padding-bottom: 8px;
border-bottom: none !important;
}
.ant-modal .ant-modal-body > .scrollbar,
.ant-tabs-nav .ant-tabs-tab {
padding-top: 0;
}
.ant-tabs-top-bar {
width: calc(100% - 55px);
position: relative;
left: -14px;
}
.ant-tabs .ant-tabs-top-content > .ant-tabs-tabpane {
overflow: hidden auto;
}
}
</style>