增加vue生成模板
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (c) 2013-Now http://jeesite.com All rights reserved. -->
|
||||
<!-- 该文件可自定义,复制 config.xml 到 config-custom.xml 相同目录下,即可生效。 -->
|
||||
<!-- Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
No deletion without permission, or be held responsible to law. -->
|
||||
<!-- 该文件可自定义,复制 config.xml 到 config-custom.xml 相同目录下,即可生效。 -->
|
||||
<config>
|
||||
<!-- 模板分类 -->
|
||||
<tplCategory>
|
||||
@@ -9,11 +10,30 @@
|
||||
<template>crud/service.xml</template>
|
||||
<template>crud/controller.xml</template>
|
||||
<template>crud/viewList.xml</template>
|
||||
<template>crud/viewIndex.xml</template>
|
||||
<template>crud/viewForm.xml</template>
|
||||
<childTable>
|
||||
<template>category-ref:dao</template>
|
||||
</childTable>
|
||||
</category>
|
||||
<category value="crud_vue" label="单表/主子表 (增删改查)Vue">
|
||||
<template>category-ref:dao</template>
|
||||
<template>crud/service.xml</template>
|
||||
<template>crud/controller.xml</template>
|
||||
<template>crud/vueApi.xml</template>
|
||||
<template>crud/vueList.xml</template>
|
||||
<template>crud/vueIndex.xml</template>
|
||||
<template>crud/vueForm.xml</template>
|
||||
<childTable>
|
||||
<template>category-ref:dao</template>
|
||||
</childTable>
|
||||
</category>
|
||||
<category value="crud_vue_only" label="单表/主子表 (增删改查)仅Vue">
|
||||
<template>crud/vueApi.xml</template>
|
||||
<template>crud/vueList.xml</template>
|
||||
<template>crud/vueIndex.xml</template>
|
||||
<template>crud/vueForm.xml</template>
|
||||
</category>
|
||||
<category value="crud_select" label="单表/主子表 (增删改查,含 listselect 选择页面)">
|
||||
<template>category-ref:crud</template>
|
||||
<template>crud/viewSelect.xml</template>
|
||||
@@ -40,6 +60,12 @@
|
||||
<category value="treeGrid" label="树表/树结构表(增删改查)">
|
||||
<template>category-ref:crud</template>
|
||||
</category>
|
||||
<category value="treeGrid_vue" label="树表/树结构表(增删改查)Vue">
|
||||
<template>category-ref:crud_vue</template>
|
||||
</category>
|
||||
<category value="treeGrid_vue_only" label="树表/树结构表(增删改查)仅Vue">
|
||||
<template>category-ref:crud_vue_only</template>
|
||||
</category>
|
||||
<category value="treeGrid_cloud" label="树表/树结构表(增删改查 Cloud,生成 Api/Client)">
|
||||
<template>category-ref:crud_cloud</template>
|
||||
</category>
|
||||
@@ -110,8 +136,6 @@
|
||||
<!-- 字段验证 -->
|
||||
<fieldValid>
|
||||
<dict value="email" label="电子邮件"/>
|
||||
<dict value="url" label="网址"/>
|
||||
<dict value="date" label="日期"/>
|
||||
<dict value="number" label="数值"/>
|
||||
<dict value="integer" label="整数"/>
|
||||
<dict value="digits" label="正整数"/>
|
||||
@@ -124,7 +148,9 @@
|
||||
<dict value="zipCode" label="邮政编码"/>
|
||||
<dict value="ipv4" label="IPv4"/>
|
||||
<dict value="ipv6" label="IPv6"/>
|
||||
<dict value="qq" label="QQ"/>
|
||||
<dict value="qq" label="QQ号"/>
|
||||
<dict value="url" label="网址"/>
|
||||
<dict value="date" label="日期"/>
|
||||
<dict value="idcard" label="身份证"/>
|
||||
</fieldValid>
|
||||
<!-- 栅格布局 -->
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
No deletion without permission, or be held responsible to law. -->
|
||||
<template>
|
||||
<name>vueApi</name>
|
||||
<filePath>vue/src/api/${moduleName}/${subModuleName}</filePath>
|
||||
<fileName>${className}.ts</fileName>
|
||||
<content><![CDATA[
|
||||
/**
|
||||
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
* No deletion without permission, or be held responsible to law.
|
||||
* @author ${functionAuthor}
|
||||
*/
|
||||
import { defHttp } from '/@/utils/http/axios';
|
||||
import { useGlobSetting } from '/@/hooks/setting';
|
||||
<% if(table.isTreeEntity){ %>
|
||||
import { TreeDataModel, TreeModel } from '../model/baseModel';
|
||||
<% }else{ %>
|
||||
import { BasicModel } from '../model/baseModel';
|
||||
<% } %>
|
||||
|
||||
const { adminPath } = useGlobSetting();
|
||||
|
||||
export interface ${ClassName} extends ${table.isTreeEntity?'Tree':'Basic'}Model<${ClassName}> {
|
||||
<%
|
||||
isExtend = false;
|
||||
// 生成字段属性
|
||||
for(c in table.columnList){
|
||||
var attrType = c.simpleAttrType;
|
||||
if (attrType == 'String') attrType = 'string';
|
||||
else if (attrType == 'Long') attrType = 'number';
|
||||
else if (attrType == 'Integer') attrType = 'number';
|
||||
else if (attrType == 'Double') attrType = 'number';
|
||||
else if (attrType == 'BigDecimal') attrType = 'number';
|
||||
else if (attrType == 'Date') attrType = 'string';
|
||||
else attrType = 'any';
|
||||
if(!@StringUtils.equalsIgnoreCase(c.columnName, 'id') && !c.isSuperColumn){
|
||||
// 如果是Extend类属性
|
||||
if(table.isExtendEntity && c.isExtendColumn){
|
||||
if(!isExtend){
|
||||
isExtend = true;
|
||||
%>
|
||||
extend?: any; // 扩展字段
|
||||
<%
|
||||
}
|
||||
}
|
||||
// 如果不是基类属性
|
||||
else if(!@StringUtils.equalsIgnoreCase(c.columnName, 'id') && !c.isSuperColumn){
|
||||
// 父类对象
|
||||
if(table.parentExists && table.parentTableFkName == c.columnName){
|
||||
%>
|
||||
${c.simpleAttrName}?: ${attrType};<% if (isNotBlank(c.comments)){ %> // ${c.comments} 父类<% } %>
|
||||
<%
|
||||
// 其它字段
|
||||
}else{
|
||||
%>
|
||||
${c.simpleAttrName}?: ${attrType};<%if(isNotBlank(c.comments)){%> // ${c.comments}<%}%>
|
||||
<%
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
%>
|
||||
<% // 生成子表列表字段
|
||||
for(child in table.childList){ %>
|
||||
${@StringUtils.uncap(child.className)}List?: any[]; // 子表列表
|
||||
<% } %>
|
||||
}
|
||||
|
||||
export const ${className}List = (params?: ${ClassName} | any) =>
|
||||
defHttp.get<${ClassName}>({ url: adminPath + '/${urlPrefix}/list', params });
|
||||
|
||||
export const ${className}ListData = (params?: ${ClassName} | any) =>
|
||||
defHttp.post<${ClassName}[]>({ url: adminPath + '/${urlPrefix}/listData', params });
|
||||
|
||||
export const ${className}Form = (params?: ${ClassName} | any) =>
|
||||
defHttp.get<${ClassName}>({ url: adminPath + '/${urlPrefix}/form', params });
|
||||
<% if(table.isTreeEntity){ %>
|
||||
|
||||
export const ${className}CreateNextNode = (params?: ${ClassName} | any) =>
|
||||
defHttp.get<${ClassName}>({ url: adminPath + '/${urlPrefix}/createNextNode', params });
|
||||
<% } %>
|
||||
|
||||
export const ${className}Save = (params?: any, data?: ${ClassName} | any) =>
|
||||
defHttp.postJson<${ClassName}>({ url: adminPath + '/${urlPrefix}/save', params, data });
|
||||
<% if(toBoolean(table.optionMap['isHaveDisableEnable'])){ %>
|
||||
|
||||
export const ${className}Disable = (params?: ${ClassName} | any) =>
|
||||
defHttp.get<${ClassName}>({ url: adminPath + '/${urlPrefix}/disable', params });
|
||||
|
||||
export const ${className}Enable = (params?: ${ClassName} | any) =>
|
||||
defHttp.get<${ClassName}>({ url: adminPath + '/${urlPrefix}/enable', params });
|
||||
<% } %>
|
||||
|
||||
export const ${className}Delete = (params?: ${ClassName} | any) =>
|
||||
defHttp.get<${ClassName}>({ url: adminPath + '/${urlPrefix}/delete', params });
|
||||
<% if(table.isTreeEntity){ %>
|
||||
|
||||
export const ${className}TreeData = (params?: any) =>
|
||||
defHttp.get<TreeDataModel[]>({ url: adminPath + '/${urlPrefix}/treeData', params });
|
||||
<% } %>
|
||||
]]>
|
||||
</content>
|
||||
</template>
|
||||
@@ -0,0 +1,355 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
No deletion without permission, or be held responsible to law. -->
|
||||
<template>
|
||||
<name>vueForm</name>
|
||||
<filePath>vue/src/views/${urlPrefix}</filePath>
|
||||
<fileName>form.vue</fileName>
|
||||
<content><![CDATA[
|
||||
<!--
|
||||
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
* No deletion without permission, or be held responsible to law.
|
||||
* @author ${functionAuthor}
|
||||
-->
|
||||
<template>
|
||||
<BasicDrawer
|
||||
v-bind="$attrs"
|
||||
:showFooter="true"
|
||||
:okAuth="'${permissionPrefix}:edit'"
|
||||
@register="registerDrawer"
|
||||
@ok="handleSubmit"
|
||||
width="60%"
|
||||
>
|
||||
<template #title>
|
||||
<Icon :icon="getTitle.icon" class="pr-1 m-1" />
|
||||
<span> {{ getTitle.value }} </span>
|
||||
</template>
|
||||
<BasicForm @register="registerForm" />
|
||||
</BasicDrawer>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
export default defineComponent({
|
||||
name: '${compNamePrefix}Form',
|
||||
});
|
||||
</script>
|
||||
<script lang="ts" setup>
|
||||
import { defineComponent, ref } from 'vue';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
import { Icon } from '/@/components/Icon';
|
||||
import { BasicForm, FormSchema, useForm } from '/@/components/Form';
|
||||
import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
|
||||
import { ${className}Save, ${className}Form<% if(table.isTreeEntity){ %>, ${className}TreeData<% } %> } from '/@/api/${moduleName}${isNotEmpty(subModuleName)?'/'+subModuleName:''}/${className}';
|
||||
<%
|
||||
var userselectExists = false;
|
||||
var officeselectExists = false;
|
||||
var areaselectExists = false;
|
||||
for(c in table.columnList){
|
||||
if(c.isQuery == "1" && !c.isTreeEntityColumn){
|
||||
if(c.showType == 'userselect'){
|
||||
userselectExists = true;
|
||||
}else if(c.showType == 'officeselect'){
|
||||
officeselectExists = true;
|
||||
}else if(c.showType == 'areaselect'){
|
||||
areaselectExists = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
%>
|
||||
<% if(userselectExists || officeselectExists) { %>
|
||||
import { officeTreeData } from '/@/api/sys/office';
|
||||
<% } %>
|
||||
<% if(areaselectExists) { %>
|
||||
import { areaTreeData } from '/@/api/sys/area';
|
||||
<% } %>
|
||||
import { router } from '/@/router';
|
||||
|
||||
const emit = defineEmits(['success', 'register']);
|
||||
|
||||
const { t } = useI18n('${moduleName}${isNotEmpty(subModuleName)?'.'+subModuleName:''}/${className}');
|
||||
const { showMessage } = useMessage();
|
||||
const record = ref<Recordable>({});
|
||||
const getTitle = {
|
||||
icon: router.currentRoute.value.meta.icon || 'ant-design:book-outlined',
|
||||
value: record.value.isNewRecord ? t('新增${functionNameSimple}') : t('编辑${functionNameSimple}'),
|
||||
};
|
||||
|
||||
const inputFormSchemas: FormSchema[] = [
|
||||
<% if(table.isTreeEntity){ %>
|
||||
{
|
||||
label: t('上级${functionNameSimple}'),
|
||||
field: 'parentCode',
|
||||
fieldLabel: 'parentName',
|
||||
component: 'TreeSelect',
|
||||
componentProps: {
|
||||
allowClear: true,
|
||||
},
|
||||
},
|
||||
<% }
|
||||
for (c in table.columnList){
|
||||
if (c.isEdit == '1' && c.showType != 'hidden'){
|
||||
// 如果是树结构的字段,则自动忽略
|
||||
if(table.isTreeEntity && @StringUtils.inString(c.columnName, 'parent_code',
|
||||
'parent_codes', 'tree_sorts', 'tree_leaf', 'tree_level', 'tree_names')
|
||||
&& c.attrName != table.treeViewCodeAttrName
|
||||
&& c.attrName != table.treeViewNameAttrName){
|
||||
continue;
|
||||
}
|
||||
// 是否强制新行获取,生成字段界面用户设定的
|
||||
var isNewLine = @Global.YES.equals(c.optionMap['isNewLine']);
|
||||
if (isBlank(c.optionMap['isNewLine'])){
|
||||
if (c.showType == 'textarea'){
|
||||
isNewLine = true;
|
||||
}
|
||||
}
|
||||
%>
|
||||
{
|
||||
label: t('${c.columnLabel}'),
|
||||
field: '${c.attrName}',
|
||||
<% if(c.showType == 'input' || c.showType == 'textarea'){ %>
|
||||
<% if (c.simpleAttrType == 'Integer' && c.attrName == 'treeSort'){ %>
|
||||
helpMessage: '升序${c.dataLength}',
|
||||
component: 'InputNumber',
|
||||
defaultValue: '30',
|
||||
<% }else{ %>
|
||||
component: '${c.showType == 'input' ? 'Input' : 'InputTextArea'}',
|
||||
<% } %>
|
||||
<% if (c.dataLength != '0'){ %>
|
||||
componentProps: {
|
||||
maxlength: ${c.dataLength},
|
||||
},
|
||||
<% } %>
|
||||
<% }else if(c.showType == 'select' || c.showType == 'select_multiple'){
|
||||
var isMultiple = (c.showType == 'select_multiple'); %>
|
||||
component: 'Select',
|
||||
componentProps: {
|
||||
dictType: '${c.optionMap['dictType']}',
|
||||
allowClear: true,
|
||||
<% if(isMultiple){ %>
|
||||
mode: 'multiple',
|
||||
<% } %>
|
||||
},
|
||||
defaultValue: '',
|
||||
<% }else if(c.showType == 'radio' || c.showType == 'checkbox'){ %>
|
||||
component: '${@StringUtils.cap(c.showType)}Group',
|
||||
componentProps: {
|
||||
dictType: '${c.optionMap['dictType']}',
|
||||
},
|
||||
<% }else if(c.showType == 'date' || c.showType == 'datetime'){
|
||||
var isTime = (c.showType == 'datetime'); %>
|
||||
component: 'DatePicker',
|
||||
componentProps: {
|
||||
format: 'YYYY-MM-DD${isTime?' HH:mm':''}',
|
||||
showTime: ${isTime?'{ format: \'HH:mm\' \}':'false'},
|
||||
},
|
||||
<% }else if(c.showType == 'userselect'){
|
||||
if (isNotBlank(c.attrName2)){ %>
|
||||
fieldLabel: '${c.attrName2}',
|
||||
<% } %>
|
||||
component: 'TreeSelect',
|
||||
componentProps: {
|
||||
api: officeTreeData,
|
||||
params: { isLoadUser: true, userIdPrefix: '' },
|
||||
canSelectParent: false,
|
||||
allowClear: true,
|
||||
},
|
||||
defaultValue: '',
|
||||
<% }else if(c.showType == 'officeselect'){
|
||||
if (isNotBlank(c.attrName2)){ %>
|
||||
fieldLabel: '${c.attrName2}',
|
||||
<% } %>
|
||||
component: 'TreeSelect',
|
||||
componentProps: {
|
||||
api: officeTreeData,
|
||||
allowClear: true,
|
||||
},
|
||||
defaultValue: '',
|
||||
<% }else if(c.showType == 'areaselect'){
|
||||
if (isNotBlank(c.attrName2)){ %>
|
||||
fieldLabel: '${c.attrName2}',
|
||||
<% } %>
|
||||
component: 'TreeSelect',
|
||||
componentProps: {
|
||||
api: areaTreeData,
|
||||
allowClear: true,
|
||||
},
|
||||
defaultValue: '',
|
||||
<% }else{ %>
|
||||
component: 'Input',
|
||||
<% }
|
||||
var fieldValid = c.optionMap['fieldValid'], fvs = [], rules = [];
|
||||
if(isNotEmpty(fieldValid)){
|
||||
var t = type.name(fieldValid);
|
||||
if (t == 'String[]' || t == 'ArrayList'){
|
||||
fvs = fieldValid;
|
||||
}else if(t == 'String' && isNotBlank(fieldValid)){
|
||||
@fvs.add(fieldValid);
|
||||
}
|
||||
}
|
||||
for(var fv in fvs){
|
||||
if (fv == 'email'){
|
||||
var s = { %>{ type: 'email', message: t('请输入邮箱地址') }<% };
|
||||
@rules.add(s);
|
||||
}
|
||||
if (fv == 'number'){
|
||||
var s = { %>{ pattern: /^(?:-?\d+|-?\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/, message: t('请输入一个数值') }<% };
|
||||
@rules.add(s);
|
||||
}
|
||||
if (fv == 'integer'){
|
||||
var s = { %>{ pattern: /^-?\d+$/, message: t('请输入一个整数') }<% };
|
||||
@rules.add(s);
|
||||
}
|
||||
if (fv == 'digits'){
|
||||
var s = { %>{ pattern: /^\d+$/, message: t('请输入一个正整数') }<% };
|
||||
@rules.add(s);
|
||||
}
|
||||
if (fv == 'userName'){
|
||||
var s = { %>{ pattern: /^[\u0391-\uFFE5\w]+$/, message: t('请输入登录账号') }<% };
|
||||
@rules.add(s);
|
||||
}
|
||||
if (fv == 'realName'){
|
||||
var s = { %>{ pattern: /^[\u4e00-\u9fa5]{2,30}$/, message: t('请输入真实姓名') }<% };
|
||||
@rules.add(s);
|
||||
}
|
||||
if (fv == 'abc'){
|
||||
var s = { %>{ pattern: /^[a-zA-Z0-9_]*$/, message: t('请输入字母数字下划线') }<% };
|
||||
@rules.add(s);
|
||||
}
|
||||
if (fv == 'mobile'){
|
||||
var s = { %>{ pattern: /^1[3,4,5,6,7,8,9]\d{9}$/g, message: t('请输入手机号码') }<% };
|
||||
@rules.add(s);
|
||||
}
|
||||
if (fv == 'simplePhone'){
|
||||
var s = { %>{ pattern: /^(\d{3,4}-?)?\d{7,9}$/g, message: t('请输入固话号码') }<% };
|
||||
@rules.add(s);
|
||||
}
|
||||
if (fv == 'phone'){
|
||||
var s = { %>{ pattern: /(^0[1-9]{1}\d{8,10}$)|(^1[3,4,5,6,7,8,9]\d{9}$)/g, message: t('请输入固话或手机号码') }<% };
|
||||
@rules.add(s);
|
||||
}
|
||||
if (fv == 'zipCode'){
|
||||
var s = { %>{ pattern: /^[0-9]{6}$/, message: t('请输入邮政编码') }<% };
|
||||
@rules.add(s);
|
||||
}
|
||||
}
|
||||
if(rules.~size == 0){
|
||||
if(c.isRequired == '1'){
|
||||
%> required: true,
|
||||
<%
|
||||
}
|
||||
} else { %>
|
||||
rules: [<%
|
||||
if(c.isRequired == '1'){
|
||||
%>{ required: true }, <%
|
||||
}
|
||||
for (var rule in rules){
|
||||
print(rule);
|
||||
if (ruleLP.index < rules.~size) {
|
||||
print(', ');
|
||||
}
|
||||
} %>],
|
||||
<%
|
||||
}
|
||||
if (isNewLine){ %>
|
||||
colProps: { lg: 24, md: 24 },
|
||||
<%
|
||||
}
|
||||
%>
|
||||
},
|
||||
<%
|
||||
}
|
||||
}
|
||||
%>
|
||||
];
|
||||
<%
|
||||
var updateSchemas = [];
|
||||
if(table.isTreeEntity){
|
||||
var s = {
|
||||
%> {
|
||||
field: 'parentCode',
|
||||
componentProps: {
|
||||
api: ${className}TreeData,
|
||||
params: {
|
||||
excludeCode: record.value.id,
|
||||
isShowRawName: true,
|
||||
},
|
||||
},
|
||||
},<%
|
||||
};
|
||||
@updateSchemas.add(s);
|
||||
}
|
||||
for (c in table.columnList){
|
||||
if (c.isPk == '1' && c.showType == 'input'){
|
||||
var s = {
|
||||
%> {
|
||||
field: '${c.attrName}',
|
||||
componentProps: {
|
||||
disabled: !record.value.isNewRecord,
|
||||
},
|
||||
},<%
|
||||
};
|
||||
@updateSchemas.add(s);
|
||||
}
|
||||
}
|
||||
%>
|
||||
const [registerForm, { resetFields, setFieldsValue<% if(updateSchemas.~size > 0){ %>, updateSchema<% } %>, validate }] = useForm({
|
||||
labelWidth: 120,
|
||||
schemas: inputFormSchemas,
|
||||
<% var formColNum = table.optionMap['formColNum']; %>
|
||||
baseColProps: { lg: ${formColNum=="1"?24:formColNum=="3"?8:12}, md: 24 },
|
||||
});
|
||||
|
||||
const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => {
|
||||
resetFields();
|
||||
setDrawerProps({ loading: true });
|
||||
const res = await ${className}Form(data);
|
||||
record.value = (res.${className} || {}) as Recordable;
|
||||
<% if(table.isTreeEntity){ %>
|
||||
if (data.parentCode && data.parentName) {
|
||||
record.value.parentCode = data.parentCode;
|
||||
record.value.parentName = data.parentName;
|
||||
}
|
||||
<% } %>
|
||||
setFieldsValue(record.value);
|
||||
<% if(updateSchemas.~size > 0){ %>
|
||||
updateSchema([
|
||||
<% for(updateSchema in updateSchemas){
|
||||
print(updateSchema + '\n');
|
||||
} %>
|
||||
]);
|
||||
<% } %>
|
||||
setDrawerProps({ loading: false });
|
||||
});
|
||||
|
||||
async function handleSubmit() {
|
||||
try {
|
||||
const data = await validate();
|
||||
setDrawerProps({ confirmLoading: true });
|
||||
const params: any = {
|
||||
isNewRecord: record.value.isNewRecord,
|
||||
<%
|
||||
for (c in table.columnList){
|
||||
if (c.isPk == '1' || c.showType == 'hidden'){ %>
|
||||
${c.attrName}: record.value.${c.attrName},
|
||||
<%
|
||||
}
|
||||
}
|
||||
%>
|
||||
};
|
||||
console.log('submit', params, data, record);
|
||||
const res = await ${className}Save(params, data);
|
||||
showMessage(res.message);
|
||||
setTimeout(closeDrawer);
|
||||
emit('success', data);
|
||||
} catch (error: any) {
|
||||
showMessage(t('您填写的信息有误,请根据提示修正。'));
|
||||
console.log('error', error);
|
||||
} finally {
|
||||
setDrawerProps({ confirmLoading: false });
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<% %>
|
||||
]]>
|
||||
</content>
|
||||
</template>
|
||||
@@ -0,0 +1,54 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
No deletion without permission, or be held responsible to law. -->
|
||||
<template>
|
||||
<name>vueIndex</name>
|
||||
<filePath>vue/src/views/${urlPrefix}</filePath>
|
||||
<fileName>index.vue</fileName>
|
||||
<content><![CDATA[
|
||||
<% if(table.isTreeEntity){ %>
|
||||
<!--
|
||||
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
* No deletion without permission, or be held responsible to law.
|
||||
* @author ${functionAuthor}
|
||||
-->
|
||||
<template>
|
||||
<PageWrapper :sidebarWidth="230">
|
||||
<template #sidebar>
|
||||
<BasicTree
|
||||
:title="t('${functionNameSimple}')"
|
||||
:search="true"
|
||||
:toolbar="true"
|
||||
:api="${className}TreeData"
|
||||
:defaultExpandLevel="1"
|
||||
@select="handleSelect"
|
||||
/>
|
||||
</template>
|
||||
<ListView :treeCode="treeCode" />
|
||||
</PageWrapper>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
export default defineComponent({
|
||||
name: '${compNamePrefix}Index',
|
||||
});
|
||||
</script>
|
||||
<script lang="ts" setup>
|
||||
import { defineComponent, ref } from 'vue';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
import { PageWrapper } from '/@/components/Page';
|
||||
import { BasicTree } from '/@/components/Tree';
|
||||
import { ${className}TreeData } from '/@/api/${moduleName}${isNotEmpty(subModuleName)?'/'+subModuleName:''}/${className}';
|
||||
import ListView from './list.vue';
|
||||
|
||||
const { t } = useI18n('sys.menu');
|
||||
const treeCode = ref<string>('');
|
||||
|
||||
function handleSelect(keys: string[]) {
|
||||
treeCode.value = keys[0];
|
||||
}
|
||||
</script>
|
||||
<% } %>
|
||||
<% %>
|
||||
]]>
|
||||
</content>
|
||||
</template>
|
||||
@@ -0,0 +1,414 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
No deletion without permission, or be held responsible to law. -->
|
||||
<template>
|
||||
<name>vueList</name>
|
||||
<filePath>vue/src/views/${urlPrefix}</filePath>
|
||||
<fileName>list.vue</fileName>
|
||||
<content><![CDATA[
|
||||
<!--
|
||||
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
* No deletion without permission, or be held responsible to law.
|
||||
* @author ${functionAuthor}
|
||||
-->
|
||||
<template>
|
||||
<div>
|
||||
<BasicTable @register="registerTable"<% if(table.isTreeEntity){ %> @fetchSuccess="fetchSuccess"<% } %>>
|
||||
<template #tableTitle>
|
||||
<Icon :icon="getTitle.icon" class="m-1 pr-1" />
|
||||
<span> {{ getTitle.value }} </span>
|
||||
</template>
|
||||
<template #toolbar>
|
||||
<% if(table.isTreeEntity){ %>
|
||||
<a-button @click="expandAll" :title="t('展开一级')">
|
||||
<Icon icon="bi:chevron-double-down" /> {{ t('展开') }}
|
||||
</a-button>
|
||||
<a-button @click="collapseAll" :title="t('展开全部')">
|
||||
<Icon icon="bi:chevron-double-up" /> {{ t('折叠') }}
|
||||
</a-button>
|
||||
<% } %>
|
||||
<a-button type="primary" @click="handleForm({})" v-auth="'${permissionPrefix}:edit'">
|
||||
<Icon icon="fluent:add-12-filled" /> {{ t('新增') }}
|
||||
</a-button>
|
||||
</template>
|
||||
<template #firstColumn="{ record }">
|
||||
<%
|
||||
var idParam = '';
|
||||
for(pk in table.pkList){
|
||||
idParam = idParam + pk.attrName + ': record.' + pk.attrName;
|
||||
if (pkLP.index == table.pkList.~size - 1) {
|
||||
idParam = idParam + ', ';
|
||||
}
|
||||
}
|
||||
if(table.isTreeEntity){
|
||||
%>
|
||||
<span class="cursor-pointer" @click="expandCollapse(record)">
|
||||
( {{ record.${table.treeViewCodeAttrName} }} )
|
||||
</span>
|
||||
<a @click="handleForm({ ${idParam} })">
|
||||
{{ record.${table.treeViewNameAttrName} }}
|
||||
</a>
|
||||
<%
|
||||
}else{
|
||||
for(c in table.columnList){
|
||||
if(c.isList == "1"){
|
||||
// 如果是树结构的字段,则自动忽略
|
||||
if(table.isTreeEntity && @StringUtils.inString(c.columnName, 'parent_code',
|
||||
'parent_codes', 'tree_sorts', 'tree_leaf', 'tree_level', 'tree_names')
|
||||
&& c.attrName != table.treeViewCodeAttrName
|
||||
&& c.attrName != table.treeViewNameAttrName){
|
||||
continue;
|
||||
}
|
||||
%>
|
||||
<a @click="handleForm({ ${idParam} })">
|
||||
{{ record.${c.attrName} }}
|
||||
</a>
|
||||
<%
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
%>
|
||||
</template>
|
||||
</BasicTable>
|
||||
<InputForm @register="registerDrawer" @success="handleSuccess" />
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
export default defineComponent({
|
||||
name: '${compNamePrefix}List',
|
||||
});
|
||||
</script>
|
||||
<script lang="ts" setup>
|
||||
import { defineComponent<% if(table.isTreeEntity){ %>, watch, nextTick<% } %> } from 'vue';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
import { Icon } from '/@/components/Icon';
|
||||
import { BasicTable, BasicColumn, useTable } from '/@/components/Table';
|
||||
import { ${className}Delete, ${className}ListData } from '/@/api/${moduleName}${isNotEmpty(subModuleName)?'/'+subModuleName:''}/${className}';
|
||||
<% if(toBoolean(table.optionMap['isHaveDisableEnable'])){ %>
|
||||
import { ${className}Disable, ${className}Enable } from '/@/api/${moduleName}${isNotEmpty(subModuleName)?'/'+subModuleName:''}/${className}';
|
||||
<% } %>
|
||||
<%
|
||||
var userselectExists = false;
|
||||
var officeselectExists = false;
|
||||
var areaselectExists = false;
|
||||
for(c in table.columnList){
|
||||
if(c.isQuery == "1" && !c.isTreeEntityColumn){
|
||||
if(c.showType == 'userselect'){
|
||||
userselectExists = true;
|
||||
}else if(c.showType == 'officeselect'){
|
||||
officeselectExists = true;
|
||||
}else if(c.showType == 'areaselect'){
|
||||
areaselectExists = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
%>
|
||||
<% if(userselectExists || officeselectExists) { %>
|
||||
import { officeTreeData } from '/@/api/sys/office';
|
||||
<% } %>
|
||||
<% if(areaselectExists) { %>
|
||||
import { areaTreeData } from '/@/api/sys/area';
|
||||
<% } %>
|
||||
import { useDrawer } from '/@/components/Drawer';
|
||||
import { FormProps } from '/@/components/Form';
|
||||
import { router } from '/@/router';
|
||||
import InputForm from './form.vue';
|
||||
|
||||
<% if(table.isTreeEntity){ %>
|
||||
const props = defineProps({
|
||||
treeCode: String,
|
||||
});
|
||||
|
||||
<% } %>
|
||||
const { t } = useI18n('${moduleName}${isNotEmpty(subModuleName)?'.'+subModuleName:''}/${className}');
|
||||
const { showMessage } = useMessage();
|
||||
const getTitle = {
|
||||
icon: router.currentRoute.value.meta.icon || 'ant-design:book-outlined',
|
||||
value: router.currentRoute.value.meta.title || t('${functionNameSimple}管理'),
|
||||
};
|
||||
|
||||
const searchForm: FormProps = {
|
||||
baseColProps: { lg: 6, md: 8 },
|
||||
labelWidth: 90,
|
||||
schemas: [
|
||||
<% for(c in table.columnList){ %>
|
||||
<% if(c.isQuery == "1" && !c.isTreeEntityColumn){ %>
|
||||
{
|
||||
label: t('${c.columnLabel}${c.queryType == 'BETWEEN'?'起':''}'),
|
||||
field: '${c.attrName}${c.queryType == 'BETWEEN'?'_gte':''}',
|
||||
<% if(c.showType == 'input' || c.showType == 'textarea'){ %>
|
||||
component: 'Input',
|
||||
<% if (c.queryType == 'BETWEEN'){ %>
|
||||
},
|
||||
{
|
||||
field: '${c.attrName}${c.queryType == 'BETWEEN'?'_lte':''}',
|
||||
label: t('${c.columnLabel}${c.queryType == 'BETWEEN'?'止':''}'),
|
||||
component: 'Input',
|
||||
<% } %>
|
||||
<% }else if(c.showType == 'select' || c.showType == 'select_multiple'){
|
||||
var isMultiple = (c.showType == 'select_multiple'); %>
|
||||
component: 'Select',
|
||||
componentProps: {
|
||||
dictType: '${c.optionMap['dictType']}',
|
||||
allowClear: true,
|
||||
<% if(isMultiple){ %>
|
||||
mode: 'multiple',
|
||||
<% } %>
|
||||
},
|
||||
defaultValue: '',
|
||||
<% }else if(c.showType == 'radio' || c.showType == 'checkbox'){ %>
|
||||
component: '${@StringUtils.cap(c.showType)}Group',
|
||||
componentProps: {
|
||||
dictType: '${c.optionMap['dictType']}',
|
||||
},
|
||||
<% }else if(c.showType == 'date' || c.showType == 'datetime'){
|
||||
var isTime = (c.showType == 'datetime'); %>
|
||||
component: 'DatePicker',
|
||||
componentProps: {
|
||||
format: 'YYYY-MM-DD${isTime?' HH:mm':''}',
|
||||
showTime: ${isTime?'{ format: \'HH:mm\' \}':'false'},
|
||||
},
|
||||
<% if (c.queryType == 'BETWEEN'){ %>
|
||||
},
|
||||
{
|
||||
label: t('${c.columnLabel}${c.queryType == 'BETWEEN'?'止':''}'),
|
||||
field: '${c.attrName}${c.queryType == 'BETWEEN'?'_lte':''}',
|
||||
component: 'DatePicker',
|
||||
componentProps: {
|
||||
format: 'YYYY-MM-DD${isTime?' HH:mm':''}',
|
||||
showTime: ${isTime?'{ format: \'HH:mm\' \}':'false'},
|
||||
},
|
||||
<% } %>
|
||||
<% }else if(c.showType == 'userselect'){ %>
|
||||
component: 'TreeSelect',
|
||||
componentProps: {
|
||||
api: officeTreeData,
|
||||
params: { isLoadUser: true, userIdPrefix: '' },
|
||||
canSelectParent: false,
|
||||
allowClear: true,
|
||||
},
|
||||
defaultValue: '',
|
||||
<% }else if(c.showType == 'officeselect'){ %>
|
||||
component: 'TreeSelect',
|
||||
componentProps: {
|
||||
api: officeTreeData,
|
||||
allowClear: true,
|
||||
},
|
||||
defaultValue: '',
|
||||
<% }else if(c.showType == 'areaselect'){ %>
|
||||
component: 'TreeSelect',
|
||||
componentProps: {
|
||||
api: areaTreeData,
|
||||
allowClear: true,
|
||||
},
|
||||
defaultValue: '',
|
||||
<% }else{ %>
|
||||
component: 'Input',
|
||||
<% } %>
|
||||
},
|
||||
<% } %>
|
||||
<% } %>
|
||||
],
|
||||
};
|
||||
|
||||
const tableColumns: BasicColumn[] = [
|
||||
<%
|
||||
var firstColumn = true;
|
||||
// 生成树表的节点列
|
||||
if(table.isTreeEntity){
|
||||
for(c in table.columnList){
|
||||
if(c.attrName == table.treeViewNameAttrName){
|
||||
%>
|
||||
{
|
||||
title: t('${c.columnLabel}'),
|
||||
dataIndex: '${c.attrName}',
|
||||
width: 250,
|
||||
align: 'left',
|
||||
slots: { customRender: 'firstColumn' },
|
||||
},
|
||||
<%
|
||||
firstColumn = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
for(c in table.columnList){
|
||||
if(c.isList == "1"){
|
||||
// 如果是树结构的字段,则自动忽略
|
||||
if(table.isTreeEntity && (@StringUtils.inString(c.columnName, 'parent_code',
|
||||
'parent_codes', 'tree_sorts', 'tree_leaf', 'tree_level', 'tree_names')
|
||||
|| c.attrName == table.treeViewCodeAttrName
|
||||
|| c.attrName == table.treeViewNameAttrName)){
|
||||
continue;
|
||||
}
|
||||
%>
|
||||
{
|
||||
title: t('${c.columnLabel}'),
|
||||
<% if(c.showType == "userselect" || c.showType == "officeselect" || c.showType == "areaselect"){ %>
|
||||
dataIndex: '${c.attrName2}',
|
||||
<% }else{ %>
|
||||
dataIndex: '${c.attrName}',
|
||||
<% } %>
|
||||
<% if(!table.isTreeEntity){ %>
|
||||
key: 'a.${c.columnName}',
|
||||
sorter: true,
|
||||
<% } %>
|
||||
<% if(firstColumn){ %>
|
||||
width: 250,
|
||||
<% }else{ %>
|
||||
width: 150,
|
||||
<% } %>
|
||||
<% if (@StringUtils.inString(c.attrType, 'java.util.Date', 'Integer', 'Long') && !firstColumn){ %>
|
||||
align: 'center',
|
||||
<% }else if (@StringUtils.inString(c.attrType, 'Float', 'Double') && !firstColumn){ %>
|
||||
align: 'right',
|
||||
<% }else{ %>
|
||||
align: 'left',
|
||||
<% } %>
|
||||
<% if(c.showType == 'select' || c.showType == 'select_multiple' || c.showType == 'checkbox' || c.showType == 'radio'){ %>
|
||||
dictType: '${c.optionMap['dictType']}',
|
||||
<% } %>
|
||||
<% if(firstColumn){ %>
|
||||
slots: { customRender: 'firstColumn' },
|
||||
<% } %>
|
||||
},
|
||||
<%
|
||||
if(firstColumn){
|
||||
firstColumn = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
%>
|
||||
];
|
||||
|
||||
const actionColumn: BasicColumn = {
|
||||
width: 160,
|
||||
actions: (record: Recordable) => [
|
||||
{
|
||||
icon: 'clarity:note-edit-line',
|
||||
title: t('编辑${functionNameSimple}'),
|
||||
onClick: handleForm.bind(this, { ${idParam} }),
|
||||
auth: '${permissionPrefix}:edit',
|
||||
},
|
||||
<% if(toBoolean(table.optionMap['isHaveDisableEnable'])){ %>
|
||||
{
|
||||
icon: 'ant-design:stop-outlined',
|
||||
color: 'error',
|
||||
title: t('停用${functionNameSimple}'),
|
||||
popConfirm: {
|
||||
title: t('是否确认停用${functionNameSimple}'),
|
||||
confirm: handleDisable.bind(this, { ${idParam} }),
|
||||
},
|
||||
auth: '${permissionPrefix}:edit',
|
||||
ifShow: () => record.status === '0',
|
||||
},
|
||||
{
|
||||
icon: 'ant-design:check-circle-outlined',
|
||||
color: 'success',
|
||||
title: t('启用${functionNameSimple}'),
|
||||
popConfirm: {
|
||||
title: t('是否确认启用${functionNameSimple}'),
|
||||
confirm: handleEnable.bind(this, { ${idParam} }),
|
||||
},
|
||||
auth: '${permissionPrefix}:edit',
|
||||
ifShow: () => record.status === '2',
|
||||
},
|
||||
<% } %>
|
||||
<% if(toBoolean(table.optionMap['isHaveDelete'])){ %>
|
||||
{
|
||||
icon: 'ant-design:delete-outlined',
|
||||
color: 'error',
|
||||
title: t('删除${functionNameSimple}'),
|
||||
popConfirm: {
|
||||
title: t('是否确认删除${functionNameSimple}'),
|
||||
confirm: handleDelete.bind(this, { ${idParam} }),
|
||||
},
|
||||
auth: '${permissionPrefix}:edit',
|
||||
},
|
||||
<% } %>
|
||||
<% if(table.isTreeEntity){ %>
|
||||
{
|
||||
icon: 'fluent:add-circle-24-regular',
|
||||
title: t('新建下级${functionNameSimple}'),
|
||||
onClick: handleForm.bind(this, {
|
||||
parentCode: record.id,
|
||||
parentName: record.${table.treeViewNameAttrName},
|
||||
}),
|
||||
auth: '${permissionPrefix}:edit',
|
||||
},
|
||||
<% } %>
|
||||
],
|
||||
};
|
||||
|
||||
const [registerDrawer, { openDrawer }] = useDrawer();
|
||||
const [registerTable, { reload<% if(table.isTreeEntity){ %>, expandAll, collapseAll, expandCollapse<% } %> }] = useTable({
|
||||
api: ${className}ListData,
|
||||
beforeFetch: (params) => {
|
||||
<% if(table.isTreeEntity){ %>
|
||||
<% for(pk in table.pkList){ %>
|
||||
params.${pk.attrName} = props.treeCode;
|
||||
<% } %>
|
||||
<% } %>
|
||||
return params;
|
||||
},
|
||||
columns: tableColumns,
|
||||
actionColumn: actionColumn,
|
||||
formConfig: searchForm,
|
||||
showTableSetting: true,
|
||||
useSearchForm: true,
|
||||
<% if(table.isTreeEntity){ %>
|
||||
isTreeTable: true,
|
||||
pagination: false,
|
||||
<% } %>
|
||||
canResize: true,
|
||||
});
|
||||
<% if(table.isTreeEntity){ %>
|
||||
|
||||
watch(
|
||||
() => props.treeCode,
|
||||
() => {
|
||||
reload();
|
||||
},
|
||||
);
|
||||
|
||||
function fetchSuccess() {
|
||||
if (props.treeCode) {
|
||||
nextTick(expandAll);
|
||||
}
|
||||
}
|
||||
<% } %>
|
||||
|
||||
function handleForm(record: Recordable) {
|
||||
openDrawer(true, record);
|
||||
}
|
||||
<% if(toBoolean(table.optionMap['isHaveDisableEnable'])){ %>
|
||||
|
||||
async function handleDisable(record: Recordable) {
|
||||
const res = await ${className}Disable(record);
|
||||
showMessage(res.message);
|
||||
handleSuccess();
|
||||
}
|
||||
|
||||
async function handleEnable(record: Recordable) {
|
||||
const res = await ${className}Enable(record);
|
||||
showMessage(res.message);
|
||||
handleSuccess();
|
||||
}
|
||||
<% } %>
|
||||
|
||||
async function handleDelete(record: Recordable) {
|
||||
const res = await ${className}Delete(record);
|
||||
showMessage(res.message);
|
||||
handleSuccess();
|
||||
}
|
||||
|
||||
function handleSuccess() {
|
||||
reload();
|
||||
}
|
||||
</script>
|
||||
<% %>
|
||||
]]>
|
||||
</content>
|
||||
</template>
|
||||
Reference in New Issue
Block a user