# 省市区选择器功能说明 ## 功能描述 在创建处方业务订单时,添加省市区级联选择器,方便用户选择收货地址的省市区信息。 ## 修改内容 ### 1. 表单界面(admin/src/views/consumer/prescription/index.vue) #### 添加省市区选择器(第 792-810 行) ```vue ``` **组件配置说明:** - `v-model="createOrderForm.region"`:绑定选中的省市区数组 - `:options="regionOptions"`:省市区数据源 - `value: 'name'`:使用 name 字段作为值 - `label: 'name'`:使用 name 字段作为显示文本 - `emitPath: false`:只返回最后一级的值(区/县) - `checkStrictly: false`:必须选择到最后一级 - `clearable`:可清空 - `filterable`:可搜索 ### 2. 数据模型更新(第 1175-1195 行) ```typescript const createOrderForm = reactive({ patient_id: '' as number | string, recipient_name: '', recipient_phone: '', region: [] as string[], // 新增:省市区数组 shipping_address: '', // 改为详细地址 // ... 其他字段 }) ``` ### 3. 省市区数据(第 1195-1340 行) 添加了常用省市区数据: - 四川省(成都市、绵阳市) - 北京市 - 上海市 - 广东省(广州市、深圳市) ```typescript const regionOptions = ref([ { name: '四川省', children: [ { name: '成都市', children: [ { name: '锦江区' }, { name: '青羊区' }, // ... 更多区县 ] } ] }, // ... 更多省份 ]) ``` ### 4. 事件处理方法 ```typescript const handleRegionChange = (value: string[]) => { console.log('选择的省市区:', value) } ``` ## 使用说明 ### 用户操作流程 1. 点击"创建业务订单"按钮 2. 选择诊单患者 3. 填写收货人和收货手机 4. **点击"省市区"选择器** 5. 依次选择:省 → 市 → 区/县 6. 在"详细地址"中填写街道、门牌号等信息 7. 填写其他订单信息 8. 提交订单 ### 界面效果 **编辑时:** ``` ┌─────────────────────────────────────────────────┐ │ 收货人: [张三] 收货手机: [138****0000] │ ├─────────────────────────────────────────────────┤ │ 省市区: [四川省 / 成都市 / 双流区 ▼] │ ├─────────────────────────────────────────────────┤ │ 详细地址: │ │ ┌─────────────────────────────────────────────┐ │ │ │ 黄甲街道黄龙大道二段280号 │ │ │ └─────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────┘ ``` **完整地址组合:** ``` 四川省成都市双流区黄甲街道黄龙大道二段280号 ``` ## 后端支持 ### 数据库字段建议 如果需要单独存储省市区信息,可以添加以下字段: ```sql -- 在 prescription_order 表中添加省市区字段 ALTER TABLE `zyt_prescription_order` ADD COLUMN `province` VARCHAR(50) DEFAULT '' COMMENT '省份' AFTER `recipient_phone`, ADD COLUMN `city` VARCHAR(50) DEFAULT '' COMMENT '城市' AFTER `province`, ADD COLUMN `district` VARCHAR(50) DEFAULT '' COMMENT '区/县' AFTER `city`; -- 或者保持现有的 shipping_address 字段,前端组合完整地址 ``` ### 后端 API 修改 #### 方案 A:前端组合完整地址(推荐) 前端在提交时将省市区和详细地址组合: ```typescript const submitOrder = async () => { const fullAddress = createOrderForm.region.join('') + createOrderForm.shipping_address await createPrescriptionOrder({ ...createOrderForm, shipping_address: fullAddress // 四川省成都市双流区黄甲街道... }) } ``` #### 方案 B:分别存储省市区 后端接收独立的省市区字段: ```php // 创建订单时 $order->province = $params['province'] ?? ''; $order->city = $params['city'] ?? ''; $order->district = $params['district'] ?? ''; $order->shipping_address = $params['shipping_address'] ?? ''; // 查询时返回 return [ 'province' => $order->province, 'city' => $order->city, 'district' => $order->district, 'shipping_address' => $order->shipping_address, 'full_address' => $order->province . $order->city . $order->district . $order->shipping_address ]; ``` ## 扩展功能 ### 1. 使用完整的省市区数据 当前只包含了部分常用省市区,实际项目中应该使用完整的数据。 **方案 A:使用 npm 包** ```bash npm install element-china-area-data ``` ```typescript import { regionData } from 'element-china-area-data' const regionOptions = ref(regionData) ``` **方案 B:从后端 API 获取** ```typescript import { getRegionTree } from '@/api/common' const regionOptions = ref([]) onMounted(async () => { const res = await getRegionTree() regionOptions.value = res.data }) ``` ### 2. 自动填充历史地址 根据患者历史订单自动填充地址: ```typescript const loadPatientLastAddress = async (patientId: number) => { const res = await getPatientLastOrder(patientId) if (res.data) { createOrderForm.region = [res.data.province, res.data.city, res.data.district] createOrderForm.shipping_address = res.data.detail_address createOrderForm.recipient_name = res.data.recipient_name createOrderForm.recipient_phone = res.data.recipient_phone } } ``` ### 3. 地址簿功能 保存常用地址,快速选择: ```vue ``` ### 4. 地址验证 验证地址的完整性和合法性: ```typescript const validateAddress = () => { if (createOrderForm.region.length !== 3) { feedback.msgError('请选择完整的省市区') return false } if (!createOrderForm.shipping_address.trim()) { feedback.msgError('请填写详细地址') return false } return true } ``` ## 注意事项 1. **数据格式**: - `region` 是数组:`['四川省', '成都市', '双流区']` - 提交时需要组合成完整地址字符串 2. **必填验证**: - 省市区选择器应该设置为必填 - 详细地址也应该必填 3. **字符限制**: - 详细地址限制 200 字符 - 建议省市区 + 详细地址总长度不超过 250 字符 4. **兼容性**: - 兼容现有的 `shipping_address` 字段 - 旧数据可能没有省市区信息,需要做好兼容处理 5. **性能优化**: - 省市区数据较大时,考虑懒加载 - 使用虚拟滚动优化长列表 ## 表单验证规则 更新验证规则: ```typescript const createOrderRules: FormRules = { // ... 其他规则 region: [ { required: true, message: '请选择省市区', trigger: 'change', validator: (rule, value, callback) => { if (!value || value.length !== 3) { callback(new Error('请选择完整的省市区')) } else { callback() } } } ], shipping_address: [ { required: true, message: '请输入详细地址', trigger: 'blur' }, { min: 5, message: '详细地址至少5个字符', trigger: 'blur' } ] } ``` ## 测试要点 ### 前端测试 1. ✅ 省市区选择器显示正常 2. ✅ 可以正常选择省市区 3. ✅ 搜索功能正常 4. ✅ 清空功能正常 5. ✅ 必填验证正常 6. ✅ 数据绑定正确 ### 集成测试 1. ✅ 创建订单 → 选择省市区 → 填写详细地址 → 提交成功 2. ✅ 查看订单 → 地址显示完整 3. ✅ 编辑订单 → 省市区回显正确 4. ✅ 打印订单 → 地址格式正确 ## 完成状态 - ✅ 前端界面添加完成 - ✅ 数据模型更新完成 - ✅ 省市区数据添加完成(简化版) - ✅ 事件处理方法添加完成 - ⏳ 等待完整省市区数据集成 - ⏳ 等待后端 API 支持 - ⏳ 等待表单验证规则更新 ## 相关文件 - `admin/src/views/consumer/prescription/index.vue` - 处方订单列表页面 - 后端需要修改的文件(待确认): - 订单模型文件 - 订单控制器文件 - 数据库迁移文件(如果需要单独存储省市区)