This commit is contained in:
clay
2024-03-04 19:13:43 +08:00
commit e44edd71c0
350 changed files with 52288 additions and 0 deletions

View File

@@ -0,0 +1,67 @@
<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="functionAuthor">
<el-input placeholder="请输入" v-model="info.functionAuthor"/>
</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 setup>
import {defineExpose, defineProps} from "vue";
const props = defineProps({
info: {
type: Object,
default: null
}
})
const basicInfoForm = ref()
const rules = ref({
tableName: [
{required: true, message: "请输入表名称", trigger: "blur"}
],
tableComment: [
{required: true, message: "请输入表描述", trigger: "blur"}
],
className: [
{required: true, message: "请输入实体类名称", trigger: "blur"}
],
functionAuthor: [
{required: true, message: "请输入作者", trigger: "blur"}
]
})
defineExpose({
basicInfoForm
})
</script>
<style scoped>
</style>

View File

@@ -0,0 +1,234 @@
<template>
<el-card style="margin-top: 15px">
<el-tabs v-model="activeName">
<el-tab-pane label="基本信息" name="info">
<basic-info-form :info="info" ref="infoRef"/>
</el-tab-pane>
<el-tab-pane label="字段信息" name="column">
<el-table ref="columnRef" :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="字段描述" 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="Java类型" min-width="11%">
<template #default="scope">
<el-select v-model="scope.row.javaType" filterable>
<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 #default="scope">
<el-input v-model="scope.row.javaField"></el-input>
</template>
</el-table-column>
<el-table-column label="插入" min-width="5%">
<template #default="scope">
<el-checkbox true-label="1" false-label="0" v-model="scope.row.isInsert"></el-checkbox>
</template>
</el-table-column>
<el-table-column label="编辑" min-width="5%">
<template #default="scope">
<el-checkbox true-label="1" false-label="0" v-model="scope.row.isEdit"></el-checkbox>
</template>
</el-table-column>
<el-table-column label="列表" min-width="5%">
<template #default="scope">
<el-checkbox true-label="1" false-label="0" v-model="scope.row.isList"></el-checkbox>
</template>
</el-table-column>
<el-table-column label="查询" min-width="5%">
<template #default="scope">
<el-checkbox true-label="1" false-label="0" v-model="scope.row.isQuery"></el-checkbox>
</template>
</el-table-column>
<el-table-column label="查询方式" min-width="10%">
<template #default="scope">
<el-select v-model="scope.row.queryType" filterable>
<el-option label="=" value="EQ"/>
<el-option label="!=" value="NE"/>
<el-option label=">" value="GT"/>
<el-option label=">=" value="GE"/>
<el-option label="<" value="LT"/>
<el-option label="<=" value="LE"/>
<el-option label="LIKE" value="LIKE"/>
<el-option label="BETWEEN" value="BETWEEN"/>
</el-select>
</template>
</el-table-column>
<el-table-column label="是否正则" min-width="10%">
<template #default="scope">
<el-select v-model="scope.row.isRegular" filterable>
<el-option v-for="item in regularOptions"
:key="item.value"
:label="item.label"
:value="item.value"/>
<span></span>
</el-select>
</template>
</el-table-column>
<el-table-column label="必填" min-width="5%">
<template #default="scope">
<el-checkbox true-label="1" false-label="0" 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" filterable>
<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 #default="scope">
<el-select v-model="scope.row.dictType" clearable filterable placeholder="请选择" >
<el-option
v-for="dict in dictOption"
:key="dict.value"
:label="dict.label"
:value="dict.value">
<span style="float: left">{{ dict.value }}</span>
<span style="float: right; color: #8492a6; font-size: 13px">{{ dict.label }}</span>
</el-option>
</el-select>
</template>
</el-table-column>
</el-table>
</el-tab-pane>
<el-tab-pane label="生成信息" name="table">
<table-info :table="tables" :info="info" :columns="columns" :option-info="optionInfo" :dict-options="dictOption" ref="tableRef"/>
</el-tab-pane>
<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-tabs>
</el-card>
</template>
<script setup>
import {getTableDetail, editCodeGen} from "@/api/rapid/code-gen";
import {getRegularOpt} from "@/api/rapid/regular";
import {getDictOption} from "@/api/system/dict-type";
import BasicInfoForm from "./basicInfoForm.vue"
import TableInfo from './tableInfo.vue'
import {ElMessage} from "element-plus";
const router = useRouter()
const params = reactive(router.currentRoute.value.params)
const activeName = ref("column")
const columns = ref([])
const info = ref([])
const regularOptions = ref([])
const tables = ref([])
const dictOption = ref([])
const optionInfo = ref()
const tableHeight = ref(document.documentElement.scrollHeight - 245 + 'px')
const getRegularOption = async () => {
getRegularOpt().then(res => {
if (res.code === 1000) {
let def = [{
value: 0,
label: "无"
}]
def.push(...res.data)
regularOptions.value = def
}
})
}
const getInfo = async () => {
getDictOption().then(res => {
if (res.code === 1000) {
dictOption.value = res.data
getDetail()
}
})
}
const submitForm = async () => {
const infoData = {...info.value}
infoData.optionInfo = {...optionInfo.value}
const obj = {
...infoData,
columns: [...columns.value]
}
await editCodeGen(obj).then(res => {
if (res.code === 1000) {
ElMessage.success(res.msg)
return
}
ElMessage.error(res.msg)
})
}
const getDetail = async () => {
getTableDetail(params.tableId).then(res => {
if (res.code === 1000) {
columns.value = res.data.columns
info.value = res.data.info
tables.value = res.data.tables
optionInfo.value = res.data.optionInfo
}else {
ElMessage.error(res.msg)
}
})
}
const close = async () => {
router.push({
path: '/rapid/gen',
})
}
const getFormPromise = async (form) => {
return new Promise(resolve => {
form.validate(res => {
resolve(res);
});
});
}
getRegularOption()
getInfo()
</script>
<style scoped>
</style>

