|
|
@@ -0,0 +1,113 @@
|
|
|
+import { createRoute, OpenAPIHono } from '@hono/zod-openapi';
|
|
|
+import { z } from '@hono/zod-openapi';
|
|
|
+import { GoodsSchema } from '@/server/modules/goods/goods.schema';
|
|
|
+import { ErrorSchema } from '@/server/utils/errorHandler';
|
|
|
+import { AppDataSource } from '@/server/data-source';
|
|
|
+import { Goods } from '@/server/modules/goods/goods.entity';
|
|
|
+import { AuthContext } from '@/server/types/context';
|
|
|
+import { authMiddleware } from '@/server/middleware/auth.middleware';
|
|
|
+import { RandomGoodsQuerySchema, RandomGoodsResponseSchema } from '@/server/modules/goods/schemas/random.schema';
|
|
|
+import { parseWithAwait } from '@/server/utils/parseWithAwait';
|
|
|
+
|
|
|
+// 定义随机商品列表路由
|
|
|
+const routeDef = createRoute({
|
|
|
+ method: 'get',
|
|
|
+ path: '/',
|
|
|
+ middleware: [authMiddleware],
|
|
|
+ request: {
|
|
|
+ query: RandomGoodsQuerySchema
|
|
|
+ },
|
|
|
+ responses: {
|
|
|
+ 200: {
|
|
|
+ description: '成功获取随机商品列表',
|
|
|
+ content: {
|
|
|
+ 'application/json': {
|
|
|
+ schema: RandomGoodsResponseSchema
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ 400: {
|
|
|
+ description: '请求参数错误',
|
|
|
+ content: {
|
|
|
+ 'application/json': {
|
|
|
+ schema: ErrorSchema
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ 500: {
|
|
|
+ description: '服务器错误',
|
|
|
+ content: {
|
|
|
+ 'application/json': {
|
|
|
+ schema: ErrorSchema
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+});
|
|
|
+
|
|
|
+// 路由实现
|
|
|
+const app = new OpenAPIHono<AuthContext>().openapi(routeDef, async (c) => {
|
|
|
+ try {
|
|
|
+ const query = c.req.valid('query');
|
|
|
+ const { limit, categoryId, includeImages } = query;
|
|
|
+
|
|
|
+ // 创建查询构建器
|
|
|
+ const queryBuilder = AppDataSource.getRepository(Goods)
|
|
|
+ .createQueryBuilder('goods')
|
|
|
+ .where('goods.state = :state', { state: 1 }) // 只获取可用的商品
|
|
|
+ .orderBy('RAND()') // 使用随机排序
|
|
|
+ .limit(limit);
|
|
|
+
|
|
|
+ // 如果指定了分类ID,添加分类过滤
|
|
|
+ if (categoryId) {
|
|
|
+ queryBuilder.andWhere(
|
|
|
+ 'goods.category_id1 = :categoryId OR goods.category_id2 = :categoryId OR goods.category_id3 = :categoryId',
|
|
|
+ { categoryId }
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ // 如果需要包含关联数据
|
|
|
+ if (includeImages) {
|
|
|
+ queryBuilder
|
|
|
+ .leftJoinAndSelect('goods.imageFile', 'imageFile')
|
|
|
+ .leftJoinAndSelect('imageFile.uploadUser', 'imageUploadUser')
|
|
|
+ .leftJoinAndSelect('goods.category1', 'category1')
|
|
|
+ .leftJoinAndSelect('goods.category2', 'category2')
|
|
|
+ .leftJoinAndSelect('goods.category3', 'category3')
|
|
|
+ .leftJoinAndSelect('goods.supplier', 'supplier');
|
|
|
+ }
|
|
|
+
|
|
|
+ // 获取随机商品
|
|
|
+ const goods = await queryBuilder.getMany();
|
|
|
+
|
|
|
+ // 获取总数(用于分页参考)
|
|
|
+ const totalQuery = AppDataSource.getRepository(Goods)
|
|
|
+ .createQueryBuilder('goods')
|
|
|
+ .where('goods.state = :state', { state: 1 });
|
|
|
+
|
|
|
+ if (categoryId) {
|
|
|
+ totalQuery.andWhere(
|
|
|
+ 'goods.category_id1 = :categoryId OR goods.category_id2 = :categoryId OR goods.category_id3 = :categoryId',
|
|
|
+ { categoryId }
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ const total = await totalQuery.getCount();
|
|
|
+
|
|
|
+ // 使用 parseWithAwait 确保数据格式正确
|
|
|
+ const validatedGoods = await parseWithAwait(z.array(GoodsSchema), goods);
|
|
|
+
|
|
|
+ return c.json({
|
|
|
+ data: validatedGoods,
|
|
|
+ total
|
|
|
+ }, 200);
|
|
|
+ } catch (error) {
|
|
|
+ console.error('获取随机商品列表失败:', error);
|
|
|
+ return c.json({
|
|
|
+ code: 500,
|
|
|
+ message: error instanceof Error ? error.message : '获取随机商品列表失败'
|
|
|
+ }, 500);
|
|
|
+ }
|
|
|
+});
|
|
|
+
|
|
|
+export default app;
|