# 联系人必填和归属机构默认选中功能说明 ## 功能概述 本次优化包含两个功能点: 1. **联系人字段设为必填**:确保急救转运任务中联系人信息完整,便于紧急情况下联系 2. **归属机构默认选中当前用户分公司**:自动设置用户所属分公司,同时更新地域过滤条件,优化用户体验 ## 实现位置 **前端文件**: `app/pages/task/create-emergency.vue` ## 一、联系人必填功能 ### 1.1 业务背景 急救转运任务中,联系人是关键信息,用于: - 紧急情况下的沟通联系 - 确认患者身份和情况 - 协调转运过程中的各项事宜 - 后续任务跟进和反馈 因此将联系人字段设为必填,确保信息完整性。 ### 1.2 技术实现 #### 模板修改 将联系人的label添加`required`类: ```vue 联系人 ``` #### 表单验证 在 `validateForm()` 方法中添加联系人验证: ```javascript validateForm() { // ... 其他验证 if (!this.taskForm.patient.contact) { this.$modal.showToast('请输入联系人') return false } if (!this.taskForm.patient.name) { this.$modal.showToast('请输入患者姓名') return false } // ... 其他验证 return true } ``` **验证顺序**: 1. 任务车辆 2. 任务类型 3. 单据类型 4. ✅ **联系人**(新增) 5. 患者姓名 6. 联系电话 7. 转出医院信息 8. 转入医院信息 ### 1.3 样式说明 必填字段标识通过CSS伪元素实现: ```scss .form-label { &.required::before { content: '*'; color: #ff4d4f; margin-right: 4rpx; font-weight: bold; } } ``` 显示效果:`* 联系人` ## 二、归属机构默认选中功能 ### 2.1 业务背景 根据项目规范和用户体验: - 用户创建任务时,归属机构通常就是自己所在的分公司 - 自动选中可以减少用户操作步骤 - 归属机构会影响医院列表的地域过滤,需要自动更新 ### 2.2 技术实现 #### 修改 loadBranchCompanies() 方法 ```javascript loadBranchCompanies() { listBranchCompany().then(response => { const list = response.data || [] // 过滤出 parent_id = 100 的部门(分公司) this.organizationOptions = list.filter(dept => dept.parentId === 100) // 生成picker的数据源(只显示名称) this.organizations = this.organizationOptions.map(dept => dept.deptName) // 默认设置为当前用户的分公司 if (this.currentUser.branchCompanyName) { const index = this.organizationOptions.findIndex( dept => dept.deptName === this.currentUser.branchCompanyName ) if (index !== -1) { this.selectedOrganization = this.currentUser.branchCompanyName // 提取地域关键词(去除"分公司"后缀) this.selectedRegion = this.selectedOrganization.replace(/分公司$/g, '').trim() console.log('默认选中归属机构:', this.selectedOrganization, '地域:', this.selectedRegion) // 加载医院列表(带地域过滤) this.loadDefaultHospitals() } } }).catch(error => { console.error('加载分公司数据失败:', error) this.organizationOptions = [] this.organizations = [] }) } ``` #### 优化 onLoad() 方法 移除重复的医院列表加载和归属机构设置: ```javascript onLoad(options) { // 先加载车辆列表,然后加载绑定车辆信息 this.getAvailableVehicles().then(() => { this.getUserBoundVehicleInfo() }) this.initSelectedStaff() this.loadDeptStaff() // 加载分公司数据(会自动设置默认分公司并加载医院列表) this.loadBranchCompanies() // 加载科室字典数据 this.loadDepartments() // 加载任务类型数据 this.loadEmergencyTaskTypes() // 加载单据类型数据 this.loadDocumentTypes() } ``` **优化说明**: - ❌ 移除了独立的 `this.selectedOrganization = this.currentUser.branchCompanyName` - ❌ 移除了独立的 `this.loadDefaultHospitals()` - ✅ `loadBranchCompanies()` 内部会完成这两个操作 - ✅ 避免了医院列表的重复加载 ### 2.3 工作流程 ``` 页面加载 (onLoad) ↓ 调用 loadBranchCompanies() ↓ 从后端加载分公司列表 ↓ 过滤 parent_id = 100 的部门 ↓ 检查当前用户的 branchCompanyName ↓ 在分公司列表中查找匹配项 ↓ 设置 selectedOrganization = 用户分公司名称 设置 selectedRegion = 提取的地域关键词 ↓ 调用 loadDefaultHospitals() 加载医院列表 ↓ 医院列表按地域过滤 ↓ UI 更新,显示选中的归属机构 ``` ### 2.4 地域提取逻辑 将分公司名称转换为地域关键词: ```javascript // 例如:"广州分公司" → "广州" this.selectedRegion = this.selectedOrganization.replace(/分公司$/g, '').trim() ``` **示例**: - "广州分公司" → "广州" - "深圳分公司" → "深圳" - "东莞分公司" → "东莞" 这个地域关键词会用于医院搜索的过滤条件。 ## 三、数据流程图 ### 联系人必填验证流程 ``` 用户点击"保存" ↓ 调用 submitTask() ↓ 调用 validateForm() ↓ 检查 taskForm.patient.contact ↓ ├─ 为空 → 提示"请输入联系人" → 阻止提交 └─ 有值 → 继续其他验证 ``` ### 归属机构默认选中流程 ``` 页面加载 ↓ 获取 currentUser.branchCompanyName ↓ ├─ 有值(如"广州分公司") │ ↓ │ 在 organizationOptions 中查找 │ ↓ │ ├─ 找到 │ │ ↓ │ │ 设置 selectedOrganization = "广州分公司" │ │ 设置 selectedRegion = "广州" │ │ 加载医院列表(地域过滤) │ │ ↓ │ │ UI 显示"广州分公司" │ │ │ └─ 未找到 │ ↓ │ 不设置默认值 │ 医院列表不过滤 │ └─ 无值 ↓ 不设置默认值 用户需要手动选择 ``` ## 四、数据结构 ### 用户信息(来自 Vuex state) ```javascript currentUser: { userId: 1, name: "张三", nickName: "张三", deptId: 101, branchCompanyId: 100, branchCompanyName: "广州分公司" // 关键字段 } ``` ### 归属机构数据 ```javascript // 原始数据(来自后端) organizationOptions: [ { deptId: 100, deptName: "广州分公司", parentId: 100 }, { deptId: 101, deptName: "深圳分公司", parentId: 100 } ] // picker 显示数据 organizations: ["广州分公司", "深圳分公司"] // 选中的值 selectedOrganization: "广州分公司" selectedRegion: "广州" // 用于医院搜索过滤 ``` ### 表单数据 ```javascript taskForm: { patient: { contact: "李四", // ✅ 必填 phone: "13800138000", // ✅ 必填 name: "王五", // ✅ 必填 gender: "male", idCard: "440106199001011234", condition: "" }, // ... 其他字段 } ``` ## 五、相关接口 ### 获取分公司列表 **API**: `GET /system/dept/list?parentId=100` **前端方法**: `listBranchCompany()` **返回数据**: ```json { "code": 200, "data": [ { "deptId": 100, "deptName": "广州分公司", "parentId": 100, "orderNum": 1, "leader": "张经理", "phone": "020-12345678", "status": "0" }, { "deptId": 101, "deptName": "深圳分公司", "parentId": 100, "orderNum": 2, "leader": "李经理", "phone": "0755-87654321", "status": "0" } ] } ``` ### 搜索医院(带地域过滤) **API**: `GET /hospital/search?keyword={keyword}®ion={region}` **调用示例**: ```javascript // selectedRegion = "广州" searchHospitals('', '广州').then(response => { // 返回广州地区的医院列表(前100条) }) ``` **过滤逻辑**(后端SQL): ```sql WHERE (HopsProvince LIKE '%广州%' OR HopsCity LIKE '%广州%' OR HopsArea LIKE '%广州%') ``` ## 六、异常处理 ### 1. 用户未设置分公司 **场景**: `currentUser.branchCompanyName` 为空 **处理**: - 不设置默认值 - `selectedOrganization` 保持为空 - picker 显示"请选择归属机构" - 医院列表不进行地域过滤 ### 2. 用户分公司不在列表中 **场景**: 数据不一致,用户的分公司不在 parent_id=100 的列表中 **处理**: ```javascript const index = this.organizationOptions.findIndex( dept => dept.deptName === this.currentUser.branchCompanyName ) if (index !== -1) { // 找到了,设置默认值 } else { // 未找到,不设置默认值 // 用户需要手动选择 } ``` ### 3. 联系人为空提交 **场景**: 用户未填写联系人就点击保存 **处理**: ```javascript if (!this.taskForm.patient.contact) { this.$modal.showToast('请输入联系人') return false // 阻止提交 } ``` **用户看到**: Toast 提示"请输入联系人" ## 七、测试建议 ### 测试场景1:联系人必填验证 **步骤**: 1. 打开创建急救转运任务页面 2. 填写其他必填字段(车辆、患者姓名、电话等) 3. 不填写联系人 4. 点击"保存"按钮 **预期结果**: - 显示 Toast 提示"请输入联系人" - 表单不提交 - 用户停留在当前页面 ### 测试场景2:归属机构默认选中 **前置条件**: 当前用户的 branchCompanyName = "广州分公司" **步骤**: 1. 打开创建急救转运任务页面 2. 观察归属机构字段 **预期结果**: - 归属机构字段自动显示"广州分公司" - `selectedRegion` = "广州" - 医院列表加载时带地域过滤 - 控制台输出: "默认选中归属机构: 广州分公司 地域: 广州" ### 测试场景3:归属机构切换 **步骤**: 1. 页面加载后,归属机构默认显示"广州分公司" 2. 用户点击归属机构选择器 3. 选择"深圳分公司" **预期结果**: - `selectedOrganization` 更新为"深圳分公司" - `selectedRegion` 更新为"深圳" - 自动重新加载医院列表(带新的地域过滤) - 医院搜索结果只显示深圳地区的医院 ### 测试场景4:用户无分公司 **前置条件**: 当前用户的 branchCompanyName 为空或 null **步骤**: 1. 打开创建急救转运任务页面 2. 观察归属机构字段 **预期结果**: - 归属机构显示"请选择归属机构" - 没有默认选中项 - 医院列表加载时不进行地域过滤 - 用户可以手动选择归属机构 ## 八、优化建议 ### 1. 联系人智能填充 根据患者姓名或历史记录,智能推荐联系人: ```javascript // 监听患者姓名变化 watch: { 'taskForm.patient.name'(newVal) { // 如果联系人为空,可以自动填充为患者姓名 if (!this.taskForm.patient.contact && newVal) { this.taskForm.patient.contact = newVal } } } ``` ### 2. 联系人常用列表 记录用户常用的联系人,提供快速选择: ```javascript // 本地存储常用联系人 const frequentContacts = uni.getStorageSync('frequentContacts') || [] // 显示快速选择按钮 {{ contact }} ``` ### 3. 归属机构权限控制 某些用户可能只能看到特定的分公司: ```javascript loadBranchCompanies() { listBranchCompany().then(response => { let list = response.data || [] // 根据用户权限过滤 if (!this.currentUser.isAdmin) { list = list.filter(dept => dept.deptId === this.currentUser.branchCompanyId ) } this.organizationOptions = list.filter(dept => dept.parentId === 100) // ... }) } ``` ## 九、相关规范 根据项目记忆: 1. **分公司数据加载规范**(memory: ba4557cf): - ✅ 调用 `/system/dept/list` 接口 - ✅ 传入 `parentId=100` 参数 - ✅ 获取 parent_id=100 的部门作为分公司列表 2. **急救转运任务车辆自动填充规则**(memory: eec5a112): - 车辆选择器必须加载当前用户所在分公司的所有车辆 - ✅ 本次修改确保了归属机构默认为用户分公司 - ✅ 地域过滤确保医院列表与分公司地域相关 ## 十、版本历史 - **2025-01-25 v1**: 初始版本 - ✅ 联系人字段设为必填 - ✅ 添加联系人必填验证 - ✅ 归属机构默认选中当前用户分公司 - ✅ 自动更新 selectedRegion - ✅ 优化 onLoad 方法,避免重复加载 - ✅ 添加调试日志