😎1、优化前端页面 2、调整代码生成页面
This commit is contained in:
parent
51400baea5
commit
71236007ee
272
Web/src/views/system/codeGen/component/codeGenStore.ts
Normal file
272
Web/src/views/system/codeGen/component/codeGenStore.ts
Normal file
@ -0,0 +1,272 @@
|
||||
import { defineStore } from 'pinia';
|
||||
import {
|
||||
AddCodeGenInput,
|
||||
ColumnOutput,
|
||||
DatabaseOutput,
|
||||
DefaultColumnConfigInput,
|
||||
EffectTreeConfigInput,
|
||||
SysCodeGenApi,
|
||||
SysDictType,
|
||||
SysDictTypeApi,
|
||||
SysMenu,
|
||||
SysMenuApi,
|
||||
SysPrint,
|
||||
SysPrintApi,
|
||||
TableOutput,
|
||||
UpdateCodeGenInput,
|
||||
} from '/@/api-services/system';
|
||||
import { getAPI } from '/@/utils/axios-utils';
|
||||
import { useUserInfo } from '/@/stores/userInfo';
|
||||
import { watch } from 'vue';
|
||||
|
||||
const apiManager = {
|
||||
detail: (id: number) => {
|
||||
return getAPI(SysCodeGenApi)
|
||||
.apiSysCodeGenDetailGet(id)
|
||||
.then((res) => res.data.result);
|
||||
},
|
||||
add: (body: AddCodeGenInput) => {
|
||||
return getAPI(SysCodeGenApi).apiSysCodeGenAddPost(body);
|
||||
},
|
||||
update: (body: UpdateCodeGenInput) => {
|
||||
return getAPI(SysCodeGenApi).apiSysCodeGenUpdatePost(body);
|
||||
},
|
||||
getColumnConfigList: (id: number) => {
|
||||
return getAPI(SysCodeGenApi)
|
||||
.apiSysCodeGenTableDetailGet(id)
|
||||
.then((res) => res.data.result);
|
||||
},
|
||||
getPrintList: () => {
|
||||
return getAPI(SysPrintApi)
|
||||
.apiSysPrintPagePost()
|
||||
.then((res) => res.data.result?.items ?? []);
|
||||
},
|
||||
getMenuList: () => {
|
||||
return getAPI(SysMenuApi)
|
||||
.apiSysMenuListGet()
|
||||
.then((res) => res.data.result ?? []);
|
||||
},
|
||||
getDictTypeList: () => {
|
||||
return getAPI(SysDictTypeApi)
|
||||
.apiSysDictTypeListGet()
|
||||
.then((res) => res.data.result ?? []);
|
||||
},
|
||||
getQuickConfigMap: () => {
|
||||
return getAPI(SysCodeGenApi)
|
||||
.apiSysCodeGenQuickConfigMapGet()
|
||||
.then((res) => res.data.result ?? {});
|
||||
},
|
||||
getNamespaceList: () => {
|
||||
return getAPI(SysCodeGenApi)
|
||||
.apiSysCodeGenApplicationNamespacesGet()
|
||||
.then((res) => res.data.result ?? []);
|
||||
},
|
||||
getDatabaseList: () => {
|
||||
return getAPI(SysCodeGenApi)
|
||||
.apiSysCodeGenDatabaseListGet()
|
||||
.then((res) => res.data.result ?? []);
|
||||
},
|
||||
getTableList: (configId: string) => {
|
||||
return getAPI(SysCodeGenApi)
|
||||
.apiSysCodeGenTableListConfigIdGet(configId)
|
||||
.then((res) => res.data.result ?? []);
|
||||
},
|
||||
getColumnList: (configId: string, tableName: string) => {
|
||||
return getAPI(SysCodeGenApi)
|
||||
.apiSysCodeGenColumnListByTableNameTableNameConfigIdGet(tableName, configId)
|
||||
.then((res) => res.data.result ?? []);
|
||||
},
|
||||
getDefaultColumnConfigList: (body: DefaultColumnConfigInput) => {
|
||||
return getAPI(SysCodeGenApi)
|
||||
.apiSysCodeGenDefaultColumnConfigListPost(body)
|
||||
.then((res) => res.data.result ?? []);
|
||||
},
|
||||
};
|
||||
|
||||
interface CodeGenStore {
|
||||
enabledWatch: boolean;
|
||||
loading: boolean;
|
||||
constList: any[];
|
||||
menuList?: SysMenu[];
|
||||
printList?: SysPrint[];
|
||||
dictList: SysDictType[];
|
||||
enumList: SysDictType[];
|
||||
namespaceList?: string[];
|
||||
databaseList?: DatabaseOutput[];
|
||||
tableMap: { [key: string]: TableOutput[] };
|
||||
columnMap: { [key: string]: ColumnOutput[] };
|
||||
quickConfigMap?: { [key: string]: EffectTreeConfigInput };
|
||||
ruleForm: UpdateCodeGenInput;
|
||||
apiManager: typeof apiManager;
|
||||
}
|
||||
|
||||
const useStore = useUserInfo();
|
||||
export const useCodeGenStore = defineStore('codeGenStore', {
|
||||
state: (): CodeGenStore => ({
|
||||
enabledWatch: false,
|
||||
loading: false,
|
||||
dictList: [],
|
||||
enumList: [],
|
||||
constList: [],
|
||||
tableMap: {},
|
||||
columnMap: {},
|
||||
ruleForm: {} as any,
|
||||
apiManager: apiManager,
|
||||
}),
|
||||
getters: {
|
||||
sceneLabel: (state) => useStore.dictList['CodeGenSceneEnum'].find((u: any) => u.value === state.ruleForm.scene)?.label,
|
||||
tableListBy: (state) => {
|
||||
return async (configId: string) => {
|
||||
if (configId && !state.tableMap[configId]) state.tableMap[configId] = await state.apiManager.getTableList(configId);
|
||||
return state.tableMap[configId];
|
||||
};
|
||||
},
|
||||
columnListBy: (state) => {
|
||||
return async (configId: string, tableName: string) => {
|
||||
const key = `${configId}:${tableName}`;
|
||||
if (tableName && configId && !state.columnMap[key]) state.columnMap[key] = await state.apiManager.getColumnList(configId, tableName);
|
||||
return state.columnMap[key];
|
||||
};
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
async init() {
|
||||
this.menuList ??= await this.apiManager.getMenuList();
|
||||
this.printList ??= await this.apiManager.getPrintList();
|
||||
this.databaseList ??= await this.apiManager.getDatabaseList();
|
||||
this.namespaceList ??= await this.apiManager.getNamespaceList();
|
||||
this.quickConfigMap ??= await this.apiManager.getQuickConfigMap();
|
||||
|
||||
this.constList = useUserInfo().constList;
|
||||
const dictList = await this.apiManager.getDictTypeList();
|
||||
this.dictList = dictList.filter((item) => !item.code.endsWith('Enum'));
|
||||
this.enumList = dictList.filter((item) => item.code.endsWith('Enum'));
|
||||
|
||||
// 监听场景改变
|
||||
watch(
|
||||
() => this.ruleForm.scene,
|
||||
(val: any) => {
|
||||
if (!this.enabledWatch) return;
|
||||
val = parseInt(val ?? '1000');
|
||||
const tableList = [{} as any, {} as any];
|
||||
this.ruleForm!.treeConfig = (val! % 100 == 10 ? { multiple: false } : undefined) as any;
|
||||
//this.ruleForm.configObj = undefined;
|
||||
switch (val) {
|
||||
case 1000: //单表
|
||||
this.ruleForm.tableList = [tableList[0]];
|
||||
break;
|
||||
case 1010: //单表树组件
|
||||
this.ruleForm.tableList = [tableList[0]];
|
||||
break;
|
||||
case 2000: //主从表
|
||||
this.ruleForm.tableList = tableList;
|
||||
this.ruleForm.isHorizontal = false;
|
||||
break;
|
||||
case 2010: //主从表树组件
|
||||
this.ruleForm.tableList = tableList;
|
||||
this.ruleForm.isHorizontal = false;
|
||||
break;
|
||||
case 3000: //关系对照
|
||||
//this.ruleForm.configObj = {};
|
||||
this.ruleForm.tableList = tableList;
|
||||
this.ruleForm.isHorizontal = false;
|
||||
break;
|
||||
case 3010: //关系对照树组件
|
||||
//this.ruleForm.configObj = {};
|
||||
this.ruleForm.tableList = tableList;
|
||||
this.ruleForm.isHorizontal = false;
|
||||
break;
|
||||
default:
|
||||
this.ruleForm.tableList = [];
|
||||
this.ruleForm.treeConfig = undefined;
|
||||
}
|
||||
}
|
||||
);
|
||||
},
|
||||
showTree() {
|
||||
return this.ruleForm.treeConfig && this.ruleForm.scene! % 100 === 10;
|
||||
},
|
||||
showRela() {
|
||||
//return this.ruleForm.configObj && Math.round(this.ruleForm.scene! / 1000) === 3;
|
||||
return Math.round(this.ruleForm.scene! / 1000) === 3;
|
||||
},
|
||||
showMaster() {
|
||||
return (this.showRela() || Math.round(this.ruleForm.scene! / 1000) <= 2) && this.ruleForm.tableList?.[0];
|
||||
},
|
||||
showSlave() {
|
||||
return (this.showRela() || Math.round(this.ruleForm.scene! / 1000) == 2) && this.ruleForm.tableList?.[1];
|
||||
},
|
||||
getLastLinkLabel(index: number) {
|
||||
if (index == 0) {
|
||||
return this.ruleForm.scene! % 1000 === 10 ? '树联表字段' : undefined;
|
||||
} else if (index == 1) {
|
||||
return [2000, 2010, 3000, 3010].includes(this.ruleForm.scene!) ? '主表联表字段' : undefined;
|
||||
}
|
||||
},
|
||||
getNextLinkLabel(index: number) {
|
||||
return index == 0 && [2000, 2010, 3000, 3010].includes(this.ruleForm.scene!) ? '从表联表字段' : undefined;
|
||||
},
|
||||
getSyncColumnListButtonDisabled(index: number) {
|
||||
const data = this.ruleForm.tableList?.[index];
|
||||
return !(data?.configId && data?.tableName);
|
||||
},
|
||||
async getDetail(id: number) {
|
||||
this.loading = true;
|
||||
try {
|
||||
const res = await this.apiManager.detail(id);
|
||||
res?.tableList?.forEach((item: any) => {
|
||||
item.columnList?.forEach((item2: any) => {
|
||||
try {
|
||||
item2.config = JSON.parse(item2.config);
|
||||
} catch (e) {}
|
||||
});
|
||||
});
|
||||
return res;
|
||||
} finally {
|
||||
this.loading = false;
|
||||
}
|
||||
},
|
||||
async getColumnConfigList(id: number) {
|
||||
this.loading = true;
|
||||
try {
|
||||
return (await this.apiManager.getColumnConfigList(id)) as any;
|
||||
} finally {
|
||||
this.loading = false;
|
||||
}
|
||||
},
|
||||
async getDefaultColumnConfigList(index: number) {
|
||||
this.loading = true;
|
||||
try {
|
||||
const data = this.ruleForm.tableList?.[index];
|
||||
if (data?.configId && data?.tableName) {
|
||||
data!.columnList = (await this.apiManager.getDefaultColumnConfigList({
|
||||
configId: data?.configId,
|
||||
tableName: data?.tableName,
|
||||
})) as any[];
|
||||
data!.columnList?.forEach((item: any) => {
|
||||
if (item.config) item.config = JSON.parse(item.config);
|
||||
item.config ??= {};
|
||||
});
|
||||
}
|
||||
return data?.columnList ?? [];
|
||||
} finally {
|
||||
this.loading = false;
|
||||
}
|
||||
},
|
||||
async save(data: any) {
|
||||
this.loading = true;
|
||||
try {
|
||||
for (const item of data.tableList) {
|
||||
item.columnList.forEach((column: any) => {
|
||||
try {
|
||||
column.config = JSON.stringify(column.config);
|
||||
} catch (e) {}
|
||||
});
|
||||
}
|
||||
return data?.id ? await this.apiManager.update(data) : await this.apiManager.add(data);
|
||||
} finally {
|
||||
this.loading = false;
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
@ -0,0 +1,79 @@
|
||||
<template>
|
||||
<div class="sys-codeGenUpload-container">
|
||||
<el-dialog v-model="state.isShowDialog" draggable :close-on-click-modal="false" :width="400" :max-height="'100px'">
|
||||
<template #header>
|
||||
<div style="color: #fff">
|
||||
<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"> <ele-Edit /> </el-icon>
|
||||
<span> 时间数据配置 </span>
|
||||
</div>
|
||||
</template>
|
||||
<el-form :model="state.ruleForm" ref="ruleFormRef" label-width="auto">
|
||||
<el-row :gutter="10">
|
||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
||||
<el-form-item label="时间格式" prop="format" :rules="[{ required: true, message: '时间格式不能为空', trigger: 'blur' }]">
|
||||
<el-select v-model="state.ruleForm.format" filterable clearable class="w100">
|
||||
<el-option label="YYYY-mm-dd HH:MM:SS" value="datetime" />
|
||||
<el-option label="YYYY-dd-MM" value="date" />
|
||||
<el-option label="HH:MM:SS" value="time" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button icon="ele-CircleCloseFilled" @click="cancel">取 消</el-button>
|
||||
<el-button type="primary" icon="ele-CircleCheckFilled" @click="submit" v-reclick="1000">确 定</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup name="sysPreviewCode">
|
||||
import { onMounted, reactive, ref } from 'vue';
|
||||
|
||||
let rowData = {} as any;
|
||||
const emits = defineEmits(['submitData']);
|
||||
const ruleFormRef = ref();
|
||||
const state = reactive({
|
||||
isShowDialog: false,
|
||||
ruleForm: {} as any,
|
||||
});
|
||||
|
||||
onMounted(async () => {});
|
||||
|
||||
// 打开弹窗
|
||||
const openDialog = async (row: any) => {
|
||||
rowData = row;
|
||||
state.isShowDialog = true;
|
||||
state.ruleForm = Object.assign({}, row.config);
|
||||
};
|
||||
|
||||
// 关闭弹窗
|
||||
const closeDialog = () => {
|
||||
rowData.config = Object.assign({}, state.ruleForm);
|
||||
emits('submitData', rowData);
|
||||
cancel();
|
||||
};
|
||||
|
||||
// 取消
|
||||
const cancel = () => {
|
||||
ruleFormRef.value?.resetFields();
|
||||
state.isShowDialog = false;
|
||||
state.ruleForm = {};
|
||||
};
|
||||
|
||||
// 提交
|
||||
const submit = () => {
|
||||
ruleFormRef.value.validate(async (valid: boolean) => {
|
||||
if (!valid) return;
|
||||
closeDialog();
|
||||
});
|
||||
};
|
||||
|
||||
// 导出对象
|
||||
defineExpose({ openDialog });
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
@ -1,601 +1,337 @@
|
||||
<template>
|
||||
<div class="sys-editCodeGen-container">
|
||||
<el-dialog v-model="state.isShowDialog" draggable :close-on-click-modal="false" width="980px">
|
||||
<el-dialog v-model="state.isShowDialog" draggable :close-on-click-modal="false" fullscreen>
|
||||
<template #header>
|
||||
<div style="color: #fff">
|
||||
<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"> <ele-Edit /> </el-icon>
|
||||
<span> {{ props.title }} </span>
|
||||
<span> {{ state.title }} </span>
|
||||
</div>
|
||||
</template>
|
||||
<el-tabs v-model="activeTab" class="demo-tabs">
|
||||
<el-tab-pane label="代码生成" name="codeGen" style="height: 700px">
|
||||
<div style="color: red; padding: 10px 10px; background: #faecd8; margin-bottom: 10px">
|
||||
<el-icon style="transform: translateY(2px)"><ele-Bell /></el-icon>
|
||||
<span> 若找不到在前端生成的实体/表,请检查配置文件中实体所在程序集或重启后台服务。 </span>
|
||||
</div>
|
||||
<el-form :model="state.ruleForm" ref="ruleFormRef" label-width="auto">
|
||||
<el-form :model="store.ruleForm" ref="ruleFormRef" label-width="auto" v-loading="store.loading">
|
||||
<el-tabs v-model="state.activeTab" class="demo-tabs">
|
||||
<el-tab-pane label="代码生成">
|
||||
<el-row :gutter="10">
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||
<el-form-item label="库定位器" prop="configId" :rules="[{ required: true, message: '请选择库定位器', trigger: 'blur' }]">
|
||||
<el-select v-model="state.ruleForm.configId" placeholder="库名" filterable @change="dbChanged()" class="w100">
|
||||
<el-option v-for="item in state.dbData" :key="item.configId" :label="item.configId" :value="item.configId" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||
<el-form-item label="库类型" prop="dbType" :rules="[{ required: true, message: '库类型不能为空', trigger: 'blur' }]">
|
||||
<g-sys-dict v-model="state.ruleForm.dbType" code="db_type" render-as="select" :disabled="state.ruleForm.tenantType == 0 && state.ruleForm.tenantType != undefined" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
||||
<el-form-item label="库地址" prop="connectionString" :rules="[{ required: true, message: '库地址不能为空', trigger: 'blur' }]">
|
||||
<el-input v-model="state.ruleForm.connectionString" disabled clearable type="textarea" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||
<el-form-item label="生成表" prop="tableName" :rules="[{ required: true, message: '生成表不能为空', trigger: 'blur' }]">
|
||||
<template v-slot:label>
|
||||
<div>
|
||||
生成表
|
||||
<el-tooltip raw-content content="若找不到在前端生成的实体/表,请检查配置文件中实体所在程序集或重启后台服务。" placement="top">
|
||||
<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"><ele-QuestionFilled /></el-icon>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</template>
|
||||
<el-select v-model="state.ruleForm.tableName" @change="tableChanged" value-key="value" filterable clearable class="w100">
|
||||
<el-option v-for="item in state.tableData" :key="item.entityName" :label="item.entityName + ' ( ' + item.tableName + ' ) [' + item.tableComment + ']'" :value="item" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||
<el-form-item label="表类型" prop="busName" :rules="[{ required: true, message: '表类型不能为空', trigger: 'blur' }]">
|
||||
<g-sys-dict v-model="state.ruleForm.tabType" code="code_gen_tab_type" render-as="select" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||
<el-form-item label="业务名" prop="busName" :rules="[{ required: true, message: '业务名不能为空', trigger: 'blur' }]">
|
||||
<el-input v-model="state.ruleForm.busName" placeholder="请输入" clearable />
|
||||
<el-input v-model="store.ruleForm.busName" placeholder="请输入" class="w100" clearable />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb5">
|
||||
<el-form-item label="场景类型" prop="scene" :rules="[{ required: true, message: '场景类型不能为空', trigger: 'blur' }]">
|
||||
<g-sys-dict v-model="store.ruleForm.scene" code="CodeGenSceneEnum" render-as="select" :disabled="!!store.ruleForm.id" :on-item-filter="(e: any) => e.value > 0" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||
<el-form-item label="Name字段" prop="treeName">
|
||||
<template v-slot:label>
|
||||
<div>
|
||||
Name字段
|
||||
<el-tooltip raw-content content="本表作为树控件的树属性Name字段。" placement="top">
|
||||
<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"><ele-QuestionFilled /></el-icon>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</template>
|
||||
<el-select v-model="state.ruleForm.treeName" @change="treeNameChanged" value-key="value" filterable clearable class="w100">
|
||||
<el-option v-for="item in state.columnData" :key="item.columnName" :label="item.columnName + ' ( ' + item.columnName + ' ) [' + item.columnComment + ']'" :value="item" />
|
||||
</el-select>
|
||||
<el-form-item label="作者姓名" prop="authorName" class="flex w100">
|
||||
<el-input v-model="store.ruleForm.authorName" clearable placeholder="请输入姓名" class="w100" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||
<el-form-item label="树key字段" prop="treeKey">
|
||||
<template v-slot:label>
|
||||
<div>
|
||||
PidKey字段
|
||||
<el-tooltip raw-content content="本表作为树控件的树属性父ID,PidKey字段字段,没有就请留空。" placement="top">
|
||||
<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"><ele-QuestionFilled /></el-icon>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</template>
|
||||
<el-select v-model="state.ruleForm.treeKey" @change="treeKeyChanged" value-key="value" filterable clearable class="w100">
|
||||
<el-option v-for="item in state.columnData" :key="item.columnName" :label="item.columnName + ' ( ' + item.columnName + ' ) [' + item.columnComment + ']'" :value="item" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||
<el-form-item label="生成菜单" prop="generateMenu">
|
||||
<el-radio-group v-model="state.ruleForm.generateMenu">
|
||||
<el-radio :value="true">是</el-radio>
|
||||
<el-radio :value="false">否</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||
<el-form-item label="菜单图标" prop="menuIcon">
|
||||
<IconSelector v-model="state.ruleForm.menuIcon" :size="getGlobalComponentSize" placeholder="菜单图标" type="all" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||
<el-form-item label="父级菜单" prop="menuPid">
|
||||
<el-cascader
|
||||
:options="state.menuData"
|
||||
:props="cascaderProps"
|
||||
placeholder="请选择上级菜单"
|
||||
:disabled="!state.ruleForm.generateMenu"
|
||||
filterable
|
||||
clearable
|
||||
class="w100"
|
||||
v-model="state.ruleForm.menuPid"
|
||||
@change="menuChange"
|
||||
>
|
||||
<template #default="{ node, data }">
|
||||
<span>{{ data.title }}</span>
|
||||
<span v-if="!node.isLeaf"> ({{ data.children.length }}) </span>
|
||||
</template>
|
||||
</el-cascader>
|
||||
<el-form-item label="作者邮箱" prop="authorName" class="flex w100">
|
||||
<el-input v-model="store.ruleForm.email" clearable placeholder="请输入邮箱" class="w100" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||
<el-form-item label="命名空间" prop="nameSpace" :rules="[{ required: true, message: '请选择命名空间', trigger: 'blur' }]">
|
||||
<!-- <el-input v-model="state.ruleForm.nameSpace" clearable placeholder="请输入" /> -->
|
||||
<el-select v-model="state.ruleForm.nameSpace" filterable clearable class="w100" placeholder="命名空间">
|
||||
<el-option v-for="(item, index) in props.applicationNamespaces" :key="index" :label="item" :value="item" />
|
||||
<el-select v-model="store.ruleForm.nameSpace" filterable clearable class="w100" placeholder="命名空间">
|
||||
<el-option v-for="(item, index) in store.namespaceList ?? []" :key="index" :label="item" :value="item" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||
<el-form-item label="前端目录" prop="pagePath" :rules="[{ required: true, message: '前端目录不能为空', trigger: 'blur' }]">
|
||||
<el-input v-model="state.ruleForm.pagePath" clearable placeholder="请输入" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||
<el-form-item label="作者姓名" prop="authorName">
|
||||
<el-input v-model="state.ruleForm.authorName" clearable placeholder="请输入" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||
<el-form-item label="生成方式" prop="generateType">
|
||||
<g-sys-dict v-model="state.ruleForm.generateType" code="code_gen_create_type" render-as="select" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||
<el-form-item label="接口模式" prop="isApiService">
|
||||
<template v-slot:label>
|
||||
<div>
|
||||
接口模式
|
||||
<el-tooltip raw-content content="接口服务模式是指根据swagger自动生成前端接口请求文件,推荐此模式。传统模式则是指手动编写接口请求并进行数据绑定。" placement="top">
|
||||
前端目录
|
||||
<el-tooltip raw-content content="指的是前端相对目录:src/views/main" placement="top">
|
||||
<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"><ele-QuestionFilled /></el-icon>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</template>
|
||||
<el-radio-group v-model="state.ruleForm.isApiService">
|
||||
<el-input v-model="store.ruleForm.pagePath" clearable placeholder="请输入" class="w100" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||
<el-form-item label="生成方式" prop="generateMethod" :rules="[{ required: true, message: '生成方式不能为空', trigger: 'blur' }]">
|
||||
<g-sys-dict v-model="store.ruleForm.generateMethod" code="CodeGenMethodEnum" render-as="select" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||
<el-form-item label="支持打印" prop="printType" :rules="[{ required: true, message: '支持打印不能为空', trigger: 'blur' }]">
|
||||
<g-sys-dict v-model="store.ruleForm.printType" code="CodeGenPrintTypeEnum" render-as="select" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||
<el-form-item label="打印模版" prop="printName" :rules="[{ required: store.ruleForm.printType == 2, message: '打印模版不能为空', trigger: 'blur' }]">
|
||||
<el-select v-model="store.ruleForm.printName" filterable class="w100" :disabled="store.ruleForm.printType != 2">
|
||||
<el-option v-for="item in store.printList" :key="item.id" :label="item.name" :value="item.name" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||
<el-form-item label="接口模式" prop="isApiService" :rules="[{ required: true, message: '接口模式不能为空', trigger: 'blur' }]">
|
||||
<template v-slot:label>
|
||||
<div>
|
||||
接口模式
|
||||
<el-tooltip
|
||||
raw-content
|
||||
content="接口服务模式是指根据swagger自动生成前端接口请求文件(需要手动双击批处理生成,目录api_build/build.bat),推荐此模式。传统模式则是指手动根据swagger编写接口请求并进行模型定义。"
|
||||
placement="top"
|
||||
>
|
||||
<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"><ele-QuestionFilled /></el-icon>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</template>
|
||||
<el-radio-group v-model="store.ruleForm.isApiService">
|
||||
<el-radio :value="true">接口服务</el-radio>
|
||||
<el-radio :value="false">传统模式</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||
<el-form-item label="支持打印" prop="printType">
|
||||
<g-sys-dict v-model="state.ruleForm.printType" code="code_gen_print_type" render-as="select" />
|
||||
<el-form-item label="生成菜单" prop="generateMenu" :rules="[{ required: true, message: '生成菜单不能为空', trigger: 'blur' }]">
|
||||
<el-radio-group v-model="store.ruleForm.generateMenu">
|
||||
<el-radio :value="true">是</el-radio>
|
||||
<el-radio :value="false">否</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20" v-if="state.ruleForm.printType == 'custom'">
|
||||
<el-form-item label="打印模版" prop="printName">
|
||||
<el-select v-model="state.ruleForm.printName" filterable class="w100">
|
||||
<el-option v-for="item in state.printList" :key="item.id" :label="item.name" :value="item.name" />
|
||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20" v-if="store.ruleForm.generateMenu">
|
||||
<el-row>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
|
||||
<el-form-item label="父级菜单" prop="menuPid">
|
||||
<el-cascader
|
||||
:options="store.menuList"
|
||||
:props="cascaderProps"
|
||||
placeholder="请选择上级菜单"
|
||||
:disabled="!store.ruleForm.generateMenu"
|
||||
filterable
|
||||
clearable
|
||||
class="w100"
|
||||
v-model="store.ruleForm.menuPid"
|
||||
>
|
||||
<template #default="{ node, data }">
|
||||
<span>{{ data.title }}</span>
|
||||
<span v-if="!node.isLeaf"> ({{ data.children.length }}) </span>
|
||||
</template>
|
||||
</el-cascader>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
|
||||
<el-form-item label="菜单图标" prop="menuIcon" :rules="[{ required: true, message: '菜单图标不能为空', trigger: 'blur' }]">
|
||||
<IconSelector v-model="store.ruleForm.menuIcon as any" :size="other.globalComponentSize()" placeholder="菜单图标" type="all" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-col>
|
||||
<el-col v-if="<number>store.ruleForm.scene >= 2000" :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||
<el-form-item label="布局方向" prop="isHorizontal" :rules="[{ required: true, message: '水平布局不能为空', trigger: 'blur' }]">
|
||||
<el-radio-group v-model="store.ruleForm.isHorizontal">
|
||||
<el-radio :value="false">水平</el-radio>
|
||||
<el-radio :value="true">垂直</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane v-if="store.showTree()" label="树组件配置">
|
||||
<el-row>
|
||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
||||
<el-form-item label="库定位器" prop="treeConfig.configId" :rules="[{ required: true, message: '库定位器不能为空', trigger: 'blur' }]">
|
||||
<el-select clearable v-model="store.ruleForm.treeConfig!.configId" placeholder="库名" filterable @change="(val: any) => dbChanged(val)" class="w100">
|
||||
<el-option v-for="item in store.databaseList ?? []" :key="item.configId" :label="item.configId" :value="item.configId" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<!-- <el-divider border-style="dashed" content-position="center">
|
||||
<div style="color: #b1b3b8">数据唯一性配置</div>
|
||||
</el-divider>
|
||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
||||
<el-button icon="ele-Plus" type="primary" plain @click="() => state.ruleForm.tableUniqueList?.push({})"> 增加配置 </el-button>
|
||||
<span style="font-size: 12px; color: gray; padding-left: 5px"> 保证字段值的唯一性,排除null值 </span>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
||||
<template v-if="state.ruleForm.tableUniqueList != undefined && state.ruleForm.tableUniqueList.length > 0">
|
||||
<el-row :gutter="10" v-for="(v, k) in state.ruleForm.tableUniqueList" :key="k">
|
||||
<el-col :xs="24" :sm="14" :md="14" :lg="14" :xl="14" class="mb20">
|
||||
<el-form-item label="字段" :prop="`tableUniqueList[${k}].columns`" :rules="[{ required: true, message: `字段不能为空`, trigger: 'blur' }]">
|
||||
<template #label>
|
||||
<el-button icon="ele-Delete" type="danger" circle plain size="small" @click="() => state.ruleForm.tableUniqueList?.splice(k, 1)" />
|
||||
<span class="ml5">字段</span>
|
||||
</template>
|
||||
<el-select
|
||||
v-model="state.ruleForm.tableUniqueList[k].columns"
|
||||
@change="(val: any) => changeTableUniqueColumn(val, k)"
|
||||
multiple
|
||||
filterable
|
||||
clearable
|
||||
collapse-tags
|
||||
collapse-tags-tooltip
|
||||
class="w100"
|
||||
>
|
||||
<el-option v-for="item in state.columnData" :key="item.columnName" :label="item.columnName + ' [' + item.columnComment + ']'" :value="item.columnName" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="10" :md="10" :lg="10" :xl="10" class="mb20">
|
||||
<el-form-item label="描述信息" :prop="`tableUniqueList[${k}].message`" :rules="[{ required: true, message: `描述信息不能为空`, trigger: 'blur' }]">
|
||||
<el-input v-model="state.ruleForm.tableUniqueList[k].message" clearable placeholder="请输入" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</template>
|
||||
</el-col> -->
|
||||
<el-col>
|
||||
<el-divider content-position="center"> 左边布局显示树形列表;右边布局上下结构显示主子表数据列表 </el-divider>
|
||||
|
||||
<!-- <p><el-tag style="border: 1 solid var(--el-border-color)">以下默认页面左右布局,左边布局显示树形列表,右边布局上下结构显示主子表数据列表</el-tag></p> -->
|
||||
<el-tabs v-model="activeName" class="demo-tabs">
|
||||
<el-tab-pane label="页面左(树列表)" name="1">
|
||||
<el-row :gutter="10">
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||
<el-form-item label="树 - 库定位器" prop="configId2">
|
||||
<el-select v-model="state.ruleForm.configId2" placeholder="库名" filterable @change="dbChanged2()" class="w100">
|
||||
<el-option v-for="item in state.dbData" :key="item.configId" :label="item.configId" :value="item.configId" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||
<el-form-item label="树表名称">
|
||||
<template v-slot:label>
|
||||
<div>
|
||||
树表名称
|
||||
<el-tooltip raw-content content="若找不到在前端生成的实体/表,同上,如表有下划线_则因实体去掉划线取不到字段。" placement="top">
|
||||
<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"><ele-QuestionFilled /></el-icon>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</template>
|
||||
<el-select v-model="state.ruleForm.leftTab" @change="leftTableChanged" value-key="value" filterable clearable class="w100">
|
||||
<el-option v-for="item in state.tableData2" :key="item.entityName" :label="item.entityName + ' ( ' + item.tableName + ' ) [' + item.tableComment + ']'" :value="item" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||
<el-form-item label="树关联字段">
|
||||
<el-select v-model="state.ruleForm.leftKey" @change="leftKeyChanged" value-key="value" filterable clearable class="w100">
|
||||
<el-option v-for="item in state.lcolumnData" :key="item.columnName" :label="item.columnName + ' ( ' + item.columnName + ' ) [' + item.columnComment + ']'" :value="item" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||
<el-form-item label="关联主表字段">
|
||||
<template v-slot:label>
|
||||
<div>
|
||||
关联主表字段
|
||||
<el-tooltip raw-content content="先选择主表才可以选择字段。" placement="top">
|
||||
<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"><ele-QuestionFilled /></el-icon>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</template>
|
||||
<el-select v-model="state.ruleForm.leftPrimaryKey" @change="leftPrimaryKeyChanged" value-key="value" filterable clearable class="w100">
|
||||
<el-option v-for="item in state.columnData" :key="item.columnName" :label="item.columnName + ' ( ' + item.columnName + ' ) [' + item.columnComment + ']'" :value="item" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||
<el-form-item label="树显示名称">
|
||||
<el-select v-model="state.ruleForm.leftName" @change="leftNameChanged" value-key="value" filterable clearable class="w100">
|
||||
<el-option v-for="item in state.lcolumnData" :key="item.columnName" :label="item.columnName + ' ( ' + item.columnName + ' ) [' + item.columnComment + ']'" :value="item" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||
<el-form-item label="模板">
|
||||
<el-input v-model="state.ruleForm.template" clearable placeholder="请输入" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="页面右(主子表)" name="2">
|
||||
<el-row :gutter="10">
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||
<el-form-item label="子表 - 库定位器" prop="configId3">
|
||||
<el-select v-model="state.ruleForm.configId3" placeholder="库名" filterable @change="dbChanged3()" class="w100">
|
||||
<el-option v-for="item in state.dbData" :key="item.configId" :label="item.configId" :value="item.configId" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||
<el-form-item label="子表名称" prop="bottomTab">
|
||||
<template v-slot:label>
|
||||
<div>
|
||||
子表名称
|
||||
<el-tooltip raw-content content="若找不到在前端生成的实体/表,同上,如表有下划线_则因实体去掉划线取不到字段。" placement="top">
|
||||
<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"><ele-QuestionFilled /></el-icon>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</template>
|
||||
<el-select v-model="state.ruleForm.bottomTab" @change="bottomTableChanged" value-key="value" filterable clearable class="w100">
|
||||
<el-option v-for="item in state.tableData3" :key="item.entityName" :label="item.entityName + ' ( ' + item.tableName + ' ) [' + item.tableComment + ']'" :value="item" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||
<el-form-item label="子表关联字段" prop="bottomKey">
|
||||
<el-select v-model="state.ruleForm.bottomKey" @change="bottomKeyChanged" value-key="value" filterable clearable class="w100">
|
||||
<el-option v-for="item in state.bcolumnData" :key="item.columnName" :label="item.columnName + ' ( ' + item.columnName + ' ) [' + item.columnComment + ']'" :value="item" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||
<el-form-item label="关联主表字段" prop="bottomPrimaryKey">
|
||||
<template v-slot:label>
|
||||
<div>
|
||||
关联主表字段
|
||||
<el-tooltip raw-content content="先选择主表才可以选择字段。" placement="top">
|
||||
<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"><ele-QuestionFilled /></el-icon>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</template>
|
||||
<el-select v-model="state.ruleForm.bottomPrimaryKey" @change="bottomPrimaryKeyChanged" value-key="value" filterable clearable class="w100">
|
||||
<el-option v-for="item in state.columnData" :key="item.columnName" :label="item.columnName + ' ( ' + item.columnName + ' ) [' + item.columnComment + ']'" :value="item" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
||||
<el-form-item label="数据库表" prop="treeConfig.tableName" :rules="[{ required: true, message: '数据库表不能为空', trigger: 'blur' }]">
|
||||
<el-select v-model="store.ruleForm.treeConfig!.tableName" filterable clearable @change="(val: any) => tableChanged(store.ruleForm.treeConfig!.configId, val, 'tree')" class="w100">
|
||||
<el-option v-for="item in state.tableData" :key="item.entityName" :label="item.tableName + ' [' + item.tableComment + ']'" :value="item" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
||||
<el-form-item label="显示字段" prop="treeConfig.displayPropertyNames" :rules="[{ required: true, message: '显示字段不能为空', trigger: 'blur' }]">
|
||||
<el-select v-model="store.ruleForm.treeConfig!.displayPropertyNames" filterable class="w100">
|
||||
<el-option v-for="item in state.columnList" :key="item.propertyName" :label="item.columnName + ' [' + item.columnComment + ']'" :value="item.propertyName" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
||||
<el-form-item label="值字段" prop="treeConfig.linkPropertyName" :rules="[{ required: true, message: '值字段不能为空', trigger: 'blur' }]">
|
||||
<el-select v-model="store.ruleForm.treeConfig!.linkPropertyName" filterable class="w100" @change="(val: any) => changeTreePropertyName(val, 'link')">
|
||||
<el-option v-for="item in state.columnList" :key="item.propertyName" :label="item.columnName + ' [' + item.columnComment + ']'" :value="item" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
||||
<el-form-item label="父级字段" prop="treeConfig.parentPropertyName" :rules="[{ required: true, message: '父级字段不能为空', trigger: 'blur' }]">
|
||||
<el-select v-model="store.ruleForm.treeConfig!.parentPropertyName" filterable class="w100" @change="(val: any) => changeTreePropertyName(val, 'parent')">
|
||||
<el-option v-for="item in state.columnList" :key="item.propertyName" :label="item.columnName + ' [' + item.columnComment + ']'" :value="item" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
||||
<el-form-item label="查询字段" prop="treeConfig.searchPropertyName" :rules="[{ required: true, message: '查询字段不能为空', trigger: 'blur' }]">
|
||||
<el-select v-model="store.ruleForm.treeConfig!.searchPropertyName" filterable class="w100" @change="(val: any) => changeTreePropertyName(val, 'search')">
|
||||
<el-option v-for="item in state.columnList" :key="item.propertyName" :label="item.columnName + ' [' + item.columnComment + ']'" :value="item" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
||||
<el-form-item label="树标题" prop="treeConfig.treeTitle" :rules="[{ required: true, message: '树标题不能为空', trigger: 'blur' }]">
|
||||
<el-input v-model="store.ruleForm.treeConfig!.treeTitle" clearable placeholder="请输入" class="w100" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
||||
<el-form-item label="是否多选">
|
||||
<el-radio-group v-model="store.ruleForm.treeConfig!.multiple" filterable>
|
||||
<el-radio :value="true">是</el-radio>
|
||||
<el-radio :value="false">否</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="选择模板" name="template" style="height: 700px">
|
||||
<el-table ref="templateTableRef" :data="templateTableData" @selection-change="handleSelectionChange" style="width: 100%">
|
||||
<el-table-column type="selection" width="65" />
|
||||
<el-table-column property="name" label="模板文件名" width="280" />
|
||||
<el-table-column property="describe" label="描述" show-overflow-tooltip />
|
||||
</el-table>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane v-if="store.showMaster()" label="主表配置">
|
||||
<TableConfig :index="0" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane v-if="store.showSlave()" label="从表配置">
|
||||
<TableConfig :index="1" />
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button icon="ele-CircleCloseFilled" @click="cancel">取 消</el-button>
|
||||
<el-button type="primary" icon="ele-CircleCheckFilled" @click="submit">确 定</el-button>
|
||||
<el-button icon="ele-CircleCloseFilled" @click="cancel" :disabled="state.loading">取 消</el-button>
|
||||
<el-button type="primary" icon="ele-CircleCheckFilled" @click="submit" :disabled="state.loading" v-reclick="1000">确 定</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- 代码生成配置 -->
|
||||
<script lang="ts" setup name="sysEditCodeGen">
|
||||
import { computed, onMounted, reactive, ref, nextTick } from 'vue';
|
||||
import IconSelector from '/@/components/iconSelector/index.vue';
|
||||
import { defineAsyncComponent, nextTick, reactive, ref } from 'vue';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import other from '/@/utils/other';
|
||||
import IconSelector from '/@/components/iconSelector/index.vue';
|
||||
|
||||
import { getAPI } from '/@/utils/axios-utils';
|
||||
import { SysCodeGenApi, SysMenuApi, SysPrintApi, SysCodeGenTemplateApi } from '/@/api-services/system/api';
|
||||
import { UpdateCodeGenInput, AddCodeGenInput, SysMenu, SysPrint } from '/@/api-services/system/models';
|
||||
import { useCodeGenStore } from './codeGenStore';
|
||||
|
||||
const props = defineProps({
|
||||
title: String,
|
||||
applicationNamespaces: Array<String>,
|
||||
});
|
||||
const TableConfig = defineAsyncComponent(() => import('./tableConfig.vue'));
|
||||
const emits = defineEmits(['handleQuery']);
|
||||
const store = useCodeGenStore();
|
||||
const ruleFormRef = ref();
|
||||
const state = reactive({
|
||||
title: '编辑代码生成',
|
||||
isShowDialog: false,
|
||||
ruleForm: {} as UpdateCodeGenInput | any,
|
||||
tableData: [] as any,
|
||||
tableData2: [] as any,
|
||||
tableData3: [] as any,
|
||||
dbData: [] as any,
|
||||
columnData: [] as any,
|
||||
lcolumnData: [] as any,
|
||||
bcolumnData: [] as any,
|
||||
menuData: [] as Array<SysMenu>,
|
||||
printList: [] as Array<SysPrint>,
|
||||
columnList: [] as any,
|
||||
loading: false,
|
||||
activeTab: '0',
|
||||
});
|
||||
const activeName = ref('1');
|
||||
const activeTab = ref('codeGen');
|
||||
const templateTableRef = ref();
|
||||
const multipleSelection = ref([] as any);
|
||||
const templateTableData = ref([] as any);
|
||||
|
||||
// 级联选择器配置选项
|
||||
const cascaderProps = { checkStrictly: true, emitPath: false, value: 'id', label: 'title' };
|
||||
|
||||
onMounted(async () => {
|
||||
state.dbData = await getAPI(SysCodeGenApi)
|
||||
.apiSysCodeGenDatabaseListGet()
|
||||
.then((res) => res.data.result ?? []);
|
||||
|
||||
state.printList = await getAPI(SysPrintApi)
|
||||
.apiSysPrintPagePost()
|
||||
.then((res) => res.data.result?.items ?? []);
|
||||
state.menuData = await getAPI(SysMenuApi)
|
||||
.apiSysMenuListGet()
|
||||
.then((res) => res.data.result ?? []);
|
||||
});
|
||||
|
||||
// 获得模板列表
|
||||
const getSysCodeGenTemplateList = async () => {
|
||||
let res = await getAPI(SysCodeGenTemplateApi).apiSysCodeGenTemplateListGet();
|
||||
let data = res.data.result ?? [];
|
||||
templateTableData.value = data;
|
||||
// 选中
|
||||
nextTick(() => {
|
||||
let checkedRows = [] as any;
|
||||
if (state.ruleForm.id) {
|
||||
// 修改
|
||||
data.forEach((element: any) => {
|
||||
if (state.ruleForm.codeGenTemplateRelations.some((ele: any) => ele.templateId == element.id)) {
|
||||
checkedRows.push(element);
|
||||
templateTableRef.value.toggleRowSelection(element, true);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// 新增
|
||||
data.forEach((element: any) => {
|
||||
if (element.isDefault) {
|
||||
checkedRows.push(element);
|
||||
templateTableRef.value.toggleRowSelection(element, true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
multipleSelection.value = checkedRows;
|
||||
});
|
||||
};
|
||||
|
||||
// 表格选中事件
|
||||
const handleSelectionChange = (val: any[]) => {
|
||||
multipleSelection.value = val;
|
||||
// console.log(val);
|
||||
};
|
||||
|
||||
// db改变
|
||||
const dbChanged = async () => {
|
||||
if (state.ruleForm.configId === '' || state.ruleForm.configId == null) return;
|
||||
state.tableData = await getAPI(SysCodeGenApi)
|
||||
.apiSysCodeGenTableListConfigIdGet(state.ruleForm.configId as string)
|
||||
.then((res) => res.data.result ?? []);
|
||||
const dbChanged = async (configId: string) => {
|
||||
if (!configId) return;
|
||||
state.tableData = await store.tableListBy(configId);
|
||||
};
|
||||
|
||||
let db = state.dbData.filter((u: any) => u.configId == state.ruleForm.configId);
|
||||
state.ruleForm.connectionString = db[0].connectionString;
|
||||
state.ruleForm.dbType = db[0].dbType.toString();
|
||||
};
|
||||
const dbChanged2 = async () => {
|
||||
if (state.ruleForm.configId === '' || state.ruleForm.configId == null) return;
|
||||
state.tableData2 = await getAPI(SysCodeGenApi)
|
||||
.apiSysCodeGenTableListConfigIdGet(state.ruleForm.configId2 as string)
|
||||
.then((res) => res.data.result ?? []);
|
||||
};
|
||||
const dbChanged3 = async () => {
|
||||
if (state.ruleForm.configId === '' || state.ruleForm.configId == null) return;
|
||||
state.tableData3 = await getAPI(SysCodeGenApi)
|
||||
.apiSysCodeGenTableListConfigIdGet(state.ruleForm.configId3 as string)
|
||||
.then((res) => res.data.result ?? []);
|
||||
};
|
||||
// table改变
|
||||
const tableChanged = (item: any) => {
|
||||
state.ruleForm.tableName = item.entityName;
|
||||
state.ruleForm.busName = item.tableComment;
|
||||
state.ruleForm.tableUniqueList = [];
|
||||
getColumnInfoList(item);
|
||||
const tableChanged = async (configId: string, item: any, type: string) => {
|
||||
if (typeof item === `string`) item = state.tableData.find((i: any) => i.entityName == item || i.tableName == item);
|
||||
if (type == 'tree') {
|
||||
store.ruleForm.treeConfig ??= {} as any;
|
||||
store.ruleForm.treeConfig!.tableComment = item?.tableComment ?? undefined;
|
||||
store.ruleForm.treeConfig!.entityName = item?.entityName ?? undefined;
|
||||
if (store.ruleForm.treeConfig!.tableName != item?.tableName) {
|
||||
store.ruleForm.treeConfig!.tableName = item?.tableName ?? undefined;
|
||||
store.ruleForm.treeConfig!.displayPropertyNames = undefined as any;
|
||||
store.ruleForm.treeConfig!.parentPropertyName = undefined;
|
||||
store.ruleForm.treeConfig!.searchPropertyName = undefined;
|
||||
store.ruleForm.treeConfig!.linkPropertyName = undefined as any;
|
||||
}
|
||||
}
|
||||
// else if (type == 'tableRelationship') {
|
||||
// store.ruleForm.configObj.entityName = item?.entityName ?? undefined;
|
||||
// store.ruleForm.configObj.tableName = item?.tableName ?? undefined;
|
||||
// store.ruleForm.configObj.propertyName1 = undefined;
|
||||
// store.ruleForm.configObj.propertyName2 = undefined;
|
||||
// }
|
||||
state.columnList = (await store.columnListBy(configId, item?.tableName)) ?? [];
|
||||
};
|
||||
|
||||
const tabTypeChanged = async (item: any) => {
|
||||
state.ruleForm.tabType = item;
|
||||
};
|
||||
const treeNameChanged = (item: any) => {
|
||||
state.ruleForm.treeName = item.columnName;
|
||||
};
|
||||
|
||||
const treeKeyChanged = (item: any) => {
|
||||
state.ruleForm.treeKey = item.columnName;
|
||||
};
|
||||
const leftTableChanged = (item: any) => {
|
||||
state.ruleForm.leftTab = item.entityName;
|
||||
console.log('leftTableChanged--', JSON.stringify(item));
|
||||
getLColumnInfoList(item);
|
||||
};
|
||||
const leftKeyChanged = (item: any) => {
|
||||
console.log('leftKeyChanged--', JSON.stringify(item));
|
||||
state.ruleForm.leftKey = item.columnName;
|
||||
};
|
||||
const leftPrimaryKeyChanged = (item: any) => {
|
||||
console.log('leftPrimaryKeyChanged--', JSON.stringify(item));
|
||||
state.ruleForm.leftPrimaryKey = item.columnName;
|
||||
};
|
||||
const leftNameChanged = (item: any) => {
|
||||
state.ruleForm.leftName = item.columnName;
|
||||
};
|
||||
const getLColumnInfoList = async (item: any) => {
|
||||
if (state.ruleForm.configId2 == '' || state.ruleForm.configId2 == null || state.ruleForm.leftTab == '' || state.ruleForm.leftTab == null) return;
|
||||
state.lcolumnData =
|
||||
(await getAPI(SysCodeGenApi)
|
||||
.apiSysCodeGenColumnListByTableNameTableNameConfigIdGet(item.tableName, state.ruleForm.configId2)
|
||||
.then((res) => res.data.result)) ?? [];
|
||||
};
|
||||
const bottomTableChanged = (item: any) => {
|
||||
state.ruleForm.bottomTab = item.entityName;
|
||||
getLBColumnInfoList(item);
|
||||
};
|
||||
const bottomKeyChanged = (item: any) => {
|
||||
state.ruleForm.bottomKey = item.columnName;
|
||||
};
|
||||
const bottomPrimaryKeyChanged = (item: any) => {
|
||||
console.log('bottomPrimaryKeyChanged--', JSON.stringify(item));
|
||||
state.ruleForm.bottomPrimaryKey = item.columnName;
|
||||
};
|
||||
const getLBColumnInfoList = async (item: any) => {
|
||||
if (state.ruleForm.configId3 == '' || state.ruleForm.configId3 == null || state.ruleForm.bottomTab == '' || state.ruleForm.bottomTab == null) return;
|
||||
state.bcolumnData =
|
||||
(await getAPI(SysCodeGenApi)
|
||||
.apiSysCodeGenColumnListByTableNameTableNameConfigIdGet(item.tableName, state.ruleForm.configId3)
|
||||
.then((res) => res.data.result)) ?? [];
|
||||
};
|
||||
// 表唯一约束配置项字段改变事件
|
||||
const changeTableUniqueColumn = (value: any, index: number) => {
|
||||
if (value?.length === 1 && !state.ruleForm.tableUniqueList[index].message) {
|
||||
state.ruleForm.tableUniqueList[index].message = state.columnData.find((u: any) => u.columnName === value[0])?.columnComment;
|
||||
// 属性改变
|
||||
const changeTreePropertyName = (item: any, type: string) => {
|
||||
if (type == 'display') {
|
||||
store.ruleForm.treeConfig!.displayPropertyNames = item.propertyName;
|
||||
//store.ruleForm!.treeConfig!.displayPropertyType = item.netType;
|
||||
} else if (type == 'link') {
|
||||
store.ruleForm.treeConfig!.linkPropertyName = item.propertyName;
|
||||
store.ruleForm!.treeConfig!.linkPropertyType = item.netType;
|
||||
} else if (type == 'search') {
|
||||
store.ruleForm.treeConfig!.searchPropertyName = item.propertyName;
|
||||
store.ruleForm!.treeConfig!.searchPropertyType = item.netType;
|
||||
} else if (type == 'parent') {
|
||||
store.ruleForm.treeConfig!.parentPropertyName = item.propertyName;
|
||||
store.ruleForm!.treeConfig!.parentPropertyType = item.netType;
|
||||
}
|
||||
};
|
||||
|
||||
const getColumnInfoList = async (item: any) => {
|
||||
if (state.ruleForm.configId == '' || state.ruleForm.configId == null || state.ruleForm.tableName == '' || state.ruleForm.tableName == null) return;
|
||||
state.columnData =
|
||||
(await getAPI(SysCodeGenApi)
|
||||
.apiSysCodeGenColumnListByTableNameTableNameConfigIdGet(item.tableName, state.ruleForm.configId)
|
||||
.then((res) => res.data.result)) ?? [];
|
||||
};
|
||||
|
||||
// 菜单改变
|
||||
const menuChange = (menu: any) => {
|
||||
state.ruleForm.pagePath = state.menuData.find((x) => x.id == menu)?.name;
|
||||
};
|
||||
|
||||
// print改变
|
||||
const printTypeChanged = () => {
|
||||
if (state.ruleForm.printType === '') return;
|
||||
if (state.ruleForm.printType == 'off') state.ruleForm.printName = '';
|
||||
};
|
||||
|
||||
// 获取全局组件大小
|
||||
const getGlobalComponentSize = computed(() => {
|
||||
return other.globalComponentSize();
|
||||
});
|
||||
|
||||
// 打开弹窗
|
||||
const openDialog = (row: any) => {
|
||||
state.ruleForm = JSON.parse(JSON.stringify(row));
|
||||
dbChanged().then(() => getColumnInfoList(row));
|
||||
state.isShowDialog = true;
|
||||
ruleFormRef.value?.resetFields();
|
||||
getSysCodeGenTemplateList();
|
||||
const openDialog = async (row: any) => {
|
||||
store.enabledWatch = !!row?.id;
|
||||
|
||||
try {
|
||||
state.loading = true;
|
||||
state.activeTab = '0';
|
||||
ruleFormRef.value?.resetFields();
|
||||
state.title = (row.id ? '编辑' : '新增') + '代码生成';
|
||||
store.ruleForm = row?.id ? await store.getDetail(row.id) : row;
|
||||
store.ruleForm.nameSpace ??= store.namespaceList?.[0] as any;
|
||||
state.isShowDialog = true;
|
||||
} finally {
|
||||
nextTick(() => {
|
||||
store.enabledWatch = true;
|
||||
// store.ruleForm.scene ??= 1000;
|
||||
});
|
||||
state.loading = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 关闭弹窗
|
||||
const closeDialog = () => {
|
||||
emits('handleQuery');
|
||||
state.isShowDialog = false;
|
||||
activeTab.value = 'codeGen';
|
||||
};
|
||||
|
||||
// 取消
|
||||
const cancel = () => {
|
||||
state.isShowDialog = false;
|
||||
activeTab.value = 'codeGen';
|
||||
};
|
||||
|
||||
// 提交
|
||||
const submit = () => {
|
||||
// 检查是否选中有模板
|
||||
if (multipleSelection.value.length == 0) {
|
||||
ElMessage({
|
||||
message: `请选择模板`,
|
||||
type: 'error',
|
||||
});
|
||||
activeTab.value = 'template';
|
||||
return;
|
||||
}
|
||||
|
||||
let codeGenTemplateIds: any[] = [];
|
||||
multipleSelection.value.forEach((item: any) => {
|
||||
codeGenTemplateIds.push(item.id);
|
||||
store.ruleForm.busName ??= store.ruleForm.tableList?.[0]?.busName;
|
||||
const data = Object.assign(store.ruleForm, {
|
||||
moduleName: store.ruleForm.moduleName ?? store.ruleForm.tableList?.[0]?.moduleName,
|
||||
});
|
||||
state.ruleForm.codeGenTemplateIds = codeGenTemplateIds;
|
||||
ruleFormRef.value.validate(async (valid: boolean) => {
|
||||
if (!valid) return;
|
||||
if (state.ruleForm.tableUniqueList?.length === 0) state.ruleForm.tableUniqueList = null;
|
||||
if (state.ruleForm.id != undefined && state.ruleForm.id > 0) {
|
||||
await getAPI(SysCodeGenApi).apiSysCodeGenUpdatePost(state.ruleForm as UpdateCodeGenInput);
|
||||
ruleFormRef.value.validate(async (isValid: boolean, fields?: any) => {
|
||||
if (isValid) {
|
||||
data.treeConfig = <number>data.scene % 100 == 10 ? data.treeConfig : undefined;
|
||||
await store.save(data);
|
||||
closeDialog();
|
||||
} else {
|
||||
await getAPI(SysCodeGenApi).apiSysCodeGenAddPost(state.ruleForm as AddCodeGenInput);
|
||||
ElMessage({
|
||||
message: `表单有${Object.keys(fields).length}处验证失败,请修改后再提交`,
|
||||
type: 'error',
|
||||
});
|
||||
}
|
||||
closeDialog();
|
||||
});
|
||||
};
|
||||
|
||||
@ -607,4 +343,7 @@ defineExpose({ openDialog });
|
||||
:deep(.el-dialog__body) {
|
||||
min-height: 450px;
|
||||
}
|
||||
:deep(.el-overlay) {
|
||||
z-index: 999 !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
167
Web/src/views/system/codeGen/component/effectLinkTableConfig.vue
Normal file
167
Web/src/views/system/codeGen/component/effectLinkTableConfig.vue
Normal file
@ -0,0 +1,167 @@
|
||||
<template>
|
||||
<div class="sys-linkTableConfig-container">
|
||||
<el-dialog v-model="state.isShowDialog" draggable :close-on-click-modal="false" width="700px">
|
||||
<template #header>
|
||||
<div style="color: #fff">
|
||||
<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"> <ele-Edit /> </el-icon>
|
||||
<span v-if="state.type == 'tree'"> 树选择配置 </span>
|
||||
<span v-if="state.type == 'fk'"> 外键配置 </span>
|
||||
</div>
|
||||
</template>
|
||||
<el-form :model="state.ruleForm" ref="ruleFormRef" label-width="auto">
|
||||
<el-row :gutter="10">
|
||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
||||
<el-form-item label="库定位器" prop="configId" :rules="[{ required: true, message: '库定位器不能为空', trigger: 'blur' }]">
|
||||
<el-select clearable v-model="state.ruleForm.configId" placeholder="库名" filterable @change="dbChanged()" class="w100">
|
||||
<el-option v-for="item in store.databaseList" :key="item.configId" :label="item.configId" :value="item.configId" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
||||
<el-form-item label="数据库表" prop="tableName" :rules="[{ required: true, message: '数据库表不能为空', trigger: 'blur' }]">
|
||||
<el-select v-model="state.ruleForm.tableName" @change="tableChanged" filterable clearable class="w100">
|
||||
<el-option v-for="item in state.tableData" :key="item.entityName" :label="item.tableName + ' [' + item.tableComment + ']'" :value="item" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
||||
<el-form-item label="显示字段" prop="displayPropertyNames" :rules="[{ required: true, message: '显示字段不能为空', trigger: 'blur' }]">
|
||||
<el-select v-model="state.ruleForm.displayPropertyNames" @change="(val: any) => changePropertyName(val, 'display')" filterable class="w100">
|
||||
<el-option v-for="item in state.columnList" :key="item.propertyName" :label="item.columnName + ' [' + item.columnComment + ']'" :value="item.propertyName" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
||||
<el-form-item label="值字段" prop="linkPropertyName" :rules="[{ required: true, message: '值字段不能为空', trigger: 'blur' }]">
|
||||
<el-select v-model="state.ruleForm.linkPropertyName" @change="(val: any) => changePropertyName(val, 'link')" filterable class="w100">
|
||||
<el-option v-for="item in state.columnList" :key="item.propertyName" :label="item.columnName + ' [' + item.columnComment + ']'" :value="item" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col v-if="state.type == 'tree'" :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
||||
<el-form-item label="父级字段" prop="parentPropertyName">
|
||||
<el-select v-model="state.ruleForm.parentPropertyName" @change="(val: any) => changePropertyName(val, 'parent')" filterable clearable class="w100">
|
||||
<el-option v-for="item in state.columnList" :key="item.propertyName" :label="item.columnName + ' [' + item.columnComment + ']'" :value="item" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
||||
<el-form-item label="查询字段" prop="searchPropertyName">
|
||||
<el-select v-model="state.ruleForm.searchPropertyName" @change="(val: any) => changePropertyName(val, 'search')" filterable class="w100">
|
||||
<el-option v-for="item in state.columnList" :key="item.propertyName" :label="item.columnName + ' [' + item.columnComment + ']'" :value="item" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20" v-if="rowData.netType.startsWith('string')">
|
||||
<el-form-item label="是否多选" prop="multiple" :rules="[{ required: true, message: '是否多选不能为空', trigger: 'blur' }]">
|
||||
<el-radio-group v-model="state.ruleForm.multiple" filterable>
|
||||
<el-radio :value="true">是</el-radio>
|
||||
<el-radio :value="false">否</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
||||
<el-form-item label="快捷设置">
|
||||
<el-button v-if="state.type == 'tree'" type="primary" icon="ele-Search" plain @click="handelQuickConfig('sysOrg')">组织机构选择器</el-button>
|
||||
<el-button v-else type="primary" icon="ele-Search" plain @click="handelQuickConfig('sysUser')">系统账号选择器</el-button>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button icon="ele-CircleCloseFilled" @click="cancel">取 消</el-button>
|
||||
<el-button type="primary" icon="ele-CircleCheckFilled" @click="submit">确 定</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- 外键配置 -->
|
||||
<script lang="ts" setup name="sysLinkTableConfig">
|
||||
import { reactive, ref } from 'vue';
|
||||
import { useCodeGenStore } from './codeGenStore';
|
||||
|
||||
let rowData = {} as any;
|
||||
const store = useCodeGenStore();
|
||||
const emits = defineEmits(['submitData']);
|
||||
const ruleFormRef = ref();
|
||||
const state = reactive({
|
||||
type: 'fk' as 'fk' | 'tree',
|
||||
isShowDialog: false,
|
||||
ruleForm: {} as any,
|
||||
dbData: [] as any,
|
||||
tableData: [] as any,
|
||||
columnList: [] as any,
|
||||
});
|
||||
|
||||
const changePropertyName = (item: any, type: string) => {
|
||||
state.ruleForm[type + 'PropertyName'] = item.propertyName;
|
||||
state.ruleForm[type + 'PropertyType'] = item.netType;
|
||||
};
|
||||
|
||||
const dbChanged = async () => {
|
||||
state.tableData = await store.tableListBy(state.ruleForm.configId);
|
||||
};
|
||||
|
||||
const tableChanged = async (item: any) => {
|
||||
state.ruleForm.displayPropertyNames = undefined;
|
||||
state.ruleForm.parentPropertyName = undefined;
|
||||
state.ruleForm.searchPropertyName = undefined;
|
||||
state.ruleForm.linkPropertyName = undefined;
|
||||
state.ruleForm.tableComment = item.tableComment;
|
||||
state.ruleForm.entityName = item.entityName;
|
||||
state.ruleForm.tableName = item.tableName;
|
||||
state.columnList = await store.columnListBy(state.ruleForm.configId, state.ruleForm.tableName);
|
||||
};
|
||||
|
||||
const handelQuickConfig = (type: string) => {
|
||||
if (store.quickConfigMap && store.quickConfigMap[type]) {
|
||||
state.ruleForm = Object.assign({}, store.quickConfigMap[type]);
|
||||
}
|
||||
};
|
||||
|
||||
// 打开弹窗
|
||||
const openDialog = async (row: any, type: 'fk' | 'tree') => {
|
||||
rowData = row;
|
||||
state.type = type;
|
||||
state.isShowDialog = true;
|
||||
state.ruleForm.multiple ??= false;
|
||||
state.ruleForm.useTable ??= false;
|
||||
state.ruleForm = Object.assign({}, row.config);
|
||||
if (state.ruleForm.configId) {
|
||||
dbChanged().then(async () => {
|
||||
if (state.ruleForm.tableName) {
|
||||
state.columnList = await store.columnListBy(state.ruleForm.configId, state.ruleForm.tableName);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// 关闭弹窗
|
||||
const closeDialog = () => {
|
||||
if (!rowData.netType.startsWith('string')) state.ruleForm.multiple = false;
|
||||
rowData.config = Object.assign({}, state.ruleForm);
|
||||
emits('submitData', rowData);
|
||||
cancel();
|
||||
};
|
||||
|
||||
// 取消
|
||||
const cancel = () => {
|
||||
state.isShowDialog = false;
|
||||
ruleFormRef.value?.resetFields();
|
||||
state.ruleForm = {};
|
||||
};
|
||||
|
||||
// 提交
|
||||
const submit = () => {
|
||||
ruleFormRef.value.validate(async (valid: boolean) => {
|
||||
if (!valid) return;
|
||||
closeDialog();
|
||||
});
|
||||
};
|
||||
|
||||
// 导出对象
|
||||
defineExpose({ openDialog });
|
||||
</script>
|
||||
@ -1,155 +0,0 @@
|
||||
<template>
|
||||
<div class="sys-codeGenFk-container">
|
||||
<el-dialog v-model="state.isShowDialog" draggable :close-on-click-modal="false" width="700px">
|
||||
<template #header>
|
||||
<div style="color: #fff">
|
||||
<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"> <ele-Edit /> </el-icon>
|
||||
<span> 外键配置 </span>
|
||||
</div>
|
||||
</template>
|
||||
<el-form :model="state.ruleForm" ref="ruleFormRef" label-width="auto">
|
||||
<el-row :gutter="10">
|
||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
||||
<el-form-item label="库定位器" prop="configId">
|
||||
<el-select clearable v-model="state.ruleForm.configId" placeholder="库名" filterable @change="DbChanged()" class="w100">
|
||||
<el-option v-for="item in state.dbData" :key="item.configId" :label="item.configId" :value="item.configId" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
||||
<el-form-item label="数据库表" prop="tableName">
|
||||
<el-select v-model="state.ruleForm.tableName" filterable clearable @change="TableChanged()" class="w100">
|
||||
<el-option v-for="item in state.tableData" :key="item.entityName" :label="item.entityName + ' ( ' + item.tableName + ' )[' + item.tableComment + ']'" :value="item.tableName" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
||||
<el-form-item label="显示字段" prop="columnName">
|
||||
<el-select v-model="state.ruleForm.columnName" filterable class="w100">
|
||||
<el-option v-for="item in state.columnData" :key="item.columnName" :label="item.columnName + ' [' + item.columnComment + ']'" :value="item.columnName" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
||||
<el-form-item label="链接字段" prop="linkColumnName">
|
||||
<el-select v-model="state.ruleForm.linkColumnName" filterable class="w100">
|
||||
<el-option v-for="item in state.columnData" :key="item.columnName" :label="item.columnName + ' [' + item.columnComment + ']'" :value="item.columnName" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button icon="ele-CircleCloseFilled" @click="cancel">取 消</el-button>
|
||||
<el-button type="primary" icon="ele-CircleCheckFilled" @click="submit">确 定</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup name="sysCodeGenFk">
|
||||
import { onMounted, reactive, ref } from 'vue';
|
||||
|
||||
import { getAPI } from '/@/utils/axios-utils';
|
||||
import { SysCodeGenApi } from '/@/api-services/system/api';
|
||||
|
||||
var rowdata = {} as any;
|
||||
const emits = defineEmits(['submitRefreshFk']);
|
||||
const ruleFormRef = ref();
|
||||
const state = reactive({
|
||||
isShowDialog: false,
|
||||
ruleForm: {} as any,
|
||||
dbData: [] as any,
|
||||
tableData: [] as any,
|
||||
columnData: [] as any,
|
||||
});
|
||||
|
||||
onMounted(async () => {
|
||||
await getDbList();
|
||||
|
||||
// 默认使用第一个库
|
||||
//state.ruleForm.configId = state.dbData[0].configId;
|
||||
//await DbChanged();
|
||||
});
|
||||
|
||||
const DbChanged = async () => {
|
||||
state.tableData = [];
|
||||
state.columnData = [];
|
||||
await getTableInfoList();
|
||||
};
|
||||
|
||||
const TableChanged = async () => {
|
||||
state.columnData = [];
|
||||
await getColumnInfoList();
|
||||
};
|
||||
|
||||
const getDbList = async () => {
|
||||
var res = await getAPI(SysCodeGenApi).apiSysCodeGenDatabaseListGet();
|
||||
state.dbData = res.data.result;
|
||||
};
|
||||
|
||||
const getTableInfoList = async () => {
|
||||
if (state.ruleForm.configId == '') return;
|
||||
var res = await getAPI(SysCodeGenApi).apiSysCodeGenTableListConfigIdGet(state.ruleForm.configId);
|
||||
state.tableData = res.data.result;
|
||||
};
|
||||
|
||||
const getColumnInfoList = async () => {
|
||||
if (state.ruleForm.configId == '' || state.ruleForm.tableName == '') return;
|
||||
console.log(state.ruleForm.configId, state.ruleForm.tableName);
|
||||
var res = await getAPI(SysCodeGenApi).apiSysCodeGenColumnListByTableNameTableNameConfigIdGet(state.ruleForm.tableName, state.ruleForm.configId);
|
||||
state.columnData = res.data.result;
|
||||
};
|
||||
|
||||
// 打开弹窗
|
||||
const openDialog = async (row: any) => {
|
||||
rowdata = row;
|
||||
if (rowdata.fkConfigId) {
|
||||
await getDbList();
|
||||
state.ruleForm.tableName = rowdata.fkTableName;
|
||||
state.ruleForm.columnName = rowdata.fkColumnName;
|
||||
state.ruleForm.linkColumnName = rowdata.fkLinkColumnName;
|
||||
state.ruleForm.configId = rowdata.fkConfigId;
|
||||
await DbChanged();
|
||||
await TableChanged();
|
||||
}
|
||||
state.isShowDialog = true;
|
||||
};
|
||||
|
||||
// 关闭弹窗
|
||||
const closeDialog = () => {
|
||||
rowdata.fkTableName = state.ruleForm.tableName;
|
||||
let tableData = state.tableData.filter((x: any) => x.tableName == state.ruleForm.tableName);
|
||||
rowdata.fkEntityName = tableData.length == 0 ? '' : tableData[0].entityName;
|
||||
rowdata.fkColumnName = state.ruleForm.columnName;
|
||||
rowdata.fkLinkColumnName = state.ruleForm.linkColumnName;
|
||||
rowdata.fkConfigId = state.ruleForm.configId;
|
||||
let columnData = state.columnData.filter((x: any) => x.columnName == state.ruleForm.columnName);
|
||||
rowdata.fkColumnNetType = columnData.length == 0 ? '' : columnData[0].netType;
|
||||
emits('submitRefreshFk', rowdata);
|
||||
cancel();
|
||||
};
|
||||
|
||||
// 取消
|
||||
const cancel = () => {
|
||||
state.isShowDialog = false;
|
||||
ruleFormRef.value?.resetFields();
|
||||
state.ruleForm = {};
|
||||
state.dbData.value = [];
|
||||
state.tableData.value = [];
|
||||
state.columnData.value = [];
|
||||
};
|
||||
|
||||
// 提交
|
||||
const submit = () => {
|
||||
ruleFormRef.value.validate(async (valid: boolean) => {
|
||||
if (!valid) return;
|
||||
closeDialog();
|
||||
});
|
||||
};
|
||||
|
||||
// 导出对象
|
||||
defineExpose({ openDialog });
|
||||
</script>
|
||||
@ -1,465 +0,0 @@
|
||||
<template>
|
||||
<div class="sys-codeGenConfig-container">
|
||||
<vxe-modal v-model="state.isShowDialog" title="生成配置" :width="800" :height="350" show-footer show-zoom resize fullscreen @close="cancel">
|
||||
<template #default>
|
||||
<vxe-grid ref="xGrid" class="xGrid-table-style" v-bind="options">
|
||||
<template #drag_default="{}">
|
||||
<span class="drag-btn">
|
||||
<i class="fa fa-arrows"></i>
|
||||
</span>
|
||||
</template>
|
||||
<template #effectType="{ row, $index }">
|
||||
<vxe-select v-model="row.effectType" class="m-2" style="width: 70%" placeholder="Select" transfer :disabled="judgeColumns(row)" @change="effectTypeChange(row, $index)" filterable>
|
||||
<vxe-option v-for="item in state.effectTypeList" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</vxe-select>
|
||||
<vxe-button v-if="row.effectType === 'ApiTreeSelector' || row.effectType === 'ForeignKey'" style="width: 30%" icon="vxe-icon-edit" @click="effectTypeChange(row, $index)">修改</vxe-button>
|
||||
</template>
|
||||
<template #columnComment="{ row }">
|
||||
<vxe-input v-model="row.columnComment" autocomplete="off" />
|
||||
</template>
|
||||
<template #dictType="{ row }">
|
||||
<vxe-select v-model="row.dictTypeCode" class="m-2" :disabled="effectTypeEnable(row)" filterable transfer>
|
||||
<vxe-option v-for="item in state.dictTypeCodeList" :key="item.code" :label="item.name" :value="item.code" />
|
||||
</vxe-select>
|
||||
</template>
|
||||
<template #whetherTable="{ row }">
|
||||
<vxe-checkbox v-model="row.whetherTable"></vxe-checkbox>
|
||||
</template>
|
||||
<template #whetherAddUpdate="{ row }">
|
||||
<vxe-checkbox v-model="row.whetherAddUpdate" :disabled="judgeColumns(row)"></vxe-checkbox>
|
||||
</template>
|
||||
<template #whetherSortable="{ row }">
|
||||
<vxe-checkbox v-model="row.whetherSortable"></vxe-checkbox>
|
||||
</template>
|
||||
<template #whetherRequired="{ row }">
|
||||
<vxe-tag v-if="row.whetherRequired" status="success">是</vxe-tag>
|
||||
<vxe-tag v-else status="info">否</vxe-tag>
|
||||
</template>
|
||||
<template #statistical="{ row }">
|
||||
<vxe-switch v-model="row.statistical" open-label="是" close-label="否" :openValue="true" :closeValue="false"></vxe-switch>
|
||||
</template>
|
||||
<template #isGroupBy="{ row }">
|
||||
<vxe-switch v-model="row.isGroupBy" open-label="是" close-label="否" :openValue="true" :closeValue="false"></vxe-switch>
|
||||
</template>
|
||||
<template #queryWhether="{ row }">
|
||||
<vxe-switch v-model="row.queryWhether" open-label="是" close-label="否" :openValue="true" :closeValue="false"></vxe-switch>
|
||||
</template>
|
||||
<template #queryType="{ row }">
|
||||
<vxe-select v-model="row.queryType" class="m-2" placeholder="Select" :disabled="!row.queryWhether" filterable transfer>
|
||||
<vxe-option v-for="item in state.queryTypeList" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</vxe-select>
|
||||
</template>
|
||||
<template #verification="{ row }">
|
||||
<vxe-button status="primary" plain v-if="row.columnKey === 'False' && !row.whetherCommon" @click="openVerifyDialog(row)">校验规则{{ row.ruleCount }}</vxe-button>
|
||||
<span v-else></span>
|
||||
</template>
|
||||
</vxe-grid>
|
||||
</template>
|
||||
<template #footer>
|
||||
<vxe-button icon="ele-CircleCloseFilled" @click="cancel">取 消</vxe-button>
|
||||
<vxe-button status="primary" icon="ele-CircleCheckFilled" @click="submit">确 定</vxe-button>
|
||||
</template>
|
||||
</vxe-modal>
|
||||
|
||||
<fkDialog ref="fkDialogRef" @submitRefreshFk="submitRefreshFk" />
|
||||
<treeDialog ref="treeDialogRef" @submitRefreshFk="submitRefreshFk" />
|
||||
<verifyDialog ref="verifyDialogRef" @submitVerify="submitVerifyOk" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup name="sysCodeGenConfig">
|
||||
import { nextTick, onMounted, onUnmounted, reactive, ref } from 'vue';
|
||||
import mittBus from '/@/utils/mitt';
|
||||
import Sortable from 'sortablejs';
|
||||
import { VxeGridInstance, VxeGridProps } from 'vxe-table';
|
||||
|
||||
import fkDialog from '/@/views/system/codeGen/component/fkDialog.vue';
|
||||
import treeDialog from '/@/views/system/codeGen/component/treeDialog.vue';
|
||||
import verifyDialog from '/@/views/system/codeGen/component/verifyDialog.vue';
|
||||
|
||||
import { getAPI } from '/@/utils/axios-utils';
|
||||
import { SysCodeGenConfigApi, SysConstApi, SysDictDataApi, SysDictTypeApi, SysEnumApi } from '/@/api-services/system/api';
|
||||
|
||||
const xGrid = ref<VxeGridInstance<any>>();
|
||||
const emits = defineEmits(['handleQuery']);
|
||||
const fkDialogRef = ref();
|
||||
const treeDialogRef = ref();
|
||||
const verifyDialogRef = ref();
|
||||
const state = reactive({
|
||||
isShowDialog: false,
|
||||
loading: false,
|
||||
EntityName: '',
|
||||
ConfigId: '',
|
||||
dbData: [] as any,
|
||||
effectTypeList: [] as any,
|
||||
dictTypeCodeList: [] as any,
|
||||
dictDataAll: [] as any,
|
||||
queryTypeList: [] as any,
|
||||
allConstSelector: [] as any,
|
||||
allEnumSelector: [] as any,
|
||||
sortable: undefined as any,
|
||||
});
|
||||
|
||||
// 表格参数配置
|
||||
const options = reactive<VxeGridProps>({
|
||||
id: 'genConfigDialog',
|
||||
height: 'auto',
|
||||
keepSource: true,
|
||||
autoResize: true,
|
||||
loading: false,
|
||||
align: 'center',
|
||||
rowConfig: { useKey: true },
|
||||
seqConfig: { seqMethod: ({ row }) => row.orderNo },
|
||||
columns: [
|
||||
{
|
||||
width: 50,
|
||||
slots: {
|
||||
default: 'drag_default',
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'orderNo',
|
||||
title: '排序',
|
||||
minWidth: 80,
|
||||
showOverflow: 'tooltip',
|
||||
},
|
||||
{
|
||||
field: 'columnName',
|
||||
title: '字段',
|
||||
minWidth: 160,
|
||||
showOverflow: 'tooltip',
|
||||
},
|
||||
{
|
||||
field: 'columnComment',
|
||||
title: '描述',
|
||||
minWidth: 120,
|
||||
showOverflow: 'tooltip',
|
||||
slots: {
|
||||
edit: 'columnComment',
|
||||
default: 'columnComment',
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'netType',
|
||||
title: '数据类型',
|
||||
minWidth: 90,
|
||||
},
|
||||
{
|
||||
field: 'effectType',
|
||||
title: '作用类型',
|
||||
minWidth: 160,
|
||||
slots: {
|
||||
edit: 'effectType',
|
||||
default: 'effectType',
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'dictTypeCode',
|
||||
title: '字典',
|
||||
minWidth: 180,
|
||||
slots: {
|
||||
edit: 'dictType',
|
||||
default: 'dictType',
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'whetherTable',
|
||||
title: '列表显示',
|
||||
minWidth: 70,
|
||||
slots: {
|
||||
edit: 'whetherTable',
|
||||
default: 'whetherTable',
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'whetherAddUpdate',
|
||||
title: '增改',
|
||||
minWidth: 70,
|
||||
slots: {
|
||||
edit: 'whetherAddUpdate',
|
||||
default: 'whetherAddUpdate',
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'whetherRequired',
|
||||
title: '必填',
|
||||
minWidth: 70,
|
||||
slots: {
|
||||
edit: 'whetherRequired',
|
||||
default: 'whetherRequired',
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'whetherSortable',
|
||||
title: '可排序',
|
||||
minWidth: 70,
|
||||
slots: {
|
||||
edit: 'whetherSortable',
|
||||
default: 'whetherSortable',
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'statistical',
|
||||
title: '统计字段',
|
||||
minWidth: 70,
|
||||
slots: {
|
||||
edit: 'statistical',
|
||||
default: 'statistical',
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'isGroupBy',
|
||||
title: 'GroupBy',
|
||||
minWidth: 70,
|
||||
slots: {
|
||||
edit: 'isGroupBy',
|
||||
default: 'isGroupBy',
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'queryWhether',
|
||||
title: '是否是查询',
|
||||
minWidth: 70,
|
||||
slots: {
|
||||
edit: 'queryWhether',
|
||||
default: 'queryWhether',
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'queryType',
|
||||
title: '查询方式',
|
||||
minWidth: 120,
|
||||
slots: {
|
||||
edit: 'queryType',
|
||||
default: 'queryType',
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '校验规则',
|
||||
width: 130,
|
||||
showOverflow: true,
|
||||
slots: {
|
||||
edit: 'verification',
|
||||
default: 'verification',
|
||||
},
|
||||
},
|
||||
],
|
||||
editConfig: { trigger: 'click', mode: 'row', showStatus: true },
|
||||
});
|
||||
|
||||
const rowDrop = () => {
|
||||
const el = document.querySelector('.xGrid-table-style .vxe-table--body tbody') as HTMLElement;
|
||||
state.sortable = Sortable.create(el, {
|
||||
animation: 300,
|
||||
handle: '.drag-btn',
|
||||
onEnd: (sortableEvent: any) => {
|
||||
const fullData = xGrid.value?.getTableData().fullData || [];
|
||||
const newIndex = sortableEvent.newIndex as number;
|
||||
const oldIndex = sortableEvent.oldIndex as number;
|
||||
var orderNo = fullData[newIndex - 1].orderNo;
|
||||
fullData[newIndex].orderNo = orderNo! + 10;
|
||||
const currentRow = fullData.splice(oldIndex, 1)[0];
|
||||
fullData.splice(newIndex, 0, currentRow);
|
||||
fullData.forEach((u, i) => (u.orderNo = 100 + i * 10));
|
||||
// 更新表格数据
|
||||
xGrid.value?.loadData(fullData);
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
// 页面初始化
|
||||
onMounted(async () => {
|
||||
// 从后端获取字典列表数据,并保存到本地状态管理中
|
||||
var res = await getAPI(SysDictDataApi).apiSysDictDataDataListCodeGet('code_gen_effect_type');
|
||||
state.effectTypeList = res.data.result;
|
||||
|
||||
// 获取字典类型代码列表,并将其保存到本地状态管理中,同时更新字典数据全集
|
||||
var res1 = await getAPI(SysDictTypeApi).apiSysDictTypeListGet();
|
||||
state.dictTypeCodeList = res1.data.result;
|
||||
state.dictDataAll = res1.data.result;
|
||||
|
||||
// 获取查询类型列表数据,并保存到本地状态管理中
|
||||
var res2 = await getAPI(SysDictDataApi).apiSysDictDataDataListCodeGet('code_gen_query_type');
|
||||
state.queryTypeList = res2.data.result;
|
||||
|
||||
// 从后端获取常量列表数据,并保存到本地状态管理中
|
||||
var res3 = await getAPI(SysConstApi).apiSysConstListGet();
|
||||
state.allConstSelector = res3.data.result;
|
||||
|
||||
// 获取枚举类型列表数据,对其进行处理后保存到本地状态管理中
|
||||
let resEnum = await getAPI(SysEnumApi).apiSysEnumEnumTypeListGet();
|
||||
state.allEnumSelector = resEnum.data.result?.map((item) => ({ ...item, name: `${item.typeDescribe} [${item.typeName?.replace('Enum', '')}]`, code: item.typeName }));
|
||||
|
||||
mittBus.on('submitRefreshFk', (data: any) => {
|
||||
let tableData = xGrid.value?.getData() || [];
|
||||
tableData[data.index] = data;
|
||||
xGrid.value?.loadData(tableData);
|
||||
});
|
||||
});
|
||||
|
||||
// 更新主键
|
||||
const submitRefreshFk = (data: any) => {
|
||||
let tableData = xGrid.value?.getData() || [];
|
||||
tableData[data.index] = data;
|
||||
xGrid.value?.reloadData(tableData);
|
||||
};
|
||||
|
||||
// 页面初始化
|
||||
onUnmounted(() => {
|
||||
// mittBus.off('submitRefresh', () => {});
|
||||
mittBus.off('submitRefreshFk', () => {});
|
||||
});
|
||||
|
||||
// 控件类型改变
|
||||
const effectTypeChange = (data: any, index: number) => {
|
||||
let value = data.effectType;
|
||||
if (value === 'ForeignKey') {
|
||||
openFkDialog(data, index);
|
||||
} else if (value === 'ApiTreeSelector') {
|
||||
openTreeDialog(data, index);
|
||||
} else if (value === 'DictSelector') {
|
||||
data.dictTypeCode = '';
|
||||
state.dictTypeCodeList = state.dictDataAll;
|
||||
} else if (value === 'ConstSelector') {
|
||||
data.dictTypeCode = '';
|
||||
state.dictTypeCodeList = state.allConstSelector;
|
||||
} else if (value == 'EnumSelector') {
|
||||
data.dictTypeCode = '';
|
||||
state.dictTypeCodeList = state.allEnumSelector;
|
||||
}
|
||||
};
|
||||
|
||||
// 查询操作
|
||||
const handleQuery = async (row: any) => {
|
||||
state.loading = true;
|
||||
var res = await getAPI(SysCodeGenConfigApi).apiSysCodeGenConfigListGet(undefined, row.id);
|
||||
var data = res.data.result ?? [];
|
||||
let lstWhetherColumn = ['whetherTable', 'whetherAddUpdate', 'whetherRequired', 'whetherSortable']; //列表显示的checkbox
|
||||
data.forEach((item: any) => {
|
||||
for (const key in item) {
|
||||
if (item[key] === 'Y') {
|
||||
item[key] = true;
|
||||
}
|
||||
if (item[key] === 'N' || (lstWhetherColumn.includes(key) && item[key] === null)) {
|
||||
item[key] = false;
|
||||
}
|
||||
}
|
||||
// 验证规则相关
|
||||
let rules = new Array();
|
||||
if (item.rules != '' && item.rules !== null) {
|
||||
rules = JSON.parse(item.rules);
|
||||
}
|
||||
item.ruleCount = rules.length > 0 ? `(${rules.length})` : '';
|
||||
});
|
||||
xGrid.value?.loadData(data);
|
||||
state.loading = false;
|
||||
};
|
||||
|
||||
// 判断是否(用于是否能选择或输入等)
|
||||
function judgeColumns(data: any) {
|
||||
return data.whetherCommon == true || data.columnKey === 'True';
|
||||
}
|
||||
|
||||
function effectTypeEnable(data: any) {
|
||||
return !['Radio', 'Checkbox', 'DictSelector', 'ConstSelector', 'EnumSelector'].some((e: any) => e === data.effectType);
|
||||
}
|
||||
|
||||
// 打开弹窗
|
||||
const openDialog = async (addRow: any) => {
|
||||
state.isShowDialog = true;
|
||||
state.ConfigId = addRow.configId;
|
||||
state.EntityName = addRow.tableName;
|
||||
nextTick(async () => {
|
||||
await handleQuery(addRow);
|
||||
rowDrop();
|
||||
});
|
||||
};
|
||||
|
||||
// 打开外键弹窗
|
||||
const openFkDialog = (addRow: any, index: number) => {
|
||||
addRow.index = index;
|
||||
fkDialogRef.value.openDialog(addRow);
|
||||
};
|
||||
|
||||
const openTreeDialog = (addRow: any, index: number) => {
|
||||
addRow.index = index;
|
||||
treeDialogRef.value.openDialog(addRow);
|
||||
};
|
||||
|
||||
// 打开校验弹窗
|
||||
const openVerifyDialog = (row: any) => {
|
||||
// handleQuery(addRow);
|
||||
// state.isShowDialog = true;
|
||||
verifyDialogRef.value.openDialog(row);
|
||||
};
|
||||
|
||||
// 验证提交回调
|
||||
const submitVerifyOk = (data: any) => {
|
||||
let tableData = xGrid.value?.getData() || [];
|
||||
for (let i = 0; i < tableData.length; i++) {
|
||||
if (tableData[i].id == data.id) {
|
||||
tableData[i].rules = data.rules;
|
||||
tableData[i].ruleCount = data.ruleCount;
|
||||
// 更新必填项
|
||||
let rules = new Array();
|
||||
if (data.rules != '' && data.rules !== null) {
|
||||
rules = JSON.parse(data.rules);
|
||||
let requiredRule = rules.find((t) => t.type === 'required');
|
||||
if (requiredRule) {
|
||||
tableData[i].whetherRequired = true;
|
||||
} else {
|
||||
tableData[i].whetherRequired = false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
xGrid.value?.reloadData(tableData);
|
||||
};
|
||||
|
||||
// 关闭弹窗
|
||||
const closeDialog = () => {
|
||||
emits('handleQuery');
|
||||
cancel();
|
||||
};
|
||||
|
||||
// 取消
|
||||
const cancel = () => {
|
||||
xGrid.value?.loadData([]);
|
||||
state.isShowDialog = false;
|
||||
if (state.sortable) {
|
||||
state.sortable.destroy();
|
||||
}
|
||||
};
|
||||
|
||||
// 提交
|
||||
const submit = async () => {
|
||||
state.loading = true;
|
||||
let lst = xGrid.value?.getData() || [];
|
||||
let ignoreFields = ['remoteVerify', 'anyRule', 'columnKey'];
|
||||
lst.forEach((item: any) => {
|
||||
// 必填那一项转换
|
||||
for (var key in item) {
|
||||
if (item[key] === true && !ignoreFields.includes(key)) {
|
||||
item[key] = 'Y';
|
||||
}
|
||||
if (item[key] === false && !ignoreFields.includes(key)) {
|
||||
item[key] = 'N';
|
||||
}
|
||||
}
|
||||
});
|
||||
await getAPI(SysCodeGenConfigApi).apiSysCodeGenConfigUpdatePost(lst);
|
||||
state.loading = false;
|
||||
closeDialog();
|
||||
};
|
||||
|
||||
// 导出对象
|
||||
defineExpose({ openDialog });
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.xGrid-table-style .drag-btn {
|
||||
cursor: move;
|
||||
font-size: 20px;
|
||||
}
|
||||
</style>
|
||||
@ -1,343 +0,0 @@
|
||||
<template>
|
||||
<div class="sys-codeGenConfig-container">
|
||||
<el-dialog v-model="state.isShowDialog" draggable :close-on-click-modal="false" width="700px">
|
||||
<template #header>
|
||||
<div style="color: #fff">
|
||||
<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"> <ele-Edit /> </el-icon>
|
||||
<span> 选择正则 </span>
|
||||
</div>
|
||||
</template>
|
||||
<div class="pattern-box">
|
||||
<div class="pattern-item" v-for="(item, index) in patternData" :key="index" :class="{ active: state.index == index }" @click="handlePatternClick(item, index)">
|
||||
<div class="title">{{ item.title }}</div>
|
||||
<div class="info">{{ item.info }}</div>
|
||||
<div class="pattern">{{ item.pattern }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button icon="ele-CircleCloseFilled" @click="cancel">取 消</el-button>
|
||||
<el-button type="primary" icon="ele-CircleCheckFilled" @click="submit">确 定</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { reactive, ref } from 'vue';
|
||||
import { ElMessage } from 'element-plus';
|
||||
|
||||
const patternData = ref([
|
||||
{
|
||||
title: '手机号',
|
||||
info: '',
|
||||
pattern: '/^1[3,4,5,6,7,8,9][0-9]{9}$/',
|
||||
},
|
||||
{
|
||||
title: '邮箱',
|
||||
info: '',
|
||||
pattern: '/^([a-zA-Z]|[0-9])(\\w|\\-)+@[a-zA-Z0-9]+\\.([a-zA-Z]{2,4})$/',
|
||||
},
|
||||
{
|
||||
title: '网址',
|
||||
info: '',
|
||||
pattern: '/^http(s)?://([\\w-]+\\.)+[\\w-]+(/[\\w- ./?%&=]*)?$/',
|
||||
},
|
||||
{
|
||||
title: '字母/数字/下划线',
|
||||
info: '',
|
||||
pattern: '/^\\w+$/',
|
||||
},
|
||||
{
|
||||
title: '中英文/数字/下划线',
|
||||
info: '',
|
||||
pattern: '/^[\\u4e00-\\u9fa5_a-zA-Z0-9]+$/',
|
||||
},
|
||||
{
|
||||
title: '中文/英文',
|
||||
info: '',
|
||||
pattern: '/^[\\u4e00-\\u9fa5a-zA-Z]+$/',
|
||||
},
|
||||
{
|
||||
title: '规范金额',
|
||||
info: '',
|
||||
pattern: '/(^[\\d]|^[1-9][\\d]*)($|[\\.][\\d]{0,2}$)/',
|
||||
},
|
||||
{
|
||||
title: '用户名不能全是数字',
|
||||
info: '',
|
||||
pattern: '/[^\\d]/g',
|
||||
},
|
||||
{
|
||||
title: '中文',
|
||||
info: '',
|
||||
pattern: '/^[\\u4e00-\\u9fa5]+$/',
|
||||
},
|
||||
{
|
||||
title: '非中文',
|
||||
info: '',
|
||||
pattern: '/^[^\\u4e00-\\u9fa5]*$/',
|
||||
},
|
||||
{
|
||||
title: '限制长度',
|
||||
info: '',
|
||||
pattern: '/^\\d{1,20}$/',
|
||||
},
|
||||
{
|
||||
title: '数字',
|
||||
info: '',
|
||||
pattern: '/^[0-9]*$/',
|
||||
},
|
||||
{
|
||||
title: '正整数及整数',
|
||||
info: '',
|
||||
pattern: '/^[1-9]\\d*$/',
|
||||
},
|
||||
{
|
||||
title: '数字(可正负)',
|
||||
info: '',
|
||||
pattern: '/^-[0-9]*[1-9][0-9]*$/',
|
||||
},
|
||||
{
|
||||
title: '数字/小数点',
|
||||
info: '',
|
||||
pattern: '/^\\d+$|^\\d*\\.\\d+$/',
|
||||
},
|
||||
{
|
||||
title: '合法IP地址',
|
||||
info: '',
|
||||
pattern: '/^(\\d{1,2}|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d{1,2}|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d{1,2}|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d{1,2}|1\\d\\d|2[0-4]\\d|25[0-5])$/',
|
||||
},
|
||||
{
|
||||
title: '手机号码或者固话',
|
||||
info: '',
|
||||
pattern: '/^((0\\d{2,3}-\\d{7,8})|(1[3456789]\\d{9}))$/',
|
||||
},
|
||||
{
|
||||
title: '身份证号码',
|
||||
info: '',
|
||||
pattern: '/(^\\d{15}$)|(^\\d{18}$)|(^\\d{17}(\\d|X|x)$)/',
|
||||
},
|
||||
{
|
||||
title: '大写字母',
|
||||
info: '',
|
||||
pattern: '/^[A-Z]+$/',
|
||||
},
|
||||
{
|
||||
title: '小写字母',
|
||||
info: '',
|
||||
pattern: '/^[a-z]+$/',
|
||||
},
|
||||
{
|
||||
title: '大小写混合',
|
||||
info: '',
|
||||
pattern: '/^[A-Za-z]+$/',
|
||||
},
|
||||
{
|
||||
title: '多个8位数字格式(yyyyMMdd)并以逗号隔开',
|
||||
info: '',
|
||||
pattern: '/^\\d{8}(\\,\\d{8})*$/',
|
||||
},
|
||||
{
|
||||
title: '数字加英文',
|
||||
info: '',
|
||||
pattern: '/^[a-zA-Z0-9]+$/',
|
||||
},
|
||||
{
|
||||
title: '前两位是数字后一位是英文',
|
||||
info: '',
|
||||
pattern: '/^\\d{2}[a-zA-Z]+$/',
|
||||
},
|
||||
{
|
||||
title: '1到100的数字',
|
||||
info: '',
|
||||
pattern: '/^[0-9]\\d{0,1}$/',
|
||||
},
|
||||
{
|
||||
title: '1-1000两位小数',
|
||||
info: '',
|
||||
pattern: '/^(.*[^0-9]|)(1000|[1-9]\\d{0,2})([^0-9].*|)$/',
|
||||
},
|
||||
{
|
||||
title: '小数点后只能有两位数(可为0)',
|
||||
info: '',
|
||||
pattern: '/^(-?\\d+)(\\.\\d{1,2})?$/',
|
||||
},
|
||||
{
|
||||
title: '密码正则',
|
||||
info: '以字母开头,长度在6~18之间,只能包含字母、数字和下划线',
|
||||
pattern: '/^[a-zA-Z]\\w{5,17}$/',
|
||||
},
|
||||
{
|
||||
title: '强密码',
|
||||
info: '必须包含大小写字母和数字的组合,不能使用特殊字符,长度在8-10之间',
|
||||
pattern: '/^(?=.\\d)(?=.[a-z])(?=.[A-Z]).{8,10}$/',
|
||||
},
|
||||
{
|
||||
title: '强密码',
|
||||
info: '最少6位,包括至少1个大写字母,1个小写字母,1个数字,1个特殊字符',
|
||||
pattern: '/^.*(?=.{6,})(?=.*\\d)(?=.*[A-Z])(?=.*[a-z])(?=.*[!@#$%^&*? ]).*$/',
|
||||
},
|
||||
{
|
||||
title: 'QQ号码',
|
||||
info: '',
|
||||
pattern: '/^[1-9][0-9]{4,12}$/',
|
||||
},
|
||||
{
|
||||
title: '微信号码',
|
||||
info: '',
|
||||
pattern: '/^[a-zA-Z]([-_a-zA-Z0-9]{5,19})+$/',
|
||||
},
|
||||
{
|
||||
title: '域名',
|
||||
info: '',
|
||||
pattern: '/^[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(/.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+/.?$/',
|
||||
},
|
||||
{
|
||||
title: '车牌号码',
|
||||
info: '',
|
||||
pattern: '/^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}[A-Z0-9]{4}[A-Z0-9挂学警港澳]{1}$/',
|
||||
},
|
||||
{
|
||||
title: '护照',
|
||||
info: '',
|
||||
pattern: '/^(P\\d{7}|G\\d{7,8}|TH\\d{7,8}|S\\d{7,8}|A\\d{7,8}|L\\d{7,8}|\\d{9}|D\\d+|1[4,5]\\d{7})$/',
|
||||
},
|
||||
{
|
||||
title: '固定电话',
|
||||
info: '',
|
||||
pattern: '/^(\\(\\d{3,4}\\)|\\d{3,4}-|\\s)?\\d{8}$/',
|
||||
},
|
||||
{
|
||||
title: '邮政编码',
|
||||
info: '',
|
||||
pattern: '/^[1-9]{1}(\\d+){5}$/',
|
||||
},
|
||||
{
|
||||
title: '经度',
|
||||
info: '',
|
||||
pattern: '/^(\\-|\\+)?(((\\d|[1-9]\\d|1[0-7]\\d|0{1,3})\\.\\d{0,6})|(\\d|[1-9]\\d|1[0-7]\\d|0{1,3})|180\\.0{0,6}|180)$/',
|
||||
},
|
||||
{
|
||||
title: '纬度',
|
||||
info: '',
|
||||
pattern: '/^(\\-|\\+)?([0-8]?\\d{1}\\.\\d{0,6}|90\\.0{0,6}|[0-8]?\\d{1}|90)$/',
|
||||
},
|
||||
{
|
||||
title: '正整数 + 0',
|
||||
info: '',
|
||||
pattern: '/^\\d+$/',
|
||||
},
|
||||
{
|
||||
title: '正整数',
|
||||
info: '',
|
||||
pattern: '/^[0-9]*[1-9][0-9]*$/',
|
||||
},
|
||||
{
|
||||
title: '负整数 + 0',
|
||||
info: '',
|
||||
pattern: '/^((-\\d+)|(0+))$/',
|
||||
},
|
||||
{
|
||||
title: '负整数',
|
||||
info: '',
|
||||
pattern: '/^-[0-9]*[1-9][0-9]*$/',
|
||||
},
|
||||
{
|
||||
title: '匹配整数',
|
||||
info: '',
|
||||
pattern: '/^-?\\d+$/',
|
||||
},
|
||||
]);
|
||||
const state = reactive({
|
||||
isShowDialog: false,
|
||||
loading: false,
|
||||
selectPattern: null,
|
||||
index: -1,
|
||||
});
|
||||
|
||||
const emit = defineEmits(['submitPattern']);
|
||||
|
||||
// 打开弹窗
|
||||
const openDialog = () => {
|
||||
state.isShowDialog = true;
|
||||
};
|
||||
|
||||
// 关闭弹窗
|
||||
const closeDialog = () => {
|
||||
state.isShowDialog = false;
|
||||
};
|
||||
|
||||
// 取消
|
||||
const cancel = () => {
|
||||
closeDialog();
|
||||
};
|
||||
|
||||
const handlePatternClick = (item: any, index: number) => {
|
||||
state.selectPattern = item;
|
||||
state.index = index;
|
||||
ElMessage({
|
||||
message: `点击确定完成操作!`,
|
||||
type: 'success',
|
||||
});
|
||||
};
|
||||
|
||||
// 提交
|
||||
const submit = async () => {
|
||||
emit('submitPattern', state.selectPattern);
|
||||
closeDialog();
|
||||
};
|
||||
|
||||
// 导出对象
|
||||
defineExpose({ openDialog });
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.pattern-box {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
flex-wrap: wrap;
|
||||
height: 400px;
|
||||
overflow-y: auto;
|
||||
padding: 0px 10px;
|
||||
|
||||
.pattern-item {
|
||||
width: 48%;
|
||||
border: 1px solid #d9d9d9;
|
||||
box-sizing: border-box;
|
||||
padding: 10px;
|
||||
border-radius: 5px;
|
||||
cursor: pointer;
|
||||
flex-shrink: 0;
|
||||
margin: 5px 0px;
|
||||
|
||||
.title {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.info {
|
||||
font-size: 12px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.pattern {
|
||||
font-size: 10px;
|
||||
margin-top: 5px;
|
||||
background: #1d1f21;
|
||||
padding: 3px 5px;
|
||||
color: #d9d9d9;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
//border: 1px solid red;
|
||||
box-shadow: 0px 0px 2px 1px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.active {
|
||||
border: 1px solid red !important;
|
||||
}
|
||||
</style>
|
||||
@ -17,10 +17,10 @@
|
||||
</template>
|
||||
</el-segmented>
|
||||
</div>
|
||||
<div ref="monacoEditorRef" style="width: 100%; height: 700px; margin-top: 6px"></div>
|
||||
<div ref="monacoEditorRef" style="width: 100%; height: 80vh; margin-top: 6px"></div>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button icon="ele-Close" @click="cancel">关 闭</el-button>
|
||||
<el-button icon="ele-CircleCloseFilled" @click="cancel">取 消</el-button>
|
||||
<el-button icon="ele-CopyDocument" type="primary" @click="handleCopy">复 制</el-button>
|
||||
</span>
|
||||
</template>
|
||||
@ -28,6 +28,7 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- 代码预览 -->
|
||||
<script lang="ts" setup name="sysPreviewCode">
|
||||
import { reactive, ref, nextTick } from 'vue';
|
||||
import * as monaco from 'monaco-editor';
|
||||
@ -38,6 +39,7 @@ import { getAPI } from '/@/utils/axios-utils';
|
||||
import { SysCodeGenApi } from '/@/api-services/system/api';
|
||||
|
||||
const { copyText } = commonFunction();
|
||||
|
||||
const props = defineProps({
|
||||
title: String,
|
||||
});
|
||||
@ -86,14 +88,14 @@ const initMonacoEditor = () => {
|
||||
// 打开弹窗
|
||||
const openDialog = async (row: any) => {
|
||||
state.isShowDialog = true;
|
||||
const { data } = await getAPI(SysCodeGenApi).apiSysCodeGenPreviewPost(row);
|
||||
const { data } = await getAPI(SysCodeGenApi).apiSysCodeGenPreviewPost({ id: row.id });
|
||||
state.codes = data.result ?? [];
|
||||
state.options = Object.keys(data.result as any).map((fileName: string) => ({
|
||||
value: fileName,
|
||||
icon: fileName?.endsWith('.cs') ? 'fa fa-hashtag' : fileName?.endsWith('.vue') ? 'fa fa-vimeo' : 'fa fa-file-code-o',
|
||||
}));
|
||||
state.current = state.options?.[0]?.value ?? '';
|
||||
if (monacoEditor == null) initMonacoEditor();
|
||||
if (!monacoEditor) initMonacoEditor();
|
||||
// 防止取不到
|
||||
nextTick(() => {
|
||||
monacoEditor.setValue(state.codes[state.current]);
|
||||
|
||||
@ -1,256 +0,0 @@
|
||||
<template>
|
||||
<div class="sys-codeGenConfig-container">
|
||||
<el-dialog v-model="state.isShowDialog" draggable :close-on-click-modal="false" width="800px">
|
||||
<template #header>
|
||||
<div style="color: #fff">
|
||||
<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"> <ele-Edit /> </el-icon>
|
||||
<span> 编辑规则 </span>
|
||||
</div>
|
||||
</template>
|
||||
<el-form :model="state.ruleForm" ref="ruleFormRef" label-width="auto">
|
||||
<el-row :gutter="10">
|
||||
<el-form-item style="display: none !important">
|
||||
<el-input v-model="state.ruleForm.id" />
|
||||
</el-form-item>
|
||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
||||
<el-form-item label=""> 本字段的数据库类型是:【{{ state.column.dataType }}】,.Net类型是:【{{ state.column.netType }}】 </el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
||||
<el-form-item label="验证类型" prop="type" :rules="rules.type">
|
||||
<el-select v-model="state.ruleForm.type" placeholder="请选择类型" @change="handleTypeChange">
|
||||
<el-option v-for="(item, index) in validTypeData" :key="index" :label="item.name" :value="item.code" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<template v-if="state.ruleForm.type == 'length' && (state.column.netType.includes('int') || state.column.netType.includes('long') || state.column.netType.includes('string'))">
|
||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
||||
<el-form-item label="最小值" prop="min" :rules="rules.min">
|
||||
<el-input-number v-model="state.ruleForm.min" :min="0" :max="100000" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
||||
<el-form-item label="最大值" prop="max" :rules="rules.max">
|
||||
<el-input-number v-model="state.ruleForm.max" :min="0" :max="100000" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</template>
|
||||
<template v-if="state.ruleForm.type == 'length' && (state.column.netType.includes('decimal') || state.column.netType.includes('float') || state.column.netType.includes('double'))">
|
||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
||||
<el-form-item label="最小值" prop="min" :rules="rules.minDecimal">
|
||||
<el-input-number v-model="state.ruleForm.min" :min="0" :max="100000" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
||||
<el-form-item label="最大值" prop="max" :rules="rules.maxDecimal">
|
||||
<el-input-number v-model="state.ruleForm.max" :min="0" :max="100000" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</template>
|
||||
<template v-if="state.ruleForm.type == 'length' && state.column.netType.includes('DateTime')">
|
||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
||||
<el-form-item label="起始日期" prop="min" :rules="rules.minDate">
|
||||
<el-date-picker v-model="state.ruleForm.min" type="date" format="YYYY-MM-DD" value-format="YYYY-MM-DD" placeholder="请选择起始日期" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
||||
<el-form-item label="结束日期" prop="max" :rules="rules.maxDate">
|
||||
<el-date-picker v-model="state.ruleForm.max" type="date" format="YYYY-MM-DD" value-format="YYYY-MM-DD" placeholder="请选择结束日期" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</template>
|
||||
<template v-if="state.ruleForm.type == 'pattern'">
|
||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
||||
<el-form-item label="提示信息" prop="message" :rules="rules.message">
|
||||
<el-input v-model="state.ruleForm.message" placeholder="请输入提示信息" maxlength="128" show-word-limit clearable />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
||||
<el-form-item label="正则式" prop="pattern" :rules="rules.pattern">
|
||||
<el-input v-model="state.ruleForm.pattern" placeholder="请输入正则表达式">
|
||||
<template #append>
|
||||
<el-button @click="openPatternDialog">选择正则</el-button>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</template>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button icon="ele-CircleCloseFilled" @click="cancel">取 消</el-button>
|
||||
<el-button type="primary" icon="ele-CircleCheckFilled" @click="submit">确 定</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<patternDialog ref="patternDialogRef" @submit-pattern="submitPatternOK" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.tool-box {
|
||||
padding-bottom: 20px;
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
align-items: center;
|
||||
// background: red;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { reactive, ref, toRaw } from 'vue';
|
||||
import patternDialog from '/@/views/system/codeGen/component/patternDialog.vue';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import type { FormRules } from 'element-plus';
|
||||
|
||||
const emit = defineEmits(['submitRule']);
|
||||
// 自行添加其他规则
|
||||
const rules = ref<FormRules>({
|
||||
type: [
|
||||
{
|
||||
required: true,
|
||||
message: '请选择验证类型',
|
||||
trigger: 'change',
|
||||
},
|
||||
],
|
||||
min: [
|
||||
{
|
||||
type: 'integer',
|
||||
required: true,
|
||||
pattern: /[^\d]/g,
|
||||
message: '请输入正确的数字',
|
||||
trigger: 'blur',
|
||||
},
|
||||
],
|
||||
minDecimal: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入正确的数字',
|
||||
trigger: 'blur',
|
||||
},
|
||||
],
|
||||
minDate: [
|
||||
{
|
||||
required: true,
|
||||
pattern: /^\d{4}-\d{2}-\d{2}$/,
|
||||
message: '请选择起始日期',
|
||||
trigger: ['change', 'blur'],
|
||||
},
|
||||
],
|
||||
max: [
|
||||
{
|
||||
type: 'integer',
|
||||
required: true,
|
||||
pattern: /[^\d]/g,
|
||||
message: '请输入正确的数字',
|
||||
trigger: 'blur',
|
||||
},
|
||||
],
|
||||
maxDecimal: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入正确的数字',
|
||||
trigger: 'blur',
|
||||
},
|
||||
],
|
||||
maxDate: [
|
||||
{
|
||||
required: true,
|
||||
pattern: /^\d{4}-\d{2}-\d{2}$/,
|
||||
message: '请选择结束日期',
|
||||
trigger: ['change', 'blur'],
|
||||
},
|
||||
],
|
||||
message: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入提示信息',
|
||||
trigger: 'blur',
|
||||
},
|
||||
],
|
||||
pattern: [{ required: true, message: '请输入正则表达式', trigger: 'blur' }],
|
||||
});
|
||||
const ruleFormRef = ref();
|
||||
const patternDialogRef = ref();
|
||||
const validTypeData = ref([
|
||||
{ code: 'required', name: '必填验证' },
|
||||
{ code: 'remote', name: '远程验证' },
|
||||
{ code: 'array', name: '数组验证' },
|
||||
{ code: 'pattern', name: '正则模式' },
|
||||
{ code: 'length', name: '长度限制' },
|
||||
]);
|
||||
|
||||
const state = reactive({
|
||||
isShowDialog: false,
|
||||
loading: false,
|
||||
ruleForm: {} as any,
|
||||
id: 0,
|
||||
column: {} as any,
|
||||
});
|
||||
|
||||
// 打开弹窗
|
||||
const openDialog = (row: any) => {
|
||||
// const data = JSON.parse(JSON.stringify(row));
|
||||
// state.ruleForm = data;
|
||||
state.id = row.id;
|
||||
state.isShowDialog = true;
|
||||
state.column = row;
|
||||
};
|
||||
|
||||
// 关闭弹窗
|
||||
const closeDialog = () => {
|
||||
// emit("reloadTable");
|
||||
ruleFormRef.value.resetFields();
|
||||
state.isShowDialog = false;
|
||||
};
|
||||
|
||||
// 打开正则选择框
|
||||
const openPatternDialog = () => {
|
||||
patternDialogRef.value.openDialog();
|
||||
};
|
||||
|
||||
// 取消
|
||||
const cancel = () => {
|
||||
// state.isShowDialog = false;
|
||||
closeDialog();
|
||||
};
|
||||
|
||||
const submitPatternOK = (data: any) => {
|
||||
// console.log('submitPatternOK', data);
|
||||
state.ruleForm.pattern = data.pattern;
|
||||
};
|
||||
|
||||
// 提交
|
||||
const submit = async () => {
|
||||
ruleFormRef.value.validate(async (isValid: boolean, fields?: any) => {
|
||||
if (isValid) {
|
||||
let values = toRaw(state.ruleForm);
|
||||
values.key = toRaw(state.id);
|
||||
emit('submitRule', Object.assign({}, values));
|
||||
closeDialog();
|
||||
} else {
|
||||
ElMessage({
|
||||
message: `表单有${Object.keys(fields).length}处验证失败,请修改后再提交`,
|
||||
type: 'error',
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 类型发生改变
|
||||
const handleTypeChange = () => {
|
||||
resetFields();
|
||||
};
|
||||
// 重置表单值
|
||||
const resetFields = () => {
|
||||
state.ruleForm.message = '';
|
||||
state.ruleForm.min = 0;
|
||||
state.ruleForm.max = 10;
|
||||
state.ruleForm.pattern = '';
|
||||
// state.ruleForm.dataType=null;
|
||||
};
|
||||
|
||||
// 导出对象
|
||||
defineExpose({ openDialog });
|
||||
</script>
|
||||
377
Web/src/views/system/codeGen/component/tableConfig.vue
Normal file
377
Web/src/views/system/codeGen/component/tableConfig.vue
Normal file
@ -0,0 +1,377 @@
|
||||
<template>
|
||||
<el-row :gutter="10" v-if="store.ruleForm.tableList?.[tableIndex]">
|
||||
<el-col :xs="24" :sm="6" :md="6" :lg="6" :xl="6" class="mb20">
|
||||
<el-form-item label="库定位器" :prop="`tableList[${tableIndex}].configId`" :rules="[{ required: true, message: '请选择库定位器', trigger: 'blur' }]">
|
||||
<el-select v-model="store.ruleForm.tableList[tableIndex].configId" :disabled="!!store.ruleForm.tableList[tableIndex].id" placeholder="库名" filterable @change="dbChanged()" class="w100">
|
||||
<el-option v-for="item in store.databaseList ?? []" :key="item.configId" :label="item.configId" :value="item.configId" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="6" :md="6" :lg="6" :xl="6" class="mb20">
|
||||
<el-form-item label="实体表名" :prop="`tableList[${tableIndex}].tableName`" :rules="[{ required: true, message: '请选择实体表名', trigger: 'blur' }]">
|
||||
<el-select v-model="store.ruleForm.tableList[tableIndex as any].tableName" :disabled="!!store.ruleForm.tableList[tableIndex].id || !store.ruleForm.tableList[tableIndex].configId" @change="tableChanged" value-key="tableName" filterable clearable class="w100">
|
||||
<template #prefix>
|
||||
<el-tooltip raw-content content="若找不到在前端生成的实体/表,请检查配置文件中实体所在程序集或重启后台服务。" placement="top">
|
||||
<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"><ele-QuestionFilled /></el-icon>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<el-option v-for="item in state.tableData" :key="item.entityName" :label="item.entityName + ' ( ' + item.tableName + ' ) [' + item.tableComment + ']'" :value="item" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="6" :md="6" :lg="6" :xl="6" class="mb20" v-if="store.getLastLinkLabel(tableIndex)">
|
||||
<el-form-item :label="store.getLastLinkLabel(tableIndex)" :prop="`tableList[${tableIndex}].lastLinkPropertyName`" :rules="[{ required: true, message: '请选择' + store.getLastLinkLabel(tableIndex), trigger: 'blur' }]">
|
||||
<el-select v-model="store.ruleForm.tableList[tableIndex].lastLinkPropertyName" :disabled="!!store.ruleForm.tableList[tableIndex].id || !store.ruleForm.tableList[tableIndex].configId" filterable clearable class="w100">
|
||||
<template #prefix>
|
||||
<el-tooltip raw-content content="与上级组件连表查询的字段" placement="top">
|
||||
<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"><ele-QuestionFilled /></el-icon>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<el-option v-for="item in state.columnList" :key="item.propertyName" :label="item.columnName + ' [' + item.columnComment + ']'" :value="item.propertyName" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="6" :md="6" :lg="6" :xl="6" class="mb20" v-if="store.getNextLinkLabel(tableIndex)">
|
||||
<el-form-item :label="store.getNextLinkLabel(tableIndex)" :prop="`tableList[${tableIndex}].nextLinkPropertyName`" :rules="[{ required: true, message: '请选择' + store.getNextLinkLabel(tableIndex), trigger: 'blur' }]">
|
||||
<el-select v-model="store.ruleForm.tableList[tableIndex].nextLinkPropertyName" :disabled="!!store.ruleForm.tableList[tableIndex].id || !store.ruleForm.tableList[tableIndex].configId" filterable clearable class="w100">
|
||||
<template #prefix>
|
||||
<el-tooltip raw-content content="与下级组件连表查询的字段" placement="top">
|
||||
<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"><ele-QuestionFilled /></el-icon>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<el-option v-for="item in state.columnList" :key="item.propertyName" :label="item.columnName + ' [' + item.columnComment + ']'" :value="item.propertyName" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="6" :md="6" :lg="6" :xl="6" class="mb20">
|
||||
<el-form-item label="业务名" :prop="`tableList[${tableIndex}].busName`" :rules="[{ required: true, message: '业务名不能为空', trigger: 'blur' }]">
|
||||
<el-input v-model="store.ruleForm.tableList[tableIndex].busName" placeholder="请输入" clearable />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="6" :md="6" :lg="6" :xl="6" class="mb20">
|
||||
<el-form-item label="模块名" :prop="`tableList[${tableIndex}].moduleName`" :rules="[{ required: true, message: '模块名不能为空', trigger: 'blur' }]">
|
||||
<el-input v-model="store.ruleForm.tableList[tableIndex].moduleName" :disabled="!!store.ruleForm.tableList[tableIndex].id" placeholder="请输入" clearable>
|
||||
<template #prefix>
|
||||
<el-tooltip raw-content content="对应后端Service接口名称前缀" placement="top">
|
||||
<el-icon size="16" style="display: inline; vertical-align: middle"><ele-QuestionFilled /></el-icon>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-divider content-position="center">
|
||||
表字段配置    <el-button type="primary" icon="ele-Refresh" :disabled="store.getSyncColumnListButtonDisabled(tableIndex)" @click="asyncColumnList()" v-reclick="1000">同步配置</el-button>
|
||||
</el-divider>
|
||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
||||
<vxe-grid ref="xGridRef" class="xGrid-table-style" v-bind="tableOptions" :data="store.ruleForm.tableList[tableIndex].columnList ?? []">
|
||||
<template #drag_default="{}">
|
||||
<span class="drag-btn">
|
||||
<i class="fa fa-arrows"></i>
|
||||
</span>
|
||||
</template>
|
||||
<template #orderNo="{ row }">
|
||||
<vxe-input v-model="row.orderNo" autocomplete="off" @change="handelChangeOrderNo" />
|
||||
</template>
|
||||
<template #effectType="{ row, rowIndex }">
|
||||
<vxe-select v-model="row.effectType" @change="effectTypeChange(row, rowIndex)" :disabled="disabledColumn(row)" :style="{ width: '100%' }" placeholder="Select" transfer filterable>
|
||||
<vxe-option v-for="item in userInfo.dictList['CodeGenEffectTypeEnum']" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</vxe-select>
|
||||
<!-- <vxe-button v-if="showConfigButton(row)" style="width: 30%" icon="vxe-icon-edit" @click="effectTypeChange(row, rowIndex)" v-reclick="1000">修改</vxe-button>-->
|
||||
<vxe-checkbox v-if="showCheckBox(row)" v-model="row.config.multiple" style="width: 30%" icon="vxe-icon-edit">多选</vxe-checkbox>
|
||||
</template>
|
||||
<template #defaultValue="{ row }">
|
||||
<vxe-input v-model="row.defaultValue" autocomplete="off" :disabled="disabledColumn(row)" />
|
||||
</template>
|
||||
<template #columnComment="{ row }">
|
||||
<vxe-input v-model="row.columnComment" autocomplete="off" :disabled="disabledColumn(row)" />
|
||||
</template>
|
||||
<template #config="{ row, rowIndex }">
|
||||
<span v-if="!row.config"></span>
|
||||
<!-- 枚举、字典、常量 -->
|
||||
<vxe-select v-else-if="useDictSelector(row)" v-model="row.config.code" class="w100 m-2" :disabled="!useDictSelector(row)" filterable transfer>
|
||||
<vxe-option v-if="row.effectType == 101" v-for="item in store.dictList" :key="item.code" :label="item.name" :value="item.code" />
|
||||
<vxe-option v-if="row.effectType == 102" v-for="item in store.constList" :key="item.code" :label="item.name" :value="item.code" />
|
||||
<vxe-option v-if="row.effectType == 103" v-for="item in store.enumList" :key="item.code" :label="item.name" :value="item.code" />
|
||||
</vxe-select>
|
||||
<!-- 时间格式 -->
|
||||
<vxe-select v-else-if="row.effectType == 107" v-model="row.config.format" placeholder="时间格式" class="w100">
|
||||
<vxe-option label="YYYY-mm-dd HH:MM:SS" value="datetime" />
|
||||
<vxe-option label="YYYY-mm-dd" value="date" />
|
||||
<vxe-option label="HH:MM:SS" value="time" />
|
||||
</vxe-select>
|
||||
<!-- 树形选择器 -->
|
||||
<vxe-input v-else-if="row.effectType == 104" v-model="row.config.entityName" readonly style="width: 67.5%"></vxe-input>
|
||||
<!-- 外键 -->
|
||||
<vxe-input v-else-if="row.effectType == 105" v-model="row.config.entityName" readonly style="width: 67.5%"></vxe-input>
|
||||
<!-- 上传配置 -->
|
||||
<vxe-input v-else-if="row.effectType == 109" readonly placeholder="上传配置" style="width: 67.5%"></vxe-input>
|
||||
<vxe-button v-if="[104, 105, 109].includes(row.effectType)" @click="effectTypeChange(row, rowIndex)" style="width: 27.5%" icon="vxe-icon-edit">修改</vxe-button>
|
||||
</template>
|
||||
<template #isTable="{ row }">
|
||||
<vxe-checkbox v-model="row.isTable"></vxe-checkbox>
|
||||
</template>
|
||||
<template #isCopy="{ row }">
|
||||
<vxe-checkbox v-model="row.isCopy" v-if="row.isTable"></vxe-checkbox>
|
||||
</template>
|
||||
<template #isAddUpdate="{ row }">
|
||||
<vxe-checkbox v-model="row.isAddUpdate" v-if="!disabledColumn(row)"></vxe-checkbox>
|
||||
</template>
|
||||
<template #isImport="{ row }">
|
||||
<vxe-checkbox v-model="row.isImport" v-if="!disabledColumn(row)"></vxe-checkbox>
|
||||
</template>
|
||||
<template #isSortable="{ row }">
|
||||
<vxe-checkbox v-model="row.isSortable" v-if="row.isTable"></vxe-checkbox>
|
||||
</template>
|
||||
<template #isRequired="{ row }">
|
||||
<vxe-tag v-if="row.isRequired" status="success">是</vxe-tag>
|
||||
<vxe-tag v-else status="info">否</vxe-tag>
|
||||
</template>
|
||||
<template #isStatistical="{ row }">
|
||||
<vxe-switch v-model="row.isStatistical" open-label="是" close-label="否" :openValue="true" :closeValue="false"></vxe-switch>
|
||||
</template>
|
||||
<template #isQuery="{ row }">
|
||||
<vxe-switch v-model="row.isQuery" open-label="是" close-label="否" :openValue="true" :closeValue="false"></vxe-switch>
|
||||
</template>
|
||||
<template #queryType="{ row }">
|
||||
<vxe-select v-model="row.queryType" class="m-2" placeholder="Select" :disabled="!row.isQuery" filterable transfer>
|
||||
<vxe-option v-for="item in userInfo.dictList['code_gen_query_type']" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</vxe-select>
|
||||
</template>
|
||||
<template #fromValid="{ row }">
|
||||
<vxe-select v-model="row.fromValid" class="m-2" placeholder="Select" :disabled="!row.isAddUpdate" filterable clearable transfer>
|
||||
<vxe-option v-for="item in userInfo.dictList['CodeGenFromRuleValidEnum']" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</vxe-select>
|
||||
</template>
|
||||
</vxe-grid>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<EffectLinkTableConfig ref="effectLinkTableDialogRef" @submitData="submitRefreshFk" />
|
||||
<UploadConfigDialog ref="uploadConfigDialogRef" @submitData="submitRefreshFk" />
|
||||
<DateTimeConfigDialog ref="dateTimeConfigDialogRef" @submitData="submitRefreshFk" />
|
||||
</template>
|
||||
|
||||
<!-- 表配置 -->
|
||||
<script lang="ts" setup name="tableConfig">
|
||||
import Sortable from "sortablejs";
|
||||
import { ref, reactive, watch, computed } from 'vue';
|
||||
import { useUserInfo } from '/@/stores/userInfo'
|
||||
import { VxeGridInstance, VxeGridProps } from "vxe-table";
|
||||
import {SysCodeGenColumn, TableOutput} from '/@/api-services/system/models';
|
||||
import EffectLinkTableConfig from "./effectLinkTableConfig.vue";
|
||||
import DateTimeConfigDialog from "./dateTimeConfigDialog.vue";
|
||||
import UploadConfigDialog from "./uploadConfigDialog.vue";
|
||||
import { useCodeGenStore } from './codeGenStore';
|
||||
import {debounce} from "xe-utils";
|
||||
|
||||
const store = useCodeGenStore();
|
||||
const uploadConfigDialogRef = ref();
|
||||
const dateTimeConfigDialogRef = ref();
|
||||
const effectLinkTableDialogRef = ref();
|
||||
const xGridRef = ref<VxeGridInstance<SysCodeGenColumn>>();
|
||||
const props = defineProps<{
|
||||
index: number,
|
||||
}>();
|
||||
const tableIndex = computed(() => props.index);
|
||||
|
||||
const userInfo = useUserInfo();
|
||||
const state = reactive({
|
||||
index: 0,
|
||||
tableData: [] as TableOutput[] | any,
|
||||
columnList: [] as Array<SysCodeGenColumn>,
|
||||
});
|
||||
|
||||
// 表格参数配置
|
||||
const tableOptions = reactive<VxeGridProps<SysCodeGenColumn>>({
|
||||
id: 'genConfigDialog',
|
||||
height: '350px',
|
||||
keepSource: true,
|
||||
autoResize: true,
|
||||
loading: false,
|
||||
align: 'center',
|
||||
rowConfig: { useKey: true },
|
||||
seqConfig: { seqMethod: ({ row }) => row.orderNo as number },
|
||||
columns: [
|
||||
{ field: 'id', width: 40, slots: { default: 'drag_default' }, },
|
||||
{ field: 'orderNo', title: '排序', minWidth: 40, showOverflow: 'tooltip', slots: { default: 'orderNo'} },
|
||||
{ field: 'columnName', title: '字段', minWidth: 100, align: 'left', showOverflow: 'tooltip', },
|
||||
{ field: 'defaultValue', title: '默认值', minWidth: 80, align: 'left', showOverflow: 'tooltip', slots: { default: 'defaultValue'} },
|
||||
{ field: 'columnComment', title: '描述', minWidth: 100, showOverflow: 'tooltip', slots: { default: 'columnComment' },},
|
||||
{ field: 'netType', title: '数据类型', minWidth: 90, align: 'left', },
|
||||
{ field: 'effectType', title: '控件类型', minWidth: 160, slots: { default: 'effectType' }, },
|
||||
{ field: 'config', title: '控件配置', minWidth: 180, slots: { default: 'config' }, },
|
||||
{ field: 'isTable', title: '列表显示', minWidth: 70, slots: { default: 'isTable' }, },
|
||||
{ field: 'isCopy', title: '复制', minWidth: 40, slots: { default: 'isCopy' }, },
|
||||
{ field: 'isAddUpdate', title: '增改字段', minWidth: 70, slots: { default: 'isAddUpdate' }, },
|
||||
{ field: 'isImport', title: '导入导出', minWidth: 70, slots: { default: 'isImport' }, },
|
||||
{ field: 'isRequired', title: '必填字段', minWidth: 70, slots: { default: 'isRequired' }, },
|
||||
{ field: 'isSortable', title: '排序字段', minWidth: 70, slots: { default: 'isSortable' }, },
|
||||
{ field: 'isStatistical', title: '统计字段', minWidth: 70, slots: { default: 'isStatistical' }, },
|
||||
{ field: 'isQuery', title: '查询字段', minWidth: 70, slots: { default: 'isQuery' },},
|
||||
{ field: 'queryType', title: '查询方式', minWidth: 120, slots: { default: 'queryType' },},
|
||||
{ field: 'fromValid', title: '校验规则', width: 130, showOverflow: true, slots: { default: 'fromValid' },},
|
||||
],
|
||||
editConfig: { trigger: 'click', mode: 'row', showStatus: true },
|
||||
data: [],
|
||||
});
|
||||
|
||||
const reset = (type: string) => {
|
||||
if (type === 'db') {
|
||||
store.ruleForm.tableList[tableIndex.value]!.busName = undefined as any;
|
||||
store.ruleForm.tableList[tableIndex.value]!.moduleName = undefined as any;
|
||||
store.ruleForm.tableList[tableIndex.value]!.tableName = undefined as any;
|
||||
store.ruleForm.tableList[tableIndex.value]!.entityName = undefined as any;
|
||||
}
|
||||
store.ruleForm.tableList[tableIndex.value].lastLinkPropertyName = undefined;
|
||||
store.ruleForm.tableList[tableIndex.value].nextLinkPropertyName = undefined;
|
||||
};
|
||||
|
||||
// 库改变事件
|
||||
watch(() => store.ruleForm.tableList?.[tableIndex.value]?.configId, () => reset('db'));
|
||||
|
||||
// 表改变事件
|
||||
watch(() => store.ruleForm.tableList?.[tableIndex.value]?.tableName, () => reset('table'))
|
||||
|
||||
// 库改变
|
||||
const dbChanged = async () => {
|
||||
state.tableData = await store.tableListBy(store.ruleForm.tableList[tableIndex.value].configId) ?? [];
|
||||
}
|
||||
|
||||
// table改变
|
||||
const tableChanged = async (item: any) => {
|
||||
tableOptions.loading = true;
|
||||
try {
|
||||
store.ruleForm.tableList[tableIndex.value].tableName = item.tableName;
|
||||
store.ruleForm.tableList[tableIndex.value].entityName = item.entityName;
|
||||
store.ruleForm.tableList[tableIndex.value].moduleName = item.entityName;
|
||||
store.ruleForm.tableList[tableIndex.value].busName = item.tableComment?.replace(/表$/, '');
|
||||
|
||||
const data = store.ruleForm.tableList[tableIndex.value];
|
||||
state.columnList = (await store.columnListBy(data.configId, data.tableName) ?? []) as any[];
|
||||
await asyncColumnList();
|
||||
} finally {
|
||||
tableOptions.loading = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 同步字段列表
|
||||
const asyncColumnList = async () => {
|
||||
tableOptions.loading = true;
|
||||
try {
|
||||
await store.getDefaultColumnConfigList(tableIndex.value);
|
||||
rowDrop();
|
||||
} finally {
|
||||
tableOptions.loading = false;
|
||||
}
|
||||
}
|
||||
|
||||
// 判断是否(用于是否能选择或输入等)
|
||||
const disabledColumn = (row: any) => row.isCommon || row.isPrimarykey;
|
||||
//const showConfigButton = (row: any) => useConfigButton(row) && !row.isCommon;
|
||||
const showCheckBox = (row: any) => useDictSelector(row) && row.netType.startsWith('string') && !row.isCommon;
|
||||
const useDictSelector = (row: any) => [101,102,103].includes(Number(row.effectType) ?? 0);
|
||||
//const useConfigButton = (row: any) => [104, 105, 107, 109].includes(Number(row.effectType));
|
||||
|
||||
// 控件类型改变
|
||||
const effectTypeChange = (row: any, index: number) => {
|
||||
row.effectType = Number(row.effectType);
|
||||
if ([101, 102, 103].includes(row.effectType)) {
|
||||
row.config = {};
|
||||
} else if (row.effectType === 104) {
|
||||
openTreeDialog(row, index);
|
||||
} else if (row.effectType === 105) {
|
||||
openFkDialog(row, index);
|
||||
} else if (row.effectType === 107) {
|
||||
openDateTimeDialog(row, index);
|
||||
} else if (row.effectType === 109) {
|
||||
openUploadDialog(row, index);
|
||||
} else {
|
||||
row.config = undefined;
|
||||
}
|
||||
// 选择器类型,默认使用 “等于” 查询方式
|
||||
if (row.effectType <= 105) row.queryType = '==';
|
||||
};
|
||||
|
||||
// 打开外键弹窗
|
||||
const openFkDialog = (row: any, index: number) => {
|
||||
row.index = index;
|
||||
effectLinkTableDialogRef.value.openDialog(row, 'fk');
|
||||
};
|
||||
|
||||
// 打开树形弹窗
|
||||
const openTreeDialog = (row: any, index: number) => {
|
||||
row.index = index;
|
||||
effectLinkTableDialogRef.value.openDialog(row, 'tree');
|
||||
};
|
||||
|
||||
// 打开上传弹窗
|
||||
const openUploadDialog = (row: any, index: number) => {
|
||||
row.index = index;
|
||||
uploadConfigDialogRef.value.openDialog(row);
|
||||
};
|
||||
|
||||
// 打开时间弹窗
|
||||
const openDateTimeDialog = (row: any, index: number) => {
|
||||
row.index = index;
|
||||
dateTimeConfigDialogRef.value.openDialog(row);
|
||||
};
|
||||
|
||||
// 更新主键
|
||||
const submitRefreshFk = (row: any) => {
|
||||
let tableData = xGridRef.value?.getFullData() || [];
|
||||
tableData[row.index] = row;
|
||||
xGridRef.value?.loadData(tableData);
|
||||
};
|
||||
|
||||
// 序号改变事件
|
||||
const handelChangeOrderNo = debounce(() => {
|
||||
let tableData = xGridRef.value?.getFullData() || [];
|
||||
tableData = tableData.sort((a: any, b: any) => a.orderNo - b.orderNo)
|
||||
xGridRef.value?.loadData(tableData);
|
||||
}, 1000)
|
||||
|
||||
const rowDrop = () => {
|
||||
const el = document.querySelector('.xGrid-table-style .vxe-table--body tbody') as HTMLElement;
|
||||
Sortable.create(el, {
|
||||
animation: 300,
|
||||
handle: '.drag-btn',
|
||||
onEnd: (sortableEvent: any) => {
|
||||
const fullData = xGridRef.value?.getTableData().fullData || [];
|
||||
const newIndex = sortableEvent.newIndex as number;
|
||||
const oldIndex = sortableEvent.oldIndex as number;
|
||||
|
||||
if (newIndex === undefined || oldIndex === undefined || newIndex === oldIndex) return;
|
||||
|
||||
const currentRow = fullData.splice(oldIndex, 1)[0];
|
||||
fullData.splice(newIndex, 0, currentRow);
|
||||
fullData.forEach((u, i) => (u.orderNo = 5 + i * 5))
|
||||
|
||||
// 重新分配 orderNo 以保持原有差距
|
||||
let prevOrderNo = newIndex > oldIndex ? fullData[newIndex - 1]?.orderNo : fullData[newIndex + 1]?.orderNo;
|
||||
let nextOrderNo = newIndex > oldIndex ? fullData[newIndex + 1]?.orderNo : fullData[newIndex - 1]?.orderNo;
|
||||
|
||||
if (prevOrderNo !== undefined && nextOrderNo !== undefined) {
|
||||
currentRow.orderNo = (prevOrderNo + nextOrderNo) / 2;
|
||||
} else if (prevOrderNo !== undefined) {
|
||||
currentRow.orderNo = prevOrderNo + 5; // 假设最小差距为 5
|
||||
if (newIndex == 0) currentRow.orderNo = 5;
|
||||
} else if (nextOrderNo !== undefined) {
|
||||
currentRow.orderNo = nextOrderNo - 5; // 假设最小差距为 5
|
||||
}
|
||||
|
||||
// 更新表格数据
|
||||
xGridRef.value?.loadData(fullData);
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.xGrid-table-style .drag-btn {
|
||||
cursor: move;
|
||||
font-size: 20px;
|
||||
}
|
||||
:deep(.vxe-cell) {
|
||||
height: auto !important;
|
||||
}
|
||||
</style>
|
||||
@ -1,167 +0,0 @@
|
||||
<template>
|
||||
<div class="sys-codeGenTree-container">
|
||||
<el-dialog v-model="state.isShowDialog" draggable :close-on-click-modal="false" width="700px">
|
||||
<template #header>
|
||||
<div style="color: #fff">
|
||||
<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"> <ele-Edit /> </el-icon>
|
||||
<span> 树选择配置 </span>
|
||||
</div>
|
||||
</template>
|
||||
<el-form :model="state.ruleForm" ref="ruleFormRef" label-width="auto">
|
||||
<el-row :gutter="10">
|
||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
||||
<el-form-item label="库定位器" prop="configId">
|
||||
<el-select clearable v-model="state.ruleForm.configId" placeholder="库名" filterable @change="DbChanged()" class="w100">
|
||||
<el-option v-for="item in state.dbData" :key="item.configId" :label="item.configId" :value="item.configId" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
||||
<el-form-item label="数据库表" prop="tableName">
|
||||
<el-select v-model="state.ruleForm.tableName" filterable clearable @change="TableChanged()" class="w100">
|
||||
<el-option v-for="item in state.tableData" :key="item.entityName" :label="item.tableName + ' [' + item.tableComment + ']'" :value="item.tableName" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
||||
<el-form-item label="显示字段" prop="displayColumn">
|
||||
<el-select v-model="state.ruleForm.displayColumn" filterable class="w100">
|
||||
<el-option v-for="item in state.columnData" :key="item.columnName" :label="item.columnName + ' [' + item.columnComment + ']'" :value="item.columnName" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
||||
<el-form-item label="选择值字段" prop="valueColumn">
|
||||
<el-select v-model="state.ruleForm.valueColumn" filterable class="w100">
|
||||
<el-option v-for="item in state.columnData" :key="item.columnName" :label="item.columnName + ' [' + item.columnComment + ']'" :value="item.columnName" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
||||
<el-form-item label="父级字段" prop="pidColumn">
|
||||
<el-select v-model="state.ruleForm.pidColumn" filterable class="w100">
|
||||
<el-option v-for="item in state.columnData" :key="item.columnName" :label="item.columnName + ' [' + item.columnComment + ']'" :value="item.columnName" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button icon="ele-CircleCloseFilled" @click="cancel">取 消</el-button>
|
||||
<el-button type="primary" icon="ele-CircleCheckFilled" @click="submit">确 定</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup name="sysCodeGenTree">
|
||||
import { onMounted, reactive, ref } from 'vue';
|
||||
|
||||
import { getAPI } from '/@/utils/axios-utils';
|
||||
import { SysCodeGenApi } from '/@/api-services/system/api';
|
||||
|
||||
var rowdata = {} as any;
|
||||
const emits = defineEmits(['submitRefreshFk']);
|
||||
const ruleFormRef = ref();
|
||||
const state = reactive({
|
||||
isShowDialog: false,
|
||||
ruleForm: {} as any,
|
||||
dbData: [] as any,
|
||||
tableData: [] as any,
|
||||
columnData: [] as any,
|
||||
});
|
||||
|
||||
onMounted(async () => {
|
||||
await getDbList();
|
||||
|
||||
// 默认使用第一个库
|
||||
//state.ruleForm.configId = state.dbData[0].configId;
|
||||
//await DbChanged();
|
||||
});
|
||||
|
||||
const DbChanged = async () => {
|
||||
state.tableData = [];
|
||||
state.columnData = [];
|
||||
await getTableInfoList();
|
||||
};
|
||||
|
||||
const TableChanged = async () => {
|
||||
state.columnData = [];
|
||||
await getColumnInfoList();
|
||||
};
|
||||
|
||||
const getDbList = async () => {
|
||||
var res = await getAPI(SysCodeGenApi).apiSysCodeGenDatabaseListGet();
|
||||
state.dbData = res.data.result;
|
||||
};
|
||||
|
||||
const getTableInfoList = async () => {
|
||||
if (state.ruleForm.configId == '') return;
|
||||
var res = await getAPI(SysCodeGenApi).apiSysCodeGenTableListConfigIdGet(state.ruleForm.configId);
|
||||
state.tableData = res.data.result;
|
||||
};
|
||||
|
||||
const getColumnInfoList = async () => {
|
||||
if (state.ruleForm.configId == '' || state.ruleForm.tableName == '') return;
|
||||
var res = await getAPI(SysCodeGenApi).apiSysCodeGenColumnListByTableNameTableNameConfigIdGet(state.ruleForm.tableName, state.ruleForm.configId);
|
||||
state.columnData = res.data.result;
|
||||
};
|
||||
|
||||
// 打开弹窗
|
||||
const openDialog = async (row: any) => {
|
||||
rowdata = row;
|
||||
state.isShowDialog = true;
|
||||
ruleFormRef.value?.resetFields();
|
||||
if (rowdata.fkConfigId) {
|
||||
await getDbList();
|
||||
state.ruleForm.tableName = rowdata.fkTableName;
|
||||
state.ruleForm.displayColumn = rowdata.displayColumn;
|
||||
state.ruleForm.valueColumn = rowdata.valueColumn;
|
||||
state.ruleForm.pidColumn = rowdata.pidColumn;
|
||||
state.ruleForm.configId = rowdata.fkConfigId;
|
||||
await DbChanged();
|
||||
await TableChanged();
|
||||
}
|
||||
};
|
||||
|
||||
// 关闭弹窗
|
||||
const closeDialog = () => {
|
||||
rowdata.fkTableName = state.ruleForm.tableName;
|
||||
// rowdata.fkEntityName = state.ruleForm.entityName;
|
||||
// 这里一定要设置 fkEntityName,因为模板文件用到了
|
||||
let tableData = state.tableData.filter((x: any) => x.tableName == state.ruleForm.tableName);
|
||||
rowdata.fkEntityName = tableData.length == 0 ? '' : tableData[0].entityName;
|
||||
// rowdata.fkColumnName = state.ruleForm.columnName;
|
||||
// rowdata.fkColumnNetType = state.ruleForm.columnNetType;
|
||||
rowdata.displayColumn = state.ruleForm.displayColumn;
|
||||
rowdata.valueColumn = state.ruleForm.valueColumn;
|
||||
rowdata.pidColumn = state.ruleForm.pidColumn;
|
||||
rowdata.fkConfigId = state.ruleForm.configId;
|
||||
emits('submitRefreshFk', rowdata);
|
||||
cancel();
|
||||
};
|
||||
|
||||
// 取消
|
||||
const cancel = () => {
|
||||
state.isShowDialog = false;
|
||||
ruleFormRef.value?.resetFields();
|
||||
state.ruleForm = {};
|
||||
state.dbData.value = [];
|
||||
state.tableData.value = [];
|
||||
state.columnData.value = [];
|
||||
};
|
||||
|
||||
// 提交
|
||||
const submit = () => {
|
||||
ruleFormRef.value.validate(async (valid: boolean) => {
|
||||
if (!valid) return;
|
||||
|
||||
closeDialog();
|
||||
});
|
||||
};
|
||||
|
||||
// 导出对象
|
||||
defineExpose({ openDialog });
|
||||
</script>
|
||||
@ -0,0 +1,95 @@
|
||||
<template>
|
||||
<div class="sys-codeGenUpload-container">
|
||||
<el-dialog v-model="state.isShowDialog" draggable :close-on-click-modal="false" width="700px">
|
||||
<template #header>
|
||||
<div style="color: #fff">
|
||||
<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"> <ele-Edit /> </el-icon>
|
||||
<span> 上传配置 </span>
|
||||
</div>
|
||||
</template>
|
||||
<el-form :model="state.ruleForm" ref="ruleFormRef" label-width="auto">
|
||||
<el-row :gutter="10">
|
||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
||||
<el-form-item label="链接预览" prop="useDownload" :rules="[{ required: true, message: '链接下载不能为空', trigger: 'blur' }]">
|
||||
<el-radio-group v-model="state.ruleForm.useDownload" filterable>
|
||||
<el-radio :value="true">是</el-radio>
|
||||
<el-radio :value="false">否</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20" v-if="state.ruleForm.useDownload">
|
||||
<el-form-item label="链接文本" prop="downloadText" :rules="[{ required: true, message: '链接文本不能为空', trigger: 'blur' }]">
|
||||
<vxe-input v-model="state.ruleForm.downloadText" placeholder="请输入" class="w100" clearable />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
|
||||
<el-form-item label="图片文件" prop="isImage" :rules="[{ required: true, message: '图片文件不能为空', trigger: 'blur' }]">
|
||||
<el-radio-group v-model="state.ruleForm.isImage" filterable>
|
||||
<el-radio :value="true">是</el-radio>
|
||||
<el-radio :value="false">否</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button icon="ele-CircleCloseFilled" @click="cancel">取 消</el-button>
|
||||
<el-button type="primary" icon="ele-CircleCheckFilled" @click="submit" v-reclick="1000">确 定</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup name="sysPreviewCode">
|
||||
import { onMounted, reactive, ref } from 'vue';
|
||||
|
||||
let rowData = {} as any;
|
||||
const emits = defineEmits(['submitData']);
|
||||
const ruleFormRef = ref();
|
||||
const state = reactive({
|
||||
isShowDialog: false,
|
||||
ruleForm: {} as any,
|
||||
});
|
||||
|
||||
onMounted(async () => {});
|
||||
|
||||
// 打开弹窗
|
||||
const openDialog = async (row: any) => {
|
||||
rowData = row;
|
||||
state.ruleForm = Object.assign({}, row.config);
|
||||
state.ruleForm.downloadText ??= '查看文件';
|
||||
state.ruleForm.useDownload ??= false;
|
||||
state.ruleForm.isImage ??= false;
|
||||
state.isShowDialog = true;
|
||||
};
|
||||
|
||||
// 关闭弹窗
|
||||
const closeDialog = () => {
|
||||
if (!rowData.netType.startsWith('string')) state.ruleForm.multiple = false;
|
||||
rowData.config = Object.assign({}, state.ruleForm);
|
||||
emits('submitData', rowData);
|
||||
cancel();
|
||||
};
|
||||
|
||||
// 取消
|
||||
const cancel = () => {
|
||||
state.isShowDialog = false;
|
||||
ruleFormRef.value?.resetFields();
|
||||
state.ruleForm = {};
|
||||
};
|
||||
|
||||
// 提交
|
||||
const submit = () => {
|
||||
ruleFormRef.value.validate(async (valid: boolean) => {
|
||||
if (!valid) return;
|
||||
closeDialog();
|
||||
});
|
||||
};
|
||||
|
||||
// 导出对象
|
||||
defineExpose({ openDialog });
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
@ -1,116 +0,0 @@
|
||||
<template>
|
||||
<div class="sys-codeGenConfig-container">
|
||||
<el-dialog v-model="state.isShowDialog" draggable :close-on-click-modal="false" width="800px">
|
||||
<template #header>
|
||||
<div style="color: #fff">
|
||||
<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"> <ele-Edit /> </el-icon>
|
||||
<span> {{ state.title }} </span>
|
||||
</div>
|
||||
</template>
|
||||
<div class="tool-box">
|
||||
<el-button type="primary" icon="ele-Plus" @click="openRuleDialog"> 新增 </el-button>
|
||||
</div>
|
||||
<el-table :data="state.tableData" style="width: 100%" v-loading="state.loading" border>
|
||||
<el-table-column prop="type" label="类型" width="120" show-overflow-tooltip />
|
||||
<el-table-column prop="message" label="提示信息" minWidth="180" show-overflow-tooltip />
|
||||
<el-table-column prop="min" label="最小值" minWidth="100" show-overflow-tooltip />
|
||||
<el-table-column prop="max" label="最大值" minWidth="100" show-overflow-tooltip />
|
||||
<el-table-column prop="pattern" label="正则式" minWidth="120" show-overflow-tooltip />
|
||||
<el-table-column prop="action" label="操作" width="100" align="center" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
<el-button icon="ele-Delete" text type="danger" @click="handleDeleteRule(scope)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button icon="ele-CircleCloseFilled" @click="cancel">取 消</el-button>
|
||||
<el-button type="primary" icon="ele-CircleCheckFilled" @click="submit">确 定</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<ruleDialog ref="ruleDialogRef" @submitRule="submitRuleOK" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { reactive, ref, toRaw } from 'vue';
|
||||
import ruleDialog from '/@/views/system/codeGen/component/ruleDialog.vue';
|
||||
|
||||
const emits = defineEmits(['submitVerify']);
|
||||
const ruleDialogRef = ref();
|
||||
const state = reactive({
|
||||
id: 0,
|
||||
isShowDialog: false,
|
||||
loading: false,
|
||||
tableData: [] as any,
|
||||
title: '',
|
||||
column: {} as any,
|
||||
});
|
||||
|
||||
// 打开弹窗
|
||||
const openDialog = (row: any) => {
|
||||
state.title = `校验规则 -- ${row.columnComment}`;
|
||||
state.tableData = new Array();
|
||||
if (row.rules != '') {
|
||||
state.tableData = JSON.parse(row.rules);
|
||||
}
|
||||
|
||||
// state.tableData = row.rules;
|
||||
state.id = row.id;
|
||||
state.isShowDialog = true;
|
||||
state.column = row;
|
||||
// console.log('column',row);
|
||||
};
|
||||
|
||||
// 打开验证规则弹窗
|
||||
const openRuleDialog = () => {
|
||||
ruleDialogRef.value.openDialog(state.column);
|
||||
};
|
||||
|
||||
// 关闭弹窗
|
||||
const closeDialog = () => {
|
||||
state.isShowDialog = false;
|
||||
};
|
||||
|
||||
// 取消
|
||||
const cancel = () => {
|
||||
state.isShowDialog = false;
|
||||
};
|
||||
|
||||
// 提交
|
||||
const submit = async () => {
|
||||
let data = toRaw(state);
|
||||
let newData = Object.assign({}, data);
|
||||
let ruleCount = newData.tableData.length > 0 ? `(${newData.tableData.length})` : '';
|
||||
emits('submitVerify', { id: newData.id, rules: JSON.stringify(newData.tableData), ruleCount: ruleCount });
|
||||
closeDialog();
|
||||
};
|
||||
|
||||
// 添加返回
|
||||
const submitRuleOK = (data: any) => {
|
||||
let row = toRaw(data);
|
||||
if (state.tableData === null) {
|
||||
state.tableData = [];
|
||||
}
|
||||
state.tableData.push(row);
|
||||
};
|
||||
|
||||
// 删除验证规则
|
||||
const handleDeleteRule = (scope: any) => {
|
||||
state.tableData.splice(scope.$index, 1);
|
||||
};
|
||||
|
||||
// 导出对象
|
||||
defineExpose({ openDialog });
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.tool-box {
|
||||
padding-bottom: 20px;
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
align-items: center;
|
||||
// background: red;
|
||||
}
|
||||
</style>
|
||||
@ -37,37 +37,30 @@
|
||||
<template #empty>
|
||||
<el-empty :image-size="200" />
|
||||
</template>
|
||||
<template #row_generateType="{ row }">
|
||||
<el-tag v-if="row.generateType == 100"> 下载压缩包 </el-tag>
|
||||
<el-tag v-else-if="row.generateType == 111"> 下载压缩包(前端) </el-tag>
|
||||
<el-tag v-else-if="row.generateType == 121"> 下载压缩包(后端) </el-tag>
|
||||
<el-tag v-else-if="row.generateType == 211"> 生成到本项目(前端) </el-tag>
|
||||
<el-tag v-else-if="row.generateType == 221"> 生成到本项目(后端) </el-tag>
|
||||
<el-tag type="danger" v-else> 生成到本项目 </el-tag>
|
||||
<template #row_entityName="{ row }">
|
||||
{{ row.tableList?.[0].entityName }}
|
||||
</template>
|
||||
<template #row_generateMethod="{ row }">
|
||||
<g-sys-dict code="CodeGenMethodEnum" v-model="row.generateMethod" />
|
||||
</template>
|
||||
<template #row_scene="{ row }">
|
||||
<g-sys-dict code="CodeGenSceneEnum" v-model="row.scene" />
|
||||
</template>
|
||||
<template #row_record="{ row }">
|
||||
<ModifyRecord :data="row" />
|
||||
</template>
|
||||
<template #row_buttons="{ row }">
|
||||
<el-tooltip content="编辑" placement="top">
|
||||
<el-button icon="ele-Edit" text type="primary" @click="handleEdit(row)"> </el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="删除" placement="top">
|
||||
<el-button icon="ele-Delete" text type="danger" @click="handleDelete(row)"> </el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="配置" placement="top">
|
||||
<el-button icon="ele-Setting" text type="danger" @click="handleConfig(row)">配置</el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="预览" placement="top">
|
||||
<el-button icon="ele-Camera" text type="primary" @click="handlePreview(row)">预览</el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="开始生成" placement="top">
|
||||
<el-button icon="ele-Cpu" text type="primary" @click="handleGenerate(row)">生成</el-button>
|
||||
</el-tooltip>
|
||||
<el-button icon="ele-Position" text type="primary" @click="handleGenerate(row)" title="生成" v-reclick="1000">生成</el-button>
|
||||
<el-button icon="ele-Camera" text type="primary" @click="handlePreview(row)" title="预览" v-reclick="1000">预览</el-button>
|
||||
<el-button icon="ele-Edit" text type="primary" @click="handleEdit(row)" title="编辑" v-reclick="1000">编辑</el-button>
|
||||
<el-button icon="ele-Delete" text type="danger" @click="handleDelete(row)" title="删除" v-reclick="1000">删除</el-button>
|
||||
<el-button icon="ele-CopyDocument" text type="primary" @click="handleCopy(row)" title="复制" v-reclick="1000">复制</el-button>
|
||||
</template>
|
||||
</vxe-grid>
|
||||
</el-card>
|
||||
|
||||
<EditCodeGenDialog ref="EditCodeGenRef" :title="state.title" :applicationNamespaces="state.applicationNamespaces" @handleQuery="handleQuery" />
|
||||
<CodeConfigDialog ref="CodeConfigRef" @handleQuery="handleQuery" />
|
||||
<PreviewDialog :title="state.title" ref="PreviewRef" />
|
||||
<EditCodeGenDialog ref="EditCodeGenRef" @handleQuery="handleQuery" />
|
||||
<PreviewDialog :title="state.title" ref="previewRef" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -77,21 +70,22 @@ import { onMounted, reactive, ref, defineAsyncComponent } from 'vue';
|
||||
import { ElMessageBox, ElMessage, ElNotification } from 'element-plus';
|
||||
import { VxeGridInstance, VxeGridListeners, VxeGridPropTypes } from 'vxe-table';
|
||||
import { useVxeTable } from '/@/hooks/useVxeTableOptionsHook';
|
||||
import { Local } from '/@/utils/storage';
|
||||
import { downloadByUrl } from '/@/utils/download';
|
||||
import { Local } from '/@/utils/storage';
|
||||
|
||||
import EditCodeGenDialog from './component/editCodeGenDialog.vue';
|
||||
import CodeConfigDialog from './component/genConfigDialog.vue';
|
||||
import { useCodeGenStore } from './component/codeGenStore';
|
||||
import ModifyRecord from '/@/components/table/modifyRecord.vue';
|
||||
|
||||
import { getAPI } from '/@/utils/axios-utils';
|
||||
import { SysCodeGenApi } from '/@/api-services/system/api';
|
||||
import { SysCodeGen, PageCodeGenInput } from '/@/api-services/system/models';
|
||||
|
||||
const PreviewDialog = defineAsyncComponent(() => import('./component/previewDialog.vue'));
|
||||
const store = useCodeGenStore();
|
||||
const xGrid = ref<VxeGridInstance>();
|
||||
const previewRef = ref<InstanceType<typeof PreviewDialog>>();
|
||||
const EditCodeGenRef = ref<InstanceType<typeof EditCodeGenDialog>>();
|
||||
const CodeConfigRef = ref<InstanceType<typeof CodeConfigDialog>>();
|
||||
const PreviewRef = ref<InstanceType<typeof PreviewDialog>>();
|
||||
const state = reactive({
|
||||
dbData: [] as any,
|
||||
configId: '',
|
||||
@ -103,7 +97,7 @@ const state = reactive({
|
||||
busName: undefined,
|
||||
},
|
||||
localPageParam: {
|
||||
pageSize: 50 as number,
|
||||
pageSize: 20 as number,
|
||||
defaultSort: { field: 'id', order: 'asc', descStr: 'desc' },
|
||||
},
|
||||
visible: false,
|
||||
@ -121,13 +115,14 @@ const options = useVxeTable<SysCodeGen>(
|
||||
columns: [
|
||||
// { type: 'checkbox', width: 40, fixed: 'left' },
|
||||
{ field: 'seq', type: 'seq', title: '序号', width: 60, fixed: 'left' },
|
||||
{ field: 'configId', title: '库定位器', minWidth: 200, showOverflow: 'tooltip' },
|
||||
{ field: 'tableName', title: '表名称', minWidth: 200, showOverflow: 'tooltip' },
|
||||
{ field: 'busName', title: '业务名', minWidth: 200, showOverflow: 'tooltip' },
|
||||
{ field: 'nameSpace', title: '命名空间', minWidth: 200, showOverflow: 'tooltip' },
|
||||
{ field: 'authorName', title: '作者姓名', minWidth: 200, showOverflow: 'tooltip' },
|
||||
{ field: 'generateType', title: '生成方式', minWidth: 140, showOverflow: 'tooltip', slots: { default: 'row_generateType' } },
|
||||
{ field: 'buttons', title: '操作', fixed: 'right', width: 280, showOverflow: true, slots: { default: 'row_buttons' } },
|
||||
{ field: 'busName', title: '业务名', align: 'left', minWidth: 120, showOverflow: 'tooltip' },
|
||||
{ field: 'scene', title: '模板场景', align: 'left', minWidth: 100, showOverflow: 'tooltip', slots: { default: 'row_scene' } },
|
||||
{ field: 'entityName', title: '主表实体', align: 'left', minWidth: 120, showOverflow: 'tooltip', slots: { default: 'row_entityName' } },
|
||||
{ field: 'nameSpace', title: '命名空间', align: 'left', showOverflow: 'tooltip' },
|
||||
{ field: 'generateMethod', title: '生成方式', align: 'left', showOverflow: 'tooltip', slots: { default: 'row_generateMethod' } },
|
||||
{ field: 'authorName', title: '作者姓名', align: 'left', showOverflow: 'tooltip' },
|
||||
{ field: 'record', title: '修改记录', width: 100, showOverflow: 'tooltip', slots: { default: 'row_record' } },
|
||||
{ field: 'buttons', title: '操作', fixed: 'right', width: 300, showOverflow: true, slots: { default: 'row_buttons' } },
|
||||
],
|
||||
},
|
||||
// vxeGrid配置参数(此处可覆写任何参数),参考vxe-table官方文档
|
||||
@ -139,17 +134,14 @@ const options = useVxeTable<SysCodeGen>(
|
||||
// 分页配置
|
||||
pagerConfig: { pageSize: Local.get(localPageParamKey)?.pageSize || state.localPageParam.pageSize },
|
||||
// 工具栏配置
|
||||
toolbarConfig: { export: true },
|
||||
toolbarConfig: { export: false },
|
||||
}
|
||||
);
|
||||
|
||||
// 页面初始化
|
||||
onMounted(async () => {
|
||||
state.localPageParam = Local.get(localPageParamKey) || state.localPageParam;
|
||||
|
||||
// 获取命名空间集合
|
||||
let res = await getAPI(SysCodeGenApi).apiSysCodeGenApplicationNamespacesGet();
|
||||
state.applicationNamespaces = res.data.result as Array<string>;
|
||||
store.init();
|
||||
});
|
||||
|
||||
// 查询api
|
||||
@ -174,26 +166,39 @@ const resetQuery = async () => {
|
||||
|
||||
// 打开新增页面
|
||||
const handleAdd = () => {
|
||||
state.title = '增加代码生成';
|
||||
EditCodeGenRef.value?.openDialog({
|
||||
authorName: 'Admin.NET',
|
||||
template: 'template',
|
||||
generateType: '200',
|
||||
printType: 'off',
|
||||
generateMethod: 200,
|
||||
printType: 1,
|
||||
menuIcon: 'ele-Menu',
|
||||
pagePath: 'main',
|
||||
configObj: {},
|
||||
nameSpace: state.applicationNamespaces[0],
|
||||
generateMenu: false,
|
||||
isApiService: false,
|
||||
isApiService: true,
|
||||
// scene: 1000,
|
||||
});
|
||||
};
|
||||
|
||||
// 打开编辑页面
|
||||
const handleEdit = (row: any) => {
|
||||
state.title = '编辑代码生成';
|
||||
EditCodeGenRef.value?.openDialog(row);
|
||||
};
|
||||
|
||||
// 打开复制页面
|
||||
const handleCopy = async (row: any) => {
|
||||
const data = await store.getDetail(row.id);
|
||||
if (data) {
|
||||
data.moduleName = undefined;
|
||||
data.tableList?.forEach((e) => {
|
||||
e.columnList?.forEach((c) => delete c.id);
|
||||
delete e.id;
|
||||
});
|
||||
delete data.id;
|
||||
}
|
||||
EditCodeGenRef.value?.openDialog(data);
|
||||
};
|
||||
|
||||
// 删除
|
||||
const handleDelete = (row: any) => {
|
||||
ElMessageBox.confirm(`确定删除吗?`, '提示', {
|
||||
@ -202,7 +207,7 @@ const handleDelete = (row: any) => {
|
||||
type: 'warning',
|
||||
})
|
||||
.then(async () => {
|
||||
await getAPI(SysCodeGenApi).apiSysCodeGenDeletePost([{ id: row.id }]);
|
||||
await getAPI(SysCodeGenApi).apiSysCodeGenDeletePost({ id: row.id });
|
||||
await handleQuery();
|
||||
ElMessage.success('操作成功');
|
||||
})
|
||||
@ -221,26 +226,17 @@ const gridEvents: VxeGridListeners<SysCodeGen> = {
|
||||
state.localPageParam.defaultSort = { field: field, order: order!, descStr: 'desc' };
|
||||
Local.set(localPageParamKey, state.localPageParam);
|
||||
},
|
||||
// 双击行事件
|
||||
async cellDblclick({ row }) {
|
||||
await handleEdit(row);
|
||||
},
|
||||
};
|
||||
|
||||
// 打开配置
|
||||
const handleConfig = (row: any) => {
|
||||
CodeConfigRef.value?.openDialog(row);
|
||||
};
|
||||
|
||||
// 开始生成代码
|
||||
const handleGenerate = (row: any) => {
|
||||
ElMessageBox.confirm(`确定要生成【${row.tableName}】表吗?`, '提示', {
|
||||
ElMessageBox.confirm(`确定要生成【${row.busName}】吗?`, '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
})
|
||||
.then(async () => {
|
||||
var res = await getAPI(SysCodeGenApi).apiSysCodeGenRunLocalPost(row);
|
||||
const res = await getAPI(SysCodeGenApi).apiSysCodeGenGeneratePost(row);
|
||||
if (res.data.result != null && res.data.result.url != null) downloadByUrl({ url: res.data.result.url });
|
||||
await handleQuery();
|
||||
|
||||
@ -257,6 +253,6 @@ const handleGenerate = (row: any) => {
|
||||
// 预览代码
|
||||
const handlePreview = (row: any) => {
|
||||
state.title = '预览代码';
|
||||
PreviewRef.value?.openDialog(row);
|
||||
previewRef.value?.openDialog(row);
|
||||
};
|
||||
</script>
|
||||
|
||||
@ -359,6 +359,7 @@ const showPreviewDialog = async (row: any) => {
|
||||
} else {
|
||||
ElMessage.error('此文件格式不支持预览');
|
||||
}
|
||||
state.loading = false;
|
||||
};
|
||||
|
||||
// 获取文件地址
|
||||
|
||||
@ -30,7 +30,7 @@
|
||||
:data="state.allApiData"
|
||||
:filter-node-method="filterNode"
|
||||
node-key="route"
|
||||
:props="{ children: 'children', label: 'text' }"
|
||||
:props="{ children: 'children', label: 'desc' }"
|
||||
show-checkbox
|
||||
icon="ele-Menu"
|
||||
highlight-current
|
||||
|
||||
@ -65,6 +65,7 @@
|
||||
<el-button icon="ele-Coin" size="small" text type="danger" @click="createTenantData(row)" :v-auth="'sysTenant/createDb'" v-if="row.tenantType === 0"> 创建租户数据 </el-button>
|
||||
<el-button icon="ele-Coin" size="small" text type="danger" @click="createTenantDb(row)" :v-auth="'sysTenant/createDb'" v-else> 创建租户库表 </el-button>
|
||||
<el-button icon="ele-Menu" size="small" text type="primary" @click="openGrantMenu(row)" v-auth="'sysTenant/grantMenu'"> 授权菜单 </el-button>
|
||||
<el-button icon="ele-Position" text type="success" v-auth="'sysTenant/goLoginUser'" @click="goUserLogin(row)">{{ $t('message.list.goTenantUserLogin') }}</el-button>
|
||||
<el-button icon="ele-Link" size="small" text type="primary" @click="openGrantApi(row)"> 接口黑名单 </el-button>
|
||||
</template>
|
||||
</vxe-grid>
|
||||
@ -93,6 +94,7 @@ import ModifyRecord from '/@/components/table/modifyRecord.vue';
|
||||
import { getAPI } from '/@/utils/axios-utils';
|
||||
import { SysTenantApi } from '/@/api-services/system/api';
|
||||
import { PageTenantInput, TenantOutput } from '/@/api-services/system/models';
|
||||
import { reLoadLoginAccessToken } from '/@/utils/request';
|
||||
|
||||
const xGrid = ref<VxeGridInstance>();
|
||||
const editTenantRef = ref<InstanceType<typeof EditTenant>>();
|
||||
@ -310,4 +312,17 @@ const syncTenantDb = () => {
|
||||
})
|
||||
.catch(() => {});
|
||||
};
|
||||
|
||||
// 进入用户端
|
||||
const goUserLogin = (row: any) => {
|
||||
ElMessageBox.confirm(`确定要进入【${row.realName}】用户端?`, '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
}).then(() =>
|
||||
getAPI(SysTenantApi)
|
||||
.apiSysTenantGoLoginUserPost({ id: row.id })
|
||||
.then((res) => reLoadLoginAccessToken(res.data.result))
|
||||
);
|
||||
};
|
||||
</script>
|
||||
|
||||
@ -88,6 +88,9 @@
|
||||
<el-tooltip :content="$t('message.list.copy')" placement="top">
|
||||
<el-button icon="ele-CopyDocument" text type="primary" v-auth="'sysUser/add'" @click="openCopyMenu(row)"> </el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip :content="$t('message.list.goUserLogin')" placement="top">
|
||||
<el-button icon="ele-Position" text type="success" v-auth="'sysTenant/goLoginUser'" @click="goUserLogin(row)"> </el-button>
|
||||
</el-tooltip>
|
||||
|
||||
<el-button icon="ele-RefreshLeft" text type="danger" v-auth="'sysUser/resetPwd'" @click="resetQueryPwd(row)">{{ $t('message.list.resetPassword') }}</el-button>
|
||||
<el-button icon="ele-Unlock" text type="primary" v-auth="'sysUser/unlockLogin'" @click="handleUnlock(row)">{{ $t('message.list.unlockAccount') }}</el-button>
|
||||
@ -119,8 +122,9 @@ import EditUser from '/@/views/system/user/component/editUser.vue';
|
||||
import ModifyRecord from '/@/components/table/modifyRecord.vue';
|
||||
|
||||
import { getAPI } from '/@/utils/axios-utils';
|
||||
import { SysUserApi, SysOrgApi } from '/@/api-services/system/api';
|
||||
import { SysUserApi, SysOrgApi, SysTenantApi } from '/@/api-services/system/api';
|
||||
import { SysOrg, PageTenantInput, UserOutput, UpdateUserInput } from '/@/api-services/system/models';
|
||||
import { reLoadLoginAccessToken } from '/@/utils/request';
|
||||
|
||||
const { t } = useI18n();
|
||||
const xGrid = ref<VxeGridInstance>();
|
||||
@ -334,4 +338,17 @@ const handleNodeChange = async (node: any) => {
|
||||
state.queryParams.phone = undefined;
|
||||
await handleQuery();
|
||||
};
|
||||
|
||||
// 进入用户端
|
||||
const goUserLogin = (row: any) => {
|
||||
ElMessageBox.confirm(`确定要进入【${row.realName}】用户端?`, '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
}).then(() =>
|
||||
getAPI(SysTenantApi)
|
||||
.apiSysTenantGoLoginUserPost({ id: row.id })
|
||||
.then((res) => reLoadLoginAccessToken(res.data.result))
|
||||
);
|
||||
};
|
||||
</script>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user