10 KiB
10 KiB
省市区选择器功能说明
功能描述
在创建处方业务订单时,添加省市区级联选择器,方便用户选择收货地址的省市区信息。
修改内容
1. 表单界面(admin/src/views/consumer/prescription/index.vue)
添加省市区选择器(第 792-810 行)
<el-col :span="12">
<el-form-item label="收货手机" prop="recipient_phone">
<el-input v-model="createOrderForm.recipient_phone" placeholder="用于物流联系" maxlength="20" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="省市区" prop="region">
<el-cascader
v-model="createOrderForm.region"
:options="regionOptions"
:props="{ value: 'name', label: 'name', children: 'children', emitPath: false, checkStrictly: false }"
placeholder="请选择省/市/区"
clearable
filterable
class="w-full"
@change="handleRegionChange"
/>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="详细地址" prop="shipping_address">
<el-input
v-model="createOrderForm.shipping_address"
type="textarea"
:rows="2"
placeholder="请输入街道、门牌号等详细地址"
maxlength="200"
show-word-limit
/>
</el-form-item>
</el-col>
组件配置说明:
v-model="createOrderForm.region":绑定选中的省市区数组:options="regionOptions":省市区数据源value: 'name':使用 name 字段作为值label: 'name':使用 name 字段作为显示文本emitPath: false:只返回最后一级的值(区/县)checkStrictly: false:必须选择到最后一级clearable:可清空filterable:可搜索
2. 数据模型更新(第 1175-1195 行)
const createOrderForm = reactive({
patient_id: '' as number | string,
recipient_name: '',
recipient_phone: '',
region: [] as string[], // 新增:省市区数组
shipping_address: '', // 改为详细地址
// ... 其他字段
})
3. 省市区数据(第 1195-1340 行)
添加了常用省市区数据:
- 四川省(成都市、绵阳市)
- 北京市
- 上海市
- 广东省(广州市、深圳市)
const regionOptions = ref([
{
name: '四川省',
children: [
{
name: '成都市',
children: [
{ name: '锦江区' },
{ name: '青羊区' },
// ... 更多区县
]
}
]
},
// ... 更多省份
])
4. 事件处理方法
const handleRegionChange = (value: string[]) => {
console.log('选择的省市区:', value)
}
使用说明
用户操作流程
- 点击"创建业务订单"按钮
- 选择诊单患者
- 填写收货人和收货手机
- 点击"省市区"选择器
- 依次选择:省 → 市 → 区/县
- 在"详细地址"中填写街道、门牌号等信息
- 填写其他订单信息
- 提交订单
界面效果
编辑时:
┌─────────────────────────────────────────────────┐
│ 收货人: [张三] 收货手机: [138****0000] │
├─────────────────────────────────────────────────┤
│ 省市区: [四川省 / 成都市 / 双流区 ▼] │
├─────────────────────────────────────────────────┤
│ 详细地址: │
│ ┌─────────────────────────────────────────────┐ │
│ │ 黄甲街道黄龙大道二段280号 │ │
│ └─────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────┘
完整地址组合:
四川省成都市双流区黄甲街道黄龙大道二段280号
后端支持
数据库字段建议
如果需要单独存储省市区信息,可以添加以下字段:
-- 在 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:前端组合完整地址(推荐)
前端在提交时将省市区和详细地址组合:
const submitOrder = async () => {
const fullAddress = createOrderForm.region.join('') + createOrderForm.shipping_address
await createPrescriptionOrder({
...createOrderForm,
shipping_address: fullAddress // 四川省成都市双流区黄甲街道...
})
}
方案 B:分别存储省市区
后端接收独立的省市区字段:
// 创建订单时
$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 包
npm install element-china-area-data
import { regionData } from 'element-china-area-data'
const regionOptions = ref(regionData)
方案 B:从后端 API 获取
import { getRegionTree } from '@/api/common'
const regionOptions = ref([])
onMounted(async () => {
const res = await getRegionTree()
regionOptions.value = res.data
})
2. 自动填充历史地址
根据患者历史订单自动填充地址:
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. 地址簿功能
保存常用地址,快速选择:
<el-select v-model="selectedAddressId" placeholder="选择常用地址" @change="fillAddress">
<el-option
v-for="addr in addressBook"
:key="addr.id"
:label="`${addr.name} ${addr.phone} ${addr.full_address}`"
:value="addr.id"
/>
</el-select>
4. 地址验证
验证地址的完整性和合法性:
const validateAddress = () => {
if (createOrderForm.region.length !== 3) {
feedback.msgError('请选择完整的省市区')
return false
}
if (!createOrderForm.shipping_address.trim()) {
feedback.msgError('请填写详细地址')
return false
}
return true
}
注意事项
-
数据格式:
region是数组:['四川省', '成都市', '双流区']- 提交时需要组合成完整地址字符串
-
必填验证:
- 省市区选择器应该设置为必填
- 详细地址也应该必填
-
字符限制:
- 详细地址限制 200 字符
- 建议省市区 + 详细地址总长度不超过 250 字符
-
兼容性:
- 兼容现有的
shipping_address字段 - 旧数据可能没有省市区信息,需要做好兼容处理
- 兼容现有的
-
性能优化:
- 省市区数据较大时,考虑懒加载
- 使用虚拟滚动优化长列表
表单验证规则
更新验证规则:
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' }
]
}
测试要点
前端测试
- ✅ 省市区选择器显示正常
- ✅ 可以正常选择省市区
- ✅ 搜索功能正常
- ✅ 清空功能正常
- ✅ 必填验证正常
- ✅ 数据绑定正确
集成测试
- ✅ 创建订单 → 选择省市区 → 填写详细地址 → 提交成功
- ✅ 查看订单 → 地址显示完整
- ✅ 编辑订单 → 省市区回显正确
- ✅ 打印订单 → 地址格式正确
完成状态
- ✅ 前端界面添加完成
- ✅ 数据模型更新完成
- ✅ 省市区数据添加完成(简化版)
- ✅ 事件处理方法添加完成
- ⏳ 等待完整省市区数据集成
- ⏳ 等待后端 API 支持
- ⏳ 等待表单验证规则更新
相关文件
admin/src/views/consumer/prescription/index.vue- 处方订单列表页面- 后端需要修改的文件(待确认):
- 订单模型文件
- 订单控制器文件
- 数据库迁移文件(如果需要单独存储省市区)