✨ 模板生成逻辑基本完成
This commit is contained in:
parent
d50e19609a
commit
bc17aa3dd4
File diff suppressed because it is too large
Load Diff
|
@ -129,11 +129,8 @@ const MainCard = defineComponent({
|
||||||
</div>
|
</div>
|
||||||
`,
|
`,
|
||||||
props: {
|
props: {
|
||||||
// 原始表列表数据,由父组件传入
|
/* 原始表列表数据,由父组件传入 */
|
||||||
rawTableList: {
|
rawTableList: {type: Array,},
|
||||||
type: Array,
|
|
||||||
default: () => []
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
const MainForm = {
|
const MainForm = {
|
||||||
name: "MainForm", template: `
|
name: "MainForm",
|
||||||
|
template: `
|
||||||
<div class="card shadow-sm mt-2 bg-body-secondary">
|
<div class="card shadow-sm mt-2 bg-body-secondary">
|
||||||
|
<!-- 表单标题和折叠控制 -->
|
||||||
<div class="card-header p-3">
|
<div class="card-header p-3">
|
||||||
<a aria-controls="generatorFormCollapse"
|
<a aria-controls="generatorFormCollapse" aria-expanded="false"
|
||||||
aria-expanded="false"
|
class="d-flex align-items-center text-decoration-none" data-bs-toggle="collapse"
|
||||||
class="d-flex align-items-center text-decoration-none"
|
|
||||||
data-bs-toggle="collapse"
|
|
||||||
href="#generatorFormCollapse">
|
href="#generatorFormCollapse">
|
||||||
<i class="bi bi-pencil me-2"></i>
|
<i class="bi bi-pencil me-2"></i>
|
||||||
<span class="fw-semibold">填写生成表单信息</span>
|
<span class="fw-semibold">填写生成表单信息</span>
|
||||||
|
@ -13,95 +13,132 @@ const MainForm = {
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 表单内容区域 -->
|
||||||
<div class="collapse" :class="{ 'show': defaultCollapse }" id="generatorFormCollapse">
|
<div class="collapse" :class="{ 'show': defaultCollapse }" id="generatorFormCollapse">
|
||||||
<form class="card-body row">
|
<form class="card-body row" @submit.prevent="handleSubmit" novalidate>
|
||||||
<!-- 基本信息输入 -->
|
<!-- 基本信息输入区域 -->
|
||||||
<div class="col-md-4 mb-3">
|
<div class="col-md-4 mb-3 has-validation">
|
||||||
<label class="form-label fw-medium" for="authorName">作者名称</label>
|
<label class="form-label fw-medium" for="authorName">作者名称</label>
|
||||||
<input class="form-control border-secondary" id="authorName" placeholder="输入作者名称" required
|
<input class="form-control border-secondary" :class="{ 'is-invalid': errors.authorName }"
|
||||||
v-model="form.authorName" type="text">
|
id="authorName" placeholder="输入作者名称" v-model="form.authorName" type="text"
|
||||||
|
@input="validateField('authorName')">
|
||||||
|
<div class="invalid-feedback">
|
||||||
|
{{ errors.authorName || '请输入作者名称' }}
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-4 mb-3">
|
|
||||||
<label class="form-label fw-medium"
|
|
||||||
for="requestMapping">requestMapping名称</label>
|
|
||||||
<input class="form-control border-secondary" id="requestMapping" placeholder="输入requestMapping名称" required
|
|
||||||
v-model="form.requestMapping" type="text">
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-4 mb-3">
|
<div class="col-md-4 mb-3 has-validation">
|
||||||
|
<label class="form-label fw-medium" for="requestMapping">requestMapping名称</label>
|
||||||
|
<input class="form-control border-secondary" :class="{ 'is-invalid': errors.requestMapping }"
|
||||||
|
id="requestMapping" placeholder="输入requestMapping名称" v-model="form.requestMapping" type="text"
|
||||||
|
@input="validateField('requestMapping')">
|
||||||
|
<div class="invalid-feedback">
|
||||||
|
{{ errors.requestMapping || '请输入requestMapping名称' }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-4 mb-3 has-validation">
|
||||||
<label class="form-label fw-medium" for="packageName">包名称</label>
|
<label class="form-label fw-medium" for="packageName">包名称</label>
|
||||||
<input class="form-control border-secondary" id="packageName" placeholder="输入包名称" required
|
<input class="form-control border-secondary" :class="{ 'is-invalid': errors.packageName }"
|
||||||
v-model="form.packageName" type="text">
|
id="packageName" placeholder="输入包名称" v-model="form.packageName" type="text"
|
||||||
|
@input="validateField('packageName')">
|
||||||
|
<div class="invalid-feedback">
|
||||||
|
{{ errors.packageName || '请输入包名称' }}
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-4 mb-3">
|
</div>
|
||||||
|
<div class="col-md-4 mb-3 has-validation">
|
||||||
<label class="form-label fw-medium" for="simpleDateFormat">时间格式</label>
|
<label class="form-label fw-medium" for="simpleDateFormat">时间格式</label>
|
||||||
<input class="form-control border-secondary" id="simpleDateFormat" placeholder="输入时间格式" required
|
<input class="form-control border-secondary" :class="{ 'is-invalid': errors.simpleDateFormat }"
|
||||||
v-model="form.simpleDateFormat" type="text">
|
id="simpleDateFormat" placeholder="输入时间格式" v-model="form.simpleDateFormat" type="text"
|
||||||
|
@input="validateField('simpleDateFormat')">
|
||||||
|
<div class="invalid-feedback">
|
||||||
|
{{ errors.simpleDateFormat || '请输入时间格式' }}
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-4 mb-3">
|
</div>
|
||||||
|
<div class="col-md-4 mb-3 has-validation">
|
||||||
<label class="form-label fw-medium" for="tablePrefixes">去除开头前缀</label>
|
<label class="form-label fw-medium" for="tablePrefixes">去除开头前缀</label>
|
||||||
<input class="form-control border-secondary" id="tablePrefixes" placeholder="去除开头前缀" required
|
<input class="form-control border-secondary" :class="{ 'is-invalid': errors.tablePrefixes }"
|
||||||
v-model="form.tablePrefixes" type="text">
|
id="tablePrefixes" placeholder="去除开头前缀" v-model="form.tablePrefixes" type="text"
|
||||||
|
@input="validateField('tablePrefixes')">
|
||||||
|
<div class="invalid-feedback">
|
||||||
|
{{ errors.tablePrefixes || '请输入去除开头前缀' }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-4 mb-3">
|
<div class="col-md-4 mb-3">
|
||||||
<label class="form-label fw-medium" for="comment">注释内容</label>
|
<label class="form-label fw-medium" for="comment">注释内容</label>
|
||||||
<input class="form-control border-secondary" id="comment" placeholder="注释内容" required
|
<input class="form-control border-secondary" id="comment" placeholder="注释内容" v-model="form.comment"
|
||||||
v-model="form.comment" type="text">
|
type="text" />
|
||||||
|
</div>
|
||||||
|
<div class="col-md-12" v-show="form.tableNames.length > 0">
|
||||||
|
<label class="form-label fw-medium" for="comment">已选择的要生成表({{form.tableNames.length}}):</label>
|
||||||
|
<span class="badge rounded-pill text-bg-dark me-1" v-for="(item,index) in form.tableNames" :ket="index">{{item}}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 前端模板选项 -->
|
<!-- 前端模板选择区域 -->
|
||||||
<div class="col-12 mt-3 mb-3 p-3 bg-light rounded">
|
<div class="col-12 mt-3 mb-3 p-3 bg-light rounded">
|
||||||
<label class="form-check-inline col-form-label fw-medium">生成前端模板:</label>
|
<label class="form-check-inline col-form-label fw-medium">生成前端模板:</label>
|
||||||
<div class="form-check form-check-inline" v-for="(web,index) in webList" :key="index">
|
<div class="form-check form-check-inline" v-for="(web,index) in webList" :key="index">
|
||||||
<input class="form-check-input border-secondary" :id="web.id" type="checkbox"
|
<input class="form-check-input border-secondary" :class="{ 'is-invalid': errors.webTemplates }"
|
||||||
:value="web.name" v-model="web.checked">
|
:id="web.id" type="checkbox" v-model="web.checked"
|
||||||
<label class="form-check-label" :for="web.id">{{web.label}}</label>
|
@change="validateTemplates">
|
||||||
|
<label class="form-check-label" :for="web.id" :title="web.name">{{web.label}}</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-check form-check-inline btn-group ms-2">
|
<div class="form-check form-check-inline btn-group ms-2">
|
||||||
<button class="btn btn-outline-primary btn-sm" type="button" @click="onTableSelectAll(webList)">全选</button>
|
<button class="btn btn-outline-primary btn-sm" type="button"
|
||||||
<button class="btn btn-outline-secondary btn-sm" type="button" @click="onTableInvertSelection(webList)">反选</button>
|
@click="onTableSelectAll(webList)">全选</button>
|
||||||
<button class="btn btn-outline-danger btn-sm" type="button" @click="onTableClearAll(webList)">全不选</button>
|
<button class="btn btn-outline-secondary btn-sm" type="button"
|
||||||
|
@click="onTableInvertSelection(webList)">反选</button>
|
||||||
|
<button class="btn btn-outline-danger btn-sm" type="button"
|
||||||
|
@click="onTableClearAll(webList)">全不选</button>
|
||||||
|
</div>
|
||||||
|
<div v-if="errors.webTemplates" class="invalid-feedback d-block">
|
||||||
|
{{ errors.webTemplates }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 后端模板选项 -->
|
<!-- 后端模板选择区域 -->
|
||||||
<div class="col-12 mt-2 mb-3 p-3 bg-light rounded">
|
<div class="col-12 mt-2 mb-3 p-3 bg-light rounded">
|
||||||
<label class="form-check-inline col-form-label fw-medium">生成后端模板:</label>
|
<label class="form-check-inline col-form-label fw-medium">生成后端模板:</label>
|
||||||
<div class="form-check form-check-inline" v-for="(server,index) in serverList" :key="index">
|
<div class="form-check form-check-inline" v-for="(server,index) in serverList" :key="index">
|
||||||
<input class="form-check-input border-secondary" :id="server.id" type="checkbox"
|
<input class="form-check-input border-secondary"
|
||||||
:value="server.name" v-model="server.checked">
|
:class="{ 'is-invalid': errors.serverTemplates }" :id="server.id" type="checkbox"
|
||||||
<label class="form-check-label" :for="server.id" :data-bs-title="server.name"
|
v-model="server.checked" @change="validateTemplates">
|
||||||
data-bs-toggle="tooltip">{{server.label}}</label>
|
<label class="form-check-label" :title="server.name" :for="server.id">{{server.label}}</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-check form-check-inline btn-group ms-2">
|
<div class="form-check form-check-inline btn-group ms-2">
|
||||||
<button class="btn btn-outline-primary btn-sm" type="button" @click="onTableSelectAll(serverList)">全选</button>
|
<button class="btn btn-outline-primary btn-sm" type="button"
|
||||||
<button class="btn btn-outline-secondary btn-sm" type="button" @click="onTableInvertSelection(serverList)">反选</button>
|
@click="onTableSelectAll(serverList)">全选</button>
|
||||||
<button class="btn btn-outline-danger btn-sm" type="button" @click="onTableClearAll(serverList)">全不选</button>
|
<button class="btn btn-outline-secondary btn-sm" type="button"
|
||||||
|
@click="onTableInvertSelection(serverList)">反选</button>
|
||||||
|
<button class="btn btn-outline-danger btn-sm" type="button"
|
||||||
|
@click="onTableClearAll(serverList)">全不选</button>
|
||||||
|
</div>
|
||||||
|
<div v-if="errors.serverTemplates" class="invalid-feedback d-block">
|
||||||
|
{{ errors.serverTemplates }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 操作按钮 -->
|
<!-- 操作按钮区域 -->
|
||||||
<div class="row mt-4">
|
<div class="row mt-4">
|
||||||
<div class="col-md-4 btn-group">
|
<div class="col-md-4 btn-group">
|
||||||
<button class="btn btn-outline-primary" data-bs-title="选择数据表中所有的内容"
|
<button class="btn btn-outline-primary" data-bs-title="选择数据表中所有的内容" data-bs-toggle="tooltip"
|
||||||
data-bs-toggle="tooltip" type="button" @click="onSelectAll">
|
type="button" @click="onSelectAll">
|
||||||
全部选择
|
全部选择
|
||||||
</button>
|
</button>
|
||||||
<button class="btn btn-outline-secondary" data-bs-title="将选择的表格内容反向选择"
|
<button class="btn btn-outline-secondary" data-bs-title="将选择的表格内容反向选择" data-bs-toggle="tooltip"
|
||||||
data-bs-toggle="tooltip" type="button" @click="onInvertSelection">
|
type="button" @click="onInvertSelection">
|
||||||
全部反选
|
全部反选
|
||||||
</button>
|
</button>
|
||||||
<button class="btn btn-outline-danger" data-bs-title="取消全部已经选择的数据表"
|
<button class="btn btn-outline-danger" data-bs-title="取消全部已经选择的数据表" data-bs-toggle="tooltip"
|
||||||
data-bs-toggle="tooltip" type="button" @click="onClearAll">
|
type="button" @click="onClearAll">
|
||||||
全部取消
|
全部取消
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-4 btn-group">
|
<div class="col-md-4 btn-group">
|
||||||
<button class="btn btn-primary" data-bs-title="取消全部已经选择的数据表"
|
<button class="btn btn-primary" data-bs-title="生成全部已经选择的数据表" data-bs-toggle="tooltip"
|
||||||
data-bs-toggle="tooltip" type="button">
|
type="submit">
|
||||||
开始生成
|
生成选中表
|
||||||
</button>
|
</button>
|
||||||
<button class="btn btn-warning" type="button">清空生成记录</button>
|
<button class="btn btn-warning" type="button" data-bs-title="取消全部已经选择的数据表" data-bs-toggle="tooltip"
|
||||||
<button class="btn btn-success" type="button">下载全部</button>
|
@click="onClearGeneratorData">清空生成记录</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-4 d-grid gap-2">
|
<div class="col-md-4 d-grid gap-2">
|
||||||
<button class="btn btn-primary text-white" type="button">下载ZIP</button>
|
<button class="btn btn-primary text-white" type="button">下载ZIP</button>
|
||||||
|
@ -112,24 +149,116 @@ const MainForm = {
|
||||||
</div>
|
</div>
|
||||||
`,
|
`,
|
||||||
props: {
|
props: {
|
||||||
form: {
|
// 表单数据对象,包含生成代码所需的各种参数
|
||||||
type: Object,
|
form: {type: Object, required: true},
|
||||||
default: {}
|
// 生成代码的回调函数
|
||||||
}
|
onGeneratorCode: {type: Function, required: true},
|
||||||
|
// 清空生成记录
|
||||||
|
onClearGeneratorData: {type: Function, required: true},
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
// 默认是否折叠编辑表单
|
// 控制表单默认是否展开
|
||||||
defaultCollapse: true,
|
defaultCollapse: true,
|
||||||
// 后端路径列表
|
// 后端模板选项列表
|
||||||
serverList: ref([]),
|
serverList: ref([]),
|
||||||
// 前端路径列表
|
// 前端模板选项列表
|
||||||
webList: ref([]),
|
webList: ref([]),
|
||||||
|
// 错误信息对象
|
||||||
|
errors: {
|
||||||
|
authorName: '',
|
||||||
|
requestMapping: '',
|
||||||
|
packageName: '',
|
||||||
|
simpleDateFormat: '',
|
||||||
|
tablePrefixes: '',
|
||||||
|
webTemplates: '',
|
||||||
|
serverTemplates: ''
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
/* 获取所有vms下的文件路径 */
|
/**
|
||||||
|
* 验证表单字段
|
||||||
|
* @param {string} field - 字段名
|
||||||
|
*/
|
||||||
|
validateField(field) {
|
||||||
|
if (!this.form[field] || this.form[field].trim() === '') {
|
||||||
|
this.errors[field] = '此字段为必填项';
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
this.errors[field] = '';
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
|
||||||
|
/* 验证模板选择 */
|
||||||
|
validateTemplates() {
|
||||||
|
// 检查列表是否有一个选中的
|
||||||
|
const hasWebSelected = this.webList.some(item => item.checked);
|
||||||
|
const hasServerSelected = this.serverList.some(item => item.checked);
|
||||||
|
|
||||||
|
// 列表都没有选中
|
||||||
|
if (!hasWebSelected && !hasServerSelected) {
|
||||||
|
this.errors.webTemplates = '请至少选择一个前端或后端模板';
|
||||||
|
this.errors.serverTemplates = '请至少选择一个前端或后端模板';
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 列表选中让错误提示小时
|
||||||
|
this.errors.webTemplates = '';
|
||||||
|
this.errors.serverTemplates = '';
|
||||||
|
|
||||||
|
// 发生选择变化时,同时父级更新表单
|
||||||
|
this.updateForm();
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
|
||||||
|
/* 验证整个表单 */
|
||||||
|
validateForm() {
|
||||||
|
let isValid = true;
|
||||||
|
|
||||||
|
// 验证文本字段
|
||||||
|
const textFields = ['authorName', 'requestMapping', 'packageName', 'simpleDateFormat', 'tablePrefixes'];
|
||||||
|
textFields.forEach(field => {
|
||||||
|
if (!this.validateField(field)) {
|
||||||
|
isValid = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 验证模板选择
|
||||||
|
if (!this.validateTemplates()) {
|
||||||
|
isValid = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return isValid;
|
||||||
|
},
|
||||||
|
|
||||||
|
/* 更新父级表单 */
|
||||||
|
updateForm() {
|
||||||
|
const webList = this.webList.filter(item => item.checked).map(item => item.name);
|
||||||
|
const serverList = this.serverList.filter(item => item.checked).map(item => item.name);
|
||||||
|
|
||||||
|
const newForm = {...this.form, path: [...webList, ...serverList,]};
|
||||||
|
this.$emit("update:form", newForm);
|
||||||
|
},
|
||||||
|
|
||||||
|
/* 处理表单提交 */
|
||||||
|
handleSubmit() {
|
||||||
|
if (this.validateForm()) {
|
||||||
|
this.updateForm();
|
||||||
|
// 如果验证通过,调用父组件提供的生成代码方法
|
||||||
|
this.onGeneratorCode();
|
||||||
|
} else {
|
||||||
|
// 验证失败,可以在这里添加额外的处理逻辑
|
||||||
|
antd.message.error("表单验证失败")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取VMS资源路径列表
|
||||||
|
* 从服务器获取前端和后端模板的路径列表
|
||||||
|
* @async
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
async getVmsResourcePathList() {
|
async getVmsResourcePathList() {
|
||||||
const response = await axiosInstance.get("/vms/vmsResourcePathList");
|
const response = await axiosInstance.get("/vms/vmsResourcePathList");
|
||||||
const {data, code, message} = response;
|
const {data, code, message} = response;
|
||||||
|
@ -138,52 +267,58 @@ const MainForm = {
|
||||||
antd.message.error(message);
|
antd.message.error(message);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.serverList = data.server;
|
// 初始化模板选择状态
|
||||||
this.webList = data.web;
|
this.serverList = data.server.map(item => ({...item, checked: false}));
|
||||||
|
this.webList = data.web.map(item => ({...item, checked: false}));
|
||||||
},
|
},
|
||||||
|
|
||||||
/* 表格选择全部 */
|
/**
|
||||||
|
* 全选指定列表
|
||||||
|
* @param {Array} list - 要处理的列表
|
||||||
|
*/
|
||||||
onTableSelectAll(list) {
|
onTableSelectAll(list) {
|
||||||
list.forEach((item) => item.checked = true)
|
list.forEach(item => item.checked = true);
|
||||||
.filter((item) => {
|
this.validateTemplates();
|
||||||
console.log(item);
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/* 表格反选所选的 */
|
/**
|
||||||
|
* 反选指定列表
|
||||||
|
* @param {Array} list - 要处理的列表
|
||||||
|
*/
|
||||||
onTableInvertSelection(list) {
|
onTableInvertSelection(list) {
|
||||||
list.forEach((item) => item.checked = !item.checked);
|
list.forEach(item => item.checked = !item.checked);
|
||||||
|
this.validateTemplates();
|
||||||
},
|
},
|
||||||
|
|
||||||
/* 表格全不选 */
|
/**
|
||||||
|
* 清空指定列表的选择
|
||||||
|
* @param {Array} list - 要处理的列表
|
||||||
|
*/
|
||||||
onTableClearAll(list) {
|
onTableClearAll(list) {
|
||||||
list.forEach((item) => item.checked = false);
|
list.forEach(item => item.checked = false);
|
||||||
|
this.validateTemplates();
|
||||||
},
|
},
|
||||||
|
|
||||||
/* 全部选择 */
|
/* 全选所有模板 */
|
||||||
onSelectAll() {
|
onSelectAll() {
|
||||||
this.webList.forEach((item) => item.checked = true);
|
this.onTableSelectAll(this.webList);
|
||||||
this.serverList.forEach((item) => item.checked = true);
|
this.onTableSelectAll(this.serverList);
|
||||||
},
|
},
|
||||||
|
|
||||||
/* 反选 */
|
/* 反选所有模板 */
|
||||||
onInvertSelection() {
|
onInvertSelection() {
|
||||||
this.webList.forEach((item) => item.checked = !item.checked);
|
this.onTableInvertSelection(this.webList);
|
||||||
this.serverList.forEach((item) => item.checked = !item.checked);
|
this.onTableInvertSelection(this.serverList);
|
||||||
},
|
},
|
||||||
|
|
||||||
/* 清除所选中的 */
|
/* 清空所有模板的选择 */
|
||||||
onClearAll() {
|
onClearAll() {
|
||||||
this.webList.forEach((item) => item.checked = false);
|
this.onTableClearAll(this.webList);
|
||||||
this.serverList.forEach((item) => item.checked = false);
|
this.onTableClearAll(this.serverList);
|
||||||
},
|
}
|
||||||
|
|
||||||
/* 开始生成 */
|
|
||||||
onGenerator() {
|
|
||||||
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
async mounted() {
|
async mounted() {
|
||||||
|
// 组件挂载时获取模板列表
|
||||||
await this.getVmsResourcePathList();
|
await this.getVmsResourcePathList();
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,159 @@
|
||||||
|
const MainGeneratorPage = defineComponent({
|
||||||
|
name: "MainGeneratorPage",
|
||||||
|
template: `
|
||||||
|
<div :class="{'show': generatorPageFlag}" class="offcanvas offcanvas-start w-50" data-bs-scroll="false">
|
||||||
|
<!-- 侧边栏头部 -->
|
||||||
|
<div class="offcanvas-header bg-primary text-white">
|
||||||
|
<div>
|
||||||
|
<h5 class="offcanvas-title mb-1" id="offcanvasWithBothOptionsLabel">
|
||||||
|
<i class="bi bi-file-earmark-code me-2"></i>模板生成页面
|
||||||
|
</h5>
|
||||||
|
<p class="small mb-0 opacity-75">已生成的文件列表</p>
|
||||||
|
</div>
|
||||||
|
<button @click="onGeneratorPageFlagClick" aria-label="Close" class="btn-close btn-close-white" type="button"></button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 侧边栏内容区域 -->
|
||||||
|
<div class="offcanvas-body p-0">
|
||||||
|
<ol class="list-group list-group-numbered rounded-0">
|
||||||
|
<li class="list-group-item border-0 p-3" v-for="[table, value] in Object.entries(generatorData)" :key="table">
|
||||||
|
<h6 class="mb-0 fw-bold text-primary d-inline-block"><i class="bi bi-table me-2"></i>{{table}}</h6>
|
||||||
|
<span class="badge bg-primary rounded-pill float-end">{{value.length}} 模板</span>
|
||||||
|
|
||||||
|
<!-- 生成的文件列表 -->
|
||||||
|
<ul class="list-group list-group-flush">
|
||||||
|
<!-- 单个文件卡片 -->
|
||||||
|
<li class="list-group-item p-0 mb-2 border-0" v-for="(item, index) in value" :key="item.id">
|
||||||
|
<div class="card shadow-sm border-0">
|
||||||
|
<!-- 文件标题 - 可折叠 -->
|
||||||
|
<div class="card-header bg-light d-flex justify-content-between align-items-center p-3"
|
||||||
|
role="button" data-bs-toggle="collapse" :data-bs-target="'#collapse-' + item.id" aria-expanded="false">
|
||||||
|
<div class="d-flex align-items-center">
|
||||||
|
<i class="bi bi-bi-file-earmark-code me-2 text-primary fs-5"></i>
|
||||||
|
<span class="text-truncate" style="max-width: 80%">
|
||||||
|
【{{item.comment}}】{{item.path}}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<i class="bi bi-chevron-down transition-all"></i>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 文件内容 -->
|
||||||
|
<div class="collapse" :id="'collapse-' + item.id">
|
||||||
|
<div class="card-body p-0 bg-dark">
|
||||||
|
<div class="position-relative">
|
||||||
|
<!-- 使用条件渲染显示不同图标 -->
|
||||||
|
<i v-if="!copied"
|
||||||
|
class="bi bi-clipboard position-absolute text-white fs-4"
|
||||||
|
role="button" style="top: 10px; right: 10px" @click="onCopyToClipboard(item.code)"></i>
|
||||||
|
|
||||||
|
<i v-else
|
||||||
|
class="bi bi-clipboard-check position-absolute text-success fs-4"
|
||||||
|
role="button" style="top: 10px; right: 10px"></i>
|
||||||
|
</div>
|
||||||
|
<pre>
|
||||||
|
<code class="language-javascript hljs">
|
||||||
|
{{item.code}}
|
||||||
|
</code>
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 侧边栏底部操作按钮 -->
|
||||||
|
<div class="offcanvas-footer p-3 bg-light border-top">
|
||||||
|
<div class="d-grid gap-2">
|
||||||
|
<button class="btn btn-primary" @click="onDownloadAllFile">
|
||||||
|
<i class="bi bi-download me-2"></i>下载全部文件
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`,
|
||||||
|
props: {
|
||||||
|
// 是否显示生成页面
|
||||||
|
generatorPageFlag: {type: Boolean, default: true},
|
||||||
|
// 生成模板数据
|
||||||
|
generatorData: {type: Object},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
// 控制图标状态的响应式变量
|
||||||
|
copied: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
/**
|
||||||
|
* 点击复制图表
|
||||||
|
* 几秒后恢复原状
|
||||||
|
*/
|
||||||
|
onCopyToClipboard(code) {
|
||||||
|
const textarea = document.createElement('textarea');
|
||||||
|
textarea.value = code;
|
||||||
|
// 避免滚动到页面底部
|
||||||
|
textarea.style.position = 'fixed';
|
||||||
|
document.body.appendChild(textarea);
|
||||||
|
textarea.select();
|
||||||
|
|
||||||
|
try {
|
||||||
|
const successful = document.execCommand('copy');
|
||||||
|
if (successful) {
|
||||||
|
this.copied = true;
|
||||||
|
antd.notification.open({
|
||||||
|
type: 'success',
|
||||||
|
message: '复制成功',
|
||||||
|
description: '已将内容复制至剪切板',
|
||||||
|
duration: 3,
|
||||||
|
});
|
||||||
|
|
||||||
|
// 几秒后恢复原状
|
||||||
|
setTimeout(() => {
|
||||||
|
this.copied = false;
|
||||||
|
}, 2000);
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
antd.notification.open({
|
||||||
|
type: 'success',
|
||||||
|
message: '复制失败',
|
||||||
|
description: err.message,
|
||||||
|
duration: 3,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
document.body.removeChild(textarea);
|
||||||
|
},
|
||||||
|
|
||||||
|
/* 下载全部文件 */
|
||||||
|
onDownloadAllFile() {
|
||||||
|
// 遍历所有文件并下载
|
||||||
|
Object.values(this.generatorData).flat().forEach(item => {
|
||||||
|
const blob = new Blob([item.code], {type: 'text/plain'});
|
||||||
|
const url = URL.createObjectURL(blob);
|
||||||
|
const link = document.createElement('a');
|
||||||
|
|
||||||
|
// 从路径中提取文件名
|
||||||
|
const fileName = item.path.split('/').pop();
|
||||||
|
|
||||||
|
link.href = url;
|
||||||
|
link.download = fileName;
|
||||||
|
document.body.appendChild(link);
|
||||||
|
link.click();
|
||||||
|
|
||||||
|
// 清理
|
||||||
|
setTimeout(() => {
|
||||||
|
document.body.removeChild(link);
|
||||||
|
URL.revokeObjectURL(url);
|
||||||
|
}, 100);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
/* 关闭窗口 */
|
||||||
|
onGeneratorPageFlagClick() {
|
||||||
|
this.$emit("update:generatorPageFlag", !this.generatorPageFlag)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
|
@ -1,50 +1,74 @@
|
||||||
const MainTable = defineComponent({
|
const MainTable = defineComponent({
|
||||||
name: "MainTable",
|
name: "MainTable",
|
||||||
props: ["tableList", "rawTableList", "loading"],
|
|
||||||
template: `
|
template: `
|
||||||
<div class="card mt-2 shadow-sm">
|
<div class="card mt-2 shadow-sm">
|
||||||
<!-- 表格标题 -->
|
<!-- 表格标题和选择选项 -->
|
||||||
<div class="card-header bg-primary bg-opacity-10">
|
<div class="d-flex justify-content-between card-header bg-primary bg-opacity-10">
|
||||||
<h5 class="card-title mb-0">
|
<h5 class="card-title mb-0">
|
||||||
<i class="bi bi-table me-2"></i>数据表列表
|
<i class="bi bi-table me-2"></i>数据表列表
|
||||||
</h5>
|
</h5>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<div class="form-check form-check-inline">
|
||||||
|
<input class="form-check-input" name="TableSelectRadios" type="radio" id="radioSelectAll"
|
||||||
|
value="all" v-model="selectedOption">
|
||||||
|
<label class="form-check-label" for="radioSelectAll">选择全部</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-check form-check-inline">
|
||||||
|
<input class="form-check-input" name="TableSelectRadios" type="radio" id="radioSelectCurrentPage"
|
||||||
|
value="current" v-model="selectedOption">
|
||||||
|
<label class="form-check-label" for="radioSelectCurrentPage">选择当前页</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 表格体 -->
|
<!-- 表格内容区域 -->
|
||||||
<div class="card-body p-0">
|
<div class="card-body p-0">
|
||||||
<div class="table-responsive">
|
<div class="table-responsive">
|
||||||
<!-- 加载中... -->
|
<!-- 加载状态 -->
|
||||||
<div class="p-5 text-center" v-if="loading">
|
<div class="p-5 text-center" v-if="loading">
|
||||||
<div class="spinner-border" role="status">
|
<div class="spinner-border" role="status">
|
||||||
<span class="visually-hidden">Loading...</span>
|
<span class="visually-hidden">Loading...</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 展示当前数据库所有的表 -->
|
<!-- 空状态提示 -->
|
||||||
|
<div class="p-5 text-center" v-else-if="tableList.length === 0">
|
||||||
|
<i class="bi bi-exclamation-circle fs-1 text-muted"></i>
|
||||||
|
<p class="mt-2 text-muted">没有找到数据表</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 数据表格 -->
|
||||||
<table class="table table-striped table-bordered table-hover mb-0" v-else>
|
<table class="table table-striped table-bordered table-hover mb-0" v-else>
|
||||||
<thead class="table-light">
|
<thead class="table-light">
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="col" width="2%">
|
<th scope="col" width="2%">
|
||||||
<input class="form-check-input border-secondary" type="checkbox" value="option2">
|
<input class="form-check-input border-secondary" type="checkbox"
|
||||||
|
v-model="tableSelectAllChecked" @change="onSelectAllTable">
|
||||||
</th>
|
</th>
|
||||||
<th scope="col" width="5%">#</th>
|
<th scope="col" width="3%">#</th>
|
||||||
<th scope="col" width="30%">表名</th>
|
<th scope="col" width="30%">表名</th>
|
||||||
<th scope="col" width="35%">注释</th>
|
<th scope="col" width="35%">注释</th>
|
||||||
<th scope="col" width="18%">所属数据库</th>
|
<th scope="col" width="20%">所属数据库</th>
|
||||||
<th class="text-center" scope="col" width="10%">操作</th>
|
<th class="text-center" scope="col" width="10%">操作</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr :key="index" v-for="(table,index) in paginatedTableList">
|
<tr :key="table.tableName" v-for="(table, index) in paginatedTableList">
|
||||||
<th scope="row">
|
<td>
|
||||||
<input class="form-check-input border-secondary" type="checkbox" value="option2">
|
<input class="form-check-input border-secondary" type="checkbox"
|
||||||
</th>
|
v-model="table.checked" @change="onSelectTable($event, table)">
|
||||||
<th scope="row">{{index + 1}}</th>
|
</td>
|
||||||
<td><a class="text-decoration-none" href="#">{{ table.tableName}}</a></td>
|
<td>{{ (currentPage - 1) * itemsPerPage + index + 1 }}</td>
|
||||||
<td>{{ table.comment }}</td>
|
<td>
|
||||||
|
<a class="text-decoration-none" href="#" @click.prevent="onGeneratorCode(table)">
|
||||||
|
{{ table.tableName }}
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
<td>{{ table.comment || '无注释' }}</td>
|
||||||
<td>{{ table.tableCat }}</td>
|
<td>{{ table.tableCat }}</td>
|
||||||
<td class="text-center">
|
<td class="text-center">
|
||||||
<button class="btn btn-sm btn-outline-primary" @click="onGeneratorCodeClick">
|
<button class="btn btn-sm btn-outline-primary" @click="onGeneratorCode(table)">
|
||||||
<i class="bi bi-gear"></i> 生成
|
<i class="bi bi-gear"></i> 生成
|
||||||
</button>
|
</button>
|
||||||
</td>
|
</td>
|
||||||
|
@ -54,37 +78,39 @@ const MainTable = defineComponent({
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 底部分页 -->
|
<!-- 分页控件 -->
|
||||||
<div class="card-footer bg-light">
|
<div class="card-footer bg-light" v-if="tableList.length > 0">
|
||||||
<div class="d-flex justify-content-between align-items-center">
|
<div class="d-flex justify-content-between align-items-center">
|
||||||
<div class="form-text">共 {{ rawTableList.length }} 条</div>
|
<div class="form-text">
|
||||||
|
显示 {{ (currentPage - 1) * itemsPerPage + 1 }}~{{ Math.min(currentPage * itemsPerPage, rawTableList.length) }} 条,共 {{ rawTableList.length }} 条
|
||||||
|
</div>
|
||||||
|
|
||||||
<nav aria-label="Page navigation">
|
<nav aria-label="Page navigation">
|
||||||
<ul class="pagination mb-0">
|
<ul class="pagination mb-0">
|
||||||
<li :class="{ disabled: currentPage === 1 }" class="page-item">
|
<li :class="{ disabled: currentPage === 1 }" class="page-item">
|
||||||
<a @click.prevent="currentPage = 1" class="page-link" href="#">
|
<a @click.prevent="goToPage(1)" class="page-link" href="#">
|
||||||
<i class="bi bi-chevron-double-left"></i>
|
<i class="bi bi-chevron-double-left"></i>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li :class="{ disabled: currentPage === 1 }" class="page-item">
|
<li :class="{ disabled: currentPage === 1 }" class="page-item">
|
||||||
<a @click.prevent="currentPage--" class="page-link" href="#">
|
<a @click.prevent="goToPage(currentPage - 1)" class="page-link" href="#">
|
||||||
<i class="bi bi-chevron-left"></i>
|
<i class="bi bi-chevron-left"></i>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<!-- 显示页码 -->
|
<!-- 显示页码 -->
|
||||||
<li :class="{ active: currentPage === page }" :key="page" class="page-item"
|
<li v-for="page in visiblePages" :key="page"
|
||||||
v-for="page in visiblePages">
|
:class="{ active: currentPage === page }" class="page-item">
|
||||||
<a @click.prevent="currentPage = page" class="page-link" href="#">{{ page }}</a>
|
<a @click.prevent="goToPage(page)" class="page-link" href="#">{{ page }}</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li :class="{ disabled: currentPage === totalPages }" class="page-item">
|
<li :class="{ disabled: currentPage === totalPages }" class="page-item">
|
||||||
<a @click.prevent="currentPage++" class="page-link" href="#">
|
<a @click.prevent="goToPage(currentPage + 1)" class="page-link" href="#">
|
||||||
<i class="bi bi-chevron-right"></i>
|
<i class="bi bi-chevron-right"></i>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li :class="{ disabled: currentPage === totalPages }" class="page-item">
|
<li :class="{ disabled: currentPage === totalPages }" class="page-item">
|
||||||
<a @click.prevent="currentPage = totalPages" class="page-link" href="#">
|
<a @click.prevent="goToPage(totalPages)" class="page-link" href="#">
|
||||||
<i class="bi bi-chevron-double-right"></i>
|
<i class="bi bi-chevron-double-right"></i>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
@ -97,9 +123,9 @@ const MainTable = defineComponent({
|
||||||
每页 {{ itemsPerPage }} 条
|
每页 {{ itemsPerPage }} 条
|
||||||
</button>
|
</button>
|
||||||
<ul aria-labelledby="itemsPerPageDropdown" class="dropdown-menu">
|
<ul aria-labelledby="itemsPerPageDropdown" class="dropdown-menu">
|
||||||
<li :key="index" v-for="(table,index) in tablePageOptions">
|
<li v-for="option in tablePageOptions" :key="option">
|
||||||
<a @click.prevent="itemsPerPage = table" class="dropdown-item" href="JavaScript:">
|
<a @click.prevent="changeItemsPerPage(option)" class="dropdown-item" href="#">
|
||||||
{{table}} 条/页
|
{{ option }} 条/页
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -108,31 +134,86 @@ const MainTable = defineComponent({
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`,
|
`,
|
||||||
|
props: {
|
||||||
|
// 加载状态
|
||||||
|
loading: {type: Boolean, default: false},
|
||||||
|
// 处理后的表格数据(包含checked状态)
|
||||||
|
tableList: {type: Array, required: true, default: () => []},
|
||||||
|
// 原始表格数据(不包含checked状态)
|
||||||
|
rawTableList: {type: Array, required: true, default: () => []},
|
||||||
|
// 生成代码的回调函数
|
||||||
|
onGeneratorCode: {type: Function, required: true},
|
||||||
|
// 表单数据
|
||||||
|
form: {type: Object, required: true},
|
||||||
|
// 数据库选择发生变化
|
||||||
|
dbSelect: {type: String, required: true},
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
// 分页相关数据
|
// 当前页码
|
||||||
currentPage: ref(1),
|
currentPage: 1,
|
||||||
// 每页数
|
// 每页显示条数
|
||||||
itemsPerPage: ref(30),
|
itemsPerPage: 30,
|
||||||
// 表格选项
|
// 每页条数选项
|
||||||
tablePageOptions: [5, 10, 15, 30, 50, 100, 150, 200]
|
tablePageOptions: [5, 10, 15, 30, 50, 100, 150, 200],
|
||||||
|
// 选择模式:all-全选 current-当前页
|
||||||
|
selectedOption: "current",
|
||||||
|
// 表头全选状态
|
||||||
|
tableSelectAllChecked: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
// 计算总页数
|
/**
|
||||||
|
* 计算总页数
|
||||||
|
* @returns {number} 总页数
|
||||||
|
*/
|
||||||
totalPages() {
|
totalPages() {
|
||||||
const totalItems = this.rawTableList.length;
|
return Math.ceil(this.rawTableList.length / this.itemsPerPage);
|
||||||
return Math.ceil(totalItems / this.itemsPerPage);
|
|
||||||
},
|
},
|
||||||
// 分页后的数据
|
|
||||||
|
/**
|
||||||
|
* 当前页的数据
|
||||||
|
* @returns {Array} 分页后的数据
|
||||||
|
*/
|
||||||
paginatedTableList() {
|
paginatedTableList() {
|
||||||
const start = (this.currentPage - 1) * this.itemsPerPage;
|
const start = (this.currentPage - 1) * this.itemsPerPage;
|
||||||
const end = start + this.itemsPerPage;
|
const end = start + this.itemsPerPage;
|
||||||
return this.tableList.slice(start, end);
|
return this.tableList.slice(start, end);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 当前选中的表名数组
|
||||||
|
* @returns {Array} 选中的表名
|
||||||
|
*/
|
||||||
|
selectedTableNames() {
|
||||||
|
return this.tableList.filter(table => table.checked).map(table => table.tableName);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
/* 计算可见的页码范围 */
|
/**
|
||||||
|
* 跳转到指定页码
|
||||||
|
* @param {number} page - 目标页码
|
||||||
|
*/
|
||||||
|
goToPage(page) {
|
||||||
|
if (page >= 1 && page <= this.totalPages) {
|
||||||
|
this.currentPage = page;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更改每页显示条数
|
||||||
|
* @param {number} size - 每页条数
|
||||||
|
*/
|
||||||
|
changeItemsPerPage(size) {
|
||||||
|
this.itemsPerPage = size;
|
||||||
|
// 重置到第一页
|
||||||
|
this.currentPage = 1;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计算可见的页码范围
|
||||||
|
* @returns {Array} 可见页码数组
|
||||||
|
*/
|
||||||
visiblePages() {
|
visiblePages() {
|
||||||
// 显示当前页前后各2页
|
// 显示当前页前后各2页
|
||||||
const range = 2;
|
const range = 2;
|
||||||
|
@ -146,9 +227,91 @@ const MainTable = defineComponent({
|
||||||
return pages;
|
return pages;
|
||||||
},
|
},
|
||||||
|
|
||||||
/* 点击生成代码 */
|
/**
|
||||||
onGeneratorCodeClick() {
|
* 表头全选/取消全选
|
||||||
console.log(6655)
|
* 当前选择的是所有书库,操作列表为 this.tableList
|
||||||
|
* 当前选择的是当前页的数据库表,操作列表为 this.paginatedTableList
|
||||||
|
*/
|
||||||
|
onSelectAllTable() {
|
||||||
|
const checked = this.tableSelectAllChecked;
|
||||||
|
|
||||||
|
// 选择是否是所有的数据库
|
||||||
|
const tablesToUpdate = this.selectedOption === "all"
|
||||||
|
? this.tableList
|
||||||
|
: this.paginatedTableList;
|
||||||
|
|
||||||
|
// 将数据库变为当前选中的状态
|
||||||
|
tablesToUpdate.forEach(table => table.checked = checked);
|
||||||
|
|
||||||
|
// 更新父级列表状态
|
||||||
|
this.updateFormSelectedTables();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 选择单个表
|
||||||
|
* @param {Event} event - 事件对象
|
||||||
|
* @param {Object} table - 表数据对象
|
||||||
|
*/
|
||||||
|
onSelectTable(event, table) {
|
||||||
|
table.checked = event.target.checked;
|
||||||
|
this.updateFormSelectedTables();
|
||||||
|
|
||||||
|
// 更新表头全选状态
|
||||||
|
if (!table.checked) {
|
||||||
|
this.tableSelectAllChecked = false;
|
||||||
|
} else {
|
||||||
|
this.tableSelectAllChecked = this.paginatedTableList.every(t => t.checked);
|
||||||
}
|
}
|
||||||
})
|
},
|
||||||
|
|
||||||
|
/* 更新表单中选中的表名 */
|
||||||
|
updateFormSelectedTables() {
|
||||||
|
const payload = {
|
||||||
|
...this.form,
|
||||||
|
tableNames: this.selectedTableNames
|
||||||
|
}
|
||||||
|
// 更新父级 form 的内容
|
||||||
|
this.$emit("update:form", payload);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重置父级表单
|
||||||
|
* 如果要同时更新会变得很复杂所以在这里讲逻辑定义为:
|
||||||
|
* 选型变化时直接取消全部,之后重新选择
|
||||||
|
*/
|
||||||
|
restForm() {
|
||||||
|
this.tableSelectAllChecked = false;
|
||||||
|
this.tableList.forEach(table => table.checked = false);
|
||||||
|
this.updateFormSelectedTables();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
/**
|
||||||
|
* 监听选择模式变化
|
||||||
|
*/
|
||||||
|
selectedOption() {
|
||||||
|
this.restForm();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 监听当前页变化
|
||||||
|
*/
|
||||||
|
currentPage() {
|
||||||
|
this.restForm();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 监听每页条数变化
|
||||||
|
*/
|
||||||
|
itemsPerPage() {
|
||||||
|
this.restForm();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据库选择发生变化也重置表单
|
||||||
|
*/
|
||||||
|
dbSelect() {
|
||||||
|
this.restForm();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
|
@ -7,8 +7,10 @@
|
||||||
<link rel="stylesheet" th:href="@{/src/lib/css/bootstrap.min.css}">
|
<link rel="stylesheet" th:href="@{/src/lib/css/bootstrap.min.css}">
|
||||||
<!-- 本地引入 Bootstrap Icons -->
|
<!-- 本地引入 Bootstrap Icons -->
|
||||||
<link rel="stylesheet" th:href="@{/src/lib/css/bootstrap-icons.min.css}">
|
<link rel="stylesheet" th:href="@{/src/lib/css/bootstrap-icons.min.css}">
|
||||||
|
<!-- 引入Highlight.js的CSS -->
|
||||||
|
<link rel="stylesheet" th:href="@{/src/lib/css/atom-one-dark.min.css}">
|
||||||
<!-- 本地引入 Vue.js -->
|
<!-- 本地引入 Vue.js -->
|
||||||
<script th:src="@{/src/lib/js/vue/vue.global.prod.js}"></script>
|
<script th:src="@{/src/lib/js/vue/vue.global.js}"></script>
|
||||||
<!-- 本地引入 Bootstrap JS -->
|
<!-- 本地引入 Bootstrap JS -->
|
||||||
<script th:src="@{/src/lib/js/boostrap/bootstrap.bundle.min.js}"></script>
|
<script th:src="@{/src/lib/js/boostrap/bootstrap.bundle.min.js}"></script>
|
||||||
<!-- 本地引入 popper JS -->
|
<!-- 本地引入 popper JS -->
|
||||||
|
@ -39,23 +41,38 @@
|
||||||
v-model:db-select="dbSelect" v-model:table-select="tableSelect"></main-card>
|
v-model:db-select="dbSelect" v-model:table-select="tableSelect"></main-card>
|
||||||
|
|
||||||
<!-- 填写生成表单 -->
|
<!-- 填写生成表单 -->
|
||||||
<main-form :form="form"></main-form>
|
<main-form :on-clear-generator-data="onClearGeneratorData" :on-generator-code="onGeneratorCode"
|
||||||
|
ref="mainFormRef"
|
||||||
|
v-model:form="form"></main-form>
|
||||||
|
|
||||||
<!-- 表格显示 -->
|
<!-- 表格显示 -->
|
||||||
<main-table :loading="loading" :raw-table-list="rawTableList" :table-list="tableList"></main-table>
|
<main-table :db-select="dbSelect" :loading="loading" :on-generator-code="onGeneratorCode"
|
||||||
|
:raw-table-list="rawTableList" :table-list="tableList" v-model:form="form"></main-table>
|
||||||
|
|
||||||
|
<!-- 模板生成页面 -->
|
||||||
|
<main-generator-page :generator-data="generatorData"
|
||||||
|
v-model:generator-page-flag="generatorPageFlag"></main-generator-page>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
|
<!-- 引入Highlight.js -->
|
||||||
|
<script th:src="@{/src/lib/js/highlightjs/highlight.min.js}"></script>
|
||||||
|
<script th:src="@{/src/lib/js/highlightjs/javascript.min.js}"></script>
|
||||||
|
<!-- 初始化 Highlight.js -->
|
||||||
|
<script th:src="@{/src/config/highlight-config.js}"></script>
|
||||||
<!-- 设置 popper 提示框 -->
|
<!-- 设置 popper 提示框 -->
|
||||||
<script th:src="@{/src/config/popper-config.js}"></script>
|
<script th:src="@{/src/config/popper-config.js}"></script>
|
||||||
<!-- 加载全局axios配置 -->
|
<!-- 加载全局axios配置 -->
|
||||||
<script th:src="@{/src/config/axios-config.js}"></script>
|
<script th:src="@{/src/config/axios-config.js}"></script>
|
||||||
|
|
||||||
<!-- 引入组件 -->
|
<!-- 引入组件 -->
|
||||||
<script th:src="@{/src/components/AppHeader.js}"></script>
|
<script th:src="@{/src/components/AppHeader.js}"></script>
|
||||||
<script th:src="@{/src/views/home/MainCard.js}"></script>
|
<script th:src="@{/src/views/home/MainCard.js}"></script>
|
||||||
<script th:src="@{/src/views/home/MainForm.js}"></script>
|
<script th:src="@{/src/views/home/MainForm.js}"></script>
|
||||||
<script th:src="@{/src/views/home/MainTable.js}"></script>
|
<script th:src="@{/src/views/home/MainTable.js}"></script>
|
||||||
|
<script th:src="@{/src/views/home/MainGeneratorPage.js}"></script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
const {createApp, ref} = Vue
|
const {createApp, ref} = Vue
|
||||||
|
|
||||||
|
@ -73,15 +90,13 @@
|
||||||
// 是否加载
|
// 是否加载
|
||||||
loading: ref(false),
|
loading: ref(false),
|
||||||
// 提交的表单
|
// 提交的表单
|
||||||
form: {
|
form: ref({
|
||||||
// 作者名称
|
// 作者名称
|
||||||
authorName: "Bunny",
|
authorName: "Bunny",
|
||||||
// requestMapping名称
|
// requestMapping名称
|
||||||
requestMapping: "/api",
|
requestMapping: "/api",
|
||||||
// 表名称
|
// 表名称
|
||||||
tableName: "",
|
tableNames: [],
|
||||||
// 类名称
|
|
||||||
className: "",
|
|
||||||
// 包名称
|
// 包名称
|
||||||
packageName: "cn.bunny",
|
packageName: "cn.bunny",
|
||||||
// 时间格式
|
// 时间格式
|
||||||
|
@ -90,21 +105,24 @@
|
||||||
tablePrefixes: "t_,sys_,qrtz_,log_",
|
tablePrefixes: "t_,sys_,qrtz_,log_",
|
||||||
// 生成代码路径
|
// 生成代码路径
|
||||||
path: []
|
path: []
|
||||||
},
|
}),
|
||||||
|
// 是否显示生成页面
|
||||||
|
generatorPageFlag: ref(false),
|
||||||
|
// 生成的数据
|
||||||
|
generatorData: ref({}),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
/* 获取[当前/所有]数据库表 */
|
/* 获取[当前/所有]数据库表 */
|
||||||
async getDatabaseTableList() {
|
async getDatabaseTableList() {
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
|
|
||||||
// 查询数据库表
|
// 查询数据库表
|
||||||
const response = await axiosInstance.get("/table/databaseTableList", {params: {dbName: this.dbSelect}});
|
const response = await axiosInstance.get("/table/databaseTableList", {params: {dbName: this.dbSelect}});
|
||||||
const {data, code, message} = response;
|
const {data, code, message} = response;
|
||||||
|
|
||||||
if (code !== 200) {
|
if (code !== 200) {
|
||||||
antd.message.error(message);
|
antd.message.error(message);
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 设置数据库列表
|
// 设置数据库列表
|
||||||
|
@ -116,6 +134,36 @@
|
||||||
|
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成代码
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
async onGeneratorCode() {
|
||||||
|
// 验证表单是否通过
|
||||||
|
const isValidate = this.$refs.mainFormRef.validateForm();
|
||||||
|
if (!isValidate) return;
|
||||||
|
|
||||||
|
// 请求生成模板
|
||||||
|
const {data, code, message} = await axiosInstance.post("/vms/generator", this.form);
|
||||||
|
|
||||||
|
// 判断是否请求成功
|
||||||
|
if (code !== 200) return;
|
||||||
|
else antd.message.success(message);
|
||||||
|
|
||||||
|
// 显示生成的页面
|
||||||
|
this.generatorPageFlag = true;
|
||||||
|
this.generatorData = data;
|
||||||
|
|
||||||
|
// 等待 DOM 更新,之后手动更新代码高亮
|
||||||
|
await this.$nextTick();
|
||||||
|
hljs.highlightAll();
|
||||||
|
},
|
||||||
|
|
||||||
|
/* 清空已经生成的内容 */
|
||||||
|
onClearGeneratorData() {
|
||||||
|
this.generatorData = {};
|
||||||
|
},
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
/* 数据表选择 */
|
/* 数据表选择 */
|
||||||
|
@ -132,7 +180,7 @@
|
||||||
// 根据表名进行过滤筛选或者根据注释内容进行筛选
|
// 根据表名进行过滤筛选或者根据注释内容进行筛选
|
||||||
this.tableList = this.tableList.filter(table => table.tableName.includes(val) || table.tablePrefixes.includes(val));
|
this.tableList = this.tableList.filter(table => table.tableName.includes(val) || table.tablePrefixes.includes(val));
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -141,6 +189,7 @@
|
||||||
app.component('MainCard', MainCard);
|
app.component('MainCard', MainCard);
|
||||||
app.component('MainForm', MainForm);
|
app.component('MainForm', MainForm);
|
||||||
app.component('MainTable', MainTable);
|
app.component('MainTable', MainTable);
|
||||||
|
app.component('MainGeneratorPage', MainGeneratorPage);
|
||||||
|
|
||||||
app.mount('#app');
|
app.mount('#app');
|
||||||
</script>
|
</script>
|
||||||
|
|
Loading…
Reference in New Issue