添加获取当前数据表列信息

This commit is contained in:
bunny 2025-07-02 19:29:44 +08:00
parent 395ec89666
commit 7f55cecb7a
2 changed files with 221 additions and 155 deletions

View File

@ -31,6 +31,6 @@ public class TableMetaData {
private String className; private String className;
@Schema(name = "columns", description = "列名称") @Schema(name = "columns", description = "列名称")
private List<ColumnMetaData> columns; private List<ColumnMetaData> columns = List.of();
} }

View File

@ -10,8 +10,8 @@ const DatabaseTable = defineComponent({
<div> <div>
<div class="form-check form-check-inline"> <div class="form-check form-check-inline">
<input class="form-check-input" name="TableSelectRadios" type="radio" id="radioSelectAll" <input class="form-check-input" name="TableSelectRadios" type="radio" id="radioSelectAll" value="all"
value="all" v-model="selectedOption"> v-model="selectedOption">
<label class="form-check-label" for="radioSelectAll">选择全部</label> <label class="form-check-label" for="radioSelectAll">选择全部</label>
</div> </div>
<div class="form-check form-check-inline"> <div class="form-check form-check-inline">
@ -47,32 +47,90 @@ const DatabaseTable = defineComponent({
v-model="tableSelectAllChecked" @change="onSelectAllTable"> v-model="tableSelectAllChecked" @change="onSelectAllTable">
</th> </th>
<th scope="col" width="3%">#</th> <th scope="col" width="3%">#</th>
<th scope="col" width="30%">表名</th> <th scope="col" width="25%">表名</th>
<th scope="col" width="35%">注释</th> <th scope="col" width="25%">注释</th>
<th scope="col" width="20%">所属数据库</th> <th scope="col" width="15%">所属数据库</th>
<th class="text-center" scope="col" width="10%">操作</th> <th class="text-center" scope="col" width="15%">操作</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr :key="table.tableName" v-for="(table, index) in paginatedTableList"> <template v-for="(table, index) in paginatedTableList" :key="table.tableName">
<tr>
<td> <td>
<input class="form-check-input border-secondary" type="checkbox" <input class="form-check-input border-secondary" type="checkbox" v-model="table.checked"
v-model="table.checked" @change="onSelectTable($event.target.checked, table)"> @change="onSelectTable($event.target.checked, table)">
</td> </td>
<td>{{ (currentPage - 1) * itemsPerPage + index + 1 }}</td> <td>{{ (currentPage - 1) * itemsPerPage + index + 1 }}</td>
<td> <td>
<a class="text-decoration-none" href="#" @click.prevent="onSelectTable(!table.checked, table)"> <a class="text-decoration-none" href="#" @click.prevent="toggleTableDetails(table)">
{{ table.tableName }} {{ table.tableName }}
<i class="bi"
:class="{'bi-chevron-down': !table.showDetails, 'bi-chevron-up': table.showDetails}"></i>
</a> </a>
</td> </td>
<td>{{ table.comment || '无注释' }}</td> <td>{{ table.comment || '无注释' }}</td>
<td>{{ table.tableCat }}</td> <td>{{ table.tableCat }}</td>
<td class="text-center"> <td class="d-flex justify-content-around">
<button class="btn btn-sm btn-outline-primary" @click="onSelectTable(!table.checked, table)"> <button class="btn btn-sm btn-outline-primary"
<i class="bi bi-gear"></i> @click="onSelectTable(!table.checked, table)">
<i class="bi bi-database-check"></i>
</button>
<button class="btn btn-sm btn-outline-primary" @click="toggleTableDetails(table)">
<i class="bi bi-gear"></i>
</button> </button>
</td> </td>
</tr> </tr>
<!-- 表详情展开行 -->
<tr v-if="table.showDetails">
<td colspan="6" class="p-0">
<div class="p-3 bg-light">
<h6 class="mb-3">表信息</h6>
<div class="row mb-4">
<div class="col-md-3">
<p class="mb-1"><strong>表名:</strong> {{table.tableName}}</p>
</div>
<div class="col-md-3">
<p class="mb-1"><strong>类型:</strong> {{table.tableType}}</p>
</div>
<div class="col-md-6">
<p class="mb-1"><strong>注释:</strong> {{table.comment || ''}}</p>
</div>
</div>
<h6 class="mb-3">列信息</h6>
<div class="table-responsive">
<table class="table table-sm table-bordered">
<thead>
<tr>
<th>列名</th>
<th>数据库类型</th>
<th>Java类型</th>
<th>JS类型</th>
<th>主键</th>
<th>注释</th>
</tr>
</thead>
<tbody>
<tr v-for="column in table.columns" :key="column.columnName">
<td>{{column.columnName}}</td>
<td>{{column.jdbcType}}</td>
<td>{{column.javaType}}</td>
<td>{{column.javascriptType}}</td>
<td>
<span class="badge bg-success"
v-if="column.isPrimaryKey"></span>
<span class="badge bg-secondary" v-else></span>
</td>
<td>{{column.comment || '无'}}</td>
</tr>
</tbody>
</table>
</div>
</div>
</td>
</tr>
</template>
</tbody> </tbody>
</table> </table>
</div> </div>
@ -82,7 +140,8 @@ const DatabaseTable = defineComponent({
<div class="card-footer bg-light" v-if="tableList.length > 0"> <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"> <div class="form-text">
显示 {{ (currentPage - 1) * itemsPerPage + 1 }}~{{ Math.min(currentPage * itemsPerPage, rawTableList.length) }} {{ rawTableList.length }} 显示 {{ (currentPage - 1) * itemsPerPage + 1 }}~{{ Math.min(currentPage * itemsPerPage,
rawTableList.length) }} {{ rawTableList.length }}
</div> </div>
<nav aria-label="Page navigation"> <nav aria-label="Page navigation">
@ -99,8 +158,8 @@ const DatabaseTable = defineComponent({
</li> </li>
<!-- 显示页码 --> <!-- 显示页码 -->
<li v-for="page in visiblePages" :key="page" <li v-for="page in visiblePages" :key="page" :class="{ active: currentPage === page }"
:class="{ active: currentPage === page }" class="page-item"> class="page-item">
<a @click.prevent="goToPage(page)" class="page-link" href="#">{{ page }}</a> <a @click.prevent="goToPage(page)" class="page-link" href="#">{{ page }}</a>
</li> </li>
@ -264,6 +323,32 @@ const DatabaseTable = defineComponent({
} }
}, },
/**
* 切换表格详情展开/收起状态
* 如果是首次展开且没有列数据则请求获取列信息
* @param {Object} table - 表格对象
* @returns {Promise<void>}
*/
async toggleTableDetails(table) {
// 如果是展开操作且没有列数据,则请求获取列信息
if (!table.showDetails && !table.columns) {
// 发送请求获取列信息
const {data, code, message} = await axiosInstance({
url: "/table/tableColumnInfo",
params: {tableName: table.tableName}
});
// 请求成功时保存列数据
if (code === 200) {
table.columns = data;
antd.message.success(message);
}
}
// 切换展开/收起状态
table.showDetails = !table.showDetails;
},
/* 更新表单中选中的表名 */ /* 更新表单中选中的表名 */
updateFormSelectedTables() { updateFormSelectedTables() {
const payload = { const payload = {
@ -279,39 +364,20 @@ const DatabaseTable = defineComponent({
* 如果要同时更新会变得很复杂所以在这里讲逻辑定义为 * 如果要同时更新会变得很复杂所以在这里讲逻辑定义为
* 选型变化时直接取消全部之后重新选择 * 选型变化时直接取消全部之后重新选择
*/ */
restForm() { resetForm() {
this.tableSelectAllChecked = false; this.tableSelectAllChecked = false;
this.tableList.forEach(table => table.checked = false); this.tableList.forEach(table => table.checked = false);
this.updateFormSelectedTables(); this.updateFormSelectedTables();
} }
}, },
watch: { watch: {
/** /* 监听选择模式变化 */
* 监听选择模式变化 selectedOption: 'resetForm',
*/ /* 监听当前页变化 */
selectedOption() { currentPage: 'resetForm',
this.restForm(); /* 监听每页条数变化 */
}, itemsPerPage: 'resetForm',
/* 数据库选择发生变化也重置表单 */
/** dbSelect: 'resetForm',
* 监听当前页变化
*/
currentPage() {
this.restForm();
},
/**
* 监听每页条数变化
*/
itemsPerPage() {
this.restForm();
},
/**
* 数据库选择发生变化也重置表单
*/
dbSelect() {
this.restForm();
}
} }
}); });