Răsfoiți Sursa

🐛 fix(platform): 修复平台表单邮箱字段验证问题并统一中文错误提示

- 修复前端表单默认值,将contactEmail从空字符串改为undefined以避免验证失败
- 更新文档故事,详细说明schema修改方案和中文错误提示要求
- 统一创建和更新DTO的中文错误提示,包括必填、邮箱格式和长度验证
yourname 2 săptămâni în urmă
părinte
comite
d6c4cf4b88

+ 1 - 1
allin-packages/platform-management-ui/src/components/PlatformManagement.tsx

@@ -39,7 +39,7 @@ const PlatformManagement: React.FC = () => {
       platformName: '',
       contactPerson: '',
       contactPhone: '',
-      contactEmail: ''
+      contactEmail: undefined
     }
   });
 

+ 33 - 9
allin-packages/platform-module/src/schemas/platform.schema.ts

@@ -38,7 +38,13 @@ export const PlatformSchema = z.object({
 
 // 创建平台DTO
 export const CreatePlatformSchema = z.object({
-  platformName: z.string().min(1).max(100).openapi({
+  platformName: z.string({
+    error: '请输入平台名称'
+  }).min(1, {
+    message: '平台名称不能为空'
+  }).max(100, {
+    message: '平台名称不能超过100个字符'
+  }).openapi({
     description: '平台名称',
     example: '微信平台'
   }),
@@ -50,10 +56,19 @@ export const CreatePlatformSchema = z.object({
     description: '联系电话',
     example: '13800138000'
   }),
-  contactEmail: z.email('请输入有效的邮箱').max(100).optional().openapi({
-    description: '联系邮箱',
-    example: 'zhangsan@example.com'
-  })
+  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'
+    })
 });
 
 // 更新平台DTO
@@ -74,10 +89,19 @@ export const UpdatePlatformSchema = z.object({
     description: '联系电话',
     example: '13800138000'
   }),
-  contactEmail: z.string().email().max(100).optional().openapi({
-    description: '联系邮箱',
-    example: 'zhangsan@example.com'
-  })
+  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'
+    })
 });
 
 // 删除平台DTO

+ 49 - 10
docs/prd/epic-009-system-test-optimization.md

@@ -11,7 +11,7 @@
 
 ## 范围
 - 平台管理模块的区域选择优化
-- 薪资管理模块的邮箱输入优化
+- 平台管理模块的邮箱输入优化
 - 残疾人个人管理模块的多项优化
 - 订单管理模块的日期选择和功能测试优化
 - 公司管理模块的公司创建优化
@@ -40,21 +40,42 @@
 - 页面路径:平台管理 > 薪资管理 > 添加薪资 > 区域选择
 - 修改区域选择组件的验证规则
 
-### 薪资管理模块
+### 平台管理模块
 
 #### 故事 009-02: 邮箱输入优化
-**作为** 薪资管理员
+**作为** 平台管理员
 **我希望** 邮箱字段改为非必要输入项
-**以便** 在不需要邮箱的场景下快速完成薪资相关操作
+**以便** 在不需要邮箱的场景下快速完成平台相关操作
 
 **验收标准:**
-- [ ] 所有薪资管理相关页面的邮箱字段改为非必填
-- [ ] 表单验证规则更新
-- [ ] 后端API支持邮箱为空
+- [ ] 所有平台管理相关页面的邮箱字段改为非必填
+- [ ] 表单验证规则更新(添加中文错误提示)
+- [ ] 后端API支持邮箱为空(空字符串自动转换为undefined)
 
 **技术说明:**
-- 页面路径:薪资管理相关输入页面
-- 更新前端表单验证和后端DTO验证
+- 页面路径:平台管理 > 创建平台/编辑平台 > 联系邮箱字段
+- 文件位置:
+  - 前端:`allin-packages/platform-management-ui/src/components/PlatformManagement.tsx`
+  - 后端:`allin-packages/platform-module/src/schemas/platform.schema.ts`
+- 技术方案:
+  1. 修改Zod schema,添加中文错误提示:
+     ```typescript
+     contactEmail: z.string({
+       error: '请输入联系邮箱'
+     }).email({
+       message: '请输入有效的邮箱地址'
+     }).max(100, {
+       message: '邮箱地址不能超过100个字符'
+     }).optional()
+       .or(z.literal(''))  // 允许空字符串
+       .transform(val => val === '' ? undefined : val)  // 将空字符串转为undefined
+     ```
+  2. 前端表单默认值从`''`改为`undefined`
+  3. 统一创建和更新DTO的验证规则
+- 测试要求:
+  - 验证空字符串自动转换为undefined
+  - 验证中文错误提示显示正确
+  - 验证邮箱格式验证正常工作
 
 ### 残疾人个人管理模块
 