View File

@@ -0,0 +1,185 @@
<template>
<el-dialog v-model="isVisited" title="导入表" width="1000px">
<el-form :model="queryParams" inline class="query-form" ref="dataSourceFrom" style="margin: 0">
<el-form-item label="数据源" prop="businessType">
<el-select v-model="queryParams.dataSourceId" placeholder="数据源" clearable filterable>
<el-option
v-for="item in dataSourceOption"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="表名称" prop="title">
<el-input v-model="queryParams.tableName" placeholder="请输入表名称" clearable></el-input>
</el-form-item>
<el-form-item label="表备注" prop="title">
<el-input v-model="queryParams.tableComment" placeholder="请输入表备注" clearable></el-input>
</el-form-item>
<el-form-item label="创建时间" prop="dateValue">
<el-config-provider>
<el-date-picker
v-model="queryParams"
type="daterange"
start-placeholder="开始日期"
end-placeholder="结束日期"
value-format="YYYY-MM-DD"
/>
</el-config-provider>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="searchTableSearch()" :icon="Search">搜索</el-button>
<el-button @click="handleReset" :icon="Refresh">重置</el-button>
</el-form-item>
</el-form>
<div class="table">
<el-table
:data="list"
row-key="operId"
:lazy="true"
ref="singleTable"
v-loading="loading"
@select="handleSelect"
>
<el-table-column type="selection" width="80"/>
<el-table-column prop="tableName" label="表名称" align="center"/>
<el-table-column prop="tableComment" label="表描述" align="center"/>
<el-table-column prop="createTime" label="创建时间" sortable align="center"/>
<el-table-column prop="updateTime" label="更新时间" sortable align="center"/>
<el-table-column label="操作">
<template #default="scope">
<el-button type="primary" size="mini" @click="handleImport(scope.row)" link>导入</el-button>
</template>
</el-table-column>
</el-table>
</div>
<paging :current-page="pageInfo.pageNum" :page-size="pageInfo.pageSize" :page-sizes="[10, 20, 30, 40,50]"
:total="total" @changeSize="handleSizeChange" @goPage="handleCurrentChange"/>
</el-dialog>
</template>
<script setup>
import {getDynamicTable, importTable} from "@/api/rapid/code-gen";
import {Search, Refresh, View} from '@element-plus/icons-vue'
import {ElMessage, ElMessageBox} from 'element-plus'
import {defineExpose, defineProps} from "vue";
import Paging from "@/components/pagination/index.vue";
const emit = defineEmits(['importSuccess'])
const queryParams = reactive({
dataSourceId: null,
tableName: '',
tableComment: '',
startTime: '',
endTime: ''
})
const pageInfo = reactive({
pageNum: 1,
pageSize: 10,
})
const list = ref([])
const dataSourceIds = ref()
const loading = ref(true)
const total = ref(0)
const isVisited = ref(false)
const props = defineProps({
dataSourceOption: {
type: Array,
default: []
},
queryId: {
type: Number,
default: 0
},
})
const searchTableSearch = async () => {
let params = {
...queryParams,
pageNum: pageInfo.pageNum,
pageSize: pageInfo.pageSize
}
loading.value = true
getDynamicTable(params).then(res => {
if (res.code === 1000) {
list.value = res.data.rows
total.value = res.data.total
loading.value = false
} else {
ElMessage.error(res.msg)
}
})
}
const handleImportTable = async (data) => {
importTable(data).then(res => {
if (res.code === 1000) {
ElMessage.success(res.msg)
isVisited.value = false
emit("importSuccess")
} else {
ElMessage.error(res.msg)
}
})
}
const handleImport = (item) => {
let data = {
dataSourceId: queryParams.dataSourceId,
tables: [item.tableName]
}
handleImportTable(data)
}
//勾选table数据行的 Checkbox
const handleSelect = async (selection, row) => {
if (selection.length !== 0) {
disabled.value = false
if (selection.length > 1) {
const del_row = selection.shift();
dataSourceIds.value.toggleRowSelection(del_row, false);
}
}
}
//重置功能
const handleReset = () => {
queryParams.dataSourceId = props.dataSourceOption[0].value
queryParams.tableName = ''
queryParams.tableComment = ''
queryParams.startTime = ''
queryParams.endTime = ''
searchTableSearch()
}
//切换每页显示条数
const handleSizeChange = async (val) => {
pageInfo.pageSize = val
await searchTableSearch()
}
//点击页码进行分页功能
const handleCurrentChange = async (val) => {
pageInfo.pageNum = val
await searchTableSearch()
}
const show = () => {
isVisited.value = true
if (props.queryId !== null) {
queryParams.dataSourceId = props.queryId
} else {
queryParams.dataSourceId = props.dataSourceOption[0].value
}
searchTableSearch()
}
defineExpose({
show
})
</script>

View File

