Files
zyt/REGION_SELECTOR_FEATURE.md
T
2026-04-15 16:31:25 +08:00

10 KiB
Raw Blame History

省市区选择器功能说明

功能描述

在创建处方业务订单时,添加省市区级联选择器,方便用户选择收货地址的省市区信息。

修改内容

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)
}

使用说明

用户操作流程

  1. 点击"创建业务订单"按钮
  2. 选择诊单患者
  3. 填写收货人和收货手机
  4. 点击"省市区"选择器
  5. 依次选择:省 → 市 → 区/县
  6. 在"详细地址"中填写街道、门牌号等信息
  7. 填写其他订单信息
  8. 提交订单

界面效果

编辑时:

┌─────────────────────────────────────────────────┐
│ 收货人: [张三]          收货手机: [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
}

注意事项

  1. 数据格式

    • region 是数组:['四川省', '成都市', '双流区']
    • 提交时需要组合成完整地址字符串
  2. 必填验证

    • 省市区选择器应该设置为必填
    • 详细地址也应该必填
  3. 字符限制

    • 详细地址限制 200 字符
    • 建议省市区 + 详细地址总长度不超过 250 字符
  4. 兼容性

    • 兼容现有的 shipping_address 字段
    • 旧数据可能没有省市区信息,需要做好兼容处理
  5. 性能优化

    • 省市区数据较大时,考虑懒加载
    • 使用虚拟滚动优化长列表

表单验证规则

更新验证规则:

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 - 处方订单列表页面
  • 后端需要修改的文件(待确认):
    • 订单模型文件
    • 订单控制器文件
    • 数据库迁移文件(如果需要单独存储省市区)