@@ -153,6 +174,9 @@
 2. 前端组件修改需要考虑用户体验一致性
 3. API接口变更需要保持向后兼容
 4. 表单验证规则的更新需要全面测试
+5. 中文错误提示需要统一格式和语言
+6. 可选字段的空字符串处理需要统一方案(使用Zod transform转换为undefined)
+7. 前端表单默认值需要与schema验证规则保持一致
 
 ## 依赖关系
 1. 各模块的优化相对独立,可并行开发
@@ -164,12 +188,21 @@
    **缓解**: 全面测试相关功能,确保不影响现有业务
 3. **风险**: 组件修改可能引入新的bug
    **缓解**: 加强单元测试和集成测试
+4. **风险**: 中文错误提示不一致或翻译错误
+   **缓解**: 统一错误提示格式,进行语言审查
+5. **风险**: 空字符串处理逻辑错误导致数据异常
+   **缓解**: 充分测试空字符串转换逻辑,确保与数据库兼容
+6. **风险**: 前端默认值与后端验证规则不一致
+   **缓解**: 同步更新前端表单默认值和后端schema验证
 
 ## 验收测试计划
 1. 功能测试:验证每个优化需求的功能完整性
 2. 回归测试:确保现有功能不受影响
 3. 性能测试:验证优化后的性能表现
 4. 用户体验测试:收集用户反馈
+5. 验证测试:测试中文错误提示显示正确性
+6. 边界测试:测试空字符串转换和可选字段行为
+7. 兼容性测试:验证前后端验证规则一致性
 
 ## 时间估算
 - 总工作量:约15-20人天
@@ -181,4 +214,10 @@
 ---
 
 *史诗创建时间: 2025-12-09*
-*状态: 进行中 (1/9 故事完成)*
+*最后更新: 2025-12-10*
+*状态: 进行中 (平台管理模块schema已更新,故事009.002待实施)*
+
+**更新记录**:
+- 2025-12-10: 修正故事009-02为平台管理模块(原误写为薪资管理模块)
+- 2025-12-10: 更新平台管理模块schema,添加中文错误提示和空字符串处理
+- 2025-12-10: 更新技术考虑、风险与缓解、验收测试计划

+ 65 - 31
docs/stories/009.002.story.md

@@ -14,30 +14,45 @@ Draft
 3. 后端API支持邮箱为空
 
 ## Tasks / Subtasks
-- [ ] 修复平台管理前端表单默认值问题 (AC: 1, 2)
-  - [ ] 修改allin-packages/platform-management-ui/src/components/PlatformManagement.tsx中的表单配置
-  - [ ] 将contactEmail字段的默认值从`''`改为`undefined`
-  - [ ] 验证contactEmail字段的FormLabel没有红色星号标记(非必填)
+- [x] 修复平台管理前端表单默认值问题 (AC: 1, 2)
+  - [x] 修改allin-packages/platform-management-ui/src/components/PlatformManagement.tsx中的表单配置
+  - [x] 将contactEmail字段的默认值从`''`改为`undefined`
+  - [x] 验证contactEmail字段的FormLabel没有红色星号标记(非必填)
   - [ ] 测试表单提交时邮箱字段可为空(不填写)
   - [ ] 测试表单提交时邮箱字段可为有效邮箱格式
   - [ ] 测试表单提交时邮箱字段为无效格式应显示验证错误
