mirror of
https://gitee.com/hhyykk/ipms-sjy.git
synced 2025-07-15 19:45:06 +08:00
将 tool 合并到 infra 模块
This commit is contained in:
61
yudao-ui-admin/src/views/infra/codegen/basicInfoForm.vue
Normal file
61
yudao-ui-admin/src/views/infra/codegen/basicInfoForm.vue
Normal file
@ -0,0 +1,61 @@
|
||||
<template>
|
||||
<el-form ref="basicInfoForm" :model="info" :rules="rules" label-width="150px">
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="表名称" prop="tableName">
|
||||
<el-input placeholder="请输入仓库名称" v-model="info.tableName" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="表描述" prop="tableComment">
|
||||
<el-input placeholder="请输入" v-model="info.tableComment" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="12">
|
||||
<el-form-item label="实体类名称" prop="className">
|
||||
<el-input placeholder="请输入" v-model="info.className" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="作者" prop="author">
|
||||
<el-input placeholder="请输入" v-model="info.author" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="备注" prop="remark">
|
||||
<el-input type="textarea" :rows="3" v-model="info.remark"></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: "BasicInfoForm",
|
||||
props: {
|
||||
info: {
|
||||
type: Object,
|
||||
default: null
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
rules: {
|
||||
tableName: [
|
||||
{ required: true, message: "请输入表名称", trigger: "blur" }
|
||||
],
|
||||
tableComment: [
|
||||
{ required: true, message: "请输入表描述", trigger: "blur" }
|
||||
],
|
||||
className: [
|
||||
{ required: true, message: "请输入实体类名称", trigger: "blur" }
|
||||
],
|
||||
author: [
|
||||
{ required: true, message: "请输入作者", trigger: "blur" }
|
||||
]
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
</script>
|
235
yudao-ui-admin/src/views/infra/codegen/editTable.vue
Normal file
235
yudao-ui-admin/src/views/infra/codegen/editTable.vue
Normal file
@ -0,0 +1,235 @@
|
||||
<template>
|
||||
<el-card>
|
||||
<el-tabs v-model="activeName">
|
||||
<el-tab-pane label="基本信息" name="basic">
|
||||
<basic-info-form ref="basicInfo" :info="table" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="字段信息" name="cloum">
|
||||
<el-table ref="dragTable" :data="columns" row-key="columnId" :max-height="tableHeight">
|
||||
<el-table-column
|
||||
label="字段列名"
|
||||
prop="columnName"
|
||||
min-width="10%"
|
||||
:show-overflow-tooltip="true"
|
||||
/>
|
||||
<el-table-column label="字段描述" min-width="10%">
|
||||
<template slot-scope="scope">
|
||||
<el-input v-model="scope.row.columnComment"></el-input>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="物理类型"
|
||||
prop="columnType"
|
||||
min-width="10%"
|
||||
:show-overflow-tooltip="true"
|
||||
/>
|
||||
<el-table-column label="Java类型" min-width="11%">
|
||||
<template slot-scope="scope">
|
||||
<el-select v-model="scope.row.javaType">
|
||||
<el-option label="Long" value="Long" />
|
||||
<el-option label="String" value="String" />
|
||||
<el-option label="Integer" value="Integer" />
|
||||
<el-option label="Double" value="Double" />
|
||||
<el-option label="BigDecimal" value="BigDecimal" />
|
||||
<el-option label="Date" value="Date" />
|
||||
<el-option label="Boolean" value="Boolean" />
|
||||
</el-select>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="java属性" min-width="10%">
|
||||
<template slot-scope="scope">
|
||||
<el-input v-model="scope.row.javaField"></el-input>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="插入" min-width="4%">
|
||||
<template slot-scope="scope">
|
||||
<el-checkbox true-label="true" false-label="false" v-model="scope.row.createOperation"></el-checkbox>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="编辑" min-width="4%">
|
||||
<template slot-scope="scope">
|
||||
<el-checkbox true-label="true" false-label="false" v-model="scope.row.updateOperation"></el-checkbox>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="列表" min-width="4%">
|
||||
<template slot-scope="scope">
|
||||
<el-checkbox true-label="true" false-label="false" v-model="scope.row.listOperationResult"></el-checkbox>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="查询" min-width="4%">
|
||||
<template slot-scope="scope">
|
||||
<el-checkbox true-label="true" false-label="false" v-model="scope.row.listOperation"></el-checkbox>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="查询方式" min-width="10%">
|
||||
<template slot-scope="scope">
|
||||
<el-select v-model="scope.row.listOperationCondition">
|
||||
<el-option label="=" value="=" />
|
||||
<el-option label="!=" value="!=" />
|
||||
<el-option label=">" value=">" />
|
||||
<el-option label=">=" value=">=" />
|
||||
<el-option label="<" value="<>" />
|
||||
<el-option label="<=" value="<=" />
|
||||
<el-option label="LIKE" value="LIKE" />
|
||||
<el-option label="BETWEEN" value="BETWEEN" />
|
||||
</el-select>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="允许空" min-width="5%">
|
||||
<template slot-scope="scope">
|
||||
<el-checkbox true-label="true" false-label="false" v-model="scope.row.nullable"></el-checkbox>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="显示类型" min-width="12%">
|
||||
<template slot-scope="scope">
|
||||
<el-select v-model="scope.row.htmlType">
|
||||
<el-option label="文本框" value="input" />
|
||||
<el-option label="文本域" value="textarea" />
|
||||
<el-option label="下拉框" value="select" />
|
||||
<el-option label="单选框" value="radio" />
|
||||
<el-option label="复选框" value="checkbox" />
|
||||
<el-option label="日期控件" value="datetime" />
|
||||
<el-option label="图片上传" value="imageUpload" />
|
||||
<el-option label="文件上传" value="fileUpload" />
|
||||
<el-option label="富文本控件" value="editor" />
|
||||
</el-select>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="字典类型" min-width="12%">
|
||||
<template slot-scope="scope">
|
||||
<el-select v-model="scope.row.dictType" clearable filterable placeholder="请选择">
|
||||
<el-option
|
||||
v-for="dict in dictOptions"
|
||||
:key="dict.id"
|
||||
:label="dict.name"
|
||||
:value="dict.type"
|
||||
/>
|
||||
</el-select>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="示例" min-width="10%">
|
||||
<template slot-scope="scope">
|
||||
<el-input v-model="scope.row.example"></el-input>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="生成信息" name="genInfo">
|
||||
<gen-info-form ref="genInfo" :info="table" :tables="tables" :menus="menus"/>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
<el-form label-width="100px">
|
||||
<el-form-item style="text-align: center;margin-left:-100px;margin-top:10px;">
|
||||
<el-button type="primary" @click="submitForm()">提交</el-button>
|
||||
<el-button @click="close()">返回</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
</template>
|
||||
<script>
|
||||
import { getCodegenDetail, updateCodegen } from "@/api/infra/codegen";
|
||||
import { listAllSimple as listAllSimpleDictType } from "@/api/system/dict/type";
|
||||
import { listSimpleMenus } from "@/api/system/menu";
|
||||
import basicInfoForm from "./basicInfoForm";
|
||||
import genInfoForm from "./genInfoForm";
|
||||
import Sortable from 'sortablejs'
|
||||
|
||||
export default {
|
||||
name: "GenEdit",
|
||||
components: {
|
||||
basicInfoForm,
|
||||
genInfoForm
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 选中选项卡的 name
|
||||
activeName: "cloum",
|
||||
// 表格的高度
|
||||
tableHeight: document.documentElement.scrollHeight - 245 + "px",
|
||||
// 表信息
|
||||
tables: [],
|
||||
// 表列信息
|
||||
columns: [],
|
||||
// 字典信息
|
||||
dictOptions: [],
|
||||
// 菜单信息
|
||||
menus: [],
|
||||
// 表详细信息
|
||||
table: {}
|
||||
};
|
||||
},
|
||||
created() {
|
||||
const tableId = this.$route.params && this.$route.params.tableId;
|
||||
if (tableId) {
|
||||
// 获取表详细信息
|
||||
getCodegenDetail(tableId).then(res => {
|
||||
this.table = res.data.table;
|
||||
this.columns = res.data.columns;
|
||||
});
|
||||
/** 查询字典下拉列表 */
|
||||
listAllSimpleDictType().then(response => {
|
||||
this.dictOptions = response.data;
|
||||
});
|
||||
/** 查询菜单下拉列表 */
|
||||
listSimpleMenus().then(response => {
|
||||
this.menus = [];
|
||||
this.menus.push(...this.handleTree(response.data, "id"));
|
||||
});
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
/** 提交按钮 */
|
||||
submitForm() {
|
||||
const basicForm = this.$refs.basicInfo.$refs.basicInfoForm;
|
||||
const genForm = this.$refs.genInfo.$refs.genInfoForm;
|
||||
Promise.all([basicForm, genForm].map(this.getFormPromise)).then(res => {
|
||||
const validateResult = res.every(item => !!item);
|
||||
if (validateResult) {
|
||||
const genTable = {};
|
||||
genTable.table = Object.assign({}, basicForm.model, genForm.model);
|
||||
genTable.columns = this.columns;
|
||||
genTable.params = {
|
||||
treeCode: genTable.treeCode,
|
||||
treeName: genTable.treeName,
|
||||
treeParentCode: genTable.treeParentCode,
|
||||
parentMenuId: genTable.parentMenuId
|
||||
};
|
||||
updateCodegen(genTable).then(res => {
|
||||
this.$modal.msgSuccess("修改成功!");
|
||||
this.close();
|
||||
});
|
||||
} else {
|
||||
this.$modal.msgError("表单校验未通过,请重新检查提交内容");
|
||||
}
|
||||
});
|
||||
},
|
||||
getFormPromise(form) {
|
||||
return new Promise(resolve => {
|
||||
form.validate(res => {
|
||||
resolve(res);
|
||||
});
|
||||
});
|
||||
},
|
||||
/** 关闭按钮 */
|
||||
close() {
|
||||
this.$tab.closeOpenPage({
|
||||
path: "/infra/codegen",
|
||||
query: { t: Date.now(), pageNum: this.$route.query.pageNum } }
|
||||
);
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
const el = this.$refs.dragTable.$el.querySelectorAll(".el-table__body-wrapper > table > tbody")[0];
|
||||
const sortable = Sortable.create(el, {
|
||||
handle: ".allowDrag",
|
||||
onEnd: evt => {
|
||||
const targetRow = this.columns.splice(evt.oldIndex, 1)[0];
|
||||
this.columns.splice(evt.newIndex, 0, targetRow);
|
||||
for (let index in this.columns) {
|
||||
this.columns[index].sort = parseInt(index) + 1;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
</script>
|
327
yudao-ui-admin/src/views/infra/codegen/genInfoForm.vue
Normal file
327
yudao-ui-admin/src/views/infra/codegen/genInfoForm.vue
Normal file
@ -0,0 +1,327 @@
|
||||
<template>
|
||||
<el-form ref="genInfoForm" :model="info" :rules="rules" label-width="150px">
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-form-item prop="templateType">
|
||||
<span slot="label">生成模板</span>
|
||||
<el-select v-model="info.templateType" @change="tplSelectChange">
|
||||
<el-option v-for="dict in this.getDictDatas(DICT_TYPE.INFRA_CODEGEN_TEMPLATE_TYPE)"
|
||||
:key="parseInt(dict.value)" :label="dict.label" :value="parseInt(dict.value)"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item prop="scene">
|
||||
<span slot="label">生成场景</span>
|
||||
<el-select v-model="info.scene">
|
||||
<el-option v-for="dict in this.getDictDatas(DICT_TYPE.INFRA_CODEGEN_SCENE)"
|
||||
:key="parseInt(dict.value)" :label="dict.label" :value="parseInt(dict.value)"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<!-- <el-col :span="12">-->
|
||||
<!-- <el-form-item prop="packageName">-->
|
||||
<!-- <span slot="label">-->
|
||||
<!-- 生成包路径-->
|
||||
<!-- <el-tooltip content="生成在哪个java包下,例如 com.ruoyi.system" placement="top">-->
|
||||
<!-- <i class="el-icon-question"></i>-->
|
||||
<!-- </el-tooltip>-->
|
||||
<!-- </span>-->
|
||||
<!-- <el-input v-model="info.packageName" />-->
|
||||
<!-- </el-form-item>-->
|
||||
<!-- </el-col>-->
|
||||
|
||||
<el-col :span="12">
|
||||
<el-form-item prop="moduleName">
|
||||
<span slot="label">
|
||||
模块名
|
||||
<el-tooltip content="模块名,即一级目录,例如 system、infra、tool 等等" placement="top">
|
||||
<i class="el-icon-question"></i>
|
||||
</el-tooltip>
|
||||
</span>
|
||||
<el-input v-model="info.moduleName" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="12">
|
||||
<el-form-item prop="businessName">
|
||||
<span slot="label">
|
||||
业务名
|
||||
<el-tooltip content="业务名,即二级目录,例如 user、permission、dict 等等" placement="top">
|
||||
<i class="el-icon-question"></i>
|
||||
</el-tooltip>
|
||||
</span>
|
||||
<el-input v-model="info.businessName" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<!-- <el-col :span="12">-->
|
||||
<!-- <el-form-item prop="businessPackage">-->
|
||||
<!-- <span slot="label">-->
|
||||
<!-- 业务包-->
|
||||
<!-- <el-tooltip content="业务包,自定义二级目录。例如说,我们希望将 dictType 和 dictData 归类成 dict 业务" placement="top">-->
|
||||
<!-- <i class="el-icon-question"></i>-->
|
||||
<!-- </el-tooltip>-->
|
||||
<!-- </span>-->
|
||||
<!-- <el-input v-model="info.businessPackage" />-->
|
||||
<!-- </el-form-item>-->
|
||||
<!-- </el-col>-->
|
||||
|
||||
<el-col :span="12">
|
||||
<el-form-item prop="className">
|
||||
<span slot="label">
|
||||
类名称
|
||||
<el-tooltip content="类名称(首字母大写),例如SysUser、SysMenu、SysDictData 等等" placement="top">
|
||||
<i class="el-icon-question"></i>
|
||||
</el-tooltip>
|
||||
</span>
|
||||
<el-input v-model="info.className" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="12">
|
||||
<el-form-item prop="classComment">
|
||||
<span slot="label">
|
||||
类描述
|
||||
<el-tooltip content="用作类描述,例如 用户" placement="top">
|
||||
<i class="el-icon-question"></i>
|
||||
</el-tooltip>
|
||||
</span>
|
||||
<el-input v-model="info.classComment" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="12">
|
||||
<el-form-item>
|
||||
<span slot="label">
|
||||
上级菜单
|
||||
<el-tooltip content="分配到指定菜单下,例如 系统管理" placement="top">
|
||||
<i class="el-icon-question"></i>
|
||||
</el-tooltip>
|
||||
</span>
|
||||
<treeselect :append-to-body="true" v-model="info.parentMenuId" :options="menus"
|
||||
:normalizer="normalizer" :show-count="true" placeholder="请选择系统菜单" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24" v-if="info.genType == '1'">
|
||||
<el-form-item prop="genPath">
|
||||
<span slot="label">
|
||||
自定义路径
|
||||
<el-tooltip content="填写磁盘绝对路径,若不填写,则生成到当前Web项目下" placement="top">
|
||||
<i class="el-icon-question"></i>
|
||||
</el-tooltip>
|
||||
</span>
|
||||
<el-input v-model="info.genPath">
|
||||
<el-dropdown slot="append">
|
||||
<el-button type="primary">
|
||||
最近路径快速选择
|
||||
<i class="el-icon-arrow-down el-icon--right"></i>
|
||||
</el-button>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item @click.native="info.genPath = '/'">恢复默认的生成基础路径</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row v-show="info.tplCategory == 'tree'">
|
||||
<h4 class="form-header">其他信息</h4>
|
||||
<el-col :span="12">
|
||||
<el-form-item>
|
||||
<span slot="label">
|
||||
树编码字段
|
||||
<el-tooltip content="树显示的编码字段名, 如:dept_id" placement="top">
|
||||
<i class="el-icon-question"></i>
|
||||
</el-tooltip>
|
||||
</span>
|
||||
<el-select v-model="info.treeCode" placeholder="请选择">
|
||||
<el-option
|
||||
v-for="(column, index) in info.columns"
|
||||
:key="index"
|
||||
:label="column.columnName + ':' + column.columnComment"
|
||||
:value="column.columnName"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item>
|
||||
<span slot="label">
|
||||
树父编码字段
|
||||
<el-tooltip content="树显示的父编码字段名, 如:parent_Id" placement="top">
|
||||
<i class="el-icon-question"></i>
|
||||
</el-tooltip>
|
||||
</span>
|
||||
<el-select v-model="info.treeParentCode" placeholder="请选择">
|
||||
<el-option
|
||||
v-for="(column, index) in info.columns"
|
||||
:key="index"
|
||||
:label="column.columnName + ':' + column.columnComment"
|
||||
:value="column.columnName"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item>
|
||||
<span slot="label">
|
||||
树名称字段
|
||||
<el-tooltip content="树节点的显示名称字段名, 如:dept_name" placement="top">
|
||||
<i class="el-icon-question"></i>
|
||||
</el-tooltip>
|
||||
</span>
|
||||
<el-select v-model="info.treeName" placeholder="请选择">
|
||||
<el-option
|
||||
v-for="(column, index) in info.columns"
|
||||
:key="index"
|
||||
:label="column.columnName + ':' + column.columnComment"
|
||||
:value="column.columnName"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row v-show="info.tplCategory == 'sub'">
|
||||
<h4 class="form-header">关联信息</h4>
|
||||
<el-col :span="12">
|
||||
<el-form-item>
|
||||
<span slot="label">
|
||||
关联子表的表名
|
||||
<el-tooltip content="关联子表的表名, 如:sys_user" placement="top">
|
||||
<i class="el-icon-question"></i>
|
||||
</el-tooltip>
|
||||
</span>
|
||||
<el-select v-model="info.subTableName" placeholder="请选择" @change="subSelectChange">
|
||||
<el-option
|
||||
v-for="(table, index) in tables"
|
||||
:key="index"
|
||||
:label="table.tableName + ':' + table.tableComment"
|
||||
:value="table.tableName"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item>
|
||||
<span slot="label">
|
||||
子表关联的外键名
|
||||
<el-tooltip content="子表关联的外键名, 如:user_id" placement="top">
|
||||
<i class="el-icon-question"></i>
|
||||
</el-tooltip>
|
||||
</span>
|
||||
<el-select v-model="info.subTableFkName" placeholder="请选择">
|
||||
<el-option
|
||||
v-for="(column, index) in subColumns"
|
||||
:key="index"
|
||||
:label="column.columnName + ':' + column.columnComment"
|
||||
:value="column.columnName"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</template>
|
||||
<script>
|
||||
import Treeselect from "@riophae/vue-treeselect";
|
||||
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
|
||||
|
||||
export default {
|
||||
name: "BasicInfoForm",
|
||||
components: { Treeselect },
|
||||
props: {
|
||||
info: {
|
||||
type: Object,
|
||||
default: null
|
||||
},
|
||||
tables: {
|
||||
type: Array,
|
||||
default: null
|
||||
},
|
||||
menus: {
|
||||
type: Array,
|
||||
default: []
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
subColumns: [],
|
||||
rules: {
|
||||
templateType: [
|
||||
{ required: true, message: "请选择生成模板", trigger: "blur" }
|
||||
],
|
||||
scene: [
|
||||
{ required: true, message: "请选择生成场景", trigger: "blur" }
|
||||
],
|
||||
// packageName: [
|
||||
// { required: true, message: "请输入生成包路径", trigger: "blur" }
|
||||
// ],
|
||||
moduleName: [
|
||||
{ required: true, message: "请输入生成模块名", trigger: "blur" }
|
||||
],
|
||||
businessName: [
|
||||
{ required: true, message: "请输入生成业务名", trigger: "blur" }
|
||||
],
|
||||
businessPackage: [
|
||||
{ required: true, message: "请输入生成业务包", trigger: "blur" }
|
||||
],
|
||||
className: [
|
||||
{ required: true, message: "请输入生成类名称", trigger: "blur" }
|
||||
],
|
||||
classComment: [
|
||||
{ required: true, message: "请输入生成类描述", trigger: "blur" }
|
||||
],
|
||||
}
|
||||
};
|
||||
},
|
||||
created() {},
|
||||
watch: {
|
||||
'info.subTableName': function(val) {
|
||||
this.setSubTableColumns(val);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
/** 转换菜单数据结构 */
|
||||
normalizer(node) {
|
||||
if (node.children && !node.children.length) {
|
||||
delete node.children;
|
||||
}
|
||||
return {
|
||||
id: node.id,
|
||||
label: node.name,
|
||||
children: node.children
|
||||
};
|
||||
},
|
||||
/** 选择子表名触发 */
|
||||
subSelectChange(value) {
|
||||
this.info.subTableFkName = '';
|
||||
},
|
||||
/** 选择生成模板触发 */
|
||||
tplSelectChange(value) {
|
||||
if (value !== 1) {
|
||||
// TODO 芋艿:暂时不考虑支持树形结构
|
||||
this.$modal.msgError('暂时不考虑支持【树形】和【主子表】的代码生成。原因是:导致 vm 模板过于复杂,不利于胖友二次开发');
|
||||
return false;
|
||||
}
|
||||
if(value !== 'sub') {
|
||||
this.info.subTableName = '';
|
||||
this.info.subTableFkName = '';
|
||||
}
|
||||
},
|
||||
/** 设置关联外键 */
|
||||
setSubTableColumns(value) {
|
||||
for (var item in this.tables) {
|
||||
const name = this.tables[item].tableName;
|
||||
if (value === name) {
|
||||
this.subColumns = this.tables[item].columns;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
106
yudao-ui-admin/src/views/infra/codegen/importTable.vue
Normal file
106
yudao-ui-admin/src/views/infra/codegen/importTable.vue
Normal file
@ -0,0 +1,106 @@
|
||||
<template>
|
||||
<!-- 导入表 -->
|
||||
<el-dialog title="导入表" :visible.sync="visible" width="800px" top="5vh" append-to-body>
|
||||
<el-form :model="queryParams" ref="queryForm" :inline="true">
|
||||
<el-form-item label="表名称" prop="tableName">
|
||||
<el-input
|
||||
v-model="queryParams.tableName"
|
||||
placeholder="请输入表名称"
|
||||
clearable
|
||||
size="small"
|
||||
@keyup.enter.native="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="表描述" prop="tableComment">
|
||||
<el-input
|
||||
v-model="queryParams.tableComment"
|
||||
placeholder="请输入表描述"
|
||||
clearable
|
||||
size="small"
|
||||
@keyup.enter.native="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-row>
|
||||
<el-table @row-click="clickRow" ref="table" :data="dbTableList" @selection-change="handleSelectionChange" height="260px">
|
||||
<el-table-column type="selection" width="55"></el-table-column>
|
||||
<el-table-column prop="tableSchema" label="数据库" :show-overflow-tooltip="true"></el-table-column>
|
||||
<el-table-column prop="tableName" label="表名称" :show-overflow-tooltip="true"></el-table-column>
|
||||
<el-table-column prop="tableComment" label="表描述" :show-overflow-tooltip="true"></el-table-column>
|
||||
<el-table-column prop="createTime" label="创建时间">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ parseTime(scope.row.createTime) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-row>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button type="primary" @click="handleImportTable">确 定</el-button>
|
||||
<el-button @click="visible = false">取 消</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getSchemaTableList, createCodegenListFromDB } from "@/api/infra/codegen";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
// 遮罩层
|
||||
visible: false,
|
||||
// 选中数组值
|
||||
tables: [],
|
||||
// 总条数
|
||||
total: 0,
|
||||
// 表数据
|
||||
dbTableList: [],
|
||||
// 查询参数
|
||||
queryParams: {
|
||||
tableName: undefined,
|
||||
tableComment: undefined
|
||||
}
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
// 显示弹框
|
||||
show() {
|
||||
this.getList();
|
||||
this.visible = true;
|
||||
},
|
||||
clickRow(row) {
|
||||
this.$refs.table.toggleRowSelection(row);
|
||||
},
|
||||
// 多选框选中数据
|
||||
handleSelectionChange(selection) {
|
||||
this.tables = selection.map(item => item.tableName);
|
||||
},
|
||||
// 查询表数据
|
||||
getList() {
|
||||
getSchemaTableList(this.queryParams).then(res => {
|
||||
this.dbTableList = res.data;
|
||||
});
|
||||
},
|
||||
/** 搜索按钮操作 */
|
||||
handleQuery() {
|
||||
this.getList();
|
||||
},
|
||||
/** 重置按钮操作 */
|
||||
resetQuery() {
|
||||
this.resetForm("queryForm");
|
||||
this.handleQuery();
|
||||
},
|
||||
/** 导入按钮操作 */
|
||||
handleImportTable() {
|
||||
createCodegenListFromDB(this.tables.join(",")).then(res => {
|
||||
this.$modal.msgSuccess("导入成功");
|
||||
this.visible = false;
|
||||
this.$emit("ok");
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
376
yudao-ui-admin/src/views/infra/codegen/index.vue
Normal file
376
yudao-ui-admin/src/views/infra/codegen/index.vue
Normal file
@ -0,0 +1,376 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<!-- 操作工作栏 -->
|
||||
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
|
||||
<el-form-item label="表名称" prop="tableName">
|
||||
<el-input v-model="queryParams.tableName" placeholder="请输入表名称" clearable size="small"
|
||||
@keyup.enter.native="handleQuery"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="表描述" prop="tableComment">
|
||||
<el-input v-model="queryParams.tableComment" placeholder="请输入表描述" clearable size="small"
|
||||
@keyup.enter.native="handleQuery"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="创建时间">
|
||||
<el-date-picker v-model="dateRange" size="small" style="width: 240px" value-format="yyyy-MM-dd" type="daterange"
|
||||
range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期"/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<!-- 操作工作栏 -->
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="info" plain icon="el-icon-upload" size="mini" @click="openImportTable"
|
||||
v-hasPermi="['infra:codegen:create']">基于 DB 导入</el-button>
|
||||
<el-button type="info" plain icon="el-icon-upload" size="mini" @click="openImportSQL"
|
||||
v-hasPermi="['infra:codegen:create']">基于 SQL 导入</el-button>
|
||||
</el-col>
|
||||
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
|
||||
<!-- 列表 -->
|
||||
<el-table v-loading="loading" :data="tableList">
|
||||
<el-table-column label="表名称" align="center" prop="tableName" :show-overflow-tooltip="true" width="200"/>
|
||||
<el-table-column label="表描述" align="center" prop="tableComment" :show-overflow-tooltip="true" width="120"/>
|
||||
<el-table-column label="实体" align="center" prop="className" :show-overflow-tooltip="true" width="200"/>
|
||||
<el-table-column label="创建时间" align="center" prop="createTime" width="160">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ parseTime(scope.row.createTime) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="更新时间" align="center" prop="createTime" width="160">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ parseTime(scope.row.updateTime) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||
<template slot-scope="scope">
|
||||
<el-button type="text" size="small" icon="el-icon-view" @click="handlePreview(scope.row)" v-hasPermi="['infra:codegen:preview']">预览</el-button>
|
||||
<el-button type="text" size="small" icon="el-icon-edit" @click="handleEditTable(scope.row)" v-hasPermi="['infra:codegen:update']">编辑</el-button>
|
||||
<el-button type="text" size="small" icon="el-icon-delete" @click="handleDelete(scope.row)" v-hasPermi="['infra:codegen:delete']">删除</el-button>
|
||||
<el-button type="text" size="small" icon="el-icon-refresh" @click="handleSynchDb(scope.row)" v-hasPermi="['infra:codegen:update']">同步</el-button>
|
||||
<el-button type="text" size="small" icon="el-icon-download" @click="handleGenTable(scope.row)" v-hasPermi="['infra:codegen:download']">生成代码</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<pagination v-show="total>0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize" @pagination="getList"/>
|
||||
|
||||
<!-- 预览界面 -->
|
||||
<el-dialog :title="preview.title" :visible.sync="preview.open" width="90%" top="5vh" append-to-body class="scrollbar">
|
||||
<el-row>
|
||||
<el-col :span="7">
|
||||
<el-tree :data="preview.fileTree" :expand-on-click-node="false" default-expand-all highlight-current
|
||||
@node-click="handleNodeClick"/>
|
||||
</el-col>
|
||||
<el-col :span="17">
|
||||
<el-tabs v-model="preview.activeName">
|
||||
<el-tab-pane v-for="item in preview.data" :label="item.filePath.substring(item.filePath.lastIndexOf('/') + 1)"
|
||||
:name="item.filePath" :key="item.filePath">
|
||||
<el-link :underline="false" icon="el-icon-document-copy" v-clipboard:copy="item.code" v-clipboard:success="clipboardSuccess" style="float:right">复制</el-link>
|
||||
<pre><code class="hljs" v-html="highlightedCode(item)"></code></pre>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 基于 DB 导入 -->
|
||||
<import-table ref="import" @ok="handleQuery" />
|
||||
|
||||
<!-- 基于 SQL 导入 -->
|
||||
<el-dialog :title="importSQL.title" :visible.sync="importSQL.open" width="800px" append-to-body>
|
||||
<el-form ref="importSQLForm" :model="importSQL.form" :rules="importSQL.rules" label-width="120px">
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="建表 SQL 语句" prop="sql">
|
||||
<el-input v-model="importSQL.form.sql" type="textarea" rows="30" style="width: 650px;" placeholder="请输入建 SQL 语句" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button type="primary" @click="submitImportSQLForm">确 定</el-button>
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getCodegenTablePage, previewCodegen, downloadCodegen, deleteCodegen,
|
||||
syncCodegenFromDB, syncCodegenFromSQL, createCodegenListFromSQL } from "@/api/infra/codegen";
|
||||
|
||||
import importTable from "./importTable";
|
||||
// 代码高亮插件
|
||||
import hljs from "highlight.js/lib/highlight";
|
||||
import "highlight.js/styles/github-gist.css";
|
||||
hljs.registerLanguage("java", require("highlight.js/lib/languages/java"));
|
||||
hljs.registerLanguage("xml", require("highlight.js/lib/languages/xml"));
|
||||
hljs.registerLanguage("html", require("highlight.js/lib/languages/xml"));
|
||||
hljs.registerLanguage("vue", require("highlight.js/lib/languages/xml"));
|
||||
hljs.registerLanguage("javascript", require("highlight.js/lib/languages/javascript"));
|
||||
hljs.registerLanguage("sql", require("highlight.js/lib/languages/sql"));
|
||||
|
||||
export default {
|
||||
name: "Codegen",
|
||||
components: { importTable },
|
||||
data() {
|
||||
return {
|
||||
// 遮罩层
|
||||
loading: true,
|
||||
// 唯一标识符
|
||||
uniqueId: "",
|
||||
// 选中表数组
|
||||
tableNames: [],
|
||||
// 显示搜索条件
|
||||
showSearch: true,
|
||||
// 总条数
|
||||
total: 0,
|
||||
// 表数据
|
||||
tableList: [],
|
||||
// 日期范围
|
||||
dateRange: "",
|
||||
// 查询参数
|
||||
queryParams: {
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
tableName: undefined,
|
||||
tableComment: undefined
|
||||
},
|
||||
// 预览参数
|
||||
preview: {
|
||||
open: false,
|
||||
title: "代码预览",
|
||||
fileTree: [],
|
||||
data: {},
|
||||
activeName: "",
|
||||
},
|
||||
// 基于 SQL 导入
|
||||
importSQL: {
|
||||
open: false,
|
||||
title: "",
|
||||
form: {
|
||||
|
||||
},
|
||||
rules: {
|
||||
sql: [{ required: true, message: "SQL 不能为空", trigger: "blur" }]
|
||||
}
|
||||
}
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.getList();
|
||||
},
|
||||
activated() {
|
||||
const time = this.$route.query.t;
|
||||
if (time != null && time !== this.uniqueId) {
|
||||
this.uniqueId = time;
|
||||
this.resetQuery();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
/** 查询表集合 */
|
||||
getList() {
|
||||
this.loading = true;
|
||||
getCodegenTablePage(this.addDateRange(this.queryParams, [
|
||||
this.dateRange[0] ? this.dateRange[0] + ' 00:00:00' : undefined,
|
||||
this.dateRange[1] ? this.dateRange[1] + ' 23:59:59' : undefined,
|
||||
], 'CreateTime')).then(response => {
|
||||
this.tableList = response.data.list;
|
||||
this.total = response.data.total;
|
||||
this.loading = false;
|
||||
}
|
||||
);
|
||||
},
|
||||
/** 搜索按钮操作 */
|
||||
handleQuery() {
|
||||
this.queryParams.pageNo = 1;
|
||||
this.getList();
|
||||
},
|
||||
/** 生成代码操作 */
|
||||
handleGenTable(row) {
|
||||
downloadCodegen(row.id).then(response => {
|
||||
this.$download.zip(response, 'codegen-' + row.tableName + '.zip');
|
||||
})
|
||||
},
|
||||
/** 同步数据库操作 */
|
||||
handleSynchDb(row) {
|
||||
// 基于 SQL 同步
|
||||
if (row.importType === 2) {
|
||||
this.importSQL.open = true;
|
||||
this.importSQL.form.tableId = row.id;
|
||||
return;
|
||||
}
|
||||
// 基于 DB 同步
|
||||
const tableName = row.tableName;
|
||||
this.$modal.confirm('确认要强制同步"' + tableName + '"表结构吗?').then(function() {
|
||||
return syncCodegenFromDB(row.id);
|
||||
}).then(() => {
|
||||
this.$modal.msgSuccess("同步成功");
|
||||
}).catch(() => {});
|
||||
},
|
||||
/** 打开导入表弹窗 */
|
||||
openImportTable() {
|
||||
this.$refs.import.show();
|
||||
},
|
||||
/** 打开 SQL 导入的弹窗 **/
|
||||
openImportSQL() {
|
||||
this.importSQL.open = true;
|
||||
},
|
||||
/** 重置按钮操作 */
|
||||
resetQuery() {
|
||||
this.dateRange = [];
|
||||
this.resetForm("queryForm");
|
||||
this.handleQuery();
|
||||
},
|
||||
/** 预览按钮 */
|
||||
handlePreview(row) {
|
||||
previewCodegen(row.id).then(response => {
|
||||
this.preview.data = response.data;
|
||||
let files = this.handleFiles(response.data);
|
||||
this.preview.fileTree = this.handleTree(files, "id", "parentId", "children",
|
||||
"/"); // "/" 为根节点
|
||||
// console.log(this.preview.fileTree)
|
||||
this.preview.activeName = response.data[0].filePath;
|
||||
this.preview.open = true;
|
||||
});
|
||||
},
|
||||
/** 高亮显示 */
|
||||
highlightedCode(item) {
|
||||
// const vmName = key.substring(key.lastIndexOf("/") + 1, key.indexOf(".vm"));
|
||||
// var language = vmName.substring(vmName.indexOf(".") + 1, vmName.length);
|
||||
var language = item.filePath.substring(item.filePath.lastIndexOf(".") + 1);
|
||||
const result = hljs.highlight(language, item.code || "", true);
|
||||
return result.value || ' ';
|
||||
},
|
||||
/** 复制代码成功 */
|
||||
clipboardSuccess(){
|
||||
this.$modal.msgSuccess("复制成功");
|
||||
},
|
||||
/** 生成 files 目录 **/
|
||||
handleFiles(datas) {
|
||||
let exists = {}; // key:file 的 id;value:true
|
||||
let files = [];
|
||||
// 遍历每个元素
|
||||
for (const data of datas) {
|
||||
let paths = data.filePath.split('/');
|
||||
let fullPath = ''; // 从头开始的路径,用于生成 id
|
||||
// 特殊处理 java 文件
|
||||
if (paths[paths.length - 1].indexOf('.java') >= 0) {
|
||||
let newPaths = [];
|
||||
for (let i = 0; i < paths.length; i++) {
|
||||
let path = paths[i];
|
||||
if (path !== 'java') {
|
||||
newPaths.push(path);
|
||||
continue;
|
||||
}
|
||||
newPaths.push(path);
|
||||
// 特殊处理中间的 package,进行合并
|
||||
let tmp = undefined;
|
||||
while (i < paths.length) {
|
||||
path = paths[i + 1];
|
||||
if (path === 'controller'
|
||||
|| path === 'convert'
|
||||
|| path === 'dal'
|
||||
|| path === 'enums'
|
||||
|| path === 'service'
|
||||
|| path === 'vo' // 下面三个,主要是兜底。可能考虑到有人改了包结构
|
||||
|| path === 'mysql'
|
||||
|| path === 'dataobject') {
|
||||
break;
|
||||
}
|
||||
tmp = tmp ? tmp + '.' + path : path;
|
||||
i++;
|
||||
}
|
||||
if (tmp) {
|
||||
newPaths.push(tmp);
|
||||
}
|
||||
}
|
||||
paths = newPaths;
|
||||
}
|
||||
// 遍历每个 path, 拼接成树
|
||||
for (let i = 0; i < paths.length; i++) {
|
||||
// 已经添加到 files 中,则跳过
|
||||
let oldFullPath = fullPath;
|
||||
// 下面的 replaceAll 的原因,是因为上面包处理了,导致和 tabs 不匹配,所以 replaceAll 下
|
||||
fullPath = fullPath.length === 0 ? paths[i] : fullPath.replaceAll('.', '/') + '/' + paths[i];
|
||||
if (exists[fullPath]) {
|
||||
continue;
|
||||
}
|
||||
// 添加到 files 中
|
||||
exists[fullPath] = true;
|
||||
files.push({
|
||||
id: fullPath,
|
||||
label: paths[i],
|
||||
parentId: oldFullPath || '/' // "/" 为根节点
|
||||
});
|
||||
}
|
||||
}
|
||||
return files;
|
||||
},
|
||||
/** 节点单击事件 **/
|
||||
handleNodeClick(data, node) {
|
||||
if (node && !node.isLeaf) {
|
||||
return false;
|
||||
}
|
||||
// 判断,如果非子节点,不允许选中
|
||||
this.preview.activeName = data.id;
|
||||
},
|
||||
/** 修改按钮操作 */
|
||||
handleEditTable(row) {
|
||||
const tableId = row.id;
|
||||
this.$router.push("/codegen/edit/" + tableId);
|
||||
},
|
||||
/** 删除按钮操作 */
|
||||
handleDelete(row) {
|
||||
const tableIds = row.id;
|
||||
this.$modal.confirm('是否确认删除表名称为"' + row.tableName + '"的数据项?').then(function() {
|
||||
return deleteCodegen(tableIds);
|
||||
}).then(() => {
|
||||
this.getList();
|
||||
this.$modal.msgSuccess("删除成功");
|
||||
}).catch(() => {});
|
||||
},
|
||||
// 取消按钮
|
||||
cancel() {
|
||||
this.importSQL.open = false;
|
||||
this.reset();
|
||||
},
|
||||
// 表单重置
|
||||
reset() {
|
||||
this.importSQL.form = {
|
||||
tableId: undefined,
|
||||
sql: undefined,
|
||||
};
|
||||
this.resetForm("importSQLForm");
|
||||
},
|
||||
// 提交 import SQL 表单
|
||||
submitImportSQLForm() {
|
||||
this.$refs["importSQLForm"].validate(valid => {
|
||||
if (!valid) {
|
||||
return;
|
||||
}
|
||||
// 修改的提交
|
||||
let form = this.importSQL.form;
|
||||
if (form.tableId != null) {
|
||||
syncCodegenFromSQL(form.tableId, form.sql).then(response => {
|
||||
this.$modal.msgSuccess("同步成功");
|
||||
this.importSQL.open = false;
|
||||
this.getList();
|
||||
});
|
||||
return;
|
||||
}
|
||||
// 添加的提交
|
||||
createCodegenListFromSQL(form).then(response => {
|
||||
this.$modal.msgSuccess("导入成功");
|
||||
this.importSQL.open = false;
|
||||
this.getList();
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
Reference in New Issue
Block a user