@@ -0,0 +1,360 @@
<template>
<div>
<el-form :model="queryParams" inline class="query-form" ref="genForm">
<el-form-item label="数据源" prop="dataSourceId">
<el-select v-model="queryParams.dataSourceId" placeholder="数据源" clearable filterable>
<el-option
v-for="item in dataSourceOption"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="表名称" prop="tableName">
<el-input v-model="queryParams.tableName" placeholder="请输入表名称" clearable></el-input>
</el-form-item>
<el-form-item label="表备注" prop="tableComment">
<el-input v-model="queryParams.tableComment" placeholder="请输入表备注" clearable></el-input>
</el-form-item>
<el-form-item label="创建时间" prop="dateValue">
<el-config-provider>
<el-date-picker
v-model="dateValue"
type="datetimerange"
:shortcuts="shortcuts"
start-placeholder="开始日期"
end-placeholder="结束日期"
value-format="YYYY-MM-DD HH:mm:ss"
/>
</el-config-provider>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="getList" :icon="Search">搜索</el-button>
<el-button @click="handleReset" :icon="Refresh">重置</el-button>
</el-form-item>
</el-form>
<div class="query-btn">
<el-button type="primary" plain :icon="UploadFilled" @click="handleImport(queryParams.dataSourceId)">导入
</el-button>
<el-button type="warning" @click="handleExport" :icon="Download" plain>导出</el-button>
<el-button type="danger" :icon="Delete"
@click="handleMoreDelete(tableId,tableName)" :disabled="disabled" plain>删除
</el-button>
</div>
<div class="table">
<el-table
:data="list"
:lazy="true"
v-loading="loading"
@select="handleSelect"
v-tabh
>
<el-table-column type="selection" width="55"/>
<el-table-column label="序号" type="index" align="center" width="60"/>
<el-table-column prop="tableName" label="表名称" align="center"/>
<el-table-column prop="tableComment" label="表描述" align="center"/>
<el-table-column prop="className" label="实体类" align="center"/>
<el-table-column prop="dataSourceId" label="数据源" align="center">
<template #default="scope">
<el-tag v-if="getDataSourceOptionItem(scope.row.dataSourceId)!==''">
{{ getDataSourceOptionItem(scope.row.dataSourceId) }}
</el-tag>
<span v-else></span>
</template>
</el-table-column>
<el-table-column prop="createTime" label="创建时间" sortable align="center"/>
<el-table-column prop="updateTime" label="更新时间" sortable align="center"/>
<el-table-column label="操作" width="260" align="center">
<template #default="scope">
<el-button type="primary" size="mini" @click="handlePreview(scope.row.tableId)" link>预览</el-button>
<el-button type="primary" size="mini" @click="handleEdit(scope.row.tableId)" link>编辑</el-button>
<el-button type="primary" size="mini"
@click="handleSynchronization(scope.row.tableId)" link>同步
</el-button>
<el-button type="primary" size="mini" @click="handleDownLoad(scope.row.tableId)" link>下载
</el-button>
<popover-delete :name="scope.row.tableName" :type="'表'"
@delete="handleDeleteTable(scope.row.tableId)"/>
</template>
</el-table-column>
</el-table>
</div>
<paging :current-page="pageInfo.pageNum" :page-size="pageInfo.pageSize" :page-sizes="[10, 20, 30, 40,50]"
:total="total" @changeSize="handleSizeChange" @goPage="handleCurrentChange"/>
<import-table ref="importTableRef" :data-source-option="dataSourceOption" :query-id="importQueryId"
@importSuccess="getList"/>
<el-dialog v-model="preview.isVisited" title="预览代码" width="1500px">
<el-tabs v-model="preview.activeName" class="demo-tabs">
<el-tab-pane
v-for="(value,key) in preview.code"
:label="key" :name="key">
<el-link :underline="false" :icon="CopyDocument" @click="clipboardSuccess(value)"
style="float:right">复制
</el-link>
<pre><code class="hljs" v-html="highlightedCode(value, key)"></code></pre>
</el-tab-pane>
</el-tabs>
</el-dialog>
</div>
</template>
<script setup>
import {getTableList, deleteTable, deleteMoreTable, previewCode} from "@/api/rapid/code-gen";
import {getDataSourceOption} from '@/api/rapid/data-source'
import {downLoadZip} from "@/utils/downloadZip";
import {Search, Refresh, Delete, Edit, View, Download, CopyDocument, UploadFilled} from '@element-plus/icons-vue'
import Paging from "@/components/pagination/index.vue";
import ImportTable from './importTable.vue'
import java from 'highlight.js/lib/languages/java'
import xml from 'highlight.js/lib/languages/xml'
import javascript from 'highlight.js/lib/languages/javascript'
import sql from 'highlight.js/lib/languages/sql'
import hljs from "highlight.js/lib/highlight";
import "highlight.js/styles/github-gist.css";
import {ElMessage, ElMessageBox} from "element-plus";
import useClipboard from "vue-clipboard3"
import {syncDatabase} from "@/api/rapid/code-gen";
import {downLoadExcel} from "@/utils/downloadZip";
hljs.registerLanguage("java", java);
hljs.registerLanguage("xml", xml);
hljs.registerLanguage("html", xml);
hljs.registerLanguage("vue", javascript);
hljs.registerLanguage("ts", javascript);
hljs.registerLanguage("tsx", javascript);
hljs.registerLanguage("js", javascript);
hljs.registerLanguage("sql", sql);
const router = useRouter()
const dsId = reactive(router.currentRoute.value.params.dsId)
const queryParams = reactive({
dataSourceId: null,
dataSourceType: '',
tableName: '',
tableComment: '',
startTime: '',
endTime: ''
})
const pageInfo = reactive({
pageNum: 1,
pageSize: 10
})
const disabled = ref(true)
const importQueryId = ref()
const tableId = ref()
const tableName = ref()
const list = ref([])
const loading = ref(true)
const total = ref()
const dateValue = ref()
const shortcuts = [
{
text: "上周",
value: () => {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
return [start, end];
}
},
{
text: "上月",
value: () => {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
return [start, end];
}
},
{
text: "三月前",
value: () => {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
return [start, end];
}
}
];
const dataSourceOption = ref()
const code = ref()
const genForm = ref()
const preview = ref({
code: null,
isVisited: false,
activeName: null
})
const importTableRef = ref(null)
const title = ref('')
const {toClipboard} = useClipboard()
onMounted(() => {
if (dsId) {
queryParams.dataSourceId = parseInt(dsId)
getList()
}
})
const handleExport = () => {
downLoadExcel('/code-gen/table/export', {...queryParams})
}
const clipboardSuccess = (value) => {
try {
toClipboard(value)
ElMessage.success("复制成功")
} catch (e) {
ElMessage.error("复制失败")
}
}
const getOption = () => {
getDataSourceOption().then(res => {
if (res.code === 1000) {
dataSourceOption.value = res.data
getList();
}
})
}
const getDataSourceOptionItem = (dataSourceId) => {
for (let item of dataSourceOption.value) {
if (item.value === dataSourceId) {
return item.label;
}
}
return "";
}
/** 下载代码 */
const handleDownLoad = async (tableId) => {
downLoadZip(`/code-gen/table/downloads/${[tableId]}`)
}
const handleEdit = (tableId) => {
router.push({
path: `/rapid/gen/edit/${tableId}`,
})
}
//同步
const handleSynchronization = async (tableId) => {
syncDatabase(tableId).then(res => {
if (res.code === 1000) {
ElMessage.success(res.msg)
getList()
} else {
ElMessage.error(res.msg)
}
})
}
/** 高亮显示 */
const highlightedCode = (code, key) => {
let language = key.split(".")[1];
const result = hljs.highlight(language, code || "", true);
// console.log(result.value)
return result.value;
}
const getList = async () => {
let params = {
...queryParams,
...pageInfo
}
const date = dateValue.value
if (date !== undefined && date !== null) {
params.startTime = date[0]
params.endTime = date[1]
}
loading.value = true
getTableList(params).then(res => {
if (res.code === 1000) {
list.value = res.data.rows
total.value = res.data.total
loading.value = false
}
})
}
//重置功能
const handleReset = () => {
genForm.value.resetFields()
dateValue.value = []
getList()
}
//切换每页显示条数
const handleSizeChange = (val) => {
pageInfo.pageSize = val
getList()
}
//点击页码进行分页功能
const handleCurrentChange = (val) => {
pageInfo.pageNum = val
getList()
}
//勾选table数据行的 Checkbox
const handleSelect = async (selection) => {
if (selection.length !== 0) {
disabled.value = false
tableId.value = selection.map(item => item.tableId).join()
tableName.value = selection.map(item => item.tableName).join()
} else {
disabled.value = true
}
}
const handleDeleteTable = (tableId) => {
deleteTable(tableId).then(res => {
if (res.code === 1000) {
ElMessage.success(res.msg)
getList()
} else {
ElMessage.error(res.msg)
}
})
}
//多删
const handleMoreDelete = (tableId, tableName) => {
ElMessageBox.confirm(`确认删除名称为${tableName}的表格吗?`, '系统提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
deleteMoreTable({
tables: tableId
}).then(res => {
if (res.code === 1000) {
ElMessage.success(res.msg)
getList()
} else {
ElMessage.error(res.msg)
}
})
})
}
//预览功能
const handlePreview = async (tableId) => {
previewCode(tableId).then(res => {
if (res.code === 1000) {
let code = res.data;
preview.value = {
isVisited: true,
activeName: Object.keys(code)[0],
code: code
}
} else {
ElMessage.error(res.msg)
}
})
}
const handleImport = async (val) => {
title.value = "导入数据源"
importQueryId.value = val
nextTick(() => {
importTableRef.value.show()
})
}
getOption();
</script>