-- [ ] 修改平台模块后端schema验证 (AC: 2, 3)
-  - [ ] 修改allin-packages/platform-module/src/schemas/platform.schema.ts中的CreatePlatformSchema
-  - [ ] 将contactEmail字段改为:`.optional().or(z.literal('')).transform(val => val === '' ? undefined : val)`
-  - [ ] 保留.email()验证(如果填写,必须是有效邮箱格式)
-  - [ ] 同样修改UpdatePlatformSchema中的contactEmail字段验证规则
-  - [ ] 确保.openapi()描述保持不变
-- [ ] 验证数据库兼容性 (AC: 3)
-  - [ ] 检查allin-packages/platform-module/src/entities/platform.entity.ts中contactEmail字段为nullable: true
+- [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添加测试,验证超长邮箱地址显示中文长度错误提示
   - [ ] 为平台schema添加测试,验证undefined通过验证(可选字段)
   - [ ] 为平台管理表单添加测试,验证邮箱字段可为空的表单提交
   - [ ] 为平台管理表单添加测试,验证邮箱字段为有效邮箱格式的表单提交
-  - [ ] 为平台管理表单添加测试,验证邮箱字段为无效格式时显示验证错误
+  - [ ] 为平台管理表单添加测试,验证邮箱字段为无效格式时显示中文验证错误
   - [ ] 添加集成测试验证端到端功能
 - [ ] 执行回归测试 (AC: 3)
   - [ ] 测试现有平台数据的显示和编辑功能
@@ -71,21 +86,28 @@ Draft
 - 表单验证:使用CreatePlatformSchema和UpdatePlatformSchema进行验证
 
 **平台schema现状**:
-- 创建DTO: `allin-packages/platform-module/src/schemas/platform.schema.ts:53` - `contactEmail`字段有`.email()`验证和`.optional()`
-- 更新DTO: `allin-packages/platform-module/src/schemas/platform.schema.ts:77` - `contactEmail`字段有`.email()`验证和`.optional()`
+- 创建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()` ❌ 需要添加
 
 **关键问题发现**:
-前端表单默认值设置有问题:
-- 文件位置:`allin-packages/platform-management-ui/src/components/PlatformManagement.tsx:42`
-- 当前默认值:`contactEmail: ''`(空字符串)
-- 问题:空字符串`''`不是有效的邮箱格式,会导致Zod验证失败
-- 正确做法:默认值应该是`undefined`
+1. **前端表单默认值问题**:
+   - 文件位置:`allin-packages/platform-management-ui/src/components/PlatformManagement.tsx:42`
+   - 当前默认值:`contactEmail: ''`(空字符串)
+   - 问题:空字符串`''`不是有效的邮箱格式,会导致Zod验证失败
+   - 正确做法:默认值应该是`undefined`
+
+2. **schema中文错误提示不统一**:
+   - 创建DTO有中文错误提示
+   - 更新DTO缺少中文错误提示
+   - 需要统一添加完整的中文错误提示
 
 **技术细节**:
 - Zod schema:`.optional()`允许`undefined`,但不允许无效的邮箱格式
@@ -93,11 +115,21 @@ Draft
 - 当前所有字段都设置为`''`,但只有`contactEmail`需要特殊处理,因为它是可选但需要邮箱验证的字段
 
 **解决方案选项**:
-1. **推荐方案**:修改schema,使用`.or(z.literal(''))`允许空字符串,然后转换
+1. **推荐方案**:修改schema,使用`.or(z.literal(''))`允许空字符串,然后转换,并添加中文错误提示
    ```typescript
-   contactEmail: z.string().email().max(100).optional()
+   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`,但用户清空输入框后还是`''`
@@ -109,9 +141,10 @@ Draft
 
 根据故事"邮箱字段改为非必要输入项"的要求,需要:
 1. 修改schema,允许空字符串并转换为`undefined`
-2. 可选:将前端表单默认值从`''`改为`undefined`
-3. 确保字段支持空值(不填写)
-4. 如果用户选择填写,验证邮箱格式
+2. 统一添加完整的中文错误提示(字符串、邮箱格式、长度限制)
+3. 可选:将前端表单默认值从`''`改为`undefined`
+4. 确保字段支持空值(不填写)
+5. 如果用户选择填写,验证邮箱格式并显示中文错误提示
 
 ### 文件位置参考
 1. **平台管理组件**: `allin-packages/platform-management-ui/src/components/PlatformManagement.tsx`
@@ -138,11 +171,12 @@ Draft
 1. schema验证:空字符串`''`转换为`undefined`通过验证
 2. schema验证:`undefined`通过验证(可选字段)
 3. schema验证:有效邮箱格式通过验证
-4. schema验证:无效邮箱格式显示验证错误
-5. 平台表单:验证提交时邮箱字段可为空(不填写)
-6. 平台表单:验证提交时邮箱字段可为有效邮箱格式
-7. 平台表单:验证提交时邮箱字段为无效格式应显示验证错误
-8. 数据兼容性:验证现有含邮箱数据的显示和编辑
+4. schema验证:无效邮箱格式显示中文错误提示"请输入有效的邮箱地址"
+5. schema验证:超长邮箱地址显示中文长度错误提示"邮箱地址不能超过100个字符"
+6. 平台表单:验证提交时邮箱字段可为空(不填写)
+7. 平台表单:验证提交时邮箱字段可为有效邮箱格式
+8. 平台表单:验证提交时邮箱字段为无效格式应显示中文验证错误
+9. 数据兼容性:验证现有含邮箱数据的显示和编辑
 
 ## Testing
 ### 测试标准