统一管理后台分页样式
- 新建 AdminTablePagination 组件,统一分页 UI - 改造 6 个前端页面使用统一分页组件: - 管理员管理 - 用户管理 - 申诉管理 - 审计日志 - 公告管理 - 钱包流水 - 订单管理前后端完整改造: - 后端:添加 PaginatedResult 结构,支持 page/page_size 参数 - 前端:API 支持分页参数,页面使用统一分页组件 - 所有列表页分页样式统一为商品管理的 .table-pagination 设计 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -72,6 +72,13 @@ type AdminActionRequest struct {
|
|||||||
|
|
||||||
type AuditMeta = auditlog.Meta
|
type AuditMeta = auditlog.Meta
|
||||||
|
|
||||||
|
type PaginatedResult struct {
|
||||||
|
Items []OrderDTO `json:"items"`
|
||||||
|
Total int64 `json:"total"`
|
||||||
|
Page int `json:"page"`
|
||||||
|
PageSize int `json:"page_size"`
|
||||||
|
}
|
||||||
|
|
||||||
type RefundStatusDTO struct {
|
type RefundStatusDTO struct {
|
||||||
OrderID uint64 `json:"order_id"`
|
OrderID uint64 `json:"order_id"`
|
||||||
OrderNo string `json:"order_no"`
|
OrderNo string `json:"order_no"`
|
||||||
|
|||||||
@@ -53,12 +53,13 @@ func (h *Handler) List(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (h *Handler) AdminList(c *gin.Context) {
|
func (h *Handler) AdminList(c *gin.Context) {
|
||||||
items, err := h.service.ListAdmin()
|
page, pageSize := parsePagination(c)
|
||||||
|
result, err := h.service.ListAdmin(page, pageSize)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeOrderError(c, err)
|
writeOrderError(c, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
response.OK(c, gin.H{"items": items})
|
response.OK(c, result)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *Handler) AdminDetail(c *gin.Context) {
|
func (h *Handler) AdminDetail(c *gin.Context) {
|
||||||
@@ -408,6 +409,21 @@ func parseID(c *gin.Context) (uint64, bool) {
|
|||||||
return id, true
|
return id, true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func parsePagination(c *gin.Context) (int, int) {
|
||||||
|
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
|
||||||
|
pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "20"))
|
||||||
|
if page < 1 {
|
||||||
|
page = 1
|
||||||
|
}
|
||||||
|
if pageSize < 1 {
|
||||||
|
pageSize = 20
|
||||||
|
}
|
||||||
|
if pageSize > 100 {
|
||||||
|
pageSize = 100
|
||||||
|
}
|
||||||
|
return page, pageSize
|
||||||
|
}
|
||||||
|
|
||||||
func writeOrderError(c *gin.Context, err error) {
|
func writeOrderError(c *gin.Context, err error) {
|
||||||
switch {
|
switch {
|
||||||
case errors.Is(err, ErrDependencyUnavailable):
|
case errors.Is(err, ErrDependencyUnavailable):
|
||||||
|
|||||||
@@ -707,20 +707,34 @@ func (r *Repository) ListForUser(userID uint64) ([]OrderDTO, error) {
|
|||||||
return items, nil
|
return items, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Repository) ListAdmin() ([]OrderDTO, error) {
|
func (r *Repository) ListAdmin(page, pageSize int) (*PaginatedResult, error) {
|
||||||
|
var total int64
|
||||||
|
if err := r.adminQuery().Count(&total).Error; err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
offset := (page - 1) * pageSize
|
||||||
var rows []orderRow
|
var rows []orderRow
|
||||||
err := r.adminQuery().
|
err := r.adminQuery().
|
||||||
Order("o.id DESC").
|
Order("o.id DESC").
|
||||||
Limit(200).
|
Limit(pageSize).
|
||||||
|
Offset(offset).
|
||||||
Scan(&rows).Error
|
Scan(&rows).Error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
items := make([]OrderDTO, 0, len(rows))
|
items := make([]OrderDTO, 0, len(rows))
|
||||||
for _, row := range rows {
|
for _, row := range rows {
|
||||||
items = append(items, row.toAdminDTO())
|
items = append(items, row.toAdminDTO())
|
||||||
}
|
}
|
||||||
return items, nil
|
|
||||||
|
return &PaginatedResult{
|
||||||
|
Items: items,
|
||||||
|
Total: total,
|
||||||
|
Page: page,
|
||||||
|
PageSize: pageSize,
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Repository) FindAdmin(orderID uint64) (*OrderDTO, error) {
|
func (r *Repository) FindAdmin(orderID uint64) (*OrderDTO, error) {
|
||||||
|
|||||||
@@ -141,11 +141,11 @@ func (s *Service) ListForUser(userID uint64) ([]OrderDTO, error) {
|
|||||||
return s.repo.ListForUser(userID)
|
return s.repo.ListForUser(userID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) ListAdmin() ([]OrderDTO, error) {
|
func (s *Service) ListAdmin(page, pageSize int) (*PaginatedResult, error) {
|
||||||
if s.repo == nil {
|
if s.repo == nil {
|
||||||
return nil, ErrDependencyUnavailable
|
return nil, ErrDependencyUnavailable
|
||||||
}
|
}
|
||||||
return s.repo.ListAdmin()
|
return s.repo.ListAdmin(page, pageSize)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) FindAdmin(orderID uint64) (*OrderDTO, error) {
|
func (s *Service) FindAdmin(orderID uint64) (*OrderDTO, error) {
|
||||||
|
|||||||
@@ -0,0 +1,67 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { computed } from 'vue'
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
currentPage: number
|
||||||
|
pageSize: number
|
||||||
|
total: number
|
||||||
|
loading?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Emits {
|
||||||
|
(e: 'update:currentPage', value: number): void
|
||||||
|
(e: 'update:pageSize', value: number): void
|
||||||
|
(e: 'pageChange'): void
|
||||||
|
}
|
||||||
|
|
||||||
|
const props = defineProps<Props>()
|
||||||
|
const emit = defineEmits<Emits>()
|
||||||
|
|
||||||
|
const totalPages = computed(() => Math.max(1, Math.ceil(props.total / props.pageSize)))
|
||||||
|
const currentCount = computed(() => {
|
||||||
|
if (!props.total) return 0
|
||||||
|
const start = (props.currentPage - 1) * props.pageSize
|
||||||
|
return Math.min(props.pageSize, props.total - start)
|
||||||
|
})
|
||||||
|
|
||||||
|
function handleSizeChange(size: number) {
|
||||||
|
emit('update:pageSize', size)
|
||||||
|
emit('update:currentPage', 1)
|
||||||
|
emit('pageChange')
|
||||||
|
}
|
||||||
|
|
||||||
|
function prevPage() {
|
||||||
|
if (props.currentPage <= 1) return
|
||||||
|
emit('update:currentPage', props.currentPage - 1)
|
||||||
|
emit('pageChange')
|
||||||
|
}
|
||||||
|
|
||||||
|
function nextPage() {
|
||||||
|
if (props.currentPage >= totalPages.value) return
|
||||||
|
emit('update:currentPage', props.currentPage + 1)
|
||||||
|
emit('pageChange')
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="table-pagination">
|
||||||
|
<span class="pagination-summary">当前页 {{ currentCount }} 条,共 {{ total }} 条</span>
|
||||||
|
<div class="pagination-controls">
|
||||||
|
<span class="pagination-size-label">每页</span>
|
||||||
|
<el-select
|
||||||
|
:model-value="pageSize"
|
||||||
|
class="page-size-select"
|
||||||
|
size="small"
|
||||||
|
@update:model-value="handleSizeChange"
|
||||||
|
>
|
||||||
|
<el-option :value="10" label="10条" />
|
||||||
|
<el-option :value="20" label="20条" />
|
||||||
|
<el-option :value="50" label="50条" />
|
||||||
|
<el-option :value="100" label="100条" />
|
||||||
|
</el-select>
|
||||||
|
<span class="pagination-page">{{ currentPage }}/{{ totalPages }}页</span>
|
||||||
|
<el-button size="small" :disabled="currentPage <= 1 || loading" @click="prevPage">上页</el-button>
|
||||||
|
<el-button size="small" :disabled="currentPage >= totalPages || loading" @click="nextPage">下页</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
@@ -15,6 +15,7 @@ import {
|
|||||||
import type { Announcement } from '@/features/announcement'
|
import type { Announcement } from '@/features/announcement'
|
||||||
import { formatDateTime } from '@/utils/time'
|
import { formatDateTime } from '@/utils/time'
|
||||||
import AnnouncementDialog from '../components/AnnouncementDialog.vue'
|
import AnnouncementDialog from '../components/AnnouncementDialog.vue'
|
||||||
|
import AdminTablePagination from '../components/AdminTablePagination.vue'
|
||||||
|
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
const announcements = ref<Announcement[]>([])
|
const announcements = ref<Announcement[]>([])
|
||||||
@@ -146,9 +147,13 @@ function handleFilterChange() {
|
|||||||
loadAnnouncements()
|
loadAnnouncements()
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleSizeChange() {
|
async function handlePageChange() {
|
||||||
|
await loadAnnouncements()
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleSizeChange() {
|
||||||
currentPage.value = 1
|
currentPage.value = 1
|
||||||
loadAnnouncements()
|
await loadAnnouncements()
|
||||||
}
|
}
|
||||||
|
|
||||||
function getCategoryLabel(category: string) {
|
function getCategoryLabel(category: string) {
|
||||||
@@ -261,18 +266,15 @@ function getStatusType(status: string): '' | 'success' | 'info' | 'warning' {
|
|||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
|
|
||||||
<div class="pagination-wrap">
|
<AdminTablePagination
|
||||||
<el-pagination
|
v-if="total > 0"
|
||||||
v-model:current-page="currentPage"
|
v-model:current-page="currentPage"
|
||||||
v-model:page-size="currentPageSize"
|
v-model:page-size="currentPageSize"
|
||||||
:total="total"
|
:total="total"
|
||||||
:page-sizes="[10, 20, 50, 100]"
|
:loading="loading"
|
||||||
layout="total, sizes, prev, pager, next"
|
@page-change="handlePageChange"
|
||||||
@current-change="loadAnnouncements"
|
|
||||||
@size-change="handleSizeChange"
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<AnnouncementDialog
|
<AnnouncementDialog
|
||||||
v-model:visible="dialogVisible"
|
v-model:visible="dialogVisible"
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { computed, onMounted, reactive, ref } from 'vue'
|
|||||||
|
|
||||||
import { fetchAdminAuditLogs, type AdminAuditLog } from '@/features/admin/api/adminAudit'
|
import { fetchAdminAuditLogs, type AdminAuditLog } from '@/features/admin/api/adminAudit'
|
||||||
import { formatDateTime } from '@/utils/time'
|
import { formatDateTime } from '@/utils/time'
|
||||||
|
import AdminTablePagination from '../components/AdminTablePagination.vue'
|
||||||
|
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
const logs = ref<AdminAuditLog[]>([])
|
const logs = ref<AdminAuditLog[]>([])
|
||||||
@@ -45,9 +46,13 @@ function resetFilters() {
|
|||||||
void loadLogs()
|
void loadLogs()
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleSizeChange() {
|
async function handlePageChange() {
|
||||||
|
await loadLogs()
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleSizeChange() {
|
||||||
currentPage.value = 1
|
currentPage.value = 1
|
||||||
loadLogs()
|
await loadLogs()
|
||||||
}
|
}
|
||||||
|
|
||||||
function actorName(row: AdminAuditLog) {
|
function actorName(row: AdminAuditLog) {
|
||||||
@@ -141,17 +146,14 @@ function actionType(action: string) {
|
|||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
|
|
||||||
<div class="pagination-wrap" v-if="total > 0">
|
<AdminTablePagination
|
||||||
<el-pagination
|
v-if="total > 0"
|
||||||
v-model:current-page="currentPage"
|
v-model:current-page="currentPage"
|
||||||
v-model:page-size="currentPageSize"
|
v-model:page-size="currentPageSize"
|
||||||
:total="total"
|
:total="total"
|
||||||
:page-sizes="[10, 20, 50, 100]"
|
:loading="loading"
|
||||||
layout="total, sizes, prev, pager, next"
|
@page-change="handlePageChange"
|
||||||
@current-change="loadLogs"
|
|
||||||
@size-change="handleSizeChange"
|
|
||||||
/>
|
/>
|
||||||
</div>
|
|
||||||
|
|
||||||
<el-dialog :model-value="!!activeLog" title="审计明细" width="720px" @update:model-value="activeLog = null">
|
<el-dialog :model-value="!!activeLog" title="审计明细" width="720px" @update:model-value="activeLog = null">
|
||||||
<div v-if="activeLog" class="dialog-body">
|
<div v-if="activeLog" class="dialog-body">
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import { arbitrateDispute, fetchAdminDisputes, type Dispute } from '@/features/d
|
|||||||
import { fetchAdminFileBlob } from '@/shared/api/files'
|
import { fetchAdminFileBlob } from '@/shared/api/files'
|
||||||
import { disputeStatusLabel } from '@/utils/statusLabels'
|
import { disputeStatusLabel } from '@/utils/statusLabels'
|
||||||
import { formatDateTime } from '@/utils/time'
|
import { formatDateTime } from '@/utils/time'
|
||||||
|
import AdminTablePagination from '../components/AdminTablePagination.vue'
|
||||||
|
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
const submitting = ref(false)
|
const submitting = ref(false)
|
||||||
@@ -32,9 +33,13 @@ async function loadDisputes() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleSizeChange() {
|
async function handlePageChange() {
|
||||||
|
await loadDisputes()
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleSizeChange() {
|
||||||
currentPage.value = 1
|
currentPage.value = 1
|
||||||
loadDisputes()
|
await loadDisputes()
|
||||||
}
|
}
|
||||||
|
|
||||||
function openArbitration(row: Dispute) {
|
function openArbitration(row: Dispute) {
|
||||||
@@ -132,17 +137,14 @@ function readError(error: unknown, fallback: string) {
|
|||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
|
|
||||||
<div class="pagination-wrap" v-if="total > 0">
|
<AdminTablePagination
|
||||||
<el-pagination
|
v-if="total > 0"
|
||||||
v-model:current-page="currentPage"
|
v-model:current-page="currentPage"
|
||||||
v-model:page-size="currentPageSize"
|
v-model:page-size="currentPageSize"
|
||||||
:total="total"
|
:total="total"
|
||||||
:page-sizes="[10, 20, 50, 100]"
|
:loading="loading"
|
||||||
layout="total, sizes, prev, pager, next"
|
@page-change="handlePageChange"
|
||||||
@current-change="loadDisputes"
|
|
||||||
@size-change="handleSizeChange"
|
|
||||||
/>
|
/>
|
||||||
</div>
|
|
||||||
|
|
||||||
<el-dialog :model-value="!!activeDispute" title="申诉仲裁" width="560px" @update:model-value="activeDispute = null">
|
<el-dialog :model-value="!!activeDispute" title="申诉仲裁" width="560px" @update:model-value="activeDispute = null">
|
||||||
<div v-if="activeDispute" class="dialog-body">
|
<div v-if="activeDispute" class="dialog-body">
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import { formatDateTime } from '@/utils/time'
|
|||||||
|
|
||||||
import AdminUserDialog from '../components/AdminUserDialog.vue'
|
import AdminUserDialog from '../components/AdminUserDialog.vue'
|
||||||
import AssignRolesDialog from '../components/AssignRolesDialog.vue'
|
import AssignRolesDialog from '../components/AssignRolesDialog.vue'
|
||||||
|
import AdminTablePagination from '../components/AdminTablePagination.vue'
|
||||||
|
|
||||||
const showDialog = ref(false)
|
const showDialog = ref(false)
|
||||||
const editingAdmin = ref<AdminMgrUser | null>(null)
|
const editingAdmin = ref<AdminMgrUser | null>(null)
|
||||||
@@ -141,17 +142,14 @@ const statusLabel: Record<string, string> = {
|
|||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
|
|
||||||
<div class="pagination-wrap" v-if="total > 0">
|
<AdminTablePagination
|
||||||
<el-pagination
|
v-if="total > 0"
|
||||||
v-model:current-page="currentPage"
|
v-model:current-page="currentPage"
|
||||||
v-model:page-size="currentPageSize"
|
v-model:page-size="currentPageSize"
|
||||||
:total="total"
|
:total="total"
|
||||||
:page-sizes="[10, 20, 50, 100]"
|
:loading="loading"
|
||||||
layout="total, sizes, prev, pager, next"
|
@page-change="loadAdmins"
|
||||||
@current-change="loadAdmins"
|
|
||||||
@size-change="handleSizeChange"
|
|
||||||
/>
|
/>
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 新建/编辑对话框 -->
|
<!-- 新建/编辑对话框 -->
|
||||||
<AdminUserDialog
|
<AdminUserDialog
|
||||||
|
|||||||
@@ -1,17 +1,34 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, ref } from 'vue'
|
import { computed, onMounted, ref } from 'vue'
|
||||||
|
|
||||||
import { fetchAdminOrders, type Order } from '@/features/orders'
|
import { fetchAdminOrders, type Order } from '@/features/orders'
|
||||||
import { useAdminTable } from '@/features/admin/composables/useAdminTable'
|
|
||||||
import { handoffStatusLabel, orderStatusLabel, settlementStatusLabel } from '@/utils/statusLabels'
|
import { handoffStatusLabel, orderStatusLabel, settlementStatusLabel } from '@/utils/statusLabels'
|
||||||
import { formatDateTime } from '@/utils/time'
|
import { formatDateTime } from '@/utils/time'
|
||||||
|
import AdminTablePagination from '../components/AdminTablePagination.vue'
|
||||||
|
|
||||||
const status = ref('')
|
const status = ref('')
|
||||||
|
const loading = ref(false)
|
||||||
|
const orders = ref<Order[]>([])
|
||||||
|
const total = ref(0)
|
||||||
|
const currentPage = ref(1)
|
||||||
|
const currentPageSize = ref(20)
|
||||||
|
|
||||||
const { loading, data: orders, load: loadOrders } = useAdminTable<Order[]>({
|
onMounted(loadOrders)
|
||||||
fetchFn: fetchAdminOrders,
|
|
||||||
initialData: [],
|
async function loadOrders() {
|
||||||
})
|
loading.value = true
|
||||||
|
try {
|
||||||
|
const result = await fetchAdminOrders(currentPage.value, currentPageSize.value)
|
||||||
|
orders.value = result.items
|
||||||
|
total.value = result.total
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handlePageChange() {
|
||||||
|
await loadOrders()
|
||||||
|
}
|
||||||
|
|
||||||
const filteredOrders = computed(() => {
|
const filteredOrders = computed(() => {
|
||||||
if (!status.value) return orders.value
|
if (!status.value) return orders.value
|
||||||
@@ -74,5 +91,14 @@ const filteredOrders = computed(() => {
|
|||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
|
|
||||||
|
<AdminTablePagination
|
||||||
|
v-if="total > 0"
|
||||||
|
v-model:current-page="currentPage"
|
||||||
|
v-model:page-size="currentPageSize"
|
||||||
|
:total="total"
|
||||||
|
:loading="loading"
|
||||||
|
@page-change="handlePageChange"
|
||||||
|
/>
|
||||||
</section>
|
</section>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import { fetchAdminUsers, freezeAdminUser, unfreezeAdminUser, type AdminUserItem
|
|||||||
import { useAdminPaginatedTable } from '@/features/admin/composables/useAdminPaginatedTable'
|
import { useAdminPaginatedTable } from '@/features/admin/composables/useAdminPaginatedTable'
|
||||||
import { userStatusLabel } from '@/utils/statusLabels'
|
import { userStatusLabel } from '@/utils/statusLabels'
|
||||||
import { formatDateTime } from '@/utils/time'
|
import { formatDateTime } from '@/utils/time'
|
||||||
|
import AdminTablePagination from '../components/AdminTablePagination.vue'
|
||||||
|
|
||||||
const submitting = ref(false)
|
const submitting = ref(false)
|
||||||
const activeUser = ref<AdminUserItem | null>(null)
|
const activeUser = ref<AdminUserItem | null>(null)
|
||||||
@@ -88,17 +89,14 @@ function readError(error: unknown, fallback: string) {
|
|||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
|
|
||||||
<div class="pagination-wrap" v-if="total > 0">
|
<AdminTablePagination
|
||||||
<el-pagination
|
v-if="total > 0"
|
||||||
v-model:current-page="currentPage"
|
v-model:current-page="currentPage"
|
||||||
v-model:page-size="currentPageSize"
|
v-model:page-size="currentPageSize"
|
||||||
:total="total"
|
:total="total"
|
||||||
:page-sizes="[10, 20, 50, 100]"
|
:loading="loading"
|
||||||
layout="total, sizes, prev, pager, next"
|
@page-change="loadUsers"
|
||||||
@current-change="loadUsers"
|
|
||||||
@size-change="handleSizeChange"
|
|
||||||
/>
|
/>
|
||||||
</div>
|
|
||||||
|
|
||||||
<el-dialog :model-value="!!activeUser" title="冻结用户" width="560px" @update:model-value="activeUser = null">
|
<el-dialog :model-value="!!activeUser" title="冻结用户" width="560px" @update:model-value="activeUser = null">
|
||||||
<div v-if="activeUser" class="dialog-body">
|
<div v-if="activeUser" class="dialog-body">
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { computed, onMounted, reactive, ref } from 'vue'
|
|||||||
import { fetchAdminWalletLedger, type AdminWalletLedger } from '@/features/admin/api/adminWallet'
|
import { fetchAdminWalletLedger, type AdminWalletLedger } from '@/features/admin/api/adminWallet'
|
||||||
import { balanceTypeLabel, ledgerDirectionLabel } from '@/utils/statusLabels'
|
import { balanceTypeLabel, ledgerDirectionLabel } from '@/utils/statusLabels'
|
||||||
import { formatDateTime } from '@/utils/time'
|
import { formatDateTime } from '@/utils/time'
|
||||||
|
import AdminTablePagination from '../components/AdminTablePagination.vue'
|
||||||
|
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
const ledger = ref<AdminWalletLedger[]>([])
|
const ledger = ref<AdminWalletLedger[]>([])
|
||||||
@@ -50,9 +51,13 @@ function resetFilters() {
|
|||||||
void loadLedger()
|
void loadLedger()
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleSizeChange() {
|
async function handlePageChange() {
|
||||||
|
await loadLedger()
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleSizeChange() {
|
||||||
currentPage.value = 1
|
currentPage.value = 1
|
||||||
loadLedger()
|
await loadLedger()
|
||||||
}
|
}
|
||||||
|
|
||||||
function money(value: number) {
|
function money(value: number) {
|
||||||
@@ -149,16 +154,13 @@ function directionLabel(direction: string) {
|
|||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
|
|
||||||
<div class="pagination-wrap" v-if="total > 0">
|
<AdminTablePagination
|
||||||
<el-pagination
|
v-if="total > 0"
|
||||||
v-model:current-page="currentPage"
|
v-model:current-page="currentPage"
|
||||||
v-model:page-size="currentPageSize"
|
v-model:page-size="currentPageSize"
|
||||||
:total="total"
|
:total="total"
|
||||||
:page-sizes="[10, 20, 50, 100]"
|
:loading="loading"
|
||||||
layout="total, sizes, prev, pager, next"
|
@page-change="handlePageChange"
|
||||||
@current-change="loadLedger"
|
|
||||||
@size-change="handleSizeChange"
|
|
||||||
/>
|
/>
|
||||||
</div>
|
|
||||||
</section>
|
</section>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -157,9 +157,11 @@ export async function fetchOrders() {
|
|||||||
return data.data.items
|
return data.data.items
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function fetchAdminOrders() {
|
export async function fetchAdminOrders(page = 1, pageSize = 20) {
|
||||||
const { data } = await apiClient.get<ApiResponse<{ items: Order[] }>>('/admin/orders')
|
const { data } = await apiClient.get<ApiResponse<{ items: Order[]; total: number; page: number; page_size: number }>>('/admin/orders', {
|
||||||
return data.data.items
|
params: { page, page_size: pageSize },
|
||||||
|
})
|
||||||
|
return data.data
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function fetchOrder(id: string | number) {
|
export async function fetchOrder(id: string | number) {
|
||||||
|
|||||||
Reference in New Issue
Block a user