View File

@@ -0,0 +1,210 @@
<template>
<el-form ref="tableForm" :model="info" :rules="rules" label-width="130px">
<el-row>
<el-col :span="11">
<el-form-item prop="tplCategory" label="生成模板">
<!-- <el-select v-model="info.tplCategory" @change="tplSelectChange" filterable>-->
<el-select v-model="info.tplCategory" filterable>
<el-option label="单表(增删改查)" value="crud"/>
<el-option label="树表(增删改查)" value="tree"/>
<el-option label="多表关联(增删改查)" value="rel"/>
<el-option label="主子表(增删改查)" value="sub"/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="11" :offset="2">
<el-form-item prop="packageName" label="生成包路径">
<el-tooltip content="生成在哪个java包下例如 cn.odliken.system" placement="top">
</el-tooltip>
<el-input v-model="info.packageName"/>
</el-form-item>
</el-col>
<el-col :span="11">
<el-form-item prop="tplCategory" label="后端模板">
<el-select v-model="info.backTemplate" filterable>
<el-option label="Mybatis" value="0"/>
<el-option label="Mybatis-Plus" value="1"/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="11" :offset="2">
<el-form-item prop="tplCategory" label="前端模板">
<el-select v-model="info.frontTemplate" filterable>
<el-option label="Vue" value="0"/>
<el-option label="React" value="1"/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="11">
<el-form-item prop="moduleName" label="生成模块名">
<el-tooltip content="可理解为子系统名,例如 system" placement="top">
<i class="el-icon-question"></i>
</el-tooltip>
<el-input v-model="info.moduleName"/>
</el-form-item>
</el-col>
<el-col :span="11" :offset="2">
<el-form-item prop="businessName" label="生成业务名">
<el-tooltip content="可理解为功能英文名,例如 user" placement="top">
<i class="el-icon-question"></i>
</el-tooltip>
<el-input v-model="info.businessName"/>
</el-form-item>
</el-col>
<el-col :span="11">
<el-form-item prop="functionName" label="生成功能名">
<el-tooltip content="用作类描述,例如 用户" placement="top">
<i class="el-icon-question"></i>
</el-tooltip>
<el-input v-model="info.functionName"/>
</el-form-item>
</el-col>
<el-col :span="11" :offset="2">
<el-form-item prop="parentMenuId" label="上级菜单">
<el-tree-select v-model="info.parentMenuId" :data="menus" style="width: 100%;"
:filter-node-method="filterNodeMethod"
filterable
:check-strictly="true"/>
</el-form-item>
</el-col>
<el-col :span="11">
<el-form-item prop="serviceName" label="服务名称">
<el-tooltip content="用作类描述,例如 用户" placement="top">
<i class="el-icon-question"></i>
</el-tooltip>
<el-input v-model="info.serviceName"/>
</el-form-item>
</el-col>
<el-col :span="11" :offset="2">
<el-form-item prop="optionInfoEnable" label="option接口生成">
<el-radio-group v-model="optionInfo.enabled">
<el-radio :label="true" border>启用option接口</el-radio>
<el-radio :label="false" border>关闭option接口</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="11" v-if="optionInfo.enabled">
<el-form-item prop="optionInfoValueField" label="值映射">
<el-select v-model="optionInfo.valueField">
<el-option
v-for="column in columns"
:key="column.id"
:label="column.javaField"
:value="column.javaField">
<span style="float: left">{{ column.javaField }}</span>
<span style="float: right; color: #8492a6; font-size: 13px">{{ column.columnComment }}</span>
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="11" :offset="2" v-if="optionInfo.enabled">
<el-form-item prop="optionInfoLabelFiled" label="标签映射">
<el-select v-model="optionInfo.labelFiled">
<el-option
v-for="column in columns"
:key="column.id"
:label="column.javaField"
:value="column.javaField">
<span style="float: left">{{ column.javaField }}</span>
<span style="float: right; color: #8492a6; font-size: 13px">{{ column.columnComment }}</span>
</el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
</el-form>
</template>
<script setup>
import {defineExpose, defineProps} from "vue";
import {getMenuOpt} from '@/api/system/menuman.js'
const props = defineProps({
info: {
type: Object,
default: {}
},
optionInfo: {
type: Object,
default: {
enabled: 0
}
},
tables: {
type: Array,
default: []
},
dictOptions: {
type: Array,
default: []
},
columns: {
type: Array,
default: []
}
})
const menus = ref([])
const tableForm = ref()
const rules = ref({
tplCategory: [
{required: true, message: "请选择生成模板", trigger: "blur"}
],
packageName: [
{required: true, message: "请输入生成包路径", trigger: "blur"}
],
moduleName: [
{required: true, message: "请输入生成模块名", trigger: "blur"}
],
businessName: [
{required: true, message: "请输入生成业务名", trigger: "blur"}
],
functionName: [
{required: false, message: "请输入生成功能名", trigger: "blur"}
],
backTemplate: [
{required: true, message: "请选择后端模板", trigger: "blur"}
],
frontTemplate: [
{required: true, message: "请选择前端模板", trigger: "blur"}
],
serviceName: [
{required: true, message: "请选输入服务名称", trigger: "blur"}
],
optionInfoEnable: [
{required: true, message: "请选择前端模板", trigger: "blur"}
],
optionInfoValueField: [
{required: true, message: "请选择值映射字段", trigger: "blur"}
],
optionInfoLabelFiled: [
{required: true, message: "请选择前端模板标签映射字段", trigger: "blur"}
],
})
const handleSearch = async () => {
getMenuOpt().then(res => {
if (res.code === 1000) {
menus.value = [{
value: 0,
label: "一级目录",
children: res.data
}]
}
})
}
const filterNodeMethod = (value, data) => data.label.includes(value)
defineExpose({
tableForm
})
handleSearch()
</script>
<style scoped>
</style>

