فهرست منبع

📝 docs(stories): 更新地点管理相关任务状态

- 添加"更新地点表单,支持省市区三级联动选择组件"任务
- 将"更新活动和路线表单,支持地点选择组件"任务从已完成改为未完成

✨ feat(activities): 添加活动地点关联查询功能

- 在活动CRUD路由中添加'venueLocation'关联关系
- 定义locationInfoSchema以支持地点信息的完整展示
- 在活动详情和列表Schema中添加venueLocation字段支持
yourname 4 ماه پیش
والد
کامیت
3af737a430
3فایلهای تغییر یافته به همراه30 افزوده شده و 2 حذف شده
  1. 2 1
      docs/stories/005.001.story.md
  2. 1 1
      src/server/api/admin/activities/index.ts
  3. 27 0
      src/server/modules/activities/activity.schema.ts

+ 2 - 1
docs/stories/005.001.story.md

@@ -89,12 +89,13 @@ Approve
   - [ ] 实现省市区创建和编辑表单
   - [ ] 支持省市区层级展示和树形结构
   - [ ] 实现省市区三级联动选择组件
+  - [ ] 更新地点表单,支持省市区三级联动选择组件
 
 - [x] 实现地点管理页面 (AC: 5)
   - [x] 创建地点管理页面 - 地点信息配置和管理
   - [x] 实现地点管理页面的搜索和筛选功能
   - [x] 实现地点创建和编辑表单
-  - [x] 更新活动和路线表单,支持地点选择组件
+  - [ ] 更新活动和路线表单,支持地点选择组件
   - [x] 支持按省市区筛选地点列表
 
 - [ ] 编写地点管理测试 (AC: 5, 6, 7, 8)

+ 1 - 1
src/server/api/admin/activities/index.ts

@@ -11,7 +11,7 @@ export const activitiesRoutes = createCrudRoutes({
   getSchema: getActivitySchema,
   listSchema: activityListResponseSchema,
   searchFields: ['name', 'description'],
-  relations: ['routes'],
+  relations: ['routes', 'venueLocation'],
   middleware: [authMiddleware],
   userTracking: {
     createdByField: 'createdBy',

+ 27 - 0
src/server/modules/activities/activity.schema.ts

@@ -2,6 +2,31 @@ import { z } from 'zod';
 import { DisabledStatus } from '@/share/types';
 import { ActivityType } from './activity.entity';
 
+// 地点信息Schema
+const locationInfoSchema = z.object({
+  id: z.number().int().positive('地点ID必须为正整数'),
+  name: z.string().min(1, '地点名称不能为空'),
+  address: z.string().optional().nullable(),
+  province: z.object({
+    id: z.number().int().positive('省份ID必须为正整数'),
+    name: z.string().min(1, '省份名称不能为空'),
+    level: z.number().int().min(1).max(3),
+    code: z.string().optional().nullable(),
+  }).optional().nullable(),
+  city: z.object({
+    id: z.number().int().positive('城市ID必须为正整数'),
+    name: z.string().min(1, '城市名称不能为空'),
+    level: z.number().int().min(1).max(3),
+    code: z.string().optional().nullable(),
+  }).optional().nullable(),
+  district: z.object({
+    id: z.number().int().positive('区县ID必须为正整数'),
+    name: z.string().min(1, '区县名称不能为空'),
+    level: z.number().int().min(1).max(3),
+    code: z.string().optional().nullable(),
+  }).optional().nullable(),
+});
+
 // 活动创建Schema
 export const createActivitySchema = z.object({
   name: z.string().min(1, '活动名称不能为空').max(255, '活动名称不能超过255个字符'),
@@ -49,6 +74,7 @@ export const getActivitySchema = z.object({
   startDate: z.coerce.date(),
   endDate: z.coerce.date(),
   venueLocationId: z.number().int().positive('举办地点ID必须为正整数'),
+  venueLocation: locationInfoSchema.optional().nullable(),
   isDisabled: z.nativeEnum(DisabledStatus),
   createdAt: z.coerce.date(),
   updatedAt: z.coerce.date(),
@@ -78,6 +104,7 @@ export const activityListResponseSchema = z.object({
   startDate: z.coerce.date(),
   endDate: z.coerce.date(),
   venueLocationId: z.number().int().positive('举办地点ID必须为正整数'),
+  venueLocation: locationInfoSchema.optional().nullable(),
   isDisabled: z.nativeEnum(DisabledStatus),
   createdAt: z.coerce.date(),
   updatedAt: z.coerce.date(),