|
|
@@ -0,0 +1,433 @@
|
|
|
+# 注册表单性别选项动态切换
|
|
|
+
|
|
|
+## 问题描述
|
|
|
+
|
|
|
+在 `src/pages/patient/components/register.form.tsx` 文件中,性别选项(genderOptions)目前硬编码为宠物性别选项:
|
|
|
+
|
|
|
+```typescript
|
|
|
+const genderOptions = [
|
|
|
+ {
|
|
|
+ value: 'male_pet',
|
|
|
+ label: (
|
|
|
+ <FormattedMessage
|
|
|
+ id="register.gender.male_pet"
|
|
|
+ defaultMessage="register.gender.male_pet"
|
|
|
+ />
|
|
|
+ ),
|
|
|
+ },
|
|
|
+ {
|
|
|
+ value: 'female_pet',
|
|
|
+ label: (
|
|
|
+ <FormattedMessage
|
|
|
+ id="register.gender.female_pet"
|
|
|
+ defaultMessage="register.gender.female_pet"
|
|
|
+ />
|
|
|
+ ),
|
|
|
+ },
|
|
|
+ // ... 其他宠物性别选项
|
|
|
+];
|
|
|
+```
|
|
|
+
|
|
|
+**问题**:
|
|
|
+1. 硬编码为宠物性别选项,无法适应人类患者
|
|
|
+2. 没有根据产品类型(DROS/VETDROS)动态切换
|
|
|
+3. 代码复用性差
|
|
|
+
|
|
|
+## 需求分析
|
|
|
+
|
|
|
+### 业务需求
|
|
|
+
|
|
|
+系统支持两种产品类型:
|
|
|
+- **DROS**: 人类医疗设备
|
|
|
+- **VETDROS**: 宠物医疗设备
|
|
|
+
|
|
|
+性别选项需要根据产品类型动态切换:
|
|
|
+- **人类患者**: 使用标准性别选项(男/女/其他/未知)
|
|
|
+- **宠物患者**: 使用宠物性别选项(公/母/其他)
|
|
|
+
|
|
|
+### 技术需求
|
|
|
+
|
|
|
+1. **动态切换**: 根据 `productName` 自动选择合适的性别选项
|
|
|
+2. **国际化支持**: 所有选项都支持多语言
|
|
|
+3. **类型安全**: 使用 TypeScript 枚举确保类型安全
|
|
|
+4. **向后兼容**: 不影响现有功能
|
|
|
+
|
|
|
+## 解决方案设计
|
|
|
+
|
|
|
+### 1. 创建性别选项配置
|
|
|
+
|
|
|
+**文件**: `src/domain/patient/genderOptions.ts`
|
|
|
+
|
|
|
+```typescript
|
|
|
+import { FormattedMessage } from 'react-intl';
|
|
|
+
|
|
|
+/**
|
|
|
+ * 人类性别枚举
|
|
|
+ */
|
|
|
+export enum HumanGender {
|
|
|
+ MALE = 'male',
|
|
|
+ FEMALE = 'female',
|
|
|
+ OTHER = 'other',
|
|
|
+ UNKNOWN = 'unknown',
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 宠物性别枚举
|
|
|
+ */
|
|
|
+export enum PetGender {
|
|
|
+ MALE_PET = 'male_pet',
|
|
|
+ FEMALE_PET = 'female_pet',
|
|
|
+ NEUTERED_MALE = 'neutered_male',
|
|
|
+ NEUTERED_FEMALE = 'neutered_female',
|
|
|
+ UNKNOWN_PET = 'unknown_pet',
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 性别选项接口
|
|
|
+ */
|
|
|
+export interface GenderOption {
|
|
|
+ value: string;
|
|
|
+ label: React.ReactNode;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 人类性别选项
|
|
|
+ */
|
|
|
+export const humanGenderOptions: GenderOption[] = [
|
|
|
+ {
|
|
|
+ value: HumanGender.MALE,
|
|
|
+ label: (
|
|
|
+ <FormattedMessage
|
|
|
+ id="register.gender.male"
|
|
|
+ defaultMessage="Male"
|
|
|
+ />
|
|
|
+ ),
|
|
|
+ },
|
|
|
+ {
|
|
|
+ value: HumanGender.FEMALE,
|
|
|
+ label: (
|
|
|
+ <FormattedMessage
|
|
|
+ id="register.gender.female"
|
|
|
+ defaultMessage="Female"
|
|
|
+ />
|
|
|
+ ),
|
|
|
+ },
|
|
|
+ {
|
|
|
+ value: HumanGender.OTHER,
|
|
|
+ label: (
|
|
|
+ <FormattedMessage
|
|
|
+ id="register.gender.other"
|
|
|
+ defaultMessage="Other"
|
|
|
+ />
|
|
|
+ ),
|
|
|
+ },
|
|
|
+ {
|
|
|
+ value: HumanGender.UNKNOWN,
|
|
|
+ label: (
|
|
|
+ <FormattedMessage
|
|
|
+ id="register.gender.unknown"
|
|
|
+ defaultMessage="Unknown"
|
|
|
+ />
|
|
|
+ ),
|
|
|
+ },
|
|
|
+];
|
|
|
+
|
|
|
+/**
|
|
|
+ * 宠物性别选项
|
|
|
+ */
|
|
|
+export const petGenderOptions: GenderOption[] = [
|
|
|
+ {
|
|
|
+ value: PetGender.MALE_PET,
|
|
|
+ label: (
|
|
|
+ <FormattedMessage
|
|
|
+ id="register.gender.male_pet"
|
|
|
+ defaultMessage="Male Pet"
|
|
|
+ />
|
|
|
+ ),
|
|
|
+ },
|
|
|
+ {
|
|
|
+ value: PetGender.FEMALE_PET,
|
|
|
+ label: (
|
|
|
+ <FormattedMessage
|
|
|
+ id="register.gender.female_pet"
|
|
|
+ defaultMessage="Female Pet"
|
|
|
+ />
|
|
|
+ ),
|
|
|
+ },
|
|
|
+ {
|
|
|
+ value: PetGender.NEUTERED_MALE,
|
|
|
+ label: (
|
|
|
+ <FormattedMessage
|
|
|
+ id="register.gender.neutered_male"
|
|
|
+ defaultMessage="Neutered Male"
|
|
|
+ />
|
|
|
+ ),
|
|
|
+ },
|
|
|
+ {
|
|
|
+ value: PetGender.NEUTERED_FEMALE,
|
|
|
+ label: (
|
|
|
+ <FormattedMessage
|
|
|
+ id="register.gender.neutered_female"
|
|
|
+ defaultMessage="Neutered Female"
|
|
|
+ />
|
|
|
+ ),
|
|
|
+ },
|
|
|
+ {
|
|
|
+ value: PetGender.UNKNOWN_PET,
|
|
|
+ label: (
|
|
|
+ <FormattedMessage
|
|
|
+ id="register.gender.unknown_pet"
|
|
|
+ defaultMessage="Unknown Pet"
|
|
|
+ />
|
|
|
+ ),
|
|
|
+ },
|
|
|
+];
|
|
|
+
|
|
|
+/**
|
|
|
+ * 根据产品类型获取性别选项
|
|
|
+ * @param productName 产品名称 ('DROS' | 'VETDROS')
|
|
|
+ * @returns 性别选项数组
|
|
|
+ */
|
|
|
+export function getGenderOptions(productName: string): GenderOption[] {
|
|
|
+ switch (productName) {
|
|
|
+ case 'DROS':
|
|
|
+ return humanGenderOptions;
|
|
|
+ case 'VETDROS':
|
|
|
+ return petGenderOptions;
|
|
|
+ default:
|
|
|
+ // 默认使用人类性别选项
|
|
|
+ console.warn(`Unknown product name: ${productName}, using human gender options`);
|
|
|
+ return humanGenderOptions;
|
|
|
+ }
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+### 2. 修改注册表单组件
|
|
|
+
|
|
|
+**文件**: `src/pages/patient/components/register.form.tsx`
|
|
|
+
|
|
|
+```typescript
|
|
|
+// 导入性别选项配置
|
|
|
+import { getGenderOptions } from '@/domain/patient/genderOptions';
|
|
|
+
|
|
|
+// 获取产品类型
|
|
|
+const productName = useSelector((state: RootState) => state.product.productName);
|
|
|
+
|
|
|
+// 动态获取性别选项
|
|
|
+const genderOptions = useMemo(() => {
|
|
|
+ return getGenderOptions(productName);
|
|
|
+}, [productName]);
|
|
|
+
|
|
|
+// 替换原有的硬编码 genderOptions
|
|
|
+// 原代码:
|
|
|
+// const genderOptions = [/* 硬编码的宠物性别选项 */];
|
|
|
+
|
|
|
+// 使用动态获取的性别选项
|
|
|
+// genderOptions 变量已在上面定义
|
|
|
+```
|
|
|
+
|
|
|
+### 3. 更新国际化文件
|
|
|
+
|
|
|
+**文件**: `src/assets/i18n/messages/en.js`
|
|
|
+
|
|
|
+添加人类性别选项的英文翻译:
|
|
|
+
|
|
|
+```javascript
|
|
|
+{
|
|
|
+ // ... 现有翻译
|
|
|
+
|
|
|
+ // 人类性别选项
|
|
|
+ "register.gender.male": "Male",
|
|
|
+ "register.gender.female": "Female",
|
|
|
+ "register.gender.other": "Other",
|
|
|
+ "register.gender.unknown": "Unknown",
|
|
|
+
|
|
|
+ // 宠物性别选项(如果需要更新)
|
|
|
+ "register.gender.male_pet": "Male",
|
|
|
+ "register.gender.female_pet": "Female",
|
|
|
+ "register.gender.neutered_male": "Neutered Male",
|
|
|
+ "register.gender.neutered_female": "Neutered Female",
|
|
|
+ "register.gender.unknown_pet": "Unknown",
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+**文件**: `src/assets/i18n/messages/zh.js`
|
|
|
+
|
|
|
+添加中文翻译:
|
|
|
+
|
|
|
+```javascript
|
|
|
+{
|
|
|
+ // ... 现有翻译
|
|
|
+
|
|
|
+ // 人类性别选项
|
|
|
+ "register.gender.male": "男",
|
|
|
+ "register.gender.female": "女",
|
|
|
+ "register.gender.other": "其他",
|
|
|
+ "register.gender.unknown": "未知",
|
|
|
+
|
|
|
+ // 宠物性别选项(如果需要更新)
|
|
|
+ "register.gender.male_pet": "公",
|
|
|
+ "register.gender.female_pet": "母",
|
|
|
+ "register.gender.neutered_male": "已绝育公",
|
|
|
+ "register.gender.neutered_female": "已绝育母",
|
|
|
+ "register.gender.unknown_pet": "未知",
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+## 实现步骤
|
|
|
+
|
|
|
+### 步骤 1: 创建性别选项配置文件
|
|
|
+
|
|
|
+1. 创建 `src/domain/patient/genderOptions.ts` 文件
|
|
|
+2. 定义人类和宠物性别枚举
|
|
|
+3. 实现性别选项配置
|
|
|
+4. 实现 `getGenderOptions` 函数
|
|
|
+
|
|
|
+### 步骤 2: 修改注册表单组件
|
|
|
+
|
|
|
+1. 在 `register.form.tsx` 中导入 `getGenderOptions`
|
|
|
+2. 获取 `productName` 从 Redux store
|
|
|
+3. 使用 `useMemo` 动态计算 `genderOptions`
|
|
|
+4. 移除原有的硬编码性别选项
|
|
|
+
|
|
|
+### 步骤 3: 更新国际化文件
|
|
|
+
|
|
|
+1. 在英文和中文国际化文件中添加新的性别选项翻译
|
|
|
+2. 确保所有性别选项都有对应的翻译
|
|
|
+
|
|
|
+### 步骤 4: 测试验证
|
|
|
+
|
|
|
+1. 测试 DROS 产品显示人类性别选项
|
|
|
+2. 测试 VETDROS 产品显示宠物性别选项
|
|
|
+3. 测试国际化切换是否正常
|
|
|
+4. 测试表单提交和数据保存
|
|
|
+
|
|
|
+## 技术细节
|
|
|
+
|
|
|
+### 1. 产品类型判断逻辑
|
|
|
+
|
|
|
+```typescript
|
|
|
+const productName = useSelector((state: RootState) => state.product.productName);
|
|
|
+
|
|
|
+const genderOptions = useMemo(() => {
|
|
|
+ return getGenderOptions(productName);
|
|
|
+}, [productName]);
|
|
|
+```
|
|
|
+
|
|
|
+- 使用 Redux selector 获取产品名称
|
|
|
+- 使用 `useMemo` 避免不必要的重新计算
|
|
|
+- 依赖 `productName` 变化时重新计算性别选项
|
|
|
+
|
|
|
+### 2. 类型安全设计
|
|
|
+
|
|
|
+```typescript
|
|
|
+// 使用枚举确保类型安全
|
|
|
+export enum HumanGender {
|
|
|
+ MALE = 'male',
|
|
|
+ FEMALE = 'female',
|
|
|
+ OTHER = 'other',
|
|
|
+ UNKNOWN = 'unknown',
|
|
|
+}
|
|
|
+
|
|
|
+// 统一的选项接口
|
|
|
+export interface GenderOption {
|
|
|
+ value: string;
|
|
|
+ label: React.ReactNode;
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+- 枚举值与国际化 key 保持一致
|
|
|
+- 接口定义确保所有选项都有统一的结构
|
|
|
+
|
|
|
+### 3. 国际化集成
|
|
|
+
|
|
|
+```typescript
|
|
|
+// 使用 FormattedMessage 进行国际化
|
|
|
+label: (
|
|
|
+ <FormattedMessage
|
|
|
+ id="register.gender.male"
|
|
|
+ defaultMessage="Male"
|
|
|
+ />
|
|
|
+),
|
|
|
+```
|
|
|
+
|
|
|
+- 支持多语言切换
|
|
|
+- 提供默认值防止 key 缺失
|
|
|
+
|
|
|
+## 优势
|
|
|
+
|
|
|
+### 1. 动态适应性
|
|
|
+- 根据产品类型自动切换性别选项
|
|
|
+- 无需手动配置,减少出错可能
|
|
|
+
|
|
|
+### 2. 代码复用性
|
|
|
+- 性别选项配置集中管理
|
|
|
+- 可在其他组件中复用
|
|
|
+
|
|
|
+### 3. 国际化支持
|
|
|
+- 所有选项都支持多语言
|
|
|
+- 统一的翻译管理
|
|
|
+
|
|
|
+### 4. 类型安全
|
|
|
+- 使用 TypeScript 枚举
|
|
|
+- 编译时检查类型错误
|
|
|
+
|
|
|
+### 5. 向后兼容
|
|
|
+- 不影响现有功能
|
|
|
+- 默认使用人类性别选项
|
|
|
+
|
|
|
+## 测试场景
|
|
|
+
|
|
|
+### 1. 功能测试
|
|
|
+
|
|
|
+| 测试场景 | 前置条件 | 操作步骤 | 预期结果 |
|
|
|
+|---------|---------|---------|---------|
|
|
|
+| DROS 产品性别选项 | 产品类型为 DROS | 打开注册表单 | 显示男/女/其他/未知选项 |
|
|
|
+| VETDROS 产品性别选项 | 产品类型为 VETDROS | 打开注册表单 | 显示公/母/已绝育公/已绝育母/未知选项 |
|
|
|
+| 表单提交 | 选择性别选项 | 提交表单 | 数据正确保存到后端 |
|
|
|
+
|
|
|
+### 2. 国际化测试
|
|
|
+
|
|
|
+| 测试场景 | 前置条件 | 操作步骤 | 预期结果 |
|
|
|
+|---------|---------|---------|---------|
|
|
|
+| 英文环境 | 切换到英文语言 | 查看性别选项 | 显示 Male/Female/Other/Unknown |
|
|
|
+| 中文环境 | 切换到中文语言 | 查看性别选项 | 显示 男/女/其他/未知 |
|
|
|
+
|
|
|
+### 3. 边界情况测试
|
|
|
+
|
|
|
+| 测试场景 | 前置条件 | 操作步骤 | 预期结果 |
|
|
|
+|---------|---------|---------|---------|
|
|
|
+| 未知产品类型 | productName 为未知值 | 打开注册表单 | 默认显示人类性别选项 |
|
|
|
+| 产品类型为空 | productName 为空字符串 | 打开注册表单 | 默认显示人类性别选项 |
|
|
|
+
|
|
|
+## 相关文件
|
|
|
+
|
|
|
+### 修改文件
|
|
|
+- `src/pages/patient/components/register.form.tsx` - 主要修改文件
|
|
|
+- `src/assets/i18n/messages/en.js` - 添加英文翻译
|
|
|
+- `src/assets/i18n/messages/zh.js` - 添加中文翻译
|
|
|
+
|
|
|
+### 新增文件
|
|
|
+- `src/domain/patient/genderOptions.ts` - 性别选项配置
|
|
|
+
|
|
|
+### 相关文件
|
|
|
+- `src/states/productSlice.ts` - 产品状态管理
|
|
|
+- `src/states/patient/register/formSlice.ts` - 表单状态管理
|
|
|
+
|
|
|
+## 总结
|
|
|
+
|
|
|
+通过创建性别选项配置文件,实现根据产品类型动态切换性别选项的功能:
|
|
|
+
|
|
|
+1. **解决了硬编码问题**:从硬编码宠物性别选项改为动态配置
|
|
|
+2. **支持多产品类型**:DROS 使用人类性别,VETDROS 使用宠物性别
|
|
|
+3. **完善国际化**:所有选项都支持多语言
|
|
|
+4. **保证类型安全**:使用 TypeScript 枚举和接口
|
|
|
+5. **保持向后兼容**:不影响现有功能
|
|
|
+
|
|
|
+该方案具有良好的扩展性,未来如需添加新的产品类型或性别选项,只需在配置文件中添加即可。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+**实现日期**: 2025-11-14
|
|
|
+**文档版本**: v1.0
|
|
|
+**作者**: Cline AI Assistant
|