fix: 修改代码格局分布

This commit is contained in:
HeXiaoLong:Suanier 2025-07-07 14:29:09 +08:00
parent 7c0bc201a5
commit 863b376020
7 changed files with 276 additions and 273 deletions

View File

@ -1,36 +1,36 @@
/** /**
* @file API文档标签定义 * @file API文档标签定义
* @author hotok * @author hotok
* @date 2025-06-29 * @date 2025-06-29
* @lastEditor hotok * @lastEditor hotok
* @lastEditTime 2025-06-29 * @lastEditTime 2025-06-29
* @description Swagger文档中的标签便 * @description Swagger文档中的标签便
*/ */
/** /**
* API文档标签枚举 * API文档标签枚举
* @description Swagger文档的接口分类 * @description Swagger文档的接口分类
*/ */
export const tags = { export const tags = {
/** 用户相关接口 */ /** 用户相关接口 */
user: 'User', user: 'User',
/** 认证相关接口 */ /** 认证相关接口 */
auth: 'Auth', auth: 'Auth',
/** 健康检查接口 */ /** 健康检查接口 */
health: 'Health', health: 'Health',
/** 测试接口 */ /** 测试接口 */
test: 'Test', test: 'Test',
/** 文件上传接口 */ /** 文件上传接口 */
upload: 'Upload', upload: 'Upload',
/** 系统管理接口 */ /** 系统管理接口 */
system: 'System', system: 'System',
/** 权限管理接口 */ /** 权限管理接口 */
permission: 'Permission', permission: 'Permission',
/** 验证码相关接口 */ /** 验证码相关接口 */
captcha: 'Captcha', captcha: 'Captcha',
} as const; } as const;
/** /**
* *
*/ */
export type ApiTag = typeof tags[keyof typeof tags]; export type ApiTag = typeof tags[keyof typeof tags];

View File

@ -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';
/** /**
* *

View File

@ -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()
/** /**

View File

@ -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', detail: {
({ user }: { user: JwtUserType }) => userService.getCurrentUser(user.userId), summary: '获取当前用户信息',
{ description: '获取当前登录用户的详细信息,包括基本信息、状态、时间等',
detail: { tags: [tags.user],
summary: '获取当前用户信息', operationId: 'getCurrentUser',
description: '获取当前登录用户的详细信息,包括基本信息、状态、时间等', security: [{ bearerAuth: [] }],
tags: [tags.user], },
operationId: 'getCurrentUser', response: GetCurrentUserResponsesSchema,
security: [{ bearerAuth: [] }] })
},
response: GetCurrentUserResponsesSchema,
}
)
/** /**
* *
* @route GET /api/users * @route GET /api/users
* @description JWT认证 * @description JWT认证
*/ */
.get( .get('/list', ({ query }) => userService.getUserList(query), {
'/list', query: UserListQuerySchema,
({ query }) => userService.getUserList(query), detail: {
{ summary: '获取用户列表',
query: UserListQuerySchema, description: '获取用户列表,支持分页查询、关键词搜索、状态筛选、排序等功能',
detail: { tags: [tags.user],
summary: '获取用户列表', operationId: 'getUserList',
description: '获取用户列表,支持分页查询、关键词搜索、状态筛选、排序等功能', security: [{ bearerAuth: [] }],
tags: [tags.user], },
operationId: 'getUserList', response: GetUserListResponsesSchema,
security: [{ bearerAuth: [] }] });
},
response: GetUserListResponsesSchema,
}
);

View File

@ -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: '用户IDbigint类型以字符串形式返回防止精度丢失',
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(
error: t.String({ t.Object({
description: '认证失败', error: t.String({
examples: ['未提供有效的认证令牌', '令牌已过期'] description: '认证失败',
}) examples: ['未提供有效的认证令牌', '令牌已过期'],
})), }),
404: responseWrapperSchema(t.Object({ }),
error: t.String({ ),
description: '用户不存在', 404: responseWrapperSchema(
examples: ['用户不存在或已被删除'] t.Object({
}) error: t.String({
})), description: '用户不存在',
500: responseWrapperSchema(t.Object({ examples: ['用户不存在或已被删除'],
error: t.String({ }),
description: '服务器错误', }),
examples: ['内部服务器错误'] ),
}) 500: responseWrapperSchema(
})) t.Object({
error: t.String({
description: '服务器错误',
examples: ['内部服务器错误'],
}),
}),
),
}; };
/**
* Schema
* @description
*/
export const UserListItemSchema = t.Object({
/** 用户ID */
id: t.String({
description: '用户IDbigint类型以字符串形式返回防止精度丢失',
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(
error: t.String({ t.Object({
description: '认证失败', error: t.String({
examples: ['未提供有效的认证令牌', '令牌已过期'] description: '认证失败',
}) examples: ['未提供有效的认证令牌', '令牌已过期'],
})), }),
403: responseWrapperSchema(t.Object({ }),
error: t.String({ ),
description: '权限不足', 403: responseWrapperSchema(
examples: ['权限不足,无法访问用户列表'] t.Object({
}) error: t.String({
})), description: '权限不足',
400: responseWrapperSchema(t.Object({ examples: ['权限不足,无法访问用户列表'],
error: t.String({ }),
description: '参数错误', }),
examples: ['分页参数无效', '搜索关键词格式错误'] ),
}) 400: responseWrapperSchema(
})), t.Object({
500: responseWrapperSchema(t.Object({ error: t.String({
error: t.String({ description: '参数错误',
description: '服务器错误', examples: ['分页参数无效', '搜索关键词格式错误'],
examples: ['内部服务器错误'] }),
}) }),
})) ),
500: responseWrapperSchema(
t.Object({
error: t.String({
description: '服务器错误',
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]>;

View File

@ -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: '用户IDbigint类型以字符串形式返回防止精度丢失',
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: '用户IDbigint类型以字符串形式返回防止精度丢失',
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>;

View File

@ -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';
/** /**
* *