improve(ui):统一调整表格页面,将总数统计显示在左下角
This commit is contained in:
1 parent
0e32e29ff6
commit
a73cf411a5
44 files changed
+234
-60
No files matched your search
@@ -9,7 +9,9 @@ type ChannelListReq struct {
|
||||
PageSize int `json:"page_size" d:"20" v:"min:1|max:100" dc:"每页数量"`
|
||||
Type int `json:"type" dc:"供应商类型筛选"`
|
||||
Status string `json:"status" dc:"状态筛选:active/disabled/testing"`
|
||||
Search string `json:"search" dc:"搜索关键词"`
|
||||
Search string `json:"search" dc:"搜索关键词(渠道名称/备注)"`
|
||||
ID int64 `json:"id" dc:"按渠道 ID 精确筛选"`
|
||||
Model string `json:"model" dc:"按支持的模型名筛选(模糊匹配平台模型名/上游模型名)"`
|
||||
}
|
||||
|
||||
// ChannelListRes 渠道列表响应
|
||||
@@ -250,7 +252,9 @@ type ChannelExportReq struct {
|
||||
Format string `json:"format" in:"query" d:"csv" v:"in:csv,xlsx" dc:"导出格式:csv / xlsx"`
|
||||
Type int `json:"type" in:"query" dc:"供应商类型筛选"`
|
||||
Status string `json:"status" in:"query" dc:"状态筛选:active/disabled/testing"`
|
||||
Search string `json:"search" in:"query" dc:"搜索关键词"`
|
||||
Search string `json:"search" in:"query" dc:"搜索关键词(渠道名称/备注)"`
|
||||
ID int64 `json:"id" in:"query" dc:"按渠道 ID 精确筛选"`
|
||||
Model string `json:"model" in:"query" dc:"按支持的模型名筛选(模糊匹配平台模型名/上游模型名)"`
|
||||
}
|
||||
|
||||
type ChannelExportRes struct{}
|
||||
|
||||
@@ -58,6 +58,14 @@ func (s *sAdmin) ListChannels(ctx context.Context, req *v1.ChannelListReq) (*v1.
|
||||
if req.Search != "" {
|
||||
query = query.Where("chn_channels.name LIKE ? OR chn_channels.remark LIKE ?", "%"+req.Search+"%", "%"+req.Search+"%")
|
||||
}
|
||||
if req.ID > 0 {
|
||||
query = query.Where("chn_channels.id", req.ID)
|
||||
}
|
||||
if req.Model != "" {
|
||||
// 按支持的模型名筛选:渠道需具备匹配的模型能力(chn_abilities)。
|
||||
// 用 EXISTS 相关子查询而非 JOIN,避免一个渠道命中多个模型时产生重复行、破坏分页与总数。
|
||||
query = query.Where("EXISTS (SELECT 1 FROM chn_abilities WHERE chn_abilities.channel_id = chn_channels.id AND (chn_abilities.model_name LIKE ? OR chn_abilities.upstream_model LIKE ?))", "%"+req.Model+"%", "%"+req.Model+"%")
|
||||
}
|
||||
|
||||
var total int
|
||||
var channels []struct {
|
||||
@@ -731,6 +739,13 @@ func (s *sAdmin) ExportChannels(ctx context.Context, req *v1.ChannelExportReq) (
|
||||
if req.Search != "" {
|
||||
query = query.Where("chn_channels.name LIKE ? OR chn_channels.remark LIKE ?", "%"+req.Search+"%", "%"+req.Search+"%")
|
||||
}
|
||||
if req.ID > 0 {
|
||||
query = query.Where("chn_channels.id", req.ID)
|
||||
}
|
||||
if req.Model != "" {
|
||||
// 与 ListChannels 保持一致:EXISTS 相关子查询避免 JOIN 重复行
|
||||
query = query.Where("EXISTS (SELECT 1 FROM chn_abilities WHERE chn_abilities.channel_id = chn_channels.id AND (chn_abilities.model_name LIKE ? OR chn_abilities.upstream_model LIKE ?))", "%"+req.Model+"%", "%"+req.Model+"%")
|
||||
}
|
||||
var batch []struct {
|
||||
ID int64 `json:"id"`
|
||||
Name string `json:"name"`
|
||||
|
||||
@@ -449,6 +449,16 @@ body {
|
||||
border-top: 1px solid var(--ta-border-light);
|
||||
}
|
||||
|
||||
/* 统计总数从表格左上角移到底部后:footer 内存在统计栏时两端对齐(统计居左、分页居右),
|
||||
无统计栏的 footer 保持右对齐不受影响(:has 特异性高于 scoped .table-footer,可统一覆盖各页脚注) */
|
||||
.page-table .table-footer:has(.table-stats) {
|
||||
justify-content: space-between;
|
||||
}
|
||||
/* 统计栏移入底部后,去掉全局样式的下边距,与分页栏垂直居中 */
|
||||
.page-table .table-footer .table-stats {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
/* Tab 内嵌表格:让 Tab 容器与面板也参与纵向 flex,保证内部表格能撑满滚动 */
|
||||
.page-table .arco-tabs {
|
||||
flex: 1;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, onMounted, h } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { Tag, Button, Space, Popconfirm, Message, Radio } from '@arco-design/web-vue'
|
||||
import { Tag, Button, Space, Popconfirm, Message, Radio, InputNumber, Select } from '@arco-design/web-vue'
|
||||
import { IconInfoCircle } from '@arco-design/web-vue/es/icon'
|
||||
import type { TableColumnData } from '@arco-design/web-vue'
|
||||
import type { FormInstance } from '@arco-design/web-vue'
|
||||
@@ -26,6 +26,8 @@ const pagination = reactive({ current: 1, pageSize: 20, total: 0, showPageSize:
|
||||
const filterType = ref<number | undefined>(undefined)
|
||||
const filterStatus = ref<string | undefined>(undefined)
|
||||
const filterSearch = ref('')
|
||||
const filterID = ref<number | undefined>(undefined)
|
||||
const filterModel = ref('')
|
||||
|
||||
const statusOptions = [
|
||||
{ label: '全部状态', value: '' },
|
||||
@@ -67,12 +69,42 @@ const columns: TableColumnData[] = [
|
||||
title: '状态', dataIndex: 'status', width: 80,
|
||||
render({ record }) { return h(Tag, { color: statusTagColor[record.status], size: 'small' }, () => statusLabel[record.status] || record.status) },
|
||||
},
|
||||
{ title: '优先级', dataIndex: 'priority', width: 70 },
|
||||
{ title: '权重', dataIndex: 'weight', width: 70 },
|
||||
{
|
||||
title: '层级', dataIndex: 'tier', width: 80,
|
||||
title: '权重', dataIndex: 'weight', width: 100,
|
||||
render({ record }) {
|
||||
return h(Tag, { color: tierTagColor[record.tier] || 'gray', size: 'small' }, () => tierLabel[record.tier] || record.tier || '-')
|
||||
// 无编辑权限时只读展示
|
||||
if (!hasPermission('channel:edit')) return h('span', {}, record.weight)
|
||||
return h(InputNumber, {
|
||||
modelValue: record.weight,
|
||||
min: 0,
|
||||
max: 100,
|
||||
size: 'small',
|
||||
disabled: record._saving,
|
||||
style: 'width: 84px',
|
||||
'onUpdate:modelValue': (val: number | undefined) => { record.weight = val ?? 0 },
|
||||
onChange: (val: number | undefined) => onWeightChange(record, val),
|
||||
})
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '层级', dataIndex: 'tier', width: 120,
|
||||
render({ record }) {
|
||||
// 无编辑权限时只读展示
|
||||
if (!hasPermission('channel:edit')) {
|
||||
return h(Tag, { color: tierTagColor[record.tier] || 'gray', size: 'small' }, () => tierLabel[record.tier] || record.tier || '-')
|
||||
}
|
||||
return h(Select, {
|
||||
modelValue: record.tier,
|
||||
size: 'small',
|
||||
style: 'width: 108px',
|
||||
options: [
|
||||
{ label: '首选', value: 'primary' },
|
||||
{ label: '备用', value: 'secondary' },
|
||||
{ label: '保底', value: 'reserve' },
|
||||
],
|
||||
'onUpdate:modelValue': (val: any) => { record.tier = val },
|
||||
onChange: (val: any) => saveTier(record, val),
|
||||
})
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -122,8 +154,12 @@ async function fetchData() {
|
||||
if (filterType.value) params.type = filterType.value
|
||||
if (filterStatus.value) params.status = filterStatus.value
|
||||
if (filterSearch.value) params.search = filterSearch.value
|
||||
if (filterID.value) params.id = filterID.value
|
||||
if (filterModel.value) params.model = filterModel.value
|
||||
const res: any = await request.get('/admin/channels', { params })
|
||||
data.value = res.data?.data?.list || res.data?.list || []
|
||||
// 记录本次加载时已持久化的权重/层级,供行内编辑失败回滚
|
||||
data.value.forEach((r: any) => { r._savedWeight = r.weight; r._tierSaved = r.tier })
|
||||
pagination.total = res.data?.data?.total || res.data?.total || 0
|
||||
} catch {
|
||||
data.value = []; pagination.total = 0
|
||||
@@ -222,6 +258,61 @@ async function toggleStatus(record: any) {
|
||||
}
|
||||
}
|
||||
|
||||
// === 行内编辑(权重 / 层级) ===
|
||||
// 行内编辑复用 PUT /admin/channels/{id}。后端 UpdateChannel 会无条件写入 priority/weight,
|
||||
// 故每次提交必须携带当前 priority 与 weight,避免被重置为 0。
|
||||
const weightTimers = new Map<number, any>()
|
||||
|
||||
function onWeightChange(record: any, val: number | undefined) {
|
||||
if (val === undefined || val === null) {
|
||||
// 清空字段时取消待提交的防抖任务,避免误提交旧值
|
||||
const timer = weightTimers.get(record.id)
|
||||
if (timer) { clearTimeout(timer); weightTimers.delete(record.id) }
|
||||
return
|
||||
}
|
||||
const timer = weightTimers.get(record.id)
|
||||
if (timer) clearTimeout(timer)
|
||||
// 防抖:连续点击步进按钮或连续输入时,只提交最后一次值
|
||||
weightTimers.set(record.id, setTimeout(() => saveWeight(record, val), 350))
|
||||
}
|
||||
|
||||
async function saveWeight(record: any, val: number) {
|
||||
if (record._saving || val === record._savedWeight) return
|
||||
const prev = record._savedWeight
|
||||
record._saving = true
|
||||
try {
|
||||
await request.put(`/admin/channels/${record.id}`, {
|
||||
priority: record.priority,
|
||||
weight: val,
|
||||
})
|
||||
record._savedWeight = val
|
||||
message.success('权重已更新')
|
||||
} catch {
|
||||
record.weight = prev // 失败回滚显示值
|
||||
} finally {
|
||||
record._saving = false
|
||||
}
|
||||
}
|
||||
|
||||
async function saveTier(record: any, val: string) {
|
||||
if (!val || record._saving || val === record._tierSaved) return
|
||||
const prev = record._tierSaved
|
||||
record._saving = true
|
||||
try {
|
||||
await request.put(`/admin/channels/${record.id}`, {
|
||||
priority: record.priority,
|
||||
weight: record.weight,
|
||||
tier: val,
|
||||
})
|
||||
record._tierSaved = val
|
||||
message.success('层级已更新')
|
||||
} catch {
|
||||
record.tier = prev // 失败回滚
|
||||
} finally {
|
||||
record._saving = false
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(fetchData)
|
||||
|
||||
// === OAuth ===
|
||||
@@ -292,6 +383,8 @@ const { exporting, exportFile } = useExport({
|
||||
type: filterType.value,
|
||||
status: filterStatus.value,
|
||||
search: filterSearch.value,
|
||||
id: filterID.value,
|
||||
model: filterModel.value,
|
||||
}),
|
||||
})
|
||||
</script>
|
||||
@@ -356,15 +449,17 @@ const { exporting, exportFile } = useExport({
|
||||
<ASelect v-model="filterType" :options="[{ label: '全部类型', value: '' }, ...providerTypeOptions]" placeholder="供应商类型" allow-clear allow-search style="width: 180px" @change="handleFilter" />
|
||||
<ASelect v-model="filterStatus" :options="statusOptions" placeholder="状态" allow-clear style="width: 120px" @change="handleFilter" />
|
||||
<AInput v-model="filterSearch" placeholder="搜索渠道名..." allow-clear style="width: 200px" @keydown.enter="handleFilter" @clear="handleFilter" />
|
||||
<AInputNumber v-model="filterID" placeholder="渠道 ID" :min="1" allow-clear style="width: 120px" @change="handleFilter" @clear="handleFilter" />
|
||||
<AInput v-model="filterModel" placeholder="搜索模型名..." allow-clear style="width: 160px" @keydown.enter="handleFilter" @clear="handleFilter" />
|
||||
<AButton @click="handleFilter">搜索</AButton>
|
||||
</ASpace>
|
||||
</ACard>
|
||||
|
||||
<!-- Table -->
|
||||
<ACard :bordered="false">
|
||||
<TableStats :total="pagination.total" />
|
||||
<ATable :columns="columns" :data="data" :loading="loading" :scroll="{ x: 1400 }" :bordered="false" :stripe="true" :pagination="false" row-key="id" />
|
||||
<div class="table-footer">
|
||||
<TableStats :total="pagination.total" />
|
||||
<APagination v-model:current="pagination.current" v-model:page-size="pagination.pageSize" :total="pagination.total" :page-size-options="pagination.pageSizeOptions" show-page-size @change="fetchData" @page-size-change="(s: number) => { pagination.pageSize = s; pagination.current = 1; fetchData() }" />
|
||||
</div>
|
||||
</ACard>
|
||||
@@ -522,11 +617,17 @@ const { exporting, exportFile } = useExport({
|
||||
<style scoped>
|
||||
.table-footer {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
margin-top: 16px;
|
||||
padding-top: 16px;
|
||||
border-top: 1px solid var(--ta-border-light);
|
||||
}
|
||||
/* 统计栏移入底部后,去掉全局样式的下边距,与分页栏垂直居中 */
|
||||
.table-footer :deep(.table-stats) {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.scheduling-hint {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
|
||||
@@ -272,7 +272,6 @@ onMounted(() => {
|
||||
</ACard>
|
||||
|
||||
<ACard :bordered="false">
|
||||
<TableStats :total="pagination.total" />
|
||||
<ATable
|
||||
:columns="columns"
|
||||
:data="data"
|
||||
@@ -284,6 +283,7 @@ onMounted(() => {
|
||||
:scroll="{ x: 1200 }"
|
||||
/>
|
||||
<div class="table-footer">
|
||||
<TableStats :total="pagination.total" />
|
||||
<APagination
|
||||
v-model:current="pagination.current"
|
||||
v-model:page-size="pagination.pageSize"
|
||||
@@ -347,9 +347,15 @@ onMounted(() => {
|
||||
}
|
||||
.table-footer {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
margin-top: 16px;
|
||||
}
|
||||
/* 统计栏移入底部后,去掉全局样式的下边距,与分页栏垂直居中 */
|
||||
.table-footer :deep(.table-stats) {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.mb-4 {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
@@ -656,7 +656,6 @@ function resetImport() {
|
||||
|
||||
<!-- Table -->
|
||||
<ACard :bordered="false">
|
||||
<TableStats :total="pagination.total" />
|
||||
<ATable
|
||||
:columns="columns"
|
||||
:data="data"
|
||||
@@ -671,6 +670,7 @@ function resetImport() {
|
||||
@selection-change="handleSelectionChange"
|
||||
/>
|
||||
<div class="table-footer">
|
||||
<TableStats :total="pagination.total" />
|
||||
<APagination
|
||||
v-model:current="pagination.current"
|
||||
v-model:page-size="pagination.pageSize"
|
||||
@@ -833,11 +833,17 @@ function resetImport() {
|
||||
<style scoped>
|
||||
.table-footer {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
margin-top: 16px;
|
||||
padding-top: 16px;
|
||||
border-top: 1px solid var(--ta-border-light);
|
||||
}
|
||||
/* 统计栏移入底部后,去掉全局样式的下边距,与分页栏垂直居中 */
|
||||
.table-footer :deep(.table-stats) {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.cap-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
|
||||
@@ -259,7 +259,6 @@ onMounted(() => {
|
||||
|
||||
<!-- Table -->
|
||||
<ACard :bordered="false">
|
||||
<TableStats :total="pagination.total" />
|
||||
<ATable
|
||||
:columns="columns"
|
||||
:data="data"
|
||||
@@ -271,6 +270,7 @@ onMounted(() => {
|
||||
row-key="id"
|
||||
/>
|
||||
<div class="table-footer">
|
||||
<TableStats :total="pagination.total" />
|
||||
<APagination
|
||||
v-model:current="pagination.current"
|
||||
v-model:page-size="pagination.pageSize"
|
||||
@@ -349,11 +349,17 @@ onMounted(() => {
|
||||
<style scoped>
|
||||
.table-footer {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
margin-top: 16px;
|
||||
padding-top: 16px;
|
||||
border-top: 1px solid var(--ta-border-light);
|
||||
}
|
||||
/* 统计栏移入底部后,去掉全局样式的下边距,与分页栏垂直居中 */
|
||||
.table-footer :deep(.table-stats) {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.detail-section-title {
|
||||
font-size: 14px;
|
||||
|
||||
@@ -94,7 +94,6 @@ const { exporting, exportFile } = useExport({
|
||||
</PageHeader>
|
||||
|
||||
<ACard :bordered="false" class="mt-4">
|
||||
<TableStats :total="billPagination.total" />
|
||||
<div class="mb-4">
|
||||
<ASpace>
|
||||
<AInput v-model="billFilterTenantId" placeholder="租户ID" allow-clear style="width: 120px" @keydown.enter="fetchBillingRecords" />
|
||||
@@ -103,6 +102,7 @@ const { exporting, exportFile } = useExport({
|
||||
</div>
|
||||
<ATable :columns="billColumns" :data="billData" :loading="billLoading" :scroll="{ x: 1800 }" :bordered="false" :stripe="true" size="small" :pagination="false" row-key="id" />
|
||||
<div class="table-footer">
|
||||
<TableStats :total="billPagination.total" />
|
||||
<APagination v-model:current="billPagination.current" v-model:page-size="billPagination.pageSize" :total="billPagination.total" :page-size-options="billPagination.pageSizeOptions" show-page-size @change="fetchBillingRecords" @page-size-change="(s: number) => { billPagination.pageSize = s; billPagination.current = 1; fetchBillingRecords() }" />
|
||||
</div>
|
||||
</ACard>
|
||||
|
||||
@@ -139,9 +139,9 @@ const { exporting, exportFile } = useExport({
|
||||
</ASpace>
|
||||
</div>
|
||||
</template>
|
||||
<TableStats :total="pagination.total" />
|
||||
<ATable :columns="columns" :data="orders" :loading="loading" row-key="id" :scroll="{ x: 1100 }" :pagination="false" />
|
||||
<div class="table-footer">
|
||||
<TableStats :total="pagination.total" />
|
||||
<APagination v-model:current="pagination.current" v-model:page-size="pagination.pageSize" :total="pagination.total" :page-size-options="pagination.pageSizeOptions" show-page-size @change="fetchOrders" @page-size-change="(s: number) => { pagination.pageSize = s; pagination.current = 1; fetchOrders() }" />
|
||||
</div>
|
||||
</ACard>
|
||||
|
||||
@@ -141,9 +141,9 @@ const { exporting, exportFile } = useExport({
|
||||
<ASelect v-model="statusFilter" :options="statusOptions" style="width: 120px" allow-clear @change="() => { pagination.current = 1; fetchPlans() }" />
|
||||
</div>
|
||||
</template>
|
||||
<TableStats :total="pagination.total" />
|
||||
<ATable :columns="columns" :data="plans" :loading="loading" row-key="id" :scroll="{ x: 1200 }" :pagination="false" />
|
||||
<div class="table-footer">
|
||||
<TableStats :total="pagination.total" />
|
||||
<APagination v-model:current="pagination.current" v-model:page-size="pagination.pageSize" :total="pagination.total" :page-size-options="pagination.pageSizeOptions" show-page-size @change="fetchPlans" @page-size-change="(s: number) => { pagination.pageSize = s; pagination.current = 1; fetchPlans() }" />
|
||||
</div>
|
||||
</ACard>
|
||||
|
||||
@@ -123,9 +123,9 @@ const { exporting, exportFile } = useExport({
|
||||
</PageHeader>
|
||||
|
||||
<ACard :bordered="false">
|
||||
<TableStats :total="pagination.total" />
|
||||
<ATable :columns="columns" :data="promoCodes" :loading="loading" row-key="id" :scroll="{ x: 1200 }" :pagination="false" />
|
||||
<div class="table-footer">
|
||||
<TableStats :total="pagination.total" />
|
||||
<APagination v-model:current="pagination.current" v-model:page-size="pagination.pageSize" :total="pagination.total" :page-size-options="pagination.pageSizeOptions" show-page-size @change="fetchList" @page-size-change="(s: number) => { pagination.pageSize = s; pagination.current = 1; fetchList() }" />
|
||||
</div>
|
||||
</ACard>
|
||||
|
||||
@@ -140,7 +140,6 @@ const { exporting, exportFile } = useExport({
|
||||
<ATabs v-model:active-key="activeTab" @change="onTabChange">
|
||||
<ATabPane key="codes" title="兑换码列表">
|
||||
<div class="flex items-center justify-between mb-4">
|
||||
<TableStats :total="pagination.total" />
|
||||
<ASelect v-model="statusFilter" :options="[
|
||||
{ label: '全部', value: '' }, { label: '可用', value: 'active' },
|
||||
{ label: '已禁用', value: 'disabled' }, { label: '已过期', value: 'expired' },
|
||||
@@ -148,14 +147,15 @@ const { exporting, exportFile } = useExport({
|
||||
</div>
|
||||
<ATable :columns="columns" :data="redemptions" :loading="loading" row-key="id" :scroll="{ x: 1100 }" :pagination="false" />
|
||||
<div class="table-footer">
|
||||
<TableStats :total="pagination.total" />
|
||||
<APagination v-model:current="pagination.current" v-model:page-size="pagination.pageSize" :total="pagination.total" :page-size-options="pagination.pageSizeOptions" show-page-size @change="fetchRedemptions" @page-size-change="(s: number) => { pagination.pageSize = s; pagination.current = 1; fetchRedemptions() }" />
|
||||
</div>
|
||||
</ATabPane>
|
||||
|
||||
<ATabPane key="usages" title="使用记录">
|
||||
<TableStats :total="usagePagination.total" />
|
||||
<ATable :columns="usageColumns" :data="usages" :loading="usageLoading" row-key="id" :scroll="{ x: 900 }" :pagination="false" />
|
||||
<div class="table-footer">
|
||||
<TableStats :total="usagePagination.total" />
|
||||
<APagination v-model:current="usagePagination.current" v-model:page-size="usagePagination.pageSize" :total="usagePagination.total" :page-size-options="usagePagination.pageSizeOptions" show-page-size @change="fetchUsages" @page-size-change="(s: number) => { usagePagination.pageSize = s; usagePagination.current = 1; fetchUsages() }" />
|
||||
</div>
|
||||
</ATabPane>
|
||||
|
||||
@@ -94,7 +94,6 @@ onMounted(fetchData)
|
||||
<PageHeader title="交易流水" description="查看所有租户的钱包交易记录" />
|
||||
|
||||
<ACard :bordered="false" class="mt-4">
|
||||
<TableStats :total="pagination.total" />
|
||||
<div class="mb-4">
|
||||
<ASpace wrap>
|
||||
<AInput v-model="filterTenantId" placeholder="租户ID" allow-clear style="width: 120px" @keydown.enter="resetAndFetch" />
|
||||
@@ -107,6 +106,7 @@ onMounted(fetchData)
|
||||
</div>
|
||||
<ATable :columns="columns" :data="data" :loading="loading" :scroll="{ x: 1200 }" :bordered="false" :stripe="true" size="small" :pagination="false" row-key="id" />
|
||||
<div class="table-footer">
|
||||
<TableStats :total="pagination.total" />
|
||||
<APagination v-model:current="pagination.current" v-model:page-size="pagination.pageSize" :total="pagination.total" :page-size-options="pagination.pageSizeOptions" show-page-size @change="fetchData" @page-size-change="(s: number) => { pagination.pageSize = s; pagination.current = 1; fetchData() }" />
|
||||
</div>
|
||||
</ACard>
|
||||
|
||||
@@ -201,9 +201,9 @@ onUnmounted(() => {
|
||||
</a-card>
|
||||
|
||||
<a-card :bordered="false">
|
||||
<TableStats :total="total" />
|
||||
<a-table :data="data" :columns="columns" :loading="loading" :pagination="false" row-key="id" />
|
||||
<div class="table-footer">
|
||||
<TableStats :total="total" />
|
||||
<a-pagination :current="pagination.current" :page-size="pagination.pageSize" :total="total" @change="handlePageChange" />
|
||||
</div>
|
||||
</a-card>
|
||||
|
||||
@@ -237,9 +237,9 @@ onMounted(() => {
|
||||
</a-card>
|
||||
|
||||
<a-card :bordered="false">
|
||||
<TableStats :total="total" />
|
||||
<a-table :data="data" :columns="columns" :loading="loading" :pagination="false" row-key="id" />
|
||||
<div class="table-footer">
|
||||
<TableStats :total="total" />
|
||||
<a-pagination :current="pagination.current" :page-size="pagination.pageSize" :total="total" @change="handlePageChange" />
|
||||
</div>
|
||||
</a-card>
|
||||
|
||||
@@ -283,7 +283,6 @@ onMounted(() => {
|
||||
|
||||
<!-- Table -->
|
||||
<ACard :bordered="false">
|
||||
<TableStats :total="total" />
|
||||
<ATable
|
||||
:data="data"
|
||||
:loading="loading"
|
||||
@@ -293,6 +292,7 @@ onMounted(() => {
|
||||
:scroll="{ x: 1400 }"
|
||||
/>
|
||||
<div class="table-footer">
|
||||
<TableStats :total="total" />
|
||||
<APagination
|
||||
v-model:current="pagination.current"
|
||||
v-model:page-size="pagination.pageSize"
|
||||
|
||||
@@ -263,7 +263,6 @@ onMounted(() => {
|
||||
</a-card>
|
||||
|
||||
<a-card :bordered="false">
|
||||
<TableStats :total="total" />
|
||||
<a-table
|
||||
:data="data"
|
||||
:columns="columns"
|
||||
@@ -272,6 +271,7 @@ onMounted(() => {
|
||||
row-key="id"
|
||||
/>
|
||||
<div class="table-footer">
|
||||
<TableStats :total="total" />
|
||||
<a-pagination
|
||||
v-model:current="pagination.current"
|
||||
v-model:page-size="pagination.pageSize"
|
||||
|
||||
@@ -228,7 +228,6 @@ onMounted(() => {
|
||||
</PageHeader>
|
||||
|
||||
<a-card :bordered="false">
|
||||
<TableStats :total="jobs.length" />
|
||||
<a-table
|
||||
:data="jobs"
|
||||
:columns="columns"
|
||||
@@ -263,6 +262,9 @@ onMounted(() => {
|
||||
</div>
|
||||
</template>
|
||||
</a-table>
|
||||
<div class="table-footer">
|
||||
<TableStats :total="jobs.length" />
|
||||
</div>
|
||||
</a-card>
|
||||
</div>
|
||||
</template>
|
||||
@@ -310,7 +310,6 @@ onMounted(() => {
|
||||
|
||||
<!-- Table -->
|
||||
<a-card :bordered="false">
|
||||
<TableStats :total="total" />
|
||||
<a-table
|
||||
:data="data"
|
||||
:columns="columns"
|
||||
@@ -322,6 +321,7 @@ onMounted(() => {
|
||||
:row-selection="{ type: 'checkbox', showCheckedAll: true, selectedRowKeys: selectedKeys, onSelect: handleSelection }"
|
||||
/>
|
||||
<div class="table-footer">
|
||||
<TableStats :total="total" />
|
||||
<a-pagination
|
||||
:current="pagination.current"
|
||||
:page-size="pagination.pageSize"
|
||||
|
||||
@@ -120,7 +120,6 @@ onMounted(() => {
|
||||
</PageHeader>
|
||||
|
||||
<a-card :bordered="false">
|
||||
<TableStats :total="data.length" />
|
||||
<a-table
|
||||
:columns="columns"
|
||||
:data="data"
|
||||
@@ -130,6 +129,9 @@ onMounted(() => {
|
||||
:scroll="{ x: 1200 }"
|
||||
size="medium"
|
||||
/>
|
||||
<div class="table-footer">
|
||||
<TableStats :total="data.length" />
|
||||
</div>
|
||||
</a-card>
|
||||
</div>
|
||||
</template>
|
||||
@@ -267,9 +267,9 @@ onMounted(fetchList)
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<TableStats :total="pagination.total" />
|
||||
<ATable :columns="columns" :data="data" :loading="loading" row-key="id" :scroll="{ x: 1400 }" :pagination="false" />
|
||||
<div class="table-footer">
|
||||
<TableStats :total="pagination.total" />
|
||||
<APagination v-model:current="pagination.current" v-model:page-size="pagination.pageSize" :total="pagination.total" :page-size-options="pagination.pageSizeOptions" show-page-size @change="fetchList" @page-size-change="(s: number) => { pagination.pageSize = s; pagination.current = 1; fetchList() }" />
|
||||
</div>
|
||||
</ACard>
|
||||
|
||||
@@ -212,9 +212,9 @@ onMounted(fetchList)
|
||||
<ASelect v-model="statusFilter" :options="statusOptions" style="width: 120px" allow-clear placeholder="状态筛选" @change="() => { pagination.current = 1; fetchList() }" />
|
||||
</div>
|
||||
</template>
|
||||
<TableStats :total="pagination.total" />
|
||||
<ATable :columns="columns" :data="announcements" :loading="loading" row-key="id" :scroll="{ x: 1400 }" :pagination="false" />
|
||||
<div class="table-footer">
|
||||
<TableStats :total="pagination.total" />
|
||||
<APagination v-model:current="pagination.current" v-model:page-size="pagination.pageSize" :total="pagination.total" :page-size-options="pagination.pageSizeOptions" show-page-size @change="fetchList" @page-size-change="(s: number) => { pagination.pageSize = s; pagination.current = 1; fetchList() }" />
|
||||
</div>
|
||||
</ACard>
|
||||
|
||||
@@ -183,9 +183,9 @@ onMounted(fetchList)
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<TableStats :total="pagination.total" />
|
||||
<ATable :columns="columns" :data="data" :loading="loading" row-key="id" :scroll="{ x: 1200 }" :pagination="false" />
|
||||
<div class="table-footer">
|
||||
<TableStats :total="pagination.total" />
|
||||
<APagination v-model:current="pagination.current" v-model:page-size="pagination.pageSize" :total="pagination.total" :page-size-options="pagination.pageSizeOptions" show-page-size @change="fetchList" @page-size-change="(s: number) => { pagination.pageSize = s; pagination.current = 1; fetchList() }" />
|
||||
</div>
|
||||
</ACard>
|
||||
|
||||
@@ -200,7 +200,6 @@ onMounted(() => {
|
||||
</a-card>
|
||||
|
||||
<a-card :bordered="false">
|
||||
<TableStats :total="sendPagination.total" />
|
||||
<a-table
|
||||
:columns="sendColumns"
|
||||
:data="sendData"
|
||||
@@ -213,6 +212,7 @@ onMounted(() => {
|
||||
row-key="id"
|
||||
/>
|
||||
<div class="table-footer">
|
||||
<TableStats :total="sendPagination.total" />
|
||||
<a-pagination
|
||||
v-model:current="sendPagination.current"
|
||||
v-model:page-size="sendPagination.pageSize"
|
||||
@@ -246,7 +246,6 @@ onMounted(() => {
|
||||
</a-card>
|
||||
|
||||
<a-card :bordered="false">
|
||||
<TableStats :total="codePagination.total" />
|
||||
<a-table
|
||||
:columns="codeColumns"
|
||||
:data="codeData"
|
||||
@@ -259,6 +258,7 @@ onMounted(() => {
|
||||
row-key="id"
|
||||
/>
|
||||
<div class="table-footer">
|
||||
<TableStats :total="codePagination.total" />
|
||||
<a-pagination
|
||||
v-model:current="codePagination.current"
|
||||
v-model:page-size="codePagination.pageSize"
|
||||
|
||||
@@ -228,9 +228,9 @@ onMounted(() => { fetchStats(); fetchList() })
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<TableStats :total="pagination.total" />
|
||||
<ATable :columns="columns" :data="data" :loading="loading" row-key="id" :scroll="{ x: 1300 }" :pagination="false" />
|
||||
<div class="table-footer">
|
||||
<TableStats :total="pagination.total" />
|
||||
<APagination v-model:current="pagination.current" v-model:page-size="pagination.pageSize" :total="pagination.total" :page-size-options="pagination.pageSizeOptions" show-page-size @change="fetchList" @page-size-change="(s: number) => { pagination.pageSize = s; pagination.current = 1; fetchList() }" />
|
||||
</div>
|
||||
</ACard>
|
||||
|
||||
@@ -326,9 +326,9 @@ onMounted(fetchList)
|
||||
<ASelect v-model="typeFilter" :options="typeOptions" style="width: 120px" allow-clear placeholder="类型筛选" @change="() => { pagination.current = 1; fetchList() }" />
|
||||
</div>
|
||||
</template>
|
||||
<TableStats :total="pagination.total" />
|
||||
<ATable :columns="columns" :data="messages" :loading="loading" row-key="id" :scroll="{ x: 1100 }" :pagination="false" />
|
||||
<div class="table-footer">
|
||||
<TableStats :total="pagination.total" />
|
||||
<APagination v-model:current="pagination.current" v-model:page-size="pagination.pageSize" :total="pagination.total" :page-size-options="pagination.pageSizeOptions" show-page-size @change="fetchList" @page-size-change="(s: number) => { pagination.pageSize = s; pagination.current = 1; fetchList() }" />
|
||||
</div>
|
||||
</ACard>
|
||||
|
||||
@@ -151,9 +151,9 @@ onMounted(fetchTemplates)
|
||||
</PageHeader>
|
||||
|
||||
<ACard :bordered="false">
|
||||
<TableStats :total="pagination.total" />
|
||||
<ATable :columns="columns" :data="templates" :loading="loading" row-key="code" :scroll="{ x: 1000 }" :pagination="false" />
|
||||
<div class="table-footer">
|
||||
<TableStats :total="pagination.total" />
|
||||
<APagination v-model:current="pagination.current" v-model:page-size="pagination.pageSize" :total="pagination.total" :page-size-options="pagination.pageSizeOptions" show-page-size @change="fetchTemplates" @page-size-change="(s: number) => { pagination.pageSize = s; pagination.current = 1; fetchTemplates() }" />
|
||||
</div>
|
||||
</ACard>
|
||||
|
||||
@@ -288,9 +288,9 @@ onMounted(fetchTickets)
|
||||
</ASpace>
|
||||
</div>
|
||||
</template>
|
||||
<TableStats :total="pagination.total" />
|
||||
<ATable :columns="columns" :data="tickets" :loading="loading" row-key="id" :scroll="{ x: 1300 }" :pagination="false" />
|
||||
<div class="table-footer">
|
||||
<TableStats :total="pagination.total" />
|
||||
<APagination v-model:current="pagination.current" v-model:page-size="pagination.pageSize" :total="pagination.total" :page-size-options="pagination.pageSizeOptions" show-page-size @change="fetchTickets" @page-size-change="(s: number) => { pagination.pageSize = s; pagination.current = 1; fetchTickets() }" />
|
||||
</div>
|
||||
</ACard>
|
||||
|
||||
@@ -218,7 +218,6 @@ const { exporting, exportFile } = useExport({
|
||||
<!-- Tab 1: Operation Logs -->
|
||||
<ATabPane key="logs" title="操作日志">
|
||||
<ACard :bordered="false" class="mt-4">
|
||||
<TableStats :total="opPagination.total" />
|
||||
<div class="mb-4">
|
||||
<ASpace wrap>
|
||||
<AInput
|
||||
@@ -255,6 +254,7 @@ const { exporting, exportFile } = useExport({
|
||||
row-key="id"
|
||||
/>
|
||||
<div class="table-footer">
|
||||
<TableStats :total="opPagination.total" />
|
||||
<APagination
|
||||
v-model:current="opPagination.current"
|
||||
v-model:page-size="opPagination.pageSize"
|
||||
@@ -271,7 +271,6 @@ const { exporting, exportFile } = useExport({
|
||||
<!-- Tab 2: Sensitive Access Logs -->
|
||||
<ATabPane key="sensitive" title="敏感访问日志">
|
||||
<ACard :bordered="false" class="mt-4">
|
||||
<TableStats :total="sensPagination.total" />
|
||||
<div class="mb-4">
|
||||
<ASpace wrap>
|
||||
<AInput
|
||||
@@ -308,6 +307,7 @@ const { exporting, exportFile } = useExport({
|
||||
row-key="id"
|
||||
/>
|
||||
<div class="table-footer">
|
||||
<TableStats :total="sensPagination.total" />
|
||||
<APagination
|
||||
v-model:current="sensPagination.current"
|
||||
v-model:page-size="sensPagination.pageSize"
|
||||
|
||||
@@ -149,7 +149,6 @@ function onDateChange(dateString: string | undefined, type: 'start' | 'end') {
|
||||
</ACard>
|
||||
|
||||
<ACard :bordered="false">
|
||||
<TableStats :total="pagination.total" />
|
||||
<ATable
|
||||
:data="list"
|
||||
:loading="loading"
|
||||
@@ -193,6 +192,7 @@ function onDateChange(dateString: string | undefined, type: 'start' | 'end') {
|
||||
</template>
|
||||
</ATable>
|
||||
<div class="table-footer">
|
||||
<TableStats :total="pagination.total" />
|
||||
<APagination
|
||||
v-model:current="pagination.current"
|
||||
v-model:page-size="pagination.pageSize"
|
||||
|
||||
@@ -58,9 +58,6 @@ onMounted(fetchPermissions)
|
||||
</PageHeader>
|
||||
|
||||
<ACard :bordered="false">
|
||||
<TableStats :total="groups.length">
|
||||
<span>{{ groups.reduce((s, g) => s + g.permissions.length, 0) }} 个权限点</span>
|
||||
</TableStats>
|
||||
<ATable
|
||||
:columns="columns"
|
||||
:data="groups"
|
||||
@@ -70,6 +67,11 @@ onMounted(fetchPermissions)
|
||||
:pagination="false"
|
||||
row-key="id"
|
||||
/>
|
||||
<div class="table-footer">
|
||||
<TableStats :total="groups.length">
|
||||
<span>{{ groups.reduce((s, g) => s + g.permissions.length, 0) }} 个权限点</span>
|
||||
</TableStats>
|
||||
</div>
|
||||
</ACard>
|
||||
</div>
|
||||
</template>
|
||||
@@ -346,7 +346,6 @@ onMounted(() => {
|
||||
</a-card>
|
||||
|
||||
<a-card :bordered="false">
|
||||
<TableStats :total="pagination.total" />
|
||||
<a-table
|
||||
:columns="columns"
|
||||
:data="data"
|
||||
@@ -359,6 +358,7 @@ onMounted(() => {
|
||||
row-key="id"
|
||||
/>
|
||||
<div class="table-footer">
|
||||
<TableStats :total="pagination.total" />
|
||||
<a-pagination
|
||||
v-model:current="pagination.current"
|
||||
v-model:page-size="pagination.pageSize"
|
||||
@@ -444,11 +444,17 @@ onMounted(() => {
|
||||
<style scoped>
|
||||
.table-footer {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
margin-top: 16px;
|
||||
padding-top: 16px;
|
||||
border-top: 1px solid var(--color-border-light, #e5e6eb);
|
||||
}
|
||||
/* 统计栏移入底部后,去掉全局样式的下边距,与分页栏垂直居中 */
|
||||
.table-footer :deep(.table-stats) {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.audit-body {
|
||||
background: var(--color-fill-2, #f7f8fa);
|
||||
padding: 12px;
|
||||
|
||||
@@ -158,7 +158,6 @@ onMounted(() => {
|
||||
</ACard>
|
||||
|
||||
<ACard :bordered="false">
|
||||
<TableStats :total="pagination.total" />
|
||||
<ATable
|
||||
:columns="columns"
|
||||
:data="data"
|
||||
@@ -170,6 +169,7 @@ onMounted(() => {
|
||||
:pagination="false"
|
||||
/>
|
||||
<div class="table-footer">
|
||||
<TableStats :total="pagination.total" />
|
||||
<APagination
|
||||
v-model:current="pagination.current"
|
||||
v-model:page-size="pagination.pageSize"
|
||||
|
||||
@@ -179,7 +179,6 @@ function onDateChange(dateString: string | undefined, type: 'start' | 'end') {
|
||||
</ACard>
|
||||
|
||||
<ACard :bordered="false">
|
||||
<TableStats :total="pagination.total" />
|
||||
<ATable
|
||||
:data="list"
|
||||
:loading="loading"
|
||||
@@ -224,6 +223,7 @@ function onDateChange(dateString: string | undefined, type: 'start' | 'end') {
|
||||
</template>
|
||||
</ATable>
|
||||
<div class="table-footer">
|
||||
<TableStats :total="pagination.total" />
|
||||
<APagination
|
||||
v-model:current="pagination.current"
|
||||
v-model:page-size="pagination.pageSize"
|
||||
|
||||
@@ -465,7 +465,6 @@ onMounted(() => {
|
||||
|
||||
<!-- 列表 -->
|
||||
<ACard :bordered="false">
|
||||
<TableStats :total="pagination.total" />
|
||||
<ASpace wrap style="margin-bottom:16px">
|
||||
<AInput v-model="filter.tenant_id" placeholder="租户ID" allow-clear style="width:110px" />
|
||||
<AInput v-model="filter.user_id" placeholder="上传者ID" allow-clear style="width:110px" />
|
||||
@@ -483,6 +482,7 @@ onMounted(() => {
|
||||
:pagination="false" row-key="id"
|
||||
/>
|
||||
<div class="table-footer">
|
||||
<TableStats :total="pagination.total" />
|
||||
<APagination
|
||||
v-model:current="pagination.current"
|
||||
v-model:page-size="pagination.pageSize"
|
||||
|
||||
@@ -159,9 +159,9 @@ onMounted(() => { fetchCategories() })
|
||||
</Space>
|
||||
</div>
|
||||
</template>
|
||||
<TableStats :total="pagination.total" />
|
||||
<ATable :columns="columns" :data="articles" :loading="loading" row-key="id" :scroll="{ x: 1300 }" :pagination="false" />
|
||||
<div class="table-footer">
|
||||
<TableStats :total="pagination.total" />
|
||||
<APagination v-model:current="pagination.current" v-model:page-size="pagination.pageSize" :total="pagination.total" show-page-size @change="fetchList" @page-size-change="(s: number) => { pagination.pageSize = s; pagination.current = 1; fetchList() }" />
|
||||
</div>
|
||||
</ACard>
|
||||
|
||||
@@ -86,9 +86,9 @@ onMounted(fetchList)
|
||||
</template>
|
||||
</PageHeader>
|
||||
<ACard :bordered="false">
|
||||
<TableStats :total="pagination.total" />
|
||||
<ATable :columns="columns" :data="categories" :loading="loading" row-key="id" :scroll="{ x: 1100 }" :pagination="false" />
|
||||
<div class="table-footer">
|
||||
<TableStats :total="pagination.total" />
|
||||
<APagination v-model:current="pagination.current" v-model:page-size="pagination.pageSize" :total="pagination.total" show-page-size @change="fetchList" @page-size-change="(s: number) => { pagination.pageSize = s; pagination.current = 1; fetchList() }" />
|
||||
</div>
|
||||
</ACard>
|
||||
|
||||
@@ -305,7 +305,6 @@ onMounted(() => {
|
||||
|
||||
<!-- Table -->
|
||||
<ACard :bordered="false">
|
||||
<TableStats :total="data.length" />
|
||||
<ATable
|
||||
:columns="columns"
|
||||
:data="data"
|
||||
@@ -319,6 +318,9 @@ onMounted(() => {
|
||||
<AEmpty v-if="!loading && data.length === 0" style="margin-top: 40px">
|
||||
<template #description>暂无已注册的插件</template>
|
||||
</AEmpty>
|
||||
<div class="table-footer">
|
||||
<TableStats :total="data.length" />
|
||||
</div>
|
||||
</ACard>
|
||||
|
||||
<!-- Config Modal -->
|
||||
|
||||
@@ -275,7 +275,6 @@ const { exporting, exportFile } = useExport({
|
||||
|
||||
<!-- Table Card -->
|
||||
<ACard :bordered="false">
|
||||
<TableStats :total="pagination.total" />
|
||||
<ATable
|
||||
:columns="columns"
|
||||
:data="data"
|
||||
@@ -287,6 +286,7 @@ const { exporting, exportFile } = useExport({
|
||||
row-key="id"
|
||||
/>
|
||||
<div class="table-footer">
|
||||
<TableStats :total="pagination.total" />
|
||||
<APagination
|
||||
v-model:current="pagination.current"
|
||||
v-model:page-size="pagination.pageSize"
|
||||
|
||||
@@ -376,7 +376,6 @@ const { exporting, exportFile } = useExport({
|
||||
|
||||
<!-- Table -->
|
||||
<ACard :bordered="false">
|
||||
<TableStats :total="pagination.total" />
|
||||
<ATable
|
||||
:columns="columns"
|
||||
:data="data"
|
||||
@@ -388,6 +387,7 @@ const { exporting, exportFile } = useExport({
|
||||
row-key="id"
|
||||
/>
|
||||
<div class="table-footer">
|
||||
<TableStats :total="pagination.total" />
|
||||
<APagination
|
||||
v-model:current="pagination.current"
|
||||
v-model:page-size="pagination.pageSize"
|
||||
|
||||
@@ -792,7 +792,6 @@ onMounted(() => {
|
||||
<template #extra>
|
||||
<AButton type="primary" size="small" @click="openGroupModal">分配分组</AButton>
|
||||
</template>
|
||||
<TableStats :total="tenantGroups.length" />
|
||||
<div v-if="tenantGroups.length === 0" style="color: var(--ta-text-tertiary)">
|
||||
暂未分配模型分组,租户可通过分组获取可用模型
|
||||
</div>
|
||||
@@ -807,13 +806,15 @@ onMounted(() => {
|
||||
row-key="group_id"
|
||||
size="small"
|
||||
/>
|
||||
<div class="table-footer">
|
||||
<TableStats :total="tenantGroups.length" />
|
||||
</div>
|
||||
</ACard>
|
||||
|
||||
<ACard :bordered="false" title="独立模型">
|
||||
<template #extra>
|
||||
<AButton type="primary" size="small" @click="openAssignModal">分配模型</AButton>
|
||||
</template>
|
||||
<TableStats :total="modelsData.length" />
|
||||
<div v-if="modelsData.length === 0" style="color: var(--ta-text-tertiary)">
|
||||
暂无独立分配的模型
|
||||
</div>
|
||||
@@ -828,6 +829,9 @@ onMounted(() => {
|
||||
row-key="id"
|
||||
:scroll="{ x: 1100 }"
|
||||
/>
|
||||
<div class="table-footer">
|
||||
<TableStats :total="modelsData.length" />
|
||||
</div>
|
||||
</ACard>
|
||||
</ATabPane>
|
||||
|
||||
|
||||
@@ -143,8 +143,10 @@ onMounted(fetchLevels)
|
||||
|
||||
<ACard :bordered="false">
|
||||
<template #title>等级配置列表</template>
|
||||
<TableStats :total="levels.length" />
|
||||
<ATable :columns="columns" :data="levels" :loading="loading" row-key="id" :scroll="{ x: 900 }" :pagination="false" />
|
||||
<div class="table-footer">
|
||||
<TableStats :total="levels.length" />
|
||||
</div>
|
||||
</ACard>
|
||||
|
||||
<ADrawer v-model:visible="showModal" :title="editingId ? '编辑等级' : '创建等级'" :width="520" :mask-closable="false" :footer="true" unmount-on-close>
|
||||
|
||||
@@ -323,7 +323,6 @@ const { exporting, exportFile } = useExport({
|
||||
|
||||
<!-- Table -->
|
||||
<ACard :bordered="false">
|
||||
<TableStats :total="pagination.total" />
|
||||
<ATable
|
||||
:columns="columns"
|
||||
:data="data"
|
||||
@@ -335,6 +334,7 @@ const { exporting, exportFile } = useExport({
|
||||
row-key="id"
|
||||
/>
|
||||
<div class="table-footer">
|
||||
<TableStats :total="pagination.total" />
|
||||
<APagination
|
||||
v-model:current="pagination.current"
|
||||
v-model:page-size="pagination.pageSize"
|
||||
|
||||
@@ -521,7 +521,6 @@ const { exporting, exportFile } = useExport({
|
||||
</a-card>
|
||||
|
||||
<a-card :bordered="false">
|
||||
<TableStats :total="pagination.total" />
|
||||
<a-table
|
||||
:columns="columns"
|
||||
:data="data"
|
||||
@@ -534,6 +533,7 @@ const { exporting, exportFile } = useExport({
|
||||
row-key="id"
|
||||
/>
|
||||
<div class="table-footer">
|
||||
<TableStats :total="pagination.total" />
|
||||
<a-pagination
|
||||
v-model:current="pagination.current"
|
||||
v-model:page-size="pagination.pageSize"
|
||||
@@ -1317,9 +1317,15 @@ const { exporting, exportFile } = useExport({
|
||||
|
||||
.table-footer {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
margin-top: 16px;
|
||||
padding-top: 16px;
|
||||
border-top: 1px solid var(--color-border-light, #e5e6eb);
|
||||
}
|
||||
/* 统计栏移入底部后,去掉全局样式的下边距,与分页栏垂直居中 */
|
||||
.table-footer :deep(.table-stats) {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
</style>
|
||||
Reference in new issue
Block a user