View File

@@ -0,0 +1,302 @@
<template>
<div>
<el-form :model="queryParams" inline class="query-form" ref="queryForm">
<el-form-item label="正则名称" prop="name">
<el-input v-model="queryParams.name" placeholder="请输正则名称" clearable></el-input>
</el-form-item>
<el-form-item label="正则内容" prop="regular">
<el-input v-model="queryParams.regular" placeholder="请输正则内容" clearable></el-input>
</el-form-item>
<el-form-item label="验证内容" prop="validation">
<el-input v-model="queryParams.validation" placeholder="请输验证内容" clearable></el-input>
</el-form-item>
<el-form-item label="是否启用" prop="enable">
<el-select v-model="queryParams.enable" placeholder="请选择是否启用" clearable filterable>
<el-option
v-for="dict in cacheStore.getDict('regular_enable')"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="getList" :icon="Search">搜索</el-button>
<el-button @click="handleReset" :icon="Refresh">重置</el-button>
</el-form-item>
</el-form>
<div class="query-btn">
<el-button type="primary" v-perm="['rapid:regular:add']" @click="handleAdd" :icon="Plus" plain>新增</el-button>
<el-button type="warning" v-perm="['rapid:regular:export']" @click="handleExport" :icon="Download" plain>导出
</el-button>
<el-button type="danger" v-perm="['rapid:regular:del']" @click="handleMoreDelete(regularId,regularNameList)" :icon="Delete" plain
:disabled="disabled">删除
</el-button>
</div>
<div class="table">
<el-table
:data="list"
row-key="id"
:lazy="true"
ref="singleTable"
v-loading="loading"
@select="handleSelect"
v-tabh
>
<el-table-column type="selection" width="55"/>
<el-table-column label="序号" type="index" align="center" width="60"/>
<el-table-column prop="name" label="正则名称" align="center"/>
<el-table-column prop="regular" label="正则内容" align="center"/>
<el-table-column prop="enable" label="是否启用" align="center">
<template #default="scope">
<tag dict-type="regular_enable" :value="scope.row.enable"/>
</template>
</el-table-column>
<el-table-column prop="createTime" label="创建时间" align="center"/>
<el-table-column prop="updateTime" label="更新时间" align="center"/>
<el-table-column label="操作">
<template #default="scope">
<el-button type="primary" size="mini" v-perm="['rapid:regular:edit']"
@click="handleEdit(scope.row.id)" link>编辑
</el-button>
<popover-delete :name="scope.row.name" :type="'正则校验'" :perm="['rapid:regular:del']"
@delete="handleDelete(scope.row.id)"/>
</template>
</el-table-column>
</el-table>
</div>
<paging :current-page="pageInfo.pageNum" :page-size="pageInfo.pageSize" :page-sizes="[10, 20, 30, 40,50]"
:total="total" @changeSize="handleSizeChange" @goPage="handleCurrentChange"/>
<el-dialog v-model="isVisited" :title="title" width="900px">
<el-form :model="form" ref="formInstance" :rules="formRules" label-width="100px" class="dialog-form">
<el-row>
<el-col :span="11">
<el-form-item label="正则名称" prop="name">
<el-input v-model="form.name" placeholder="请输入正则名称"></el-input>
</el-form-item>
</el-col>
<el-col :span="11" :offset="2">
<el-form-item label="正则内容" prop="regular">
<el-input v-model="form.regular" placeholder="请输入正则内容"></el-input>
</el-form-item>
</el-col>
<el-col :span="11">
<el-form-item label="验证内容" prop="validation">
<el-input v-model="form.validation" placeholder="请输入验证内容"></el-input>
</el-form-item>
</el-col>
<el-col :span="11" :offset="2">
<el-form-item label="是否启用" prop="enable">
<el-select v-model="form.enable" placeholder="请选择是否启用" clearable filterable>
<el-option
v-for="dict in cacheStore.getDict('regular_enable')"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<span>
<el-button @click="handleCancel">取消</el-button>
<el-button type="primary" @click="handleSubmit(formInstance)">确定</el-button>
</span>
</template>
</el-dialog>
</div>
</template>
<script setup>
import {getRegularList, getRegularDetails, addRegular, editRegular, delRegular} from "@/api/rapid/regular";
import {Search, Refresh, Delete, Plus, Edit, Download} from '@element-plus/icons-vue'
import {ElMessage, ElMessageBox} from "element-plus";
import {useCacheStore} from '@/stores/cache.js'
import Paging from "@/components/pagination/index.vue";
const cacheStore = useCacheStore()
cacheStore.setCacheKey(['regular_enable'])
import {downLoadExcel} from "@/utils/downloadZip";
import Tag from '@/components/Tag.vue'
//查询参数
const queryParams = reactive({
name: '',
regular: '',
validation: '',
enable: undefined,
})
//页面信息
const pageInfo = reactive({
pageNum: 1,
pageSize: 10,
})
const disabled = ref(true)
const list = ref([])
const queryForm = ref([])
const regularId = ref([])
const regularNameList = ref([])
const loading = ref(true)
const total = ref()
const singleTable = ref()
const title = ref('')
const isVisited = ref(false)
const form = ref()
const formInstance = ref()
const formRules = ref({
name: [
{required: true, message: "正则名称不能为空", trigger: "blur"},
],
regular: [
{required: true, message: "正则内容不能为空", trigger: "blur"},
],
validation: [
{required: true, message: "验证内容不能为空", trigger: "blur"},
],
enable: [
{required: true, message: "是否启用 1:启动 2:关闭不能为空", trigger: "change"},
],
})
//重置搜索
const handleReset = () => {
queryForm.value.resetFields()
getList()
}
//获取数据
const getList = async () => {
let params = {
...queryParams,
...pageInfo
}
loading.value = true
getRegularList(params).then(res => {
if (res.code === 1000) {
list.value = res.data.rows
total.value = res.data.total
loading.value = false
} else {
ElMessage.error(res.msg)
}
})
}
//重置from表单
const restFrom = () => {
form.value = {
name: null,
regular: null,
validation: null,
enable: null,
}
}
//取消
const handleCancel = () => {
restFrom()
isVisited.value = false
}
//提交
const handleSubmit = async (instance) => {
if (!instance) return
instance.validate(async (valid) => {
if (!valid) return
if (title.value === '新增校验规则表') {
addRegular(form.value).then(res => {
if (res.code === 1000) {
ElMessage.success(res.msg)
getList()
isVisited.value = false
} else {
ElMessage.error(res.msg)
}
})
} else {
editRegular(form.value).then(res => {
if (res.code === 1000) {
ElMessage.success(res.msg)
getList()
isVisited.value = false
} else {
ElMessage.error(res.msg)
}
})
}
})
}
//添加
const handleAdd = async () => {
restFrom()
title.value = "新增校验规则表"
isVisited.value = true
nextTick(()=>{
// 清空校验
formInstance.value.clearValidate()
})
}
//修改
const handleEdit = async (id) => {
restFrom()
getRegularDetails(id).then(res => {
if (res.code === 1000) {
form.value = res.data
title.value = "编辑校验规则表"
isVisited.value = true
} else {
ElMessage.error(res.msg)
}
})
nextTick(()=>{
// 清空校验
formInstance.value.clearValidate()
})
}
//导出excel
const handleExport = () => {
downLoadExcel('/code-gen/rapid/regular/export', {...queryParams})
}
//勾选table数据行的 Checkbox
const handleSelect = async (selection, row) => {
if (selection.length !== 0) {
disabled.value = false
regularId.value = selection.map(item => item.id).join()
regularNameList.value = selection.map(item => item.name).join()
} else {
disabled.value = true
}
}
//切换每页显示条数
const handleSizeChange = async (val) => {
pageInfo.value.pageSize = val
await getList()
}
//点击页码进行分页功能
const handleCurrentChange = async (val) => {
pageInfo.value.pageNum = val
await getList()
}
const handleMoreDelete=(regularId,regularNameList)=>{
ElMessageBox.confirm(`确认删除名称为${regularNameList}的校验规则表吗?`, '系统提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
handleDelete(regularId)
})
}
//删除
const handleDelete = async (id) => {
delRegular(id).then(res => {
if (res.code === 1000) {
ElMessage.success(res.msg)
getList()
} else {
ElMessage.error(res.msg)
}
})
}
getList()
</script>

