💄 主页面组件
This commit is contained in:
parent
f8467610f6
commit
0cd9129efa
|
@ -3,7 +3,7 @@ server:
|
|||
|
||||
spring:
|
||||
profiles:
|
||||
active: prod
|
||||
active: dev
|
||||
application:
|
||||
name: generator-code
|
||||
thymeleaf:
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
// 如果一开始定义过了 defineComponent 就不要在下 script 标签中再写了
|
||||
const {defineComponent} = Vue;
|
||||
|
||||
// 定义 Header 组件
|
||||
const AppHeader = defineComponent({
|
||||
name: "AppHeader",
|
||||
template: `
|
||||
<div class="text-center mb-4">
|
||||
<h2 class="text-primary fw-bold">
|
||||
<i class="bi bi-code-square me-2"></i>
|
||||
代码生成器
|
||||
</h2>
|
||||
<p class="text-muted">快速生成数据库表对应的代码</p>
|
||||
</div>
|
||||
`
|
||||
});
|
|
@ -0,0 +1,194 @@
|
|||
const MainCard = defineComponent({
|
||||
name: "MainCard",
|
||||
props: {
|
||||
rawTableList: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 选择的数据库名称
|
||||
dbName: ref(""),
|
||||
// 输入的表名
|
||||
tableName: ref(""),
|
||||
// 查询数据库加载
|
||||
dbLoading: ref(false),
|
||||
// 数据库信息
|
||||
databaseInfo: ref({}),
|
||||
// 所有数据库列表
|
||||
databaseList: ref([]),
|
||||
}
|
||||
},
|
||||
template: `
|
||||
<div class="card shadow-sm">
|
||||
<!-- 卡片头部 -->
|
||||
<div class="card-header bg-primary bg-opacity-10 border-bottom">
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<div>
|
||||
<h5 class="card-title mb-0">
|
||||
<i class="bi bi-info-circle-fill text-primary me-2"></i>使用提示
|
||||
</h5>
|
||||
</div>
|
||||
<div>
|
||||
<span class="badge bg-primary rounded-pill me-2">
|
||||
<i class="bi bi-database me-1"></i>
|
||||
数据库: <span class="fw-normal">{{databaseList.length}}</span>
|
||||
</span>
|
||||
<span class="badge bg-primary rounded-pill">
|
||||
<i class="bi bi-table me-1"></i>
|
||||
数据库表: <span class="fw-normal">{{rawTableList.length}}</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<p class="card-subtitle mt-2 text-muted">
|
||||
<i class="bi bi-mouse me-1"></i>
|
||||
点击 <code class="bg-primary bg-opacity-10">表名</code> 或
|
||||
<code class="bg-primary bg-opacity-10">生成</code> 进行跳转
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- 卡片主体 -->
|
||||
<div class="card-body">
|
||||
<div class="d-flex flex-wrap align-items-center gap-3">
|
||||
<!-- GitHub 链接 -->
|
||||
<a class="btn btn-outline-dark d-flex align-items-center gap-2"
|
||||
href="https://github.com/BunnyMaster/generator-code-server" target="_blank">
|
||||
<svg class="feather feather-github" fill="none" height="20" stroke="currentColor"
|
||||
stroke-linecap="round" stroke-linejoin="round" stroke-width="2" viewBox="0 0 24 24"
|
||||
width="20"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M9 19c-5 1.5-5-2.5-7-3m14 6v-3.87a3.37 3.37 0 0 0-.94-2.61c3.14-.35 6.44-1.54 6.44-7A5.44 5.44 0 0 0 20 4.77 5.07 5.07 0 0 0 19.91 1S18.73.65 16 2.48a13.38 13.38 0 0 0-7 0C6.27.65 5.09 1 5.09 1A5.07 5.07 0 0 0 5 4.77a5.44 5.44 0 0 0-1.5 3.78c0 5.42 3.3 6.61 6.44 7A3.37 3.37 0 0 0 9 18.13V22"></path>
|
||||
</svg>
|
||||
GitHub 仓库
|
||||
</a>
|
||||
|
||||
<!-- Gitee 链接 -->
|
||||
<a class="btn btn-outline-danger d-flex align-items-center gap-2"
|
||||
href="https://gitee.com/BunnyBoss/generator-code-server" target="_blank">
|
||||
<svg height="20" viewBox="0 0 24 24" width="20" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M11.984 0A12 12 0 0 0 0 12a12 12 0 0 0 12 12a12 12 0 0 0 12-12A12 12 0 0 0 12 0zm6.09 5.333c.328 0 .593.266.592.593v1.482a.594.594 0 0 1-.593.592H9.777c-.982 0-1.778.796-1.778 1.778v5.63c0 .327.266.592.593.592h5.63c.982 0 1.778-.796 1.778-1.778v-.296a.593.593 0 0 0-.592-.593h-4.15a.59.59 0 0 1-.592-.592v-1.482a.593.593 0 0 1 .593-.592h6.815c.327 0 .593.265.593.592v3.408a4 4 0 0 1-4 4H5.926a.593.593 0 0 1-.593-.593V9.778a4.444 4.444 0 0 1 4.445-4.444h8.296Z"
|
||||
fill="currentColor"/>
|
||||
</svg>
|
||||
Gitee 仓库
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 卡片底部 - 数据库选择 -->
|
||||
<div class="card-footer bg-light">
|
||||
<div class="row g-3 align-items-end">
|
||||
<div class="col-md-5">
|
||||
<label class="form-label fw-semibold" for="databaseSelect">
|
||||
<i class="bi bi-database me-1"></i>数据库选择
|
||||
</label>
|
||||
<select class="form-select shadow-sm" id="databaseSelect" v-model="dbName">
|
||||
<option disabled selected>请选择数据库...</option>
|
||||
<option :key="index" :title="db.comment" :value="db.tableCat"
|
||||
v-for="(db,index) in databaseList">
|
||||
{{db.tableCat}}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="col-md-5">
|
||||
<label class="form-label fw-semibold" for="tableSelect">
|
||||
<i class="bi bi-table me-1"></i>
|
||||
数据库表选择
|
||||
</label>
|
||||
<input class="form-control shadow-sm" id="tableSelect" placeholder="输入表名或表注释"
|
||||
v-model="tableName"/>
|
||||
</div>
|
||||
|
||||
<div class="col-md-2 d-grid">
|
||||
<button class="btn btn-primary shadow-sm" disabled type="button"
|
||||
v-if="dbLoading">
|
||||
<span aria-hidden="true" class="spinner-grow spinner-grow-sm"></span>
|
||||
<span role="status">Loading...</span>
|
||||
</button>
|
||||
|
||||
<button @click="onRefresh" class="btn btn-primary shadow-sm" v-else>
|
||||
<i class="bi bi-search me-1"></i>
|
||||
查询
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="pt-1 bg-light">
|
||||
<a class="d-flex align-items-center text-decoration-none" data-bs-toggle="collapse"
|
||||
href="#dbInfoCollapse">
|
||||
<i class="bi bi-database me-2"></i>
|
||||
<span>数据库连接详情</span>
|
||||
<i class="bi bi-chevron-down ms-auto"></i>
|
||||
</a>
|
||||
<div class="collapse mt-2" id="dbInfoCollapse">
|
||||
<div class="card card-body bg-white">
|
||||
<ul class="list-unstyled mb-0">
|
||||
<li class="mb-2">
|
||||
<strong>数据库:</strong> {{databaseInfo.databaseProductName}}
|
||||
{{databaseInfo.databaseProductVersion}}
|
||||
</li>
|
||||
<li class="mb-2">
|
||||
<strong>驱动:</strong> {{databaseInfo.driverName}}
|
||||
({{databaseInfo.driverVersion}})
|
||||
</li>
|
||||
<li class="mb-2"><strong>URL:</strong>
|
||||
<code class="d-block text-break">{{databaseInfo.url}}</code>
|
||||
</li>
|
||||
<li class="mb-2"><strong>用户:</strong> {{databaseInfo.username}}</li>
|
||||
<li><strong>当前库:</strong> {{dbName}}</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
methods: {
|
||||
/* 当前连接的数据库信息 */
|
||||
async getDatabaseInfoMetaData() {
|
||||
this.dbLoading = true;
|
||||
|
||||
const response = await axios.get("/table/databaseInfoMetaData");
|
||||
const {data, code} = response.data;
|
||||
if (code !== 200) return;
|
||||
|
||||
this.databaseInfo = data
|
||||
|
||||
// 设置返回的所有的数据库列表
|
||||
this.databaseList = data.databaseList;
|
||||
|
||||
// 设置当前的数据库,为空时赋值,否则就用自己选择的
|
||||
if (!this.dbName) {
|
||||
this.dbName = data.currentDatabase;
|
||||
}
|
||||
|
||||
this.dbLoading = false;
|
||||
},
|
||||
|
||||
/* 刷新查询 */
|
||||
async onRefresh() {
|
||||
await this.getDatabaseInfoMetaData();
|
||||
this.$emit("getDatabaseTableList")
|
||||
}
|
||||
},
|
||||
async mounted() {
|
||||
// 当前连接的数据库信息
|
||||
await this.getDatabaseInfoMetaData();
|
||||
},
|
||||
watch: {
|
||||
/* 绑定到外部的变量---dbSelect */
|
||||
dbName: {
|
||||
handler(val) {
|
||||
this.$emit("update:dbSelect", val)
|
||||
},
|
||||
},
|
||||
|
||||
/* 绑定到外部的变量---tableSelect */
|
||||
tableName: {
|
||||
handler(val) {
|
||||
this.$emit("update:tableSelect", val)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
|
@ -0,0 +1,142 @@
|
|||
const MainTable = defineComponent({
|
||||
name: "MainTable",
|
||||
props: ["tableList", "rawTableList", "loading"],
|
||||
template: `
|
||||
<div class="card mt-4 shadow-sm">
|
||||
<div class="card-header bg-primary bg-opacity-10">
|
||||
<h5 class="card-title mb-0">
|
||||
<i class="bi bi-table me-2"></i>数据表列表
|
||||
</h5>
|
||||
</div>
|
||||
|
||||
<div class="card-body p-0">
|
||||
<div class="table-responsive">
|
||||
<!-- 加载中... -->
|
||||
<div class="p-5 text-center" v-if="loading">
|
||||
<div class="spinner-border" role="status">
|
||||
<span class="visually-hidden">Loading...</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 展示当前数据库所有的表 -->
|
||||
<table class="table table-striped table-bordered table-hover mb-0" v-else>
|
||||
<thead class="table-light">
|
||||
<tr>
|
||||
<th scope="col" width="5%">#</th>
|
||||
<th scope="col" width="30%">表名</th>
|
||||
<th scope="col" width="35%">注释</th>
|
||||
<th scope="col" width="20%">所属数据库</th>
|
||||
<th class="text-center" scope="col" width="10%">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr :key="index" v-for="(table,index) in paginatedTableList">
|
||||
<th scope="row">{{index + 1}}</th>
|
||||
<td><a class="text-decoration-none" href="#">{{ table.tableName}}</a></td>
|
||||
<td>{{ table.comment }}</td>
|
||||
<td>{{ table.tableCat }}</td>
|
||||
<td class="text-center">
|
||||
<button class="btn btn-sm btn-outline-primary">
|
||||
<i class="bi bi-gear"></i> 生成
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 在表格显示卡片底部添加分页 -->
|
||||
<div class="card-footer bg-light">
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<div class="form-text">共 {{ totalItems }} 条</div>
|
||||
|
||||
<nav aria-label="Page navigation">
|
||||
<ul class="pagination mb-0">
|
||||
<li :class="{ disabled: currentPage === 1 }" class="page-item">
|
||||
<a @click.prevent="currentPage = 1" class="page-link" href="#">
|
||||
<i class="bi bi-chevron-double-left"></i>
|
||||
</a>
|
||||
</li>
|
||||
<li :class="{ disabled: currentPage === 1 }" class="page-item">
|
||||
<a @click.prevent="currentPage--" class="page-link" href="#">
|
||||
<i class="bi bi-chevron-left"></i>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<!-- 显示页码 -->
|
||||
<li :class="{ active: currentPage === page }" :key="page" class="page-item"
|
||||
v-for="page in visiblePages">
|
||||
<a @click.prevent="currentPage = page" class="page-link" href="#">{{ page }}</a>
|
||||
</li>
|
||||
|
||||
<li :class="{ disabled: currentPage === totalPages }" class="page-item">
|
||||
<a @click.prevent="currentPage++" class="page-link" href="#">
|
||||
<i class="bi bi-chevron-right"></i>
|
||||
</a>
|
||||
</li>
|
||||
<li :class="{ disabled: currentPage === totalPages }" class="page-item">
|
||||
<a @click.prevent="currentPage = totalPages" class="page-link" href="#">
|
||||
<i class="bi bi-chevron-double-right"></i>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
<div class="dropdown">
|
||||
<button aria-expanded="false" class="btn btn-outline-secondary dropdown-toggle"
|
||||
data-bs-toggle="dropdown" id="itemsPerPageDropdown" type="button">
|
||||
每页 {{ itemsPerPage }} 条
|
||||
</button>
|
||||
<ul aria-labelledby="itemsPerPageDropdown" class="dropdown-menu">
|
||||
<li :key="index" v-for="(table,index) in tablePageOptions">
|
||||
<a @click.prevent="itemsPerPage = table" class="dropdown-item" href="JavaScript:">
|
||||
{{table}} 条/页
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
data() {
|
||||
return {
|
||||
// 分页相关数据
|
||||
currentPage: ref(1),
|
||||
// 每页数
|
||||
itemsPerPage: ref(10),
|
||||
// 总的数据条数
|
||||
totalItems: ref(0),
|
||||
// 表格选项
|
||||
tablePageOptions: [5, 10, 20, 50, 100, 150, 200]
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
// 计算总页数
|
||||
totalPages() {
|
||||
return Math.ceil(this.totalItems / this.itemsPerPage);
|
||||
},
|
||||
// 分页后的数据
|
||||
paginatedTableList() {
|
||||
const start = (this.currentPage - 1) * this.itemsPerPage;
|
||||
const end = start + this.itemsPerPage;
|
||||
return this.tableList.slice(start, end);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
/* 计算可见的页码范围 */
|
||||
visiblePages() {
|
||||
// 显示当前页前后各2页
|
||||
const range = 2;
|
||||
const start = Math.max(1, this.currentPage - range);
|
||||
const end = Math.min(this.totalPages, this.currentPage + range);
|
||||
|
||||
const pages = [];
|
||||
for (let i = start; i <= end; i++) {
|
||||
pages.push(i);
|
||||
}
|
||||
return pages;
|
||||
}
|
||||
}
|
||||
})
|
Loading…
Reference in New Issue