新增加代码生成功能
This commit is contained in:
parent
05418644f4
commit
bf5ee4d39e
12
README.md
12
README.md
@ -49,7 +49,6 @@ yarn dev
|
||||
|
||||
|
||||
## 🍖内置功能
|
||||
目前只开发了以下功能,其他功能陆续开发中...
|
||||
|
||||
1. 用户管理:用户是系统操作者,该功能主要完成系统用户配置。
|
||||
2. 部门管理:配置系统组织机构(公司、部门、小组),树结构展现。
|
||||
@ -61,12 +60,15 @@ yarn dev
|
||||
7. 登录日志:系统登录日志记录查询包含登录异常。
|
||||
8. 系统接口:使用swagger生成相关api接口文档。
|
||||
9. 参数设置:常用参数配置
|
||||
10. 发送邮件:可以对多个用户进行发送邮件
|
||||
11. 任务系统:基于Quartz.NET,可以在线(添加、修改、删除、手动执行)任务调度包含执行结果日志。
|
||||
12. 文章管理:可以写文章记录。
|
||||
13. 代码生成:可以一键生成前后端代码(.cs、.vue、.js、SQL文件等),支持下载,自定义配置前端展示控件、让开发更快捷高效。
|
||||
14. 文件管理:可以进行上传文件管理,目前支持上传到本地、阿里云
|
||||
15. 通知管理:系统通知公告信息发布维护
|
||||
16. 参数管理:对系统动态配置常用参数。
|
||||
|
||||
## 计划
|
||||
- [ ] 服务监控
|
||||
- [ ] 代码生成
|
||||
- [ ] 文章管理
|
||||
- [ ] 任务系统
|
||||
- [ ] 控制台
|
||||
|
||||
## 🎉优势
|
||||
|
||||
@ -22,6 +22,7 @@
|
||||
"element-plus": "^2.1.8",
|
||||
"file-saver": "2.0.5",
|
||||
"fuse.js": "6.4.6",
|
||||
"highlight.js": "^11.5.1",
|
||||
"js-cookie": "3.0.1",
|
||||
"jsencrypt": "3.2.1",
|
||||
"mavon-editor": "^2.10.4",
|
||||
|
||||
61
src/views/tool/gen/basicInfoForm.vue
Normal file
61
src/views/tool/gen/basicInfoForm.vue
Normal file
@ -0,0 +1,61 @@
|
||||
<template>
|
||||
<el-form ref="basicInfoForm" :model="info" :rules="rules" label-width="100px">
|
||||
<el-row>
|
||||
<el-col :lg="6">
|
||||
<el-form-item label="表名称" prop="tableName">
|
||||
<el-input placeholder="请输入仓库名称" v-model="info.tableName" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :lg="6">
|
||||
<el-form-item label="表描述" prop="tableComment">
|
||||
<el-input placeholder="请输入" v-model="info.tableComment" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :lg="6">
|
||||
<el-form-item label="实体类名称" prop="className">
|
||||
<el-input placeholder="请输入" v-model="info.className" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :lg="6">
|
||||
<el-form-item label="作者" prop="functionAuthor">
|
||||
<el-input placeholder="请输入" v-model="info.functionAuthor" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :lg="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" }
|
||||
],
|
||||
functionAuthor: [
|
||||
{ required: true, message: "请输入作者", trigger: "blur" }
|
||||
]
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
</script>
|
||||
216
src/views/tool/gen/editTable.vue
Normal file
216
src/views/tool/gen/editTable.vue
Normal file
@ -0,0 +1,216 @@
|
||||
<template>
|
||||
<el-card>
|
||||
<el-tabs v-model="activeName" tab-position="top">
|
||||
<el-tab-pane label="基本信息" name="basic">
|
||||
<basic-info-form ref="basicInfo" :info="info" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="生成信息" name="genInfo">
|
||||
<gen-info-form ref="genInfo" :info="info" :tables="tables" :columns="columns" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="字段信息" name="cloum">
|
||||
<el-table ref="dragTable" v-loading="loading" :data="columns" row-key="columnId" :max-height="tableHeight">
|
||||
<el-table-column label="序号" type="index" min-width="5%" class-name="allowDrag" />
|
||||
<el-table-column label="字段列名" prop="columnName" min-width="10%" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="字段描述" prop="columnComment" min-width="10%">
|
||||
<template #default="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="C#类型" min-width="11%">
|
||||
<template #default="scope">
|
||||
<el-select v-model="scope.row.csharpType">
|
||||
<el-option label="int" value="int" />
|
||||
<el-option label="long" value="long" />
|
||||
<el-option label="string" value="string" />
|
||||
<el-option label="double" value="double" />
|
||||
<el-option label="decimal" value="decimal" />
|
||||
<el-option label="DateTime" value="DateTime" />
|
||||
<el-option label="bool" value="bool" />
|
||||
</el-select>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="C#属性" min-width="10%">
|
||||
<template #default="scope">
|
||||
<el-input v-model="scope.row.csharpField"></el-input>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="插入" min-width="5%" v-if="info.tplCategory != 'select'">
|
||||
<template #default="scope">
|
||||
<el-checkbox v-model="scope.row.isInsert" :disabled="scope.row.isIncrement"></el-checkbox>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="编辑" min-width="5%" v-if="info.tplCategory != 'select'">
|
||||
<template #default="scope">
|
||||
<el-checkbox v-model="scope.row.isEdit" :disabled="scope.row.isPk || scope.row.isIncrement"></el-checkbox>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="列表" min-width="5%">
|
||||
<template #default="scope">
|
||||
<el-checkbox v-model="scope.row.isList"></el-checkbox>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="查询" min-width="5%">
|
||||
<template #default="scope">
|
||||
<el-checkbox v-model="scope.row.isQuery" :disabled="scope.row.htmlType == 'imageUpload' || scope.row.htmlType == 'fileUpload'">
|
||||
</el-checkbox>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="查询方式" min-width="10%">
|
||||
<template #default="scope">
|
||||
<el-select v-model="scope.row.queryType" :disabled="scope.row.htmlType == 'datetime'" v-if="scope.row.isQuery">
|
||||
<el-option label="=" value="EQ" />
|
||||
<el-option label="!=" value="NE" />
|
||||
<el-option label=">" value="GT" />
|
||||
<el-option label=">=" value="GTE" />
|
||||
<el-option label="<" value="LT" />
|
||||
<el-option label="<=" value="LTE" />
|
||||
<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 #default="scope">
|
||||
<el-checkbox v-model="scope.row.isRequired"></el-checkbox>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="表单显示类型" min-width="12%">
|
||||
<template #default="scope">
|
||||
<el-select v-model="scope.row.htmlType">
|
||||
<el-option label="文本框" value="input" />
|
||||
<el-option label="数字框" value="inputNumber" />
|
||||
<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-option label="自定义输入框" value="customInput" />
|
||||
</el-select>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="字典类型" min-width="12%">
|
||||
<template #default="scope">
|
||||
<el-select v-model="scope.row.dictType" clearable filterable placeholder="请选择"
|
||||
v-if="scope.row.htmlType == 'select' || scope.row.htmlType == 'radio' || scope.row.htmlType =='checkbox'">
|
||||
<el-option v-for="dict in dictOptions" :key="dict.dictType" :label="dict.dictName" :value="dict.dictType">
|
||||
<span style="float: left">{{ dict.dictName }}</span>
|
||||
<span style="float: right; color: #8492a6; font-size: 13px">{{ dict.dictType }}</span>
|
||||
</el-option>
|
||||
</el-select>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</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" icon="check" @click="submitForm()">提交</el-button>
|
||||
<el-button type="success" icon="refresh" @click="handleQuery()">刷新</el-button>
|
||||
<el-button icon="back" @click="close()">返回</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
</template>
|
||||
<script setup name="genedit">
|
||||
import { updateGenTable, getGenTable } from '@/api/tool/gen'
|
||||
import { listType } from '@/api/system/dict/type'
|
||||
import basicInfoForm from './basicInfoForm'
|
||||
import genInfoForm from './genInfoForm'
|
||||
import { getCurrentInstance, reactive } from 'vue-demi'
|
||||
import { useRoute } from 'vue-router'
|
||||
// import Sortable from 'sortablejs'
|
||||
|
||||
// 选中选项卡的 name
|
||||
const activeName = ref('cloum')
|
||||
// 表格的高度
|
||||
const tableHeight = ref(document.documentElement.scrollHeight - 245 + 'px')
|
||||
// 表信息
|
||||
const tables = ref([])
|
||||
// 表列信息
|
||||
const columns = ref([])
|
||||
// 字典信息
|
||||
const dictOptions = ref([])
|
||||
// 表详细信息
|
||||
const info = ref({})
|
||||
const loading = ref(true)
|
||||
|
||||
const route = useRoute()
|
||||
const { proxy } = getCurrentInstance()
|
||||
|
||||
function handleQuery() {
|
||||
const tableId = route.query && route.query.tableId
|
||||
|
||||
if (tableId) {
|
||||
// 获取表详细信息
|
||||
getGenTable(tableId).then((res) => {
|
||||
loading.value = false
|
||||
columns.value = res.data.info.columns
|
||||
info.value = res.data.info
|
||||
tables.value = res.data.tables // 子表
|
||||
})
|
||||
}
|
||||
}
|
||||
/** 提交按钮 */
|
||||
function submitForm() {
|
||||
const basicForm = proxy.$refs.basicInfo.$refs.basicInfoForm
|
||||
const genForm = proxy.$refs.genInfo.$refs.genInfoForm
|
||||
|
||||
Promise.all([basicForm, genForm].map(getFormPromise)).then((res) => {
|
||||
const validateResult = res.every((item) => !!item)
|
||||
|
||||
if (validateResult) {
|
||||
const genTable = Object.assign({}, info.value)
|
||||
genTable.columns = this.columns
|
||||
|
||||
// 额外参数拼接
|
||||
genTable.params = {
|
||||
treeCode: info.value.treeCode,
|
||||
treeName: info.value.treeName,
|
||||
treeParentCode: info.value.treeParentCode,
|
||||
parentMenuId: info.value.parentMenuId,
|
||||
sortField: info.value.sortField,
|
||||
sortType: info.value.sortType,
|
||||
checkedBtn: info.value.checkedBtn?.toString(),
|
||||
permissionPrefix: info.value.permissionPrefix,
|
||||
}
|
||||
console.log('genForm', genTable)
|
||||
|
||||
updateGenTable(genTable).then((res) => {
|
||||
proxy.$modal.msgSuccess(res.msg)
|
||||
if (res.code === 200) {
|
||||
close()
|
||||
}
|
||||
})
|
||||
} else {
|
||||
proxy.$modal.msgError('表单校验未通过,请重新检查提交内容')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function getFormPromise(form) {
|
||||
return new Promise((resolve) => {
|
||||
form.validate((res) => {
|
||||
resolve(res)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/** 查询字典下拉列表 */
|
||||
listType({ pageSize: 100 }).then((response) => {
|
||||
dictOptions.value = response.data.result
|
||||
})
|
||||
/** 关闭按钮 */
|
||||
function close() {
|
||||
const obj = {
|
||||
path: '/tool/gen',
|
||||
query: { t: Date.now(), pageNum: route.query.pageNum },
|
||||
}
|
||||
proxy.$tab.closeOpenPage(obj)
|
||||
}
|
||||
handleQuery()
|
||||
</script>
|
||||
371
src/views/tool/gen/genInfoForm.vue
Normal file
371
src/views/tool/gen/genInfoForm.vue
Normal file
@ -0,0 +1,371 @@
|
||||
<template>
|
||||
<el-form ref="genInfoForm" :model="info" :rules="rules" label-width="150px">
|
||||
<el-row>
|
||||
<el-col :lg="12">
|
||||
<el-form-item prop="tplCategory">
|
||||
<template #label>生成模板</template>
|
||||
<el-select v-model="info.tplCategory" @change="tplSelectChange">
|
||||
<el-option label="单表(增删改查)" value="crud" />
|
||||
<el-option label="单表查询" value="select" />
|
||||
<el-option label="树表(增删改查)" value="tree" />
|
||||
<!-- <el-option label="导航查询" value="subNav"></el-option> -->
|
||||
<!-- <el-option label="主子表(增删改查)" value="sub" /> -->
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :lg="12">
|
||||
<el-form-item prop="baseNameSpace">
|
||||
<template #label>
|
||||
生成命名空间前缀
|
||||
<el-tooltip content="比如 ZR." placement="top">
|
||||
<el-icon>
|
||||
<question-filled />
|
||||
</el-icon>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<el-input v-model="info.baseNameSpace" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :lg="12">
|
||||
<el-form-item prop="moduleName">
|
||||
<template #label>
|
||||
生成模块名
|
||||
<el-tooltip content="可理解为子系统名,例如 system、user、tool(一般文件夹归类)" placement="top">
|
||||
<el-icon>
|
||||
<question-filled />
|
||||
</el-icon>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<el-input v-model="info.moduleName" auto-complete="" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :lg="12">
|
||||
<el-form-item prop="businessName">
|
||||
<template #label>
|
||||
生成业务名
|
||||
<el-tooltip content="可理解为功能英文名,例如 user" placement="top">
|
||||
<el-icon>
|
||||
<question-filled />
|
||||
</el-icon>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<el-input v-model="info.businessName" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :lg="12">
|
||||
<el-form-item prop="functionName">
|
||||
<template #label>
|
||||
生成功能名
|
||||
<el-tooltip content="用作类描述,例如 用户,代码生成,文章系统" placement="top">
|
||||
<el-icon>
|
||||
<question-filled />
|
||||
</el-icon>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<el-input v-model="info.functionName" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :lg="12">
|
||||
<el-form-item>
|
||||
<template #label>
|
||||
上级菜单
|
||||
<el-tooltip content="分配到指定菜单下,例如 系统管理" placement="top">
|
||||
<el-icon>
|
||||
<question-filled />
|
||||
</el-icon>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<tree-select v-model:value="info.parentMenuId" :options="menuOptions" :show-count="true"
|
||||
:objMap="{ value: 'menuId', label: 'menuName', children: 'children' }" placeholder="选择上级菜单" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :lg="12">
|
||||
<el-form-item label="查询排序字段">
|
||||
<el-select v-model="info.sortField" placeholder="请选择字段" class="mr10" clearable="">
|
||||
<el-option v-for="item in columns" :key="item.columnId" :label="item.csharpField" :value="item.csharpField">
|
||||
</el-option>
|
||||
</el-select>
|
||||
|
||||
<el-radio v-model="info.sortType" label="asc">正序</el-radio>
|
||||
<el-radio v-model="info.sortType" label="desc">倒序</el-radio>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :lg="12">
|
||||
<el-form-item prop="permissionPrefix">
|
||||
<template #label>
|
||||
权限前缀
|
||||
<el-tooltip content="eg:system:user:add中的'system:user'" placement="top">
|
||||
<el-icon>
|
||||
<question-filled />
|
||||
</el-icon>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<el-input v-model="info.permissionPrefix" placeholder="请输入权限前缀"></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :lg="12">
|
||||
<el-form-item prop="genType">
|
||||
<template #label>
|
||||
生成代码方式
|
||||
<el-tooltip content="默认为zip压缩包下载" placement="top">
|
||||
<el-icon>
|
||||
<question-filled />
|
||||
</el-icon>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<el-radio v-model="info.genType" label="0">zip压缩包</el-radio>
|
||||
<el-radio v-model="info.genType" label="1">自定义路径</el-radio>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :lg="24" v-if="info.genType == '1'">
|
||||
<el-form-item prop="genPath">
|
||||
<template #label>
|
||||
自定义路径
|
||||
<el-tooltip content="填写磁盘绝对路径,若不填写,则生成到当前Web项目下" placement="top">
|
||||
<el-icon>
|
||||
<question-filled />
|
||||
</el-icon>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<el-input v-model="info.genPath">
|
||||
<template #append>
|
||||
<el-dropdown>
|
||||
<el-button type="primary">
|
||||
最近路径快速选择
|
||||
<el-icon>
|
||||
<question-filled />
|
||||
</el-icon>
|
||||
</el-button>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item @click="info.genPath = '/'">恢复默认的生成基础路径</el-dropdown-item>
|
||||
<el-dropdown-item @click="info.genPath = ''">本项目</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :lg="24" v-show="info.tplCategory != 'select'">
|
||||
<el-form-item label="显示按钮">
|
||||
<el-checkbox-group v-model="info.checkedBtn" @change="checkedBtnSelect">
|
||||
<el-checkbox :label="1">
|
||||
<el-tag>添加</el-tag>
|
||||
</el-checkbox>
|
||||
<el-checkbox :label="2">
|
||||
<el-tag type="success">修改</el-tag>
|
||||
</el-checkbox>
|
||||
<el-checkbox :label="3">
|
||||
<el-tag type="danger">删除</el-tag>
|
||||
</el-checkbox>
|
||||
<el-checkbox :label="4">
|
||||
<el-tag type="warning">导出</el-tag>
|
||||
</el-checkbox>
|
||||
</el-checkbox-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row v-show="info.tplCategory == 'tree'">
|
||||
<h4 class="form-header">其他信息</h4>
|
||||
<el-col :lg="12">
|
||||
<el-form-item>
|
||||
<template #label>
|
||||
树编码字段
|
||||
<el-tooltip content="树显示的编码字段名, 如:dept_id" placement="top">
|
||||
<el-icon>
|
||||
<question-filled />
|
||||
</el-icon>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<el-select v-model="info.treeCode" placeholder="请选择">
|
||||
<el-option v-for="(column, index) in columns" :key="index" :label="column.csharpField + ':' + column.columnComment"
|
||||
:value="column.csharpField"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :lg="12">
|
||||
<el-form-item>
|
||||
<template #label>
|
||||
树父编码字段
|
||||
<el-tooltip content="树显示的父编码字段名, 如:parent_Id" placement="top">
|
||||
<el-icon>
|
||||
<question-filled />
|
||||
</el-icon>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<el-select v-model="info.treeParentCode" placeholder="请选择">
|
||||
<el-option v-for="(column, index) in columns" :key="index" :label="column.csharpField + ':' + column.columnComment"
|
||||
:value="column.csharpField"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :lg="12">
|
||||
<el-form-item>
|
||||
<template label>
|
||||
树名称字段
|
||||
<el-tooltip content="树节点的显示名称字段名, 如:dept_name" placement="top">
|
||||
<el-icon>
|
||||
<question-filled />
|
||||
</el-icon>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<el-select v-model="info.treeName" placeholder="请选择">
|
||||
<el-option v-for="(column, index) in columns" :key="index" :label="column.csharpField + ':' + column.columnComment"
|
||||
:value="column.csharpField"></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 :lg="12">
|
||||
<el-form-item>
|
||||
<template #label>
|
||||
关联子表的表名
|
||||
<el-tooltip content="关联子表的表名, 如:sys_user" placement="top">
|
||||
<el-icon>
|
||||
<question-filled />
|
||||
</el-icon>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<el-select v-model="info.subTableName" placeholder="请选择" @change="subSelectChange(this)">
|
||||
<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 :lg="12">
|
||||
<el-form-item>
|
||||
<template #label>
|
||||
子表关联的外键名
|
||||
<el-tooltip content="子表关联的外键名, 如:user_id" placement="top">
|
||||
<el-icon>
|
||||
<question-filled />
|
||||
</el-icon>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<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 setup name="genInfoForm">
|
||||
import { listMenu } from '@/api/system/menu'
|
||||
import { queryColumnInfo } from '@/api/tool/gen'
|
||||
import { watch } from 'vue-demi'
|
||||
|
||||
const subColumns = ref([])
|
||||
const menuOptions = ref([])
|
||||
// const checkedBtn = ref([])
|
||||
const { proxy } = getCurrentInstance()
|
||||
|
||||
const props = defineProps({
|
||||
info: {
|
||||
type: Object,
|
||||
default: null,
|
||||
},
|
||||
// 字表
|
||||
tables: {
|
||||
type: Array,
|
||||
default: null,
|
||||
},
|
||||
// 列
|
||||
columns: {
|
||||
type: Array,
|
||||
default: [],
|
||||
},
|
||||
})
|
||||
// 表单校验
|
||||
const rules = ref({
|
||||
tplCategory: [{ required: true, message: '请选择生成模板', trigger: 'blur' }],
|
||||
moduleName: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入生成模块名',
|
||||
trigger: 'blur',
|
||||
pattern: /^[A-Za-z]+$/,
|
||||
},
|
||||
],
|
||||
businessName: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入生成业务名',
|
||||
trigger: 'blur',
|
||||
pattern: /^[A-Za-z]+$/,
|
||||
},
|
||||
],
|
||||
functionName: [
|
||||
{ required: true, message: '请输入生成功能名', trigger: 'blur' },
|
||||
],
|
||||
permissionPrefix: {
|
||||
required: true,
|
||||
message: '请输入权限前缀',
|
||||
trigger: 'blur',
|
||||
},
|
||||
})
|
||||
function subSelectChange(value) {
|
||||
props.info.subTableFkName = ''
|
||||
}
|
||||
function tplSelectChange(value) {
|
||||
if (value !== 'sub') {
|
||||
props.info.subTableName = ''
|
||||
props.info.subTableFkName = ''
|
||||
}
|
||||
}
|
||||
function setSubTableColumns(value) {
|
||||
if (value == null || value == undefined || value == '') {
|
||||
return
|
||||
}
|
||||
for (var item in props.tables) {
|
||||
const obj = props.tables[item]
|
||||
if (value === obj.tableName) {
|
||||
// subColumns.value = props.tables[item].columns
|
||||
queryColumnInfo(obj.tableId).then((res) => {
|
||||
if (res.code == 200) {
|
||||
subColumns.value = res.data.columns
|
||||
}
|
||||
})
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
/** 查询菜单下拉树结构 */
|
||||
function getMenuTreeselect() {
|
||||
/** 查询菜单下拉列表 */
|
||||
listMenu().then((response) => {
|
||||
menuOptions.value = response.data
|
||||
})
|
||||
}
|
||||
function checkedBtnSelect(value) {
|
||||
console.log(value)
|
||||
// checkedBtn.value = value
|
||||
}
|
||||
watch(
|
||||
() => props.info.subTableName,
|
||||
(val) => {
|
||||
setSubTableColumns(val)
|
||||
}
|
||||
)
|
||||
|
||||
// watch(
|
||||
// () => props.info.checkedBtn,
|
||||
// (val) => {
|
||||
// checkedBtn.value = val
|
||||
// }
|
||||
// )
|
||||
|
||||
getMenuTreeselect()
|
||||
</script>
|
||||
124
src/views/tool/gen/importTable.vue
Normal file
124
src/views/tool/gen/importTable.vue
Normal file
@ -0,0 +1,124 @@
|
||||
<template>
|
||||
<!-- 导入表 -->
|
||||
<el-dialog title="导入表" v-model="visible" width="900px" top="5vh" append-to-body>
|
||||
<el-form ref="queryRef" :inline="true" :rules="rules" :model="queryParams">
|
||||
<el-form-item label="数据库" prop="dbName">
|
||||
<el-select v-model="queryParams.dbName" clearable placeholder="请选择" @change="handleQuery">
|
||||
<el-option v-for="item in dbList" :key="item" :label="item" :value="item" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="表名">
|
||||
<el-input v-model="queryParams.tableName" clearable placeholder="输入要查询的表名" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="search" @click="handleQuery()">查询</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-row>
|
||||
<el-table ref="table" @row-click="clickRow" :data="dbTableList" highlight-current-row height="300px" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55"></el-table-column>
|
||||
<el-table-column prop="name" label="表名" sortable="custom" width="380" />
|
||||
<el-table-column prop="description" label="表描述" />
|
||||
</el-table>
|
||||
<pagination v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" v-model:total="total" @pagination="getList" />
|
||||
|
||||
</el-row>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button type="primary" @click="handleImportTable">确 定</el-button>
|
||||
<el-button @click="visible = false">取 消</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { listDbTable, importTable, codeGetDBList } from '@/api/tool/gen'
|
||||
import { reactive } from 'vue-demi'
|
||||
|
||||
const total = ref(0)
|
||||
const visible = ref(false)
|
||||
const tables = ref([])
|
||||
const dbTableList = ref([])
|
||||
const { proxy } = getCurrentInstance()
|
||||
// 数据库数据
|
||||
const dbList = ref([])
|
||||
const queryParams = reactive({
|
||||
dbName: '',
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
tableName: undefined,
|
||||
})
|
||||
const rules = reactive({
|
||||
dbName: [{ required: true, message: '请选择数据库名称', trigger: 'blur' }],
|
||||
})
|
||||
const emit = defineEmits(['ok'])
|
||||
|
||||
/** 查询参数列表 */
|
||||
function show() {
|
||||
getList()
|
||||
visible.value = true
|
||||
}
|
||||
/** 单击选择行 */
|
||||
function clickRow(row) {
|
||||
proxy.$refs.table.toggleRowSelection(row)
|
||||
}
|
||||
/** 多选框选中数据 */
|
||||
function handleSelectionChange(selection) {
|
||||
tables.value = selection.map((item) => item.name)
|
||||
console.log(tables.value)
|
||||
}
|
||||
/** 查询表数据 */
|
||||
function getList() {
|
||||
codeGetDBList().then((res) => {
|
||||
dbList.value = res.data.dbList
|
||||
})
|
||||
if (queryParams.dbName !== '') {
|
||||
listDbTable(queryParams).then((res) => {
|
||||
dbTableList.value = res.data.result
|
||||
total.value = res.data.totalNum
|
||||
})
|
||||
}
|
||||
}
|
||||
/** 搜索按钮操作 */
|
||||
function handleQuery() {
|
||||
queryParams.pageNum = 1
|
||||
getList()
|
||||
}
|
||||
/** 重置按钮操作 */
|
||||
function resetQuery() {
|
||||
proxy.resetForm('queryRef')
|
||||
handleQuery()
|
||||
}
|
||||
/** 导入按钮操作 */
|
||||
function handleImportTable() {
|
||||
// const tableNames = tables.value.join(',')
|
||||
// if (tableNames == '') {
|
||||
// proxy.$modal.msgError('请选择要导入的表')
|
||||
// return
|
||||
// }
|
||||
// importTable({ tables: tableNames }).then((res) => {
|
||||
// proxy.$modal.msgSuccess(res.msg)
|
||||
// if (res.code === 200) {
|
||||
// visible.value = false
|
||||
// emit('ok')
|
||||
// }
|
||||
// })
|
||||
console.log(JSON.stringify(tables.value))
|
||||
|
||||
importTable({
|
||||
tables: tables.value.join(','),
|
||||
dbName: queryParams.dbName,
|
||||
}).then((res) => {
|
||||
proxy.$modal.msgSuccess(res.msg)
|
||||
if (res.code === 200) {
|
||||
visible.value = false
|
||||
emit('ok')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
show,
|
||||
})
|
||||
</script>
|
||||
@ -1,3 +1,274 @@
|
||||
<template>
|
||||
敬请期待...
|
||||
<div class="app-container">
|
||||
|
||||
<el-form ref="codeform" :inline="true" :model="queryParams">
|
||||
<el-form-item label="表名" prop="tableName">
|
||||
<el-input v-model="queryParams.tableName" clearable placeholder="输入要查询的表名" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="search" @click="getList()">查询</el-button>
|
||||
<!-- <el-button type="default" icon="refresh" @click="loadTableData()">刷新</el-button> -->
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<el-row :gutter="10" class="mb10">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="info" plain icon="upload" @click="openImportTable" v-hasPermi="['tool:gen:import']">导入</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="danger" :disabled="multiple" plain icon="delete" @click="handleDelete" v-hasPermi="['tool:gen:remove']">
|
||||
删除</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-table ref="gridtable" v-loading="tableloading" :data="tableList" border @selection-change="handleSelectionChange" highlight-current-row
|
||||
height="480px">
|
||||
<el-table-column type="selection" align="center" width="55"></el-table-column>
|
||||
<el-table-column label="序号" type="index" width="50" align="center">
|
||||
<template #default="scope">
|
||||
<span>{{(queryParams.pageNum - 1) * queryParams.pageSize + scope.$index + 1}}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="dbName" label="数据库名" width="90" />
|
||||
<el-table-column prop="tableId" label="表id" width="70" sortable="" />
|
||||
<el-table-column prop="tableName" label="表名" width="110" :show-overflow-tooltip="true" />
|
||||
<el-table-column prop="tableComment" label="表描述" :show-overflow-tooltip="true" width="120" />
|
||||
<el-table-column prop="className" label="实体" :show-overflow-tooltip="true" />
|
||||
<el-table-column prop="createTime" label="创建时间" />
|
||||
<el-table-column prop="updateTime" label="更新时间" />
|
||||
<el-table-column label="操作" align="center" width="320">
|
||||
<template #default="scope">
|
||||
<el-button type="text" icon="view" @click="handlePreview(scope.row)" v-hasPermi="['tool:gen:preview']">预览</el-button>
|
||||
<el-button type="text" icon="edit" @click="handleEditTable(scope.row)" v-hasPermi="['tool:gen:edit']">编辑</el-button>
|
||||
<el-button type="text" icon="delete" @click="handleDelete(scope.row)" v-hasPermi="['tool:gen:remove']">删除</el-button>
|
||||
<el-button type="text" icon="refresh" @click="handleSynchDb(scope.row)" v-hasPermi="['tool:gen:edit']">同步</el-button>
|
||||
<el-button type="text" icon="download" @click="handleGenTable(scope.row)" v-hasPermi="['tool:gen:code']">生成代码
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<pagination :page="queryParams.pageNum" v-model:limit="queryParams.pageSize" v-model:total="total" @pagination="getList" />
|
||||
|
||||
<!-- 预览界面 -->
|
||||
<el-dialog :title="preview.title" v-model="preview.open" width="80%" top="5vh" append-to-body>
|
||||
<el-tabs v-model="preview.activeName">
|
||||
<el-tab-pane v-for="(item, key) in preview.data" :label="item.title" :name="key.toString()" :key="key">
|
||||
<el-link :underline="false" icon="document-copy" v-clipboard:copy="item.content" v-clipboard:success="clipboardSuccess" style="float:right">
|
||||
复制</el-link>
|
||||
<pre><code class="hljs" v-html="highlightedCode(item.content, item.title)"></code></pre>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</el-dialog>
|
||||
<import-table ref="importRef" @ok="getList" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="gen">
|
||||
import {
|
||||
codeGenerator,
|
||||
listTable,
|
||||
delTable,
|
||||
previewTable,
|
||||
synchDb,
|
||||
} from '@/api/tool/gen'
|
||||
import { useRouter } from 'vue-router'
|
||||
import importTable from './importTable'
|
||||
import hljs from 'highlight.js'
|
||||
import 'highlight.js/styles/idea.css' // 这里有多个样式,自己可以根据需要切换
|
||||
|
||||
// const route = useRoute()
|
||||
const router = useRouter()
|
||||
const { proxy } = getCurrentInstance()
|
||||
|
||||
const tableList = ref([])
|
||||
const tableloading = ref(true)
|
||||
const showSearch = ref(true)
|
||||
const tableIds = ref([])
|
||||
const single = ref(true)
|
||||
const multiple = ref(true)
|
||||
const total = ref(0)
|
||||
const tableNames = ref([])
|
||||
const dateRange = ref([])
|
||||
const uniqueId = ref('')
|
||||
const showGenerate = ref(false)
|
||||
// 选中行的表
|
||||
const currentSelected = ref({})
|
||||
|
||||
const data = reactive({
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
tableName: undefined,
|
||||
// tableComment: undefined,
|
||||
},
|
||||
preview: {
|
||||
open: false,
|
||||
title: '代码预览',
|
||||
data: {},
|
||||
activeName: '0',
|
||||
},
|
||||
})
|
||||
|
||||
const { queryParams, preview } = toRefs(data)
|
||||
|
||||
// onActivated(() => {
|
||||
// const time = route.query.t
|
||||
// if (time != null && time != uniqueId.value) {
|
||||
// uniqueId.value = time
|
||||
// queryParams.value.pageNum = Number(route.query.pageNum)
|
||||
// dateRange.value = []
|
||||
// proxy.resetForm('queryForm')
|
||||
// getList()
|
||||
// }
|
||||
// })
|
||||
|
||||
/** 查询表集合 */
|
||||
function getList() {
|
||||
tableloading.value = true
|
||||
listTable(proxy.addDateRange(queryParams.value, dateRange.value)).then(
|
||||
(response) => {
|
||||
tableList.value = response.data.result
|
||||
total.value = response.data.totalNum
|
||||
tableloading.value = false
|
||||
}
|
||||
)
|
||||
}
|
||||
/** 搜索按钮操作 */
|
||||
function handleQuery() {
|
||||
queryParams.value.pageNum = 1
|
||||
getList()
|
||||
}
|
||||
/** 生成代码操作 */
|
||||
function handleGenTable(row) {
|
||||
currentSelected.value = row
|
||||
if (!currentSelected.value) {
|
||||
proxy.$modal.msgError('请先选择要生成代码的数据表')
|
||||
return false
|
||||
}
|
||||
proxy.$refs['codeform'].validate((valid) => {
|
||||
if (valid) {
|
||||
proxy.$modal.loading('正在生成代码...')
|
||||
|
||||
var seachdata = {
|
||||
tableId: currentSelected.value.tableId,
|
||||
tableName: currentSelected.value.name,
|
||||
}
|
||||
|
||||
codeGenerator(seachdata)
|
||||
.then((res) => {
|
||||
const { data } = res
|
||||
showGenerate.value = false
|
||||
if (row.genType === '1') {
|
||||
proxy.$modal.msgSuccess('成功生成到自定义路径')
|
||||
} else {
|
||||
proxy.$modal.msgSuccess('恭喜你,代码生成完成!')
|
||||
proxy.download(data.path)
|
||||
}
|
||||
proxy.$modal.closeLoading()
|
||||
})
|
||||
.catch((erre) => {
|
||||
proxy.$modal.closeLoading()
|
||||
})
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
})
|
||||
}
|
||||
/** 同步数据库操作 */
|
||||
function handleSynchDb(row) {
|
||||
const tableName = row.tableName
|
||||
proxy
|
||||
.$confirm('确认要强制同步"' + tableName + '"表结构吗?')
|
||||
.then(function () {
|
||||
return synchDb(row.tableId, { tableName, dbName: row.dbName })
|
||||
})
|
||||
.then(() => {
|
||||
proxy.$modal.msgSuccess('同步成功')
|
||||
})
|
||||
.catch(() => {})
|
||||
}
|
||||
/** 打开导入表弹窗 */
|
||||
function openImportTable() {
|
||||
proxy.$refs['importRef'].show()
|
||||
}
|
||||
/** 重置按钮操作 */
|
||||
function resetQuery() {
|
||||
dateRange.value = []
|
||||
proxy.resetForm('queryParams')
|
||||
handleQuery()
|
||||
}
|
||||
/** 预览按钮 */
|
||||
function handlePreview(row) {
|
||||
proxy.$refs['codeform'].validate((valid) => {
|
||||
if (!valid) {
|
||||
proxy.$modal.msgError('请先完成表格')
|
||||
return
|
||||
}
|
||||
proxy.$modal.loading('请稍后...')
|
||||
previewTable(row.tableId).then((res) => {
|
||||
if (res.code === 200) {
|
||||
showGenerate.value = false
|
||||
preview.value.open = true
|
||||
preview.value.data = res.data
|
||||
proxy.$modal.closeLoading()
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
// 多选框选中数据
|
||||
function handleSelectionChange(selection) {
|
||||
tableIds.value = selection.map((item) => item.tableId)
|
||||
// tableNames.value = selection.map((item) => item.tableName)
|
||||
// single.value = selection.length != 1
|
||||
multiple.value = !selection.length
|
||||
}
|
||||
/** 编辑表格 */
|
||||
function handleEditTable(row) {
|
||||
queryParams.value.tableName = row.tableName
|
||||
getList()
|
||||
|
||||
router.push({
|
||||
path: '/gen/editTable',
|
||||
query: { tableId: row.tableId },
|
||||
})
|
||||
}
|
||||
/** 删除按钮操作 */
|
||||
function handleDelete(row) {
|
||||
const tableIds = row.tableId || tableIds.value
|
||||
proxy
|
||||
.$confirm('此操作将永久删除该文件, 是否继续?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
})
|
||||
.then(() => {
|
||||
delTable(tableIds.toString()).then((res) => {
|
||||
if (res.code == 200) {
|
||||
proxy.$modal.msgSuccess('删除成功')
|
||||
|
||||
handleQuery()
|
||||
}
|
||||
})
|
||||
})
|
||||
.catch(() => {
|
||||
proxy.$message({
|
||||
type: 'info',
|
||||
message: '已取消删除',
|
||||
})
|
||||
})
|
||||
}
|
||||
/** 高亮显示 */
|
||||
function highlightedCode(code, key) {
|
||||
// var language = key.substring(key.lastIndexOf(".") , key.length)
|
||||
const result = hljs.highlightAuto(code || '')
|
||||
return result.value || ' '
|
||||
}
|
||||
/** 复制代码成功 */
|
||||
function clipboardSuccess() {
|
||||
proxy.$modal.msgSuccess('复制成功')
|
||||
}
|
||||
function cancel() {
|
||||
showGenerate.value = false
|
||||
currentSelected.value = {}
|
||||
}
|
||||
getList()
|
||||
</script>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user