diff --git a/admin-frontend-vue/src/api/users-model.ts b/admin-frontend-vue/src/api/users-model.ts new file mode 100644 index 00000000..9142575e --- /dev/null +++ b/admin-frontend-vue/src/api/users-model.ts @@ -0,0 +1,54 @@ +/** 用户列表查询适配(任务 42):纯解析模块,无 axios 依赖,与 Java AdminUserListVo 对齐。 */ +import { unwrap } from './envelope.ts' +import { emptyUserPageResult, type UserPageResult } from './users-dto.ts' +import type { AdminUser } from '../types/admin' + +function text(value: unknown): string { + return typeof value === 'string' ? value : '' +} + +function numberOrNull(value: unknown): number | null { + return typeof value === 'number' && Number.isFinite(value) ? value : null +} + +/** 把 Java AdminUserItemVo(snake_case) 映射为前端 AdminUser(camelCase);缺 id 视为无效。 */ +export function toAdminUserItem(raw: unknown): AdminUser | null { + if (!raw || typeof raw !== 'object') return null + const r = raw as Record + const id = numberOrNull(r.id) + if (id === null) return null + const item: AdminUser = { id, username: text(r.username), role: text(r.role) } + if (typeof r.is_admin === 'boolean') item.isAdmin = r.is_admin + const createdById = numberOrNull(r.created_by_id) + if (createdById !== null) item.createdById = createdById + const createdAt = text(r.created_at) + if (createdAt) item.createdAt = createdAt + const creator = text(r.creator_username) + if (creator) item.creatorUsername = creator + const abbr = text(r.pinyin_abbr) + if (abbr) item.pinyinAbbr = abbr + return item +} + +/** + * 归一化 Java 用户列表负载(data:{items,total,page,page_size} 或已解包 VO)为前端 + * UserPageResult;空/缺省字段回默认,success=false 抛后端 message。 + */ +export function parseUserPage(payload: unknown): UserPageResult { + const out = emptyUserPageResult() + const core = unwrap(payload) + if (!core || typeof core !== 'object') return out + const record = core as Record + if (Array.isArray(record.items)) { + out.items = record.items + .map((raw) => toAdminUserItem(raw)) + .filter((item): item is AdminUser => item !== null) + } + if (typeof record.total === 'number') out.total = record.total + if (typeof record.page === 'number' && record.page >= 1) out.page = Math.floor(record.page) + const rawSize = record.page_size ?? record.pageSize + if (typeof rawSize === 'number' && rawSize >= 1) out.pageSize = Math.floor(rawSize) + if (typeof record.current_user_id === 'number') out.currentUserId = record.current_user_id + if (typeof record.current_user_username === 'string') out.currentUserUsername = record.current_user_username + return out +} diff --git a/admin-frontend-vue/src/api/users.ts b/admin-frontend-vue/src/api/users.ts new file mode 100644 index 00000000..0b09c491 --- /dev/null +++ b/admin-frontend-vue/src/api/users.ts @@ -0,0 +1,15 @@ +import { http } from './http' +import { parseUserPage } from './users-model' +import { + normalizeUserPageParams, + toUserListQuery, + type UserListParams, + type UserPageResult, +} from './users-dto' + +/** 分页查询用户列表:归一化参数 → GET /api/admin/users → 解析 Java 分页负载。 */ +export async function fetchUserList(params: Partial = {}): Promise { + const normalized = normalizeUserPageParams(params) + const { data } = await http.get('/api/admin/users', { params: toUserListQuery(normalized) }) + return parseUserPage(data) +} diff --git a/admin-frontend-vue/src/pages/account/UsersPage.vue b/admin-frontend-vue/src/pages/account/UsersPage.vue index 013985cb..8393a125 100644 --- a/admin-frontend-vue/src/pages/account/UsersPage.vue +++ b/admin-frontend-vue/src/pages/account/UsersPage.vue @@ -1,9 +1,9 @@