# 任务类型和单据类型默认选中功能说明 ## 功能概述 在创建急救转运任务页面中,**任务类型**和**单据类型**字段需要在数据加载完成后自动选中第一个选项,提升用户体验,避免用户遗漏这两个必填字段。 ## 实现位置 **前端文件**: `app/pages/task/create-emergency.vue` ## 业务背景 根据项目规范: - 任务类型和单据类型都是**必填字段** - 用户在创建任务时若未选择这两个字段,会导致表单验证失败 - 默认选中第一个选项可以: - 减少用户操作步骤 - 降低遗漏必填项的风险 - 提升表单填写效率 ## 技术实现 ### 1. 任务类型默认选中 修改 `loadEmergencyTaskTypes()` 方法,在加载数据成功后自动选中第一个: ```javascript loadEmergencyTaskTypes() { getServiceOrderTypes().then(response => { const list = response.data || [] this.emergencyTaskTypes = list this.emergencyTaskTypeOptions = list.map(item => ({ id: item.vID, text: item.vtext })) // 默认选中第一个任务类型 if (this.emergencyTaskTypeOptions.length > 0) { this.selectedEmergencyTaskType = this.emergencyTaskTypeOptions[0].text this.selectedEmergencyTaskTypeId = this.emergencyTaskTypeOptions[0].id console.log('默认选中任务类型:', this.selectedEmergencyTaskType) } }).catch(error => { console.error('加载任务类型失败:', error) this.emergencyTaskTypes = [] this.emergencyTaskTypeOptions = [] }) } ``` ### 2. 单据类型默认选中 修改 `loadDocumentTypes()` 方法,在加载数据成功后自动选中第一个: ```javascript loadDocumentTypes() { getServiceOrdAreaTypes().then(response => { const list = response.data || [] this.documentTypes = list this.documentTypeOptions = list.map(item => ({ id: item.vID, text: item.vtext })) // 默认选中第一个单据类型 if (this.documentTypeOptions.length > 0) { this.selectedDocumentType = this.documentTypeOptions[0].text this.selectedDocumentTypeId = this.documentTypeOptions[0].id console.log('默认选中单据类型:', this.selectedDocumentType) } }).catch(error => { console.error('加载单据类型失败:', error) this.documentTypes = [] this.documentTypeOptions = [] }) } ``` ### 3. 模板部分 picker组件通过双向绑定显示选中的值: ```vue 任务类型 {{ selectedEmergencyTaskType || '请选择任务类型' }} 单据类型 {{ selectedDocumentType || '请选择单据类型' }} ``` ## 工作流程 ### 页面加载流程 ``` 页面加载 (onLoad) ↓ 调用 loadEmergencyTaskTypes() ↓ 从 SQL Server 加载任务类型列表 ↓ 数据加载成功 ↓ 检查列表长度 > 0 ↓ 设置 selectedEmergencyTaskType = 第一项的text 设置 selectedEmergencyTaskTypeId = 第一项的id ↓ UI 自动更新,显示选中的任务类型 ``` 单据类型的流程相同。 ### 用户交互流程 1. **页面初始化**: - 任务类型和单据类型都自动选中第一个选项 - 用户可以看到已有默认值 2. **用户修改**: - 用户点击picker,可以重新选择其他选项 - 选择后触发 `onEmergencyTaskTypeChange` 或 `onDocumentTypeChange` - 更新选中的值 3. **表单提交**: - 因为已有默认值,必填验证更容易通过 - 提交时使用 `selectedEmergencyTaskTypeId` 和 `selectedDocumentTypeId` ## 数据结构 ### 任务类型数据(来自 SQL Server - dictionary 表) **查询条件**: `vtitle='ServiceOrderType' AND vType>=1` ```javascript emergencyTaskTypeOptions: [ { id: 1, // vID - 任务类型ID text: "急救转运" // vtext - 任务类型名称 }, { id: 2, text: "院间转运" } // ... ] // 选中的值 selectedEmergencyTaskType: "急救转运" // 第一个的text selectedEmergencyTaskTypeId: 1 // 第一个的id ``` ### 单据类型数据(来自 SQL Server - dictionary 表) **查询条件**: `vtitle='ServiceOrdAreaType' AND vType>=1` ```javascript documentTypeOptions: [ { id: 1, // vID - 单据类型ID text: "本地单" // vtext - 单据类型名称 }, { id: 2, text: "外地单" } // ... ] // 选中的值 selectedDocumentType: "本地单" // 第一个的text selectedDocumentTypeId: 1 // 第一个的id ``` ## 相关接口 ### 任务类型接口 **API**: `GET /api/dictionary/service-order-types` **后端方法**: `getServiceOrderTypes()` **数据源**: SQL Server - `dictionary` 表 **查询条件**: ```sql SELECT vID, vtext FROM dictionary WHERE vtitle = 'ServiceOrderType' AND vType >= 1 ORDER BY vID ``` ### 单据类型接口 **API**: `GET /api/dictionary/service-ord-area-types` **后端方法**: `getServiceOrdAreaTypes()` **数据源**: SQL Server - `dictionary` 表 **查询条件**: ```sql SELECT vID, vtext FROM dictionary WHERE vtitle = 'ServiceOrdAreaType' AND vType >= 1 ORDER BY vID ``` ## 异常处理 ### 1. 数据加载失败 ```javascript .catch(error => { console.error('加载任务类型失败:', error) this.emergencyTaskTypes = [] this.emergencyTaskTypeOptions = [] }) ``` **表现**: - 选项列表为空 - picker显示"请选择任务类型" - 不会自动选中任何值 ### 2. 数据为空 ```javascript if (this.emergencyTaskTypeOptions.length > 0) { // 只有在有数据时才设置默认值 } ``` **表现**: - 不设置默认值 - picker保持空状态 - 用户需要手动选择(但没有可选项) ### 3. 用户手动清空选择 虽然picker组件不支持清空操作,但逻辑上考虑: - 用户可以重新选择其他选项 - 必填验证会在提交时检查是否有值 ## 必填验证 在表单提交时,需要验证这两个字段: ```javascript submitTask() { // 验证任务类型 if (!this.selectedEmergencyTaskTypeId) { uni.showToast({ title: '请选择任务类型', icon: 'none' }) return } // 验证单据类型 if (!this.selectedDocumentTypeId) { uni.showToast({ title: '请选择单据类型', icon: 'none' }) return } // ... 继续提交逻辑 } ``` ## 优化建议 ### 1. 智能默认选择 根据历史数据或使用频率,选择最常用的类型作为默认值: ```javascript // 示例:优先选择"急救转运" if (this.emergencyTaskTypeOptions.length > 0) { const defaultType = this.emergencyTaskTypeOptions.find(t => t.text === '急救转运') if (defaultType) { this.selectedEmergencyTaskType = defaultType.text this.selectedEmergencyTaskTypeId = defaultType.id } else { // 如果没有找到,选择第一个 this.selectedEmergencyTaskType = this.emergencyTaskTypeOptions[0].text this.selectedEmergencyTaskTypeId = this.emergencyTaskTypeOptions[0].id } } ``` ### 2. 用户偏好记忆 记住用户上次选择的类型,下次自动选中: ```javascript // 加载用户偏好 const lastTaskType = uni.getStorageSync('lastTaskType') if (lastTaskType && this.emergencyTaskTypeOptions.some(t => t.id === lastTaskType)) { const selected = this.emergencyTaskTypeOptions.find(t => t.id === lastTaskType) this.selectedEmergencyTaskType = selected.text this.selectedEmergencyTaskTypeId = selected.id } else { // 使用默认第一个 this.selectedEmergencyTaskType = this.emergencyTaskTypeOptions[0].text this.selectedEmergencyTaskTypeId = this.emergencyTaskTypeOptions[0].id } // 保存用户选择 onEmergencyTaskTypeChange(e) { const index = e.detail.value const selected = this.emergencyTaskTypeOptions[index] this.selectedEmergencyTaskType = selected.text this.selectedEmergencyTaskTypeId = selected.id // 记住用户偏好 uni.setStorageSync('lastTaskType', selected.id) } ``` ### 3. 根据归属机构自动选择 不同分公司可能有不同的常用类型: ```javascript loadEmergencyTaskTypes() { getServiceOrderTypes().then(response => { const list = response.data || [] this.emergencyTaskTypeOptions = list.map(item => ({ id: item.vID, text: item.vtext })) // 根据分公司设置默认类型 const branchDefaults = { '广州分公司': '院间转运', '深圳分公司': '急救转运' } const defaultText = branchDefaults[this.currentUser.branchCompanyName] if (defaultText) { const defaultType = this.emergencyTaskTypeOptions.find(t => t.text === defaultText) if (defaultType) { this.selectedEmergencyTaskType = defaultType.text this.selectedEmergencyTaskTypeId = defaultType.id return } } // 如果没有配置或找不到,使用第一个 if (this.emergencyTaskTypeOptions.length > 0) { this.selectedEmergencyTaskType = this.emergencyTaskTypeOptions[0].text this.selectedEmergencyTaskTypeId = this.emergencyTaskTypeOptions[0].id } }) } ``` ## 调试日志 功能包含调试日志,便于排查问题: ```javascript console.log('默认选中任务类型:', this.selectedEmergencyTaskType) console.log('默认选中单据类型:', this.selectedDocumentType) ``` 在开发环境可以看到: ``` 默认选中任务类型: 急救转运 默认选中单据类型: 本地单 ``` ## 相关规范 根据项目规范记忆: 1. **任务类型必填校验**(memory: 03ff216f): - 急救转运任务创建时,任务类型字段必须进行非空校验 - 未选择时应阻止表单提交并提示用户 - ✅ 默认选中第一个可以降低遗漏风险 2. **单据类型必填校验**(memory: d58c004f): - 急救转运任务创建时,单据类型字段必须进行非空校验 - 未选择时应阻止表单提交并提示用户 - ✅ 默认选中第一个可以降低遗漏风险 ## 测试建议 ### 测试场景1:正常加载 **操作**: 1. 打开创建急救转运任务页面 2. 等待数据加载完成 **预期结果**: - 任务类型字段显示第一个选项的文本(如"急救转运") - 单据类型字段显示第一个选项的文本(如"本地单") - 控制台输出默认选中日志 ### 测试场景2:数据为空 **操作**: 1. 模拟后端返回空数组 2. 打开页面 **预期结果**: - 任务类型和单据类型都显示"请选择..." - 不会报错 - 用户无法选择(因为没有选项) ### 测试场景3:用户重新选择 **操作**: 1. 页面加载后,默认选中第一个 2. 用户点击picker,选择其他选项 **预期结果**: - 显示更新为用户选择的选项 - `selectedEmergencyTaskTypeId` 更新为新选项的ID - 提交时使用新选择的值 ### 测试场景4:表单提交验证 **操作**: 1. 页面加载后有默认值 2. 填写其他必填字段 3. 点击提交 **预期结果**: - 任务类型和单据类型验证通过 - 不会提示"请选择任务类型"或"请选择单据类型" - 使用默认选中的ID提交数据 ## 版本历史 - **2025-01-25 v1**: 初始版本,实现任务类型和单据类型默认选中功能 - 在 `loadEmergencyTaskTypes()` 中添加默认选中逻辑 - 在 `loadDocumentTypes()` 中添加默认选中逻辑 - 添加调试日志输出 - 添加数组长度检查,避免空数组错误