View File

@@ -0,0 +1,380 @@
<template>
<div>
<el-form :model="queryParams" inline class="query-form" ref="sourceForm" @submit.prevent="getList">
<el-form-item label="数据源名称" prop="dsName">
<el-input v-model="queryParams.dsName" placeholder="请输入数据源名称" clearable></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="getList" :icon="Search">搜索</el-button>
<el-button @click="handleReset" :icon="Refresh">重置</el-button>
</el-form-item>
</el-form>
<div class="query-btn">
<el-button type="primary" @click="handleAdd" :icon="Plus" plain>新增</el-button>
<el-button type="warning" @click="handleExport" :icon="Download" plain>导出</el-button>
<el-button type="danger" @click="handleMoreDelete(sourceId,sourceNameList)" :icon="Delete" plain
:disabled="disabled">删除
</el-button>
</div>
<div class="table">
<el-table
:data="list"
row-key="dsId"
:lazy="true"
ref="singleTable"
v-loading="loading"
@select="handleSelect"
v-tabh
>
<el-table-column type="selection" width="55"/>
<el-table-column label="序号" type="index" width="60" align="center"/>
<el-table-column prop="dsName" label="数据源名称" align="center"/>
<el-table-column prop="dbName" label="数据库名称" align="center"/>
<el-table-column prop="username" label="用户名称" align="center"/>
<el-table-column prop="jdbcUrl" label="数据库连接url" align="center" width="140">
<template #default="scope">
<div class="formatterJdbcUrl">{{ scope.row.jdbcUrl }}</div>
</template>
</el-table-column>
<el-table-column prop="confType" label="数据源配置类型" align="center">
<template #default="scope">
<tag dict-type="data_source_config" :value="scope.row.confType"/>
</template>
</el-table-column>
<el-table-column prop="createTime" label="创建时间" align="center"/>
<el-table-column label="操作" align="center">
<template #default="scope">
<el-button type="primary" size="mini" @click="handleEdit(scope.row.dsId)" link>编辑</el-button>
<el-button type="primary" size="mini" @click="handleAssociatedData(scope.row.dsId)" link>关联数据</el-button>
<popover-delete :name="scope.row.dsName" :type="'数据源信息'"
@delete="handleDelete(scope.row.dsId)"/>
</template>
</el-table-column>
</el-table>
</div>
<paging :current-page="pageInfo.pageNum" :page-size="pageInfo.pageSize" :page-sizes="[10, 20, 30, 40,50]"
:total="total" @changeSize="handleSizeChange" @goPage="handleCurrentChange"/>
<el-dialog v-model="isVisited" :title="title" width="900px">
<el-form :model="form" ref="formInstance" :rules="formRules" class="dialog-form">
<el-row>
<el-col :span="11">
<el-form-item label="类型" prop="type">
<el-select v-model="form.type" placeholder="请选择数据源类型" filterable @change="handleTypeChange(form.type)">
<el-option
v-for="typeItem in typeList"
:key="typeItem.value"
:label="typeItem.label"
:value="typeItem.value"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="11" :offset="2">
<el-form-item label="数据源名称" prop="dsName">
<el-input v-model="form.dsName" placeholder="请输入数据源名称"></el-input>
</el-form-item>
</el-col>
<el-col :span="11">
<el-form-item label="用户名" prop="username">
<el-input v-model="form.username" placeholder="请输入用户名"></el-input>
</el-form-item>
</el-col>
<el-col :span="11" :offset="2">
<el-form-item label="密码" prop="password">
<el-input v-model="form.password" placeholder="请输入密码"></el-input>
</el-form-item>
</el-col>
<el-col :span="11">
<el-form-item label="配置类型" prop="confType">
<el-radio-group v-model="form.confType">
<el-radio border :label="1">主机</el-radio>
<el-radio border :label="2">JDBC</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="11" :offset="2" v-if="form.confType === 1">
<el-form-item label="端口" prop="port">
<el-input-number v-model="form.port"></el-input-number>
</el-form-item>
</el-col>
<el-col :span="11" v-if="form.confType === 1">
<el-form-item label="主机" prop="host">
<el-input v-model="form.host" placeholder="请输入主机"></el-input>
</el-form-item>
</el-col>
<el-col :span="11" :offset="2" v-if="form.confType === 1">
<el-form-item label="数据库名称" prop="dbName">
<el-input v-model="form.dbName" placeholder="请输入数据库名称"></el-input>
</el-form-item>
</el-col>
<el-col :span="24" v-if="form.confType === 2">
<el-form-item label="连接地址" prop="jdbcUrl">
<el-input v-model="form.jdbcUrl"
:rows="4"
type="textarea" placeholder="请输入连接地址"></el-input>
</el-form-item>
</el-col>
<el-col :span="24" v-if="form.confType === 1">
<el-form-item label="配置参数" prop="args">
<el-input v-model="form.args" :rows="4"
type="textarea" placeholder="请输入配置参数"></el-input>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="服务名称" prop="params.serviceName" v-if="form.type === 'ORACLE' && form.confType===1">
<el-input v-model="form.params.serviceName" placeholder="请输入服务名称"></el-input>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="命名空间" prop="params.namespace" v-if="form.type === 'POSTGRES' && form.confType===1">
<el-input v-model="form.params.namespace" placeholder="请输入命名空间"></el-input>
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<span>
<el-button @click="handleCancel">取消</el-button>
<el-button type="primary" @click="handleSubmit(formInstance)">确定</el-button>
</span>
</template>
</el-dialog>
</div>
</template>
<script setup>
import {
getDataSourceList,
deleteDataSource,
getDataSource,
addDataSource,
editDataSource,
getDataSourceOptionType
} from "@/api/rapid/data-source";
import {Search, Refresh, Delete, Plus, Edit, Download} from '@element-plus/icons-vue'
import {ElMessage, ElMessageBox} from "element-plus";
import Paging from "@/components/pagination/index.vue";
import {downLoadExcel} from "@/utils/downloadZip";
const router = useRouter()
const queryParams = reactive({
dsName: '',
})
const pageInfo = reactive({
pageNum: 1,
pageSize: 10,
})
const disabled = ref(true)
const typeList = ref([])
const list = ref([])
const sourceForm = ref([])
const loading = ref(true)
const total = ref()
const title = ref('')
const isVisited = ref(false)
const sourceId = ref();
const sourceNameList = ref();
const singleTable = ref();
const form = ref()
const formInstance = ref()
const formRules = ref({
type: [{required: true, message: '请输选择数据库类型', trigger: 'blur'}],
dsName: [{required: true, message: '请输入数据源名称', trigger: 'blur'}],
username: [{required: true, message: '请输入用户名', trigger: 'blur'}],
password: [{required: true, message: '请输入密码', trigger: 'blur'}],
confType: [{required: true, message: '请输选择配置类型', trigger: 'blur'}],
port: [{required: true, message: '请输入服务端口', trigger: 'blur'}],
host: [{required: true, message: '请输入主机', trigger: 'blur'}],
dbName: [{required: true, message: '请输入数据库名称', trigger: 'blur'}],
jdbcUrl: [{required: true, message: '请输入连接地址', trigger: 'blur'}],
params: {
serviceName: [{required: true, message: '请输入服务名称', trigger: 'blur'}],
namespace: [{required: true, message: '请输入命名空间', trigger: 'blur'}]
}
})
const handleReset = () => {
sourceForm.value.resetFields()
getList()
}
const getTypeOption = () => {
getDataSourceOptionType().then(res => {
typeList.value = res.data
})
}
const handleTypeChange = (type) => {
if (form.value.confType !== 1) {
return;
}
if (type === 'ORACLE') {
form.value.params = {
serviceName: ''
}
}
if (type === 'POSTGRES') {
form.value.params = {
namespace: ''
}
}
}
const getList = async () => {
let params = {
...queryParams,
...pageInfo
}
loading.value = true
getDataSourceList(params).then(res => {
if (res.code === 1000) {
list.value = res.data.rows
total.value = res.data.total
loading.value = false
} else {
ElMessage.error(res.msg)
}
})
}
const restFrom = () => {
form.value = {
remark: null,
dsId: null,
dsName: "",
username: "",
password: "",
host: "",
port: 0,
type: "",
dbName: "",
jdbcUrl: null,
confType: 1,
args: null,
params: null
}
getTypeOption()
}
const handleCancel = () => {
restFrom()
isVisited.value = false
}
const handleSubmit = async (instance) => {
if (!instance) return
instance.validate(async (valid, fields) => {
if (!valid) return
if (title.value === '新增数据源') {
console.log('form.value', form.value)
addDataSource(form.value).then(res => {
if (res.code === 1000) {
ElMessage.success(res.msg)
getList()
isVisited.value = false
} else {
ElMessage.error(res.msg)
}
})
} else {
editDataSource(form.value).then(res => {
if (res.code === 1000) {
ElMessage.success(res.msg)
getList()
isVisited.value = false
} else {
ElMessage.error(res.msg)
}
})
}
})
}
const handleAdd = () => {
formRules.value.password[0].required = true
restFrom()
title.value = "新增数据源"
isVisited.value = true
nextTick(() => {
// 清空校验
formInstance.value.clearValidate()
})
}
const handleAssociatedData = (dsId) => {
router.push('/rapid/data/' + dsId)
}
const handleEdit = async (dsId) => {
restFrom()
getDataSource(dsId).then(res => {
if (res.code === 1000) {
formRules.value.password[0].required = false
form.value = res.data
title.value = "编辑数据源"
isVisited.value = true
nextTick(() => {
// 清空校验
formInstance.value.clearValidate()
})
} else {
ElMessage.error(res.msg)
}
})
}
const handleExport = () => {
downLoadExcel('/code-gen/data-source/export', {...queryParams})
}
//勾选table数据行的 Checkbox
const handleSelect = async (selection) => {
if (selection.length !== 0) {
disabled.value = false
sourceId.value = selection.map(item => item.dsId).join()
sourceNameList.value = selection.map(item => item.dsName).join()
} else {
disabled.value = true
}
}
//切换每页显示条数
const handleSizeChange = async (val) => {
pageInfo.value.pageSize = val
await getList()
}
//点击页码进行分页功能
const handleCurrentChange = async (val) => {
pageInfo.value.pageNum = val
await getList()
}
const handleMoreDelete = (dsId, sourceNameList) => {
ElMessageBox.confirm(`确认删除名称为${sourceNameList}的数据源信息吗?`, '系统提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
handleDelete(dsId)
})
}
const handleDelete = async (dsId) => {
deleteDataSource(dsId).then(res => {
if (res.code === 1000) {
ElMessage.success(res.msg)
getList()
} else {
ElMessage.error(res.msg)
}
})
}
getList()
</script>
<style scoped>
.formatterJdbcUrl {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
}
</style>