新增加代码生成功能

This commit is contained in:
不做码农 2022-04-17 22:14:09 +08:00
parent 05418644f4
commit bf5ee4d39e
7 changed files with 1053 additions and 7 deletions

View File

@ -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. 参数管理:对系统动态配置常用参数。
## 计划
- [ ] 服务监控
- [ ] 代码生成
- [ ] 文章管理
- [ ] 任务系统
- [ ] 控制台
## 🎉优势

View File

@ -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",

View 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>

View 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>

View 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="egsystem: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>

View 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>

View File

@ -1,3 +1,274 @@
<template>
敬请期待...
</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 || '&nbsp;'
}
/** 复制代码成功 */
function clipboardSuccess() {
proxy.$modal.msgSuccess('复制成功')
}
function cancel() {
showGenerate.value = false
currentSelected.value = {}
}
getList()
</script>