# Story 009.002: 邮箱输入优化 ## Status In Progress ## Story **As a** 平台管理员 **I want** 邮箱字段改为非必要输入项 **so that** 在不需要邮箱的场景下快速完成平台相关操作 ## Acceptance Criteria 1. 所有平台管理相关页面的邮箱字段改为非必填 2. 表单验证规则更新 3. 后端API支持邮箱为空 ## Tasks / Subtasks - [x] 修复平台管理前端表单默认值问题 (AC: 1, 2) - [x] 修改allin-packages/platform-management-ui/src/components/PlatformManagement.tsx中的表单配置 - [x] 将contactEmail字段的默认值从`''`改为`undefined` - [x] 验证contactEmail字段的FormLabel没有红色星号标记(非必填) - [ ] 测试表单提交时邮箱字段可为空(不填写) - [ ] 测试表单提交时邮箱字段可为有效邮箱格式 - [ ] 测试表单提交时邮箱字段为无效格式应显示验证错误 - [x] 修改平台模块后端schema验证 (AC: 2, 3) - [x] 修改allin-packages/platform-module/src/schemas/platform.schema.ts中的CreatePlatformSchema - [x] 将contactEmail字段改为包含中文错误提示和空字符串处理: ```typescript contactEmail: z.string({ error: '请输入联系邮箱' }).email({ message: '请输入有效的邮箱地址' }).max(100, { message: '邮箱地址不能超过100个字符' }).optional() .or(z.literal('')) // 允许空字符串 .transform(val => val === '' ? undefined : val) // 将空字符串转为undefined .openapi({ description: '联系邮箱', example: 'zhangsan@example.com' }) ``` - [x] 同样修改UpdatePlatformSchema中的contactEmail字段验证规则 - [x] 可选:为其他字段添加中文错误提示(如platformName必填验证) - [x] 验证数据库兼容性 (AC: 3) - [x] 检查allin-packages/platform-module/src/entities/platform.entity.ts中contactEmail字段为nullable: true - [ ] 验证现有数据可以正常读取和更新 - [ ] 编写单元测试 (AC: 1, 2, 3) - [ ] 为平台schema添加测试,验证空字符串转换为undefined - [ ] 为平台schema添加测试,验证有效邮箱格式通过验证 - [ ] 为平台schema添加测试,验证无效邮箱格式显示中文错误提示 - [ ] 为平台schema添加测试,验证超长邮箱地址显示中文长度错误提示 - [ ] 为平台schema添加测试,验证undefined通过验证(可选字段) - [ ] 为平台管理表单添加测试,验证邮箱字段可为空的表单提交 - [ ] 为平台管理表单添加测试,验证邮箱字段为有效邮箱格式的表单提交 - [ ] 为平台管理表单添加测试,验证邮箱字段为无效格式时显示中文验证错误 - [ ] 添加集成测试验证端到端功能 - [ ] 执行回归测试 (AC: 3) - [ ] 测试现有平台数据的显示和编辑功能 - [ ] 验证API响应格式不变 - [ ] 确保其他字段验证不受影响 ## Dev Notes ### 技术架构信息 **前端技术栈**: - React 19.1.0 + TypeScript [Source: architecture/tech-stack.md#前端框架] - UI组件库: shadcn/ui (基于Radix UI) [Source: architecture/component-architecture.md#技术栈配置] - 状态管理: @tanstack/react-query (服务端状态) + Context (本地状态) [Source: architecture/component-architecture.md#技术栈配置] - 构建工具: Vite 7.0.0 [Source: architecture/tech-stack.md#构建工具] **项目结构**: - 平台管理UI包: `allin-packages/platform-management-ui` [Source: 实际项目结构检查] - 平台模块: `allin-packages/platform-module` [Source: 实际项目结构检查] ### 组件规范 **UI包开发规范**: - 必须遵循[UI包开发规范](./ui-package-standards.md) [Source: architecture/coding-standards.md#UI包开发提示] - API路径映射验证:开发前必须验证故事中的API路径映射与实际后端路由定义的一致性 [Source: architecture/coding-standards.md#关键检查点] - 类型推断最佳实践:必须使用RPC推断类型,而不是直接导入schema类型 [Source: architecture/coding-standards.md#关键检查点] - 测试选择器优化:必须为关键交互元素添加`data-testid`属性 [Source: architecture/coding-standards.md#关键检查点] ### 现有实现分析 **平台管理表单现状**: - 文件位置: `allin-packages/platform-management-ui/src/components/PlatformManagement.tsx:395-406` - 当前表单字段:contactEmail字段有FormLabel但没有红色星号标记 - 表单验证:使用CreatePlatformSchema和UpdatePlatformSchema进行验证 **平台schema现状**: - 创建DTO: `allin-packages/platform-module/src/schemas/platform.schema.ts:53` - `contactEmail`字段有`z.email('请输入有效的邮箱')`验证和`.optional()` - 更新DTO: `allin-packages/platform-module/src/schemas/platform.schema.ts:77` - `contactEmail`字段有`z.string().email()`验证和`.optional()`(缺少中文错误提示) - 数据库实体: `allin-packages/platform-module/src/entities/platform.entity.ts:47` - `contactEmail`字段为`nullable: true` **问题分析**: 当前schema中contactEmail字段有`.optional()`和`.email()`验证,这意味着: 1. 字段是可选的(可以是`undefined`)✅ 符合"非必要输入项"要求 2. 如果填写了,必须是有效的邮箱格式 ⚠️ 当前有.email()验证 3. 创建DTO有中文错误提示`z.email('请输入有效的邮箱')` ✅ 4. 更新DTO缺少中文错误提示`z.string().email()` ❌ 需要添加 **关键问题发现**: 1. **前端表单默认值问题**: - 文件位置:`allin-packages/platform-management-ui/src/components/PlatformManagement.tsx:42` - 当前默认值:`contactEmail: ''`(空字符串) - 问题:空字符串`''`不是有效的邮箱格式,会导致Zod验证失败 - 正确做法:默认值应该是`undefined` 2. **schema中文错误提示不统一**: - 创建DTO有中文错误提示 - 更新DTO缺少中文错误提示 - 需要统一添加完整的中文错误提示 **技术细节**: - Zod schema:`.optional()`允许`undefined`,但不允许无效的邮箱格式 - React Hook Form:`defaultValues`中可以使用`undefined`,但输入框清空后值是`''` - 当前所有字段都设置为`''`,但只有`contactEmail`需要特殊处理,因为它是可选但需要邮箱验证的字段 **解决方案选项**: 1. **推荐方案**:修改schema,使用`.or(z.literal(''))`允许空字符串,然后转换,并添加中文错误提示 ```typescript contactEmail: z.string({ error: '请输入联系邮箱' }).email({ message: '请输入有效的邮箱地址' }).max(100, { message: '邮箱地址不能超过100个字符' }).optional() .or(z.literal('')) // 允许空字符串 .transform(val => val === '' ? undefined : val) // 将空字符串转为undefined .openapi({ description: '联系邮箱', example: 'zhangsan@example.com' }) ``` 2. **备选方案**:前端在提交前将空字符串转换为`undefined` 3. **简单方案**:只修改默认值为`undefined`,但用户清空输入框后还是`''` 根据故事需求,推荐使用方案1,因为它: - 保持邮箱验证(如果填写了) - 允许空字符串(用户清空输入框) - 在API层面将空字符串转为`undefined` 根据故事"邮箱字段改为非必要输入项"的要求,需要: 1. 修改schema,允许空字符串并转换为`undefined` 2. 统一添加完整的中文错误提示(字符串、邮箱格式、长度限制) 3. 可选:将前端表单默认值从`''`改为`undefined` 4. 确保字段支持空值(不填写) 5. 如果用户选择填写,验证邮箱格式并显示中文错误提示 ### 文件位置参考 1. **平台管理组件**: `allin-packages/platform-management-ui/src/components/PlatformManagement.tsx` 2. **平台schema**: `allin-packages/platform-module/src/schemas/platform.schema.ts` 3. **平台实体**: `allin-packages/platform-module/src/entities/platform.entity.ts` ### 技术约束 - 保持向后兼容性:现有数据必须能正常显示和编辑 - API兼容性:不能修改现有API的请求/响应格式 - 数据库兼容性:`contactEmail`字段已经是`nullable: true`,无需修改数据库结构 ### 测试 **测试策略**: - 单元测试:使用Vitest框架 [Source: architecture/testing-strategy.md#单元测试] - 组件测试:使用Testing Library [Source: architecture/testing-strategy.md#单元测试] - 测试位置:`tests/`文件夹与源码并列 [Source: 实际项目结构检查] **测试要求**: - 覆盖率目标:核心业务逻辑 > 80% [Source: architecture/coding-standards.md#覆盖率目标] - 测试类型:单元测试、集成测试 [Source: architecture/coding-standards.md#测试类型] - 错误处理:测试各种错误场景和边界条件 [Source: architecture/coding-standards.md#错误处理] **具体测试场景**: 1. schema验证:空字符串`''`转换为`undefined`通过验证 2. schema验证:`undefined`通过验证(可选字段) 3. schema验证:有效邮箱格式通过验证 4. schema验证:无效邮箱格式显示中文错误提示"请输入有效的邮箱地址" 5. schema验证:超长邮箱地址显示中文长度错误提示"邮箱地址不能超过100个字符" 6. 平台表单:验证提交时邮箱字段可为空(不填写) 7. 平台表单:验证提交时邮箱字段可为有效邮箱格式 8. 平台表单:验证提交时邮箱字段为无效格式应显示中文验证错误 9. 数据兼容性:验证现有含邮箱数据的显示和编辑 ## Testing ### 测试标准 - **测试框架**: Vitest + Testing Library [Source: architecture/tech-stack.md#新技术添加] - **测试位置**: `tests/`文件夹与源码并列 [Source: 实际项目结构检查] - **覆盖率要求**: 核心业务逻辑 > 80% [Source: architecture/coding-standards.md#覆盖率目标] ### 组件测试要求 - 必须为关键交互元素添加`data-testid`属性 [Source: architecture/coding-standards.md#关键检查点] - 测试平台管理表单在邮箱字段为空时的提交行为 - 测试平台管理表单在邮箱字段为有效邮箱格式时的提交行为 - 测试平台管理表单在邮箱字段为无效格式时的验证错误显示 ### 集成测试要求 - 测试平台管理表单的完整提交流程 - 验证邮箱字段为空的表单提交 - 验证邮箱字段为有效邮箱格式的表单提交 - 验证邮箱字段为无效格式的表单提交应显示验证错误 - 测试现有数据的兼容性 ### 测试文件位置 1. 平台管理测试: `allin-packages/platform-management-ui/tests/integration/platform-management.integration.test.tsx` ## Change Log | Date | Version | Description | Author | |------|---------|-------------|--------| | 2025-12-10 | 1.0 | 初始故事创建 | Scrum Master Bob | ## Dev Agent Record *此部分由开发代理在实施期间填写* ## QA Results *此部分由QA代理在审查期间填写*