|
|
@@ -0,0 +1,193 @@
|
|
|
+import { createRoute, OpenAPIHono } from '@hono/zod-openapi';
|
|
|
+import { UserService } from '../modules/users/user.service';
|
|
|
+import { z } from 'zod';
|
|
|
+
|
|
|
+const app = new OpenAPIHono()
|
|
|
+const userService = new UserService();
|
|
|
+
|
|
|
+const UserSchema = z.object({
|
|
|
+ id: z.number().openapi({ example: 1 }),
|
|
|
+ username: z.string().openapi({ example: 'john_doe' }),
|
|
|
+ email: z.string().email().openapi({ example: 'john@example.com' }),
|
|
|
+ createdAt: z.string().datetime().openapi({ example: '2025-05-28T00:00:00Z' })
|
|
|
+});
|
|
|
+
|
|
|
+const CreateUserSchema = z.object({
|
|
|
+ username: z.string().min(3).openapi({
|
|
|
+ example: 'john_doe',
|
|
|
+ description: 'Minimum 3 characters'
|
|
|
+ }),
|
|
|
+ password: z.string().min(6).openapi({
|
|
|
+ example: 'password123',
|
|
|
+ description: 'Minimum 6 characters'
|
|
|
+ }),
|
|
|
+ email: z.string().email().openapi({ example: 'john@example.com' })
|
|
|
+});
|
|
|
+
|
|
|
+const UpdateUserSchema = CreateUserSchema.partial();
|
|
|
+
|
|
|
+// 创建用户
|
|
|
+const createUserRoute = createRoute({
|
|
|
+ method: 'post',
|
|
|
+ path: '/users',
|
|
|
+ request: {
|
|
|
+ query: CreateUserSchema
|
|
|
+ },
|
|
|
+ responses: {
|
|
|
+ 201: {
|
|
|
+ description: 'Created',
|
|
|
+ content: {
|
|
|
+ 'application/json': {
|
|
|
+ schema: UserSchema
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ 400: { description: 'Invalid input' }
|
|
|
+ }
|
|
|
+});
|
|
|
+
|
|
|
+export const createUserHandler = app.openapi(createUserRoute, async (c) => {
|
|
|
+ const data = c.req.valid('query');
|
|
|
+ const user = await userService.createUser(data);
|
|
|
+ return c.json(user, 201);
|
|
|
+});
|
|
|
+
|
|
|
+// 获取用户列表
|
|
|
+export const listUsersRoute = createRoute({
|
|
|
+ method: 'get',
|
|
|
+ path: '/users',
|
|
|
+ responses: {
|
|
|
+ 200: {
|
|
|
+ description: 'Success',
|
|
|
+ content: {
|
|
|
+ 'application/json': {
|
|
|
+ schema: z.array(UserSchema)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+});
|
|
|
+
|
|
|
+export const listUsersHandler = app.openapi(
|
|
|
+ listUsersRoute,
|
|
|
+ async (c) => {
|
|
|
+ const users = await userService.getUsers();
|
|
|
+ const usersOut = users.map(user => {
|
|
|
+ return {
|
|
|
+ ...user,
|
|
|
+ createdAt: user.createdAt.toISOString(),
|
|
|
+ updatedAt: user.updatedAt?.toISOString()
|
|
|
+ };
|
|
|
+ })
|
|
|
+
|
|
|
+ return c.json(usersOut);
|
|
|
+ }
|
|
|
+);
|
|
|
+
|
|
|
+// 获取单个用户
|
|
|
+export const getUserRoute = createRoute({
|
|
|
+ method: 'get',
|
|
|
+ path: '/users/{id}',
|
|
|
+ request: {
|
|
|
+ params: z.object({
|
|
|
+ id: z.string().openapi({ example: '1' })
|
|
|
+ })
|
|
|
+ },
|
|
|
+ responses: {
|
|
|
+ 200: {
|
|
|
+ description: 'Success',
|
|
|
+ content: {
|
|
|
+ 'application/json': {
|
|
|
+ schema: UserSchema
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ 404: { description: 'User not found' }
|
|
|
+ }
|
|
|
+});
|
|
|
+
|
|
|
+export const getUserHandler = app.openapi(
|
|
|
+ getUserRoute,
|
|
|
+ async (c) => {
|
|
|
+ const { id } = c.req.valid('param');
|
|
|
+ const user = await userService.getUserById(parseInt(id));
|
|
|
+ if (!user) return c.notFound();
|
|
|
+ return c.json(user);
|
|
|
+ }
|
|
|
+);
|
|
|
+
|
|
|
+// 更新用户
|
|
|
+export const updateUserRoute = createRoute({
|
|
|
+ method: 'patch',
|
|
|
+ path: '/users/{id}',
|
|
|
+ request: {
|
|
|
+ params: z.object({
|
|
|
+ id: z.string().openapi({ example: '1' })
|
|
|
+ }),
|
|
|
+ body: {
|
|
|
+ content: {
|
|
|
+ 'application/json': {
|
|
|
+ schema: UpdateUserSchema
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ responses: {
|
|
|
+ 200: {
|
|
|
+ description: 'Success',
|
|
|
+ content: {
|
|
|
+ 'application/json': {
|
|
|
+ schema: UserSchema
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ 404: { description: 'User not found' }
|
|
|
+ }
|
|
|
+});
|
|
|
+
|
|
|
+export const updateUserHandler = app.openapi(
|
|
|
+ updateUserRoute,
|
|
|
+ async (c) => {
|
|
|
+ const { id } = c.req.valid('param');
|
|
|
+ const data = c.req.valid('json');
|
|
|
+ const user = await userService.updateUser(parseInt(id), data);
|
|
|
+ if (!user) return c.notFound();
|
|
|
+ return c.json(user);
|
|
|
+ }
|
|
|
+);
|
|
|
+
|
|
|
+// 删除用户
|
|
|
+export const deleteUserRoute = createRoute({
|
|
|
+ method: 'delete',
|
|
|
+ path: '/users/{id}',
|
|
|
+ request: {
|
|
|
+ params: z.object({
|
|
|
+ id: z.string().openapi({ example: '1' })
|
|
|
+ })
|
|
|
+ },
|
|
|
+ responses: {
|
|
|
+ 204: { description: 'No Content' },
|
|
|
+ 404: { description: 'User not found' }
|
|
|
+ }
|
|
|
+});
|
|
|
+
|
|
|
+export const deleteUserHandler = app.openapi(
|
|
|
+ deleteUserRoute,
|
|
|
+ async (c) => {
|
|
|
+ const { id } = c.req.valid('param');
|
|
|
+ await userService.deleteUser(parseInt(id));
|
|
|
+ return c.body(null, 204);
|
|
|
+ }
|
|
|
+);
|
|
|
+
|
|
|
+export const userRoutes = {
|
|
|
+ createUser: createUserHandler,
|
|
|
+ listUsers: listUsersHandler,
|
|
|
+ getUser: getUserHandler,
|
|
|
+ updateUser: updateUserHandler,
|
|
|
+ deleteUser: deleteUserHandler
|
|
|
+};
|
|
|
+
|
|
|
+export type UserRoutes = typeof userRoutes;
|
|
|
+
|
|
|
+export const userOpenApiApp = app;
|