|
|
@@ -0,0 +1,380 @@
|
|
|
+import { createRoute, OpenAPIHono } from '@hono/zod-openapi';
|
|
|
+import { z } from '@hono/zod-openapi';
|
|
|
+import { authMiddleware } from '@/server/middleware/auth.middleware';
|
|
|
+import { PassengerService } from '@/server/modules/passengers/passenger.service';
|
|
|
+import {
|
|
|
+ PassengerCreateSchema,
|
|
|
+ PassengerUpdateSchema,
|
|
|
+ PassengerResponseSchema,
|
|
|
+ PassengerListResponseSchema,
|
|
|
+ PassengerListParams
|
|
|
+} from '@/server/modules/passengers/passenger.schema';
|
|
|
+import { ErrorSchema } from '@/server/utils/errorHandler';
|
|
|
+import { AuthContext } from '@/server/types/context';
|
|
|
+
|
|
|
+// 创建用户端乘客API路由
|
|
|
+
|
|
|
+// 获取用户乘客列表路由
|
|
|
+const listRoute = createRoute({
|
|
|
+ method: 'get',
|
|
|
+ path: '/',
|
|
|
+ middleware: [authMiddleware],
|
|
|
+ request: {
|
|
|
+ query: z.object({
|
|
|
+ page: z.coerce.number<number>().int().positive().default(1).openapi({
|
|
|
+ example: 1,
|
|
|
+ description: '页码,从1开始'
|
|
|
+ }),
|
|
|
+ pageSize: z.coerce.number<number>().int().positive().default(20).openapi({
|
|
|
+ example: 20,
|
|
|
+ description: '每页数量'
|
|
|
+ }),
|
|
|
+ keyword: z.string().optional().openapi({
|
|
|
+ example: '搜索关键词',
|
|
|
+ description: '搜索关键词'
|
|
|
+ })
|
|
|
+ })
|
|
|
+ },
|
|
|
+ responses: {
|
|
|
+ 200: {
|
|
|
+ description: '成功获取乘客列表',
|
|
|
+ content: {
|
|
|
+ 'application/json': {
|
|
|
+ schema: PassengerListResponseSchema
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ 401: {
|
|
|
+ description: '未授权',
|
|
|
+ content: { 'application/json': { schema: ErrorSchema } }
|
|
|
+ },
|
|
|
+ 500: {
|
|
|
+ description: '服务器错误',
|
|
|
+ content: { 'application/json': { schema: ErrorSchema } }
|
|
|
+ }
|
|
|
+ }
|
|
|
+});
|
|
|
+
|
|
|
+// 创建乘客路由
|
|
|
+const createRouteDef = createRoute({
|
|
|
+ method: 'post',
|
|
|
+ path: '/',
|
|
|
+ middleware: [authMiddleware],
|
|
|
+ request: {
|
|
|
+ body: {
|
|
|
+ content: {
|
|
|
+ 'application/json': { schema: PassengerCreateSchema }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ responses: {
|
|
|
+ 201: {
|
|
|
+ description: '创建乘客成功',
|
|
|
+ content: { 'application/json': { schema: PassengerResponseSchema } }
|
|
|
+ },
|
|
|
+ 400: {
|
|
|
+ description: '输入数据无效',
|
|
|
+ content: { 'application/json': { schema: ErrorSchema } }
|
|
|
+ },
|
|
|
+ 401: {
|
|
|
+ description: '未授权',
|
|
|
+ content: { 'application/json': { schema: ErrorSchema } }
|
|
|
+ },
|
|
|
+ 500: {
|
|
|
+ description: '服务器错误',
|
|
|
+ content: { 'application/json': { schema: ErrorSchema } }
|
|
|
+ }
|
|
|
+ }
|
|
|
+});
|
|
|
+
|
|
|
+// 获取乘客详情路由
|
|
|
+const getRouteDef = createRoute({
|
|
|
+ method: 'get',
|
|
|
+ path: '/{id}',
|
|
|
+ middleware: [authMiddleware],
|
|
|
+ request: {
|
|
|
+ params: z.object({
|
|
|
+ id: z.coerce.number<number>().openapi({
|
|
|
+ param: { name: 'id', in: 'path' },
|
|
|
+ example: 1,
|
|
|
+ description: '乘客ID'
|
|
|
+ })
|
|
|
+ })
|
|
|
+ },
|
|
|
+ responses: {
|
|
|
+ 200: {
|
|
|
+ description: '成功获取乘客详情',
|
|
|
+ content: { 'application/json': { schema: PassengerResponseSchema } }
|
|
|
+ },
|
|
|
+ 401: {
|
|
|
+ description: '未授权',
|
|
|
+ content: { 'application/json': { schema: ErrorSchema } }
|
|
|
+ },
|
|
|
+ 404: {
|
|
|
+ description: '乘客不存在',
|
|
|
+ content: { 'application/json': { schema: ErrorSchema } }
|
|
|
+ },
|
|
|
+ 500: {
|
|
|
+ description: '服务器错误',
|
|
|
+ content: { 'application/json': { schema: ErrorSchema } }
|
|
|
+ }
|
|
|
+ }
|
|
|
+});
|
|
|
+
|
|
|
+// 更新乘客路由
|
|
|
+const updateRouteDef = createRoute({
|
|
|
+ method: 'put',
|
|
|
+ path: '/{id}',
|
|
|
+ middleware: [authMiddleware],
|
|
|
+ request: {
|
|
|
+ params: z.object({
|
|
|
+ id: z.coerce.number<number>().openapi({
|
|
|
+ param: { name: 'id', in: 'path' },
|
|
|
+ example: 1,
|
|
|
+ description: '乘客ID'
|
|
|
+ })
|
|
|
+ }),
|
|
|
+ body: {
|
|
|
+ content: {
|
|
|
+ 'application/json': { schema: PassengerUpdateSchema }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ responses: {
|
|
|
+ 200: {
|
|
|
+ description: '更新乘客成功',
|
|
|
+ content: { 'application/json': { schema: PassengerResponseSchema } }
|
|
|
+ },
|
|
|
+ 400: {
|
|
|
+ description: '无效输入',
|
|
|
+ content: { 'application/json': { schema: ErrorSchema } }
|
|
|
+ },
|
|
|
+ 401: {
|
|
|
+ description: '未授权',
|
|
|
+ content: { 'application/json': { schema: ErrorSchema } }
|
|
|
+ },
|
|
|
+ 404: {
|
|
|
+ description: '乘客不存在',
|
|
|
+ content: { 'application/json': { schema: ErrorSchema } }
|
|
|
+ },
|
|
|
+ 500: {
|
|
|
+ description: '服务器错误',
|
|
|
+ content: { 'application/json': { schema: ErrorSchema } }
|
|
|
+ }
|
|
|
+ }
|
|
|
+});
|
|
|
+
|
|
|
+// 删除乘客路由
|
|
|
+const deleteRouteDef = createRoute({
|
|
|
+ method: 'delete',
|
|
|
+ path: '/{id}',
|
|
|
+ middleware: [authMiddleware],
|
|
|
+ request: {
|
|
|
+ params: z.object({
|
|
|
+ id: z.coerce.number<number>().openapi({
|
|
|
+ param: { name: 'id', in: 'path' },
|
|
|
+ example: 1,
|
|
|
+ description: '乘客ID'
|
|
|
+ })
|
|
|
+ })
|
|
|
+ },
|
|
|
+ responses: {
|
|
|
+ 204: { description: '删除乘客成功' },
|
|
|
+ 401: {
|
|
|
+ description: '未授权',
|
|
|
+ content: { 'application/json': { schema: ErrorSchema } }
|
|
|
+ },
|
|
|
+ 404: {
|
|
|
+ description: '乘客不存在',
|
|
|
+ content: { 'application/json': { schema: ErrorSchema } }
|
|
|
+ },
|
|
|
+ 500: {
|
|
|
+ description: '服务器错误',
|
|
|
+ content: { 'application/json': { schema: ErrorSchema } }
|
|
|
+ }
|
|
|
+ }
|
|
|
+});
|
|
|
+
|
|
|
+// 设置默认乘客路由
|
|
|
+const setDefaultRoute = createRoute({
|
|
|
+ method: 'post',
|
|
|
+ path: '/{id}/set-default',
|
|
|
+ middleware: [authMiddleware],
|
|
|
+ request: {
|
|
|
+ params: z.object({
|
|
|
+ id: z.coerce.number<number>().openapi({
|
|
|
+ param: { name: 'id', in: 'path' },
|
|
|
+ example: 1,
|
|
|
+ description: '乘客ID'
|
|
|
+ })
|
|
|
+ })
|
|
|
+ },
|
|
|
+ responses: {
|
|
|
+ 200: {
|
|
|
+ description: '设置默认乘客成功',
|
|
|
+ content: { 'application/json': { schema: PassengerResponseSchema } }
|
|
|
+ },
|
|
|
+ 401: {
|
|
|
+ description: '未授权',
|
|
|
+ content: { 'application/json': { schema: ErrorSchema } }
|
|
|
+ },
|
|
|
+ 404: {
|
|
|
+ description: '乘客不存在',
|
|
|
+ content: { 'application/json': { schema: ErrorSchema } }
|
|
|
+ },
|
|
|
+ 500: {
|
|
|
+ description: '服务器错误',
|
|
|
+ content: { 'application/json': { schema: ErrorSchema } }
|
|
|
+ }
|
|
|
+ }
|
|
|
+});
|
|
|
+
|
|
|
+// 注册路由处理函数
|
|
|
+const passengerService = new PassengerService();
|
|
|
+
|
|
|
+const app = new OpenAPIHono<AuthContext>()
|
|
|
+ .openapi(listRoute, async (c) => {
|
|
|
+ try {
|
|
|
+ const user = c.get('user');
|
|
|
+ const query = c.req.valid('query');
|
|
|
+
|
|
|
+ // 用户只能查看自己的乘客
|
|
|
+ const params: PassengerListParams = {
|
|
|
+ ...query,
|
|
|
+ userId: user.id
|
|
|
+ };
|
|
|
+
|
|
|
+ const result = await passengerService.getPassengers(params);
|
|
|
+ return c.json(result, 200);
|
|
|
+ } catch (error) {
|
|
|
+ console.error('获取乘客列表失败:', error);
|
|
|
+ return c.json({
|
|
|
+ code: 500,
|
|
|
+ message: error instanceof Error ? error.message : '获取乘客列表失败'
|
|
|
+ }, 500);
|
|
|
+ }
|
|
|
+ })
|
|
|
+ .openapi(createRouteDef, async (c) => {
|
|
|
+ try {
|
|
|
+ const user = c.get('user');
|
|
|
+ const data = c.req.valid('json');
|
|
|
+
|
|
|
+ // 用户只能为自己创建乘客
|
|
|
+ const passengerData = {
|
|
|
+ ...data,
|
|
|
+ userId: user.id
|
|
|
+ };
|
|
|
+
|
|
|
+ const result = await passengerService.createPassenger(passengerData);
|
|
|
+ return c.json(result, 201);
|
|
|
+ } catch (error) {
|
|
|
+ console.error('创建乘客失败:', error);
|
|
|
+ return c.json({
|
|
|
+ code: 500,
|
|
|
+ message: error instanceof Error ? error.message : '创建乘客失败'
|
|
|
+ }, 500);
|
|
|
+ }
|
|
|
+ })
|
|
|
+ .openapi(getRouteDef, async (c) => {
|
|
|
+ try {
|
|
|
+ const user = c.get('user');
|
|
|
+ const { id } = c.req.valid('param');
|
|
|
+
|
|
|
+ const passenger = await passengerService.getPassengerById(id);
|
|
|
+
|
|
|
+ if (!passenger) {
|
|
|
+ return c.json({ code: 404, message: '乘客不存在' }, 404);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 用户只能查看自己的乘客
|
|
|
+ if (passenger.userId !== user.id) {
|
|
|
+ return c.json({ code: 403, message: '无权访问该乘客信息' }, 403);
|
|
|
+ }
|
|
|
+
|
|
|
+ return c.json(passenger, 200);
|
|
|
+ } catch (error) {
|
|
|
+ console.error('获取乘客详情失败:', error);
|
|
|
+ return c.json({
|
|
|
+ code: 500,
|
|
|
+ message: error instanceof Error ? error.message : '获取乘客详情失败'
|
|
|
+ }, 500);
|
|
|
+ }
|
|
|
+ })
|
|
|
+ .openapi(updateRouteDef, async (c) => {
|
|
|
+ try {
|
|
|
+ const user = c.get('user');
|
|
|
+ const { id } = c.req.valid('param');
|
|
|
+ const data = c.req.valid('json');
|
|
|
+
|
|
|
+ // 先检查乘客是否存在且属于当前用户
|
|
|
+ const existingPassenger = await passengerService.getPassengerById(id);
|
|
|
+ if (!existingPassenger) {
|
|
|
+ return c.json({ code: 404, message: '乘客不存在' }, 404);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (existingPassenger.userId !== user.id) {
|
|
|
+ return c.json({ code: 403, message: '无权修改该乘客信息' }, 403);
|
|
|
+ }
|
|
|
+
|
|
|
+ const result = await passengerService.updatePassenger(id, data);
|
|
|
+ return c.json(result, 200);
|
|
|
+ } catch (error) {
|
|
|
+ console.error('更新乘客失败:', error);
|
|
|
+ return c.json({
|
|
|
+ code: 500,
|
|
|
+ message: error instanceof Error ? error.message : '更新乘客失败'
|
|
|
+ }, 500);
|
|
|
+ }
|
|
|
+ })
|
|
|
+ .openapi(deleteRouteDef, async (c) => {
|
|
|
+ try {
|
|
|
+ const user = c.get('user');
|
|
|
+ const { id } = c.req.valid('param');
|
|
|
+
|
|
|
+ // 先检查乘客是否存在且属于当前用户
|
|
|
+ const existingPassenger = await passengerService.getPassengerById(id);
|
|
|
+ if (!existingPassenger) {
|
|
|
+ return c.json({ code: 404, message: '乘客不存在' }, 404);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (existingPassenger.userId !== user.id) {
|
|
|
+ return c.json({ code: 403, message: '无权删除该乘客信息' }, 403);
|
|
|
+ }
|
|
|
+
|
|
|
+ await passengerService.deletePassenger(id);
|
|
|
+ return c.body(null, 204);
|
|
|
+ } catch (error) {
|
|
|
+ console.error('删除乘客失败:', error);
|
|
|
+ return c.json({
|
|
|
+ code: 500,
|
|
|
+ message: error instanceof Error ? error.message : '删除乘客失败'
|
|
|
+ }, 500);
|
|
|
+ }
|
|
|
+ })
|
|
|
+ .openapi(setDefaultRoute, async (c) => {
|
|
|
+ try {
|
|
|
+ const user = c.get('user');
|
|
|
+ const { id } = c.req.valid('param');
|
|
|
+
|
|
|
+ // 先检查乘客是否存在且属于当前用户
|
|
|
+ const existingPassenger = await passengerService.getPassengerById(id);
|
|
|
+ if (!existingPassenger) {
|
|
|
+ return c.json({ code: 404, message: '乘客不存在' }, 404);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (existingPassenger.userId !== user.id) {
|
|
|
+ return c.json({ code: 403, message: '无权设置该乘客为默认' }, 403);
|
|
|
+ }
|
|
|
+
|
|
|
+ const result = await passengerService.setDefaultPassenger(user.id, id);
|
|
|
+ return c.json(result, 200);
|
|
|
+ } catch (error) {
|
|
|
+ console.error('设置默认乘客失败:', error);
|
|
|
+ return c.json({
|
|
|
+ code: 500,
|
|
|
+ message: error instanceof Error ? error.message : '设置默认乘客失败'
|
|
|
+ }, 500);
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+export default app;
|