fix: 修改代码格局分布
This commit is contained in:
parent
7c0bc201a5
commit
863b376020
@ -11,7 +11,7 @@ import { Elysia } from 'elysia';
|
|||||||
import { RegisterSchema, ActivateSchema, LoginSchema, RefreshSchema, ResetPasswordRequestSchema, ResetPasswordConfirmSchema } from './auth.schema';
|
import { RegisterSchema, ActivateSchema, LoginSchema, RefreshSchema, ResetPasswordRequestSchema, ResetPasswordConfirmSchema } from './auth.schema';
|
||||||
import { RegisterResponsesSchema, ActivateResponsesSchema, LoginResponsesSchema, RefreshResponsesSchema, ResetPasswordRequestResponsesSchema, ResetPasswordConfirmResponsesSchema } from './auth.response';
|
import { RegisterResponsesSchema, ActivateResponsesSchema, LoginResponsesSchema, RefreshResponsesSchema, ResetPasswordRequestResponsesSchema, ResetPasswordConfirmResponsesSchema } from './auth.response';
|
||||||
import { authService } from './auth.service';
|
import { authService } from './auth.service';
|
||||||
import { tags } from '@/modules/tags';
|
import { tags } from '@/constants/swaggerTags';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 认证控制器
|
* 认证控制器
|
||||||
|
@ -9,7 +9,7 @@ import { Elysia, t } from 'elysia';
|
|||||||
import { GenerateCaptchaSchema, VerifyCaptchaSchema } from './captcha.schema';
|
import { GenerateCaptchaSchema, VerifyCaptchaSchema } from './captcha.schema';
|
||||||
import { responseWrapperSchema } from '@/utils/responseFormate';
|
import { responseWrapperSchema } from '@/utils/responseFormate';
|
||||||
import { captchaService } from './captcha.service';
|
import { captchaService } from './captcha.service';
|
||||||
import { tags } from '@/modules/tags';
|
import { tags } from '@/constants/swaggerTags';
|
||||||
|
|
||||||
export const captchaController = new Elysia()
|
export const captchaController = new Elysia()
|
||||||
/**
|
/**
|
||||||
|
@ -11,7 +11,7 @@ import { Elysia } from 'elysia';
|
|||||||
import { userService } from './user.service';
|
import { userService } from './user.service';
|
||||||
import { GetCurrentUserResponsesSchema, GetUserListResponsesSchema } from './user.response';
|
import { GetCurrentUserResponsesSchema, GetUserListResponsesSchema } from './user.response';
|
||||||
import { UserListQuerySchema } from './user.schema';
|
import { UserListQuerySchema } from './user.schema';
|
||||||
import { tags } from '@/modules/tags';
|
import { tags } from '@/constants/swaggerTags';
|
||||||
import { jwtAuthPlugin } from '@/plugins/jwt/jwt.plugins';
|
import { jwtAuthPlugin } from '@/plugins/jwt/jwt.plugins';
|
||||||
import type { JwtUserType } from '@/type/jwt.type';
|
import type { JwtUserType } from '@/type/jwt.type';
|
||||||
|
|
||||||
@ -26,37 +26,29 @@ export const userController = new Elysia()
|
|||||||
* @description 获取当前登录用户的详细信息,需要JWT认证
|
* @description 获取当前登录用户的详细信息,需要JWT认证
|
||||||
*/
|
*/
|
||||||
.use(jwtAuthPlugin)
|
.use(jwtAuthPlugin)
|
||||||
.get(
|
.get('/me', ({ user }: { user: JwtUserType }) => userService.getCurrentUser(user.userId), {
|
||||||
'/me',
|
|
||||||
({ user }: { user: JwtUserType }) => userService.getCurrentUser(user.userId),
|
|
||||||
{
|
|
||||||
detail: {
|
detail: {
|
||||||
summary: '获取当前用户信息',
|
summary: '获取当前用户信息',
|
||||||
description: '获取当前登录用户的详细信息,包括基本信息、状态、时间等',
|
description: '获取当前登录用户的详细信息,包括基本信息、状态、时间等',
|
||||||
tags: [tags.user],
|
tags: [tags.user],
|
||||||
operationId: 'getCurrentUser',
|
operationId: 'getCurrentUser',
|
||||||
security: [{ bearerAuth: [] }]
|
security: [{ bearerAuth: [] }],
|
||||||
},
|
},
|
||||||
response: GetCurrentUserResponsesSchema,
|
response: GetCurrentUserResponsesSchema,
|
||||||
}
|
})
|
||||||
)
|
|
||||||
/**
|
/**
|
||||||
* 用户列表查询接口
|
* 用户列表查询接口
|
||||||
* @route GET /api/users
|
* @route GET /api/users
|
||||||
* @description 获取用户列表,支持分页、搜索、筛选等功能,需要JWT认证
|
* @description 获取用户列表,支持分页、搜索、筛选等功能,需要JWT认证
|
||||||
*/
|
*/
|
||||||
.get(
|
.get('/list', ({ query }) => userService.getUserList(query), {
|
||||||
'/list',
|
|
||||||
({ query }) => userService.getUserList(query),
|
|
||||||
{
|
|
||||||
query: UserListQuerySchema,
|
query: UserListQuerySchema,
|
||||||
detail: {
|
detail: {
|
||||||
summary: '获取用户列表',
|
summary: '获取用户列表',
|
||||||
description: '获取用户列表,支持分页查询、关键词搜索、状态筛选、排序等功能',
|
description: '获取用户列表,支持分页查询、关键词搜索、状态筛选、排序等功能',
|
||||||
tags: [tags.user],
|
tags: [tags.user],
|
||||||
operationId: 'getUserList',
|
operationId: 'getUserList',
|
||||||
security: [{ bearerAuth: [] }]
|
security: [{ bearerAuth: [] }],
|
||||||
},
|
},
|
||||||
response: GetUserListResponsesSchema,
|
response: GetUserListResponsesSchema,
|
||||||
}
|
});
|
||||||
);
|
|
||||||
|
@ -9,7 +9,64 @@
|
|||||||
|
|
||||||
import { t, type Static } from 'elysia';
|
import { t, type Static } from 'elysia';
|
||||||
import { responseWrapperSchema } from '@/utils/responseFormate';
|
import { responseWrapperSchema } from '@/utils/responseFormate';
|
||||||
import { CurrentUserSchema, UserListResponseSchema } from './user.schema';
|
import { createPaginationResponseSchema } from '@/utils/pagination';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 当前用户信息响应Schema
|
||||||
|
* @description 获取当前用户信息的响应数据结构
|
||||||
|
*/
|
||||||
|
export const CurrentUserSchema = t.Object({
|
||||||
|
/** 用户ID */
|
||||||
|
id: t.String({
|
||||||
|
description: '用户ID(bigint类型以字符串形式返回防止精度丢失)',
|
||||||
|
examples: ['1', '2', '3'],
|
||||||
|
}),
|
||||||
|
/** 用户名 */
|
||||||
|
username: t.String({
|
||||||
|
description: '用户名',
|
||||||
|
examples: ['admin', 'testuser'],
|
||||||
|
}),
|
||||||
|
/** 邮箱地址 */
|
||||||
|
email: t.String({
|
||||||
|
description: '邮箱地址',
|
||||||
|
examples: ['user@example.com'],
|
||||||
|
}),
|
||||||
|
/** 昵称 */
|
||||||
|
nickname: t.Union([t.String(), t.Null()], {
|
||||||
|
description: '用户昵称',
|
||||||
|
examples: ['管理员', '测试用户', null],
|
||||||
|
}),
|
||||||
|
/** 头像URL */
|
||||||
|
avatar: t.Union([t.String(), t.Null()], {
|
||||||
|
description: '用户头像URL',
|
||||||
|
examples: ['https://example.com/avatar.jpg', null],
|
||||||
|
}),
|
||||||
|
/** 手机号 */
|
||||||
|
phone: t.Union([t.String(), t.Null()], {
|
||||||
|
description: '手机号码',
|
||||||
|
examples: ['13800138000', null],
|
||||||
|
}),
|
||||||
|
/** 账号状态 */
|
||||||
|
status: t.String({
|
||||||
|
description: '账号状态',
|
||||||
|
examples: ['active', 'inactive', 'pending'],
|
||||||
|
}),
|
||||||
|
/** 最后登录时间 */
|
||||||
|
lastLoginAt: t.Union([t.String(), t.Null()], {
|
||||||
|
description: '最后登录时间',
|
||||||
|
examples: ['2024-12-19T10:30:00Z', null],
|
||||||
|
}),
|
||||||
|
/** 创建时间 */
|
||||||
|
createdAt: t.String({
|
||||||
|
description: '创建时间',
|
||||||
|
examples: ['2024-12-19T10:30:00Z'],
|
||||||
|
}),
|
||||||
|
/** 更新时间 */
|
||||||
|
updatedAt: t.String({
|
||||||
|
description: '更新时间',
|
||||||
|
examples: ['2024-12-19T10:30:00Z'],
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取当前用户信息接口响应组合
|
* 获取当前用户信息接口响应组合
|
||||||
@ -17,60 +74,172 @@ import { CurrentUserSchema, UserListResponseSchema } from './user.schema';
|
|||||||
*/
|
*/
|
||||||
export const GetCurrentUserResponsesSchema = {
|
export const GetCurrentUserResponsesSchema = {
|
||||||
200: responseWrapperSchema(CurrentUserSchema),
|
200: responseWrapperSchema(CurrentUserSchema),
|
||||||
401: responseWrapperSchema(t.Object({
|
401: responseWrapperSchema(
|
||||||
|
t.Object({
|
||||||
error: t.String({
|
error: t.String({
|
||||||
description: '认证失败',
|
description: '认证失败',
|
||||||
examples: ['未提供有效的认证令牌', '令牌已过期']
|
examples: ['未提供有效的认证令牌', '令牌已过期'],
|
||||||
})
|
}),
|
||||||
})),
|
}),
|
||||||
404: responseWrapperSchema(t.Object({
|
),
|
||||||
|
404: responseWrapperSchema(
|
||||||
|
t.Object({
|
||||||
error: t.String({
|
error: t.String({
|
||||||
description: '用户不存在',
|
description: '用户不存在',
|
||||||
examples: ['用户不存在或已被删除']
|
examples: ['用户不存在或已被删除'],
|
||||||
})
|
}),
|
||||||
})),
|
}),
|
||||||
500: responseWrapperSchema(t.Object({
|
),
|
||||||
|
500: responseWrapperSchema(
|
||||||
|
t.Object({
|
||||||
error: t.String({
|
error: t.String({
|
||||||
description: '服务器错误',
|
description: '服务器错误',
|
||||||
examples: ['内部服务器错误']
|
examples: ['内部服务器错误'],
|
||||||
})
|
}),
|
||||||
}))
|
}),
|
||||||
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户列表项Schema
|
||||||
|
* @description 用户列表中单个用户的数据结构
|
||||||
|
*/
|
||||||
|
export const UserListItemSchema = t.Object({
|
||||||
|
/** 用户ID */
|
||||||
|
id: t.String({
|
||||||
|
description: '用户ID(bigint类型以字符串形式返回防止精度丢失)',
|
||||||
|
examples: ['1', '2', '3'],
|
||||||
|
}),
|
||||||
|
/** 用户名 */
|
||||||
|
username: t.String({
|
||||||
|
description: '用户名',
|
||||||
|
examples: ['admin', 'testuser'],
|
||||||
|
}),
|
||||||
|
/** 邮箱地址 */
|
||||||
|
email: t.String({
|
||||||
|
description: '邮箱地址',
|
||||||
|
examples: ['user@example.com'],
|
||||||
|
}),
|
||||||
|
/** 手机号 */
|
||||||
|
mobile: t.Union([t.String(), t.Null()], {
|
||||||
|
description: '手机号码',
|
||||||
|
examples: ['13800138000', null],
|
||||||
|
}),
|
||||||
|
/** 昵称 */
|
||||||
|
nickname: t.Union([t.String(), t.Null()], {
|
||||||
|
description: '用户昵称',
|
||||||
|
examples: ['管理员', '测试用户', null],
|
||||||
|
}),
|
||||||
|
/** 头像URL */
|
||||||
|
avatar: t.Union([t.String(), t.Null()], {
|
||||||
|
description: '用户头像URL',
|
||||||
|
examples: ['https://example.com/avatar.jpg', null],
|
||||||
|
}),
|
||||||
|
/** 账号状态 */
|
||||||
|
status: t.String({
|
||||||
|
description: '账号状态',
|
||||||
|
examples: ['active', 'inactive', 'pending'],
|
||||||
|
}),
|
||||||
|
/** 性别 */
|
||||||
|
gender: t.Union([t.Number(), t.Null()], {
|
||||||
|
description: '性别:0-未知,1-男,2-女',
|
||||||
|
examples: [0, 1, 2, null],
|
||||||
|
}),
|
||||||
|
/** 生日 */
|
||||||
|
birthday: t.Union([t.String(), t.Null()], {
|
||||||
|
description: '生日',
|
||||||
|
examples: ['1990-01-01', null],
|
||||||
|
}),
|
||||||
|
/** 个人简介 */
|
||||||
|
bio: t.Union([t.String(), t.Null()], {
|
||||||
|
description: '个人简介',
|
||||||
|
examples: ['这是一段个人简介', null],
|
||||||
|
}),
|
||||||
|
/** 登录次数 */
|
||||||
|
loginCount: t.Number({
|
||||||
|
description: '登录次数',
|
||||||
|
examples: [0, 10, 100],
|
||||||
|
}),
|
||||||
|
/** 最后登录时间 */
|
||||||
|
lastLoginAt: t.Union([t.String(), t.Null()], {
|
||||||
|
description: '最后登录时间',
|
||||||
|
examples: ['2024-12-19T10:30:00Z', null],
|
||||||
|
}),
|
||||||
|
/** 最后登录IP */
|
||||||
|
lastLoginIp: t.Union([t.String(), t.Null()], {
|
||||||
|
description: '最后登录IP',
|
||||||
|
examples: ['192.168.1.1', null],
|
||||||
|
}),
|
||||||
|
/** 失败尝试次数 */
|
||||||
|
failedAttempts: t.Number({
|
||||||
|
description: '失败尝试次数',
|
||||||
|
examples: [0, 1, 5],
|
||||||
|
}),
|
||||||
|
/** 是否超级管理员 */
|
||||||
|
isRoot: t.Boolean({
|
||||||
|
description: '是否超级管理员',
|
||||||
|
examples: [true, false],
|
||||||
|
}),
|
||||||
|
/** 创建时间 */
|
||||||
|
createdAt: t.String({
|
||||||
|
description: '创建时间',
|
||||||
|
examples: ['2024-12-19T10:30:00Z'],
|
||||||
|
}),
|
||||||
|
/** 更新时间 */
|
||||||
|
updatedAt: t.String({
|
||||||
|
description: '更新时间',
|
||||||
|
examples: ['2024-12-19T10:30:00Z'],
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取用户列表接口响应组合
|
* 获取用户列表接口响应组合
|
||||||
* @description 用于Controller中定义所有可能的响应格式
|
* @description 用于Controller中定义所有可能的响应格式
|
||||||
*/
|
*/
|
||||||
export const GetUserListResponsesSchema = {
|
export const GetUserListResponsesSchema = {
|
||||||
200: responseWrapperSchema(UserListResponseSchema),
|
200: responseWrapperSchema(createPaginationResponseSchema(UserListItemSchema)),
|
||||||
401: responseWrapperSchema(t.Object({
|
401: responseWrapperSchema(
|
||||||
|
t.Object({
|
||||||
error: t.String({
|
error: t.String({
|
||||||
description: '认证失败',
|
description: '认证失败',
|
||||||
examples: ['未提供有效的认证令牌', '令牌已过期']
|
examples: ['未提供有效的认证令牌', '令牌已过期'],
|
||||||
})
|
}),
|
||||||
})),
|
}),
|
||||||
403: responseWrapperSchema(t.Object({
|
),
|
||||||
|
403: responseWrapperSchema(
|
||||||
|
t.Object({
|
||||||
error: t.String({
|
error: t.String({
|
||||||
description: '权限不足',
|
description: '权限不足',
|
||||||
examples: ['权限不足,无法访问用户列表']
|
examples: ['权限不足,无法访问用户列表'],
|
||||||
})
|
}),
|
||||||
})),
|
}),
|
||||||
400: responseWrapperSchema(t.Object({
|
),
|
||||||
|
400: responseWrapperSchema(
|
||||||
|
t.Object({
|
||||||
error: t.String({
|
error: t.String({
|
||||||
description: '参数错误',
|
description: '参数错误',
|
||||||
examples: ['分页参数无效', '搜索关键词格式错误']
|
examples: ['分页参数无效', '搜索关键词格式错误'],
|
||||||
})
|
}),
|
||||||
})),
|
}),
|
||||||
500: responseWrapperSchema(t.Object({
|
),
|
||||||
|
500: responseWrapperSchema(
|
||||||
|
t.Object({
|
||||||
error: t.String({
|
error: t.String({
|
||||||
description: '服务器错误',
|
description: '服务器错误',
|
||||||
examples: ['内部服务器错误']
|
examples: ['内部服务器错误'],
|
||||||
})
|
}),
|
||||||
}))
|
}),
|
||||||
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** 当前用户信息响应类型 */
|
||||||
|
export type CurrentUserResponse = Static<typeof CurrentUserSchema>;
|
||||||
|
|
||||||
|
/** 用户列表项类型 */
|
||||||
|
export type UserListItem = Static<typeof UserListItemSchema>;
|
||||||
|
|
||||||
/** 获取当前用户信息成功响应数据类型 */
|
/** 获取当前用户信息成功响应数据类型 */
|
||||||
export type GetCurrentUserSuccessType = Static<typeof GetCurrentUserResponsesSchema[200]>;
|
export type GetCurrentUserSuccessType = Static<(typeof GetCurrentUserResponsesSchema)[200]>;
|
||||||
|
|
||||||
/** 获取用户列表成功响应数据类型 */
|
/** 获取用户列表成功响应数据类型 */
|
||||||
export type GetUserListSuccessType = Static<typeof GetUserListResponsesSchema[200]>;
|
export type GetUserListSuccessType = Static<(typeof GetUserListResponsesSchema)[200]>;
|
||||||
|
@ -10,62 +10,6 @@
|
|||||||
import { t, type Static } from 'elysia';
|
import { t, type Static } from 'elysia';
|
||||||
import { createPaginationResponseSchema, createQuerySchema } from '@/utils/pagination';
|
import { createPaginationResponseSchema, createQuerySchema } from '@/utils/pagination';
|
||||||
|
|
||||||
/**
|
|
||||||
* 当前用户信息响应Schema
|
|
||||||
* @description 获取当前用户信息的响应数据结构
|
|
||||||
*/
|
|
||||||
export const CurrentUserSchema = t.Object({
|
|
||||||
/** 用户ID */
|
|
||||||
id: t.String({
|
|
||||||
description: '用户ID(bigint类型以字符串形式返回防止精度丢失)',
|
|
||||||
examples: ['1', '2', '3']
|
|
||||||
}),
|
|
||||||
/** 用户名 */
|
|
||||||
username: t.String({
|
|
||||||
description: '用户名',
|
|
||||||
examples: ['admin', 'testuser']
|
|
||||||
}),
|
|
||||||
/** 邮箱地址 */
|
|
||||||
email: t.String({
|
|
||||||
description: '邮箱地址',
|
|
||||||
examples: ['user@example.com']
|
|
||||||
}),
|
|
||||||
/** 昵称 */
|
|
||||||
nickname: t.Union([t.String(), t.Null()], {
|
|
||||||
description: '用户昵称',
|
|
||||||
examples: ['管理员', '测试用户', null]
|
|
||||||
}),
|
|
||||||
/** 头像URL */
|
|
||||||
avatar: t.Union([t.String(), t.Null()], {
|
|
||||||
description: '用户头像URL',
|
|
||||||
examples: ['https://example.com/avatar.jpg', null]
|
|
||||||
}),
|
|
||||||
/** 手机号 */
|
|
||||||
phone: t.Union([t.String(), t.Null()], {
|
|
||||||
description: '手机号码',
|
|
||||||
examples: ['13800138000', null]
|
|
||||||
}),
|
|
||||||
/** 账号状态 */
|
|
||||||
status: t.String({
|
|
||||||
description: '账号状态',
|
|
||||||
examples: ['active', 'inactive', 'pending']
|
|
||||||
}),
|
|
||||||
/** 最后登录时间 */
|
|
||||||
lastLoginAt: t.Union([t.String(), t.Null()], {
|
|
||||||
description: '最后登录时间',
|
|
||||||
examples: ['2024-12-19T10:30:00Z', null]
|
|
||||||
}),
|
|
||||||
/** 创建时间 */
|
|
||||||
createdAt: t.String({
|
|
||||||
description: '创建时间',
|
|
||||||
examples: ['2024-12-19T10:30:00Z']
|
|
||||||
}),
|
|
||||||
/** 更新时间 */
|
|
||||||
updatedAt: t.String({
|
|
||||||
description: '更新时间',
|
|
||||||
examples: ['2024-12-19T10:30:00Z']
|
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用户列表查询参数Schema
|
* 用户列表查询参数Schema
|
||||||
@ -104,112 +48,9 @@ export const UserListQuerySchema = createQuerySchema(t.Object({
|
|||||||
}))
|
}))
|
||||||
}));
|
}));
|
||||||
|
|
||||||
/**
|
|
||||||
* 用户列表项Schema
|
|
||||||
* @description 用户列表中单个用户的数据结构
|
|
||||||
*/
|
|
||||||
export const UserListItemSchema = t.Object({
|
|
||||||
/** 用户ID */
|
|
||||||
id: t.String({
|
|
||||||
description: '用户ID(bigint类型以字符串形式返回防止精度丢失)',
|
|
||||||
examples: ['1', '2', '3']
|
|
||||||
}),
|
|
||||||
/** 用户名 */
|
|
||||||
username: t.String({
|
|
||||||
description: '用户名',
|
|
||||||
examples: ['admin', 'testuser']
|
|
||||||
}),
|
|
||||||
/** 邮箱地址 */
|
|
||||||
email: t.String({
|
|
||||||
description: '邮箱地址',
|
|
||||||
examples: ['user@example.com']
|
|
||||||
}),
|
|
||||||
/** 手机号 */
|
|
||||||
mobile: t.Union([t.String(), t.Null()], {
|
|
||||||
description: '手机号码',
|
|
||||||
examples: ['13800138000', null]
|
|
||||||
}),
|
|
||||||
/** 昵称 */
|
|
||||||
nickname: t.Union([t.String(), t.Null()], {
|
|
||||||
description: '用户昵称',
|
|
||||||
examples: ['管理员', '测试用户', null]
|
|
||||||
}),
|
|
||||||
/** 头像URL */
|
|
||||||
avatar: t.Union([t.String(), t.Null()], {
|
|
||||||
description: '用户头像URL',
|
|
||||||
examples: ['https://example.com/avatar.jpg', null]
|
|
||||||
}),
|
|
||||||
/** 账号状态 */
|
|
||||||
status: t.String({
|
|
||||||
description: '账号状态',
|
|
||||||
examples: ['active', 'inactive', 'pending']
|
|
||||||
}),
|
|
||||||
/** 性别 */
|
|
||||||
gender: t.Union([t.Number(), t.Null()], {
|
|
||||||
description: '性别:0-未知,1-男,2-女',
|
|
||||||
examples: [0, 1, 2, null]
|
|
||||||
}),
|
|
||||||
/** 生日 */
|
|
||||||
birthday: t.Union([t.String(), t.Null()], {
|
|
||||||
description: '生日',
|
|
||||||
examples: ['1990-01-01', null]
|
|
||||||
}),
|
|
||||||
/** 个人简介 */
|
|
||||||
bio: t.Union([t.String(), t.Null()], {
|
|
||||||
description: '个人简介',
|
|
||||||
examples: ['这是一段个人简介', null]
|
|
||||||
}),
|
|
||||||
/** 登录次数 */
|
|
||||||
loginCount: t.Number({
|
|
||||||
description: '登录次数',
|
|
||||||
examples: [0, 10, 100]
|
|
||||||
}),
|
|
||||||
/** 最后登录时间 */
|
|
||||||
lastLoginAt: t.Union([t.String(), t.Null()], {
|
|
||||||
description: '最后登录时间',
|
|
||||||
examples: ['2024-12-19T10:30:00Z', null]
|
|
||||||
}),
|
|
||||||
/** 最后登录IP */
|
|
||||||
lastLoginIp: t.Union([t.String(), t.Null()], {
|
|
||||||
description: '最后登录IP',
|
|
||||||
examples: ['192.168.1.1', null]
|
|
||||||
}),
|
|
||||||
/** 失败尝试次数 */
|
|
||||||
failedAttempts: t.Number({
|
|
||||||
description: '失败尝试次数',
|
|
||||||
examples: [0, 1, 5]
|
|
||||||
}),
|
|
||||||
/** 是否超级管理员 */
|
|
||||||
isRoot: t.Boolean({
|
|
||||||
description: '是否超级管理员',
|
|
||||||
examples: [true, false]
|
|
||||||
}),
|
|
||||||
/** 创建时间 */
|
|
||||||
createdAt: t.String({
|
|
||||||
description: '创建时间',
|
|
||||||
examples: ['2024-12-19T10:30:00Z']
|
|
||||||
}),
|
|
||||||
/** 更新时间 */
|
|
||||||
updatedAt: t.String({
|
|
||||||
description: '更新时间',
|
|
||||||
examples: ['2024-12-19T10:30:00Z']
|
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用户列表响应Schema
|
|
||||||
* @description 用户列表查询的响应数据结构
|
|
||||||
*/
|
|
||||||
export const UserListResponseSchema = createPaginationResponseSchema(UserListItemSchema);
|
|
||||||
|
|
||||||
/** 当前用户信息响应类型 */
|
|
||||||
export type CurrentUserResponse = Static<typeof CurrentUserSchema>;
|
|
||||||
|
|
||||||
/** 用户列表查询参数类型 */
|
/** 用户列表查询参数类型 */
|
||||||
export type UserListQueryRequest = Static<typeof UserListQuerySchema>;
|
export type UserListQueryRequest = Static<typeof UserListQuerySchema>;
|
||||||
|
|
||||||
/** 用户列表项类型 */
|
|
||||||
export type UserListItem = Static<typeof UserListItemSchema>;
|
|
||||||
|
|
||||||
/** 用户列表响应类型 */
|
|
||||||
export type UserListResponse = Static<typeof UserListResponseSchema>;
|
|
@ -15,7 +15,8 @@ import { successResponse, errorResponse, BusinessError } from '@/utils/responseF
|
|||||||
|
|
||||||
import { calculatePagination, normalizePaginationParams } from '@/utils/pagination';
|
import { calculatePagination, normalizePaginationParams } from '@/utils/pagination';
|
||||||
import type { GetCurrentUserSuccessType, GetUserListSuccessType } from './user.response';
|
import type { GetCurrentUserSuccessType, GetUserListSuccessType } from './user.response';
|
||||||
import type { UserListQueryRequest, UserListItem } from './user.schema';
|
import type { UserListQueryRequest } from './user.schema';
|
||||||
|
import type { UserListItem } from './user.response';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用户服务类
|
* 用户服务类
|
||||||
|
Loading…
Reference in New Issue
Block a user