ThinkPHP + uni-app + uni-data-picker
环境
ThinkPHP版本:3.2.3
PHP版本:5.6
vue版本: vue3
数据库:MySQL5.7.40
省市区数据源
数据源giteee(json文件):city-china.json
数据库设计
1.uni-app的uni-data-picker每项数据之多只需要3个key:text,value,children
2.JSON文件与上下级关联的主要是code和parent_code,数据库可以从简设计
3.将数据保存至数据库,不需要每次都遍历一次JSON数组,消耗性能,同时分级查询省市区逻辑更清晰
数据库
省/直辖市
省/直辖市 的数据库只需要设计id,text,value,code四项就可以了,其中id主键
CREATE TABLE `你的数据库名`.`province_data` (
`id` INT(11) NOT NULL AUTO_INCREMENT ,
`text` VARCHAR(255) NOT NULL ,
`value` VARCHAR(255) NOT NULL ,
`code` VARCHAR(255) NOT NULL , PRIMARY KEY (`id`)
);
市、区/县
市、区/县属于次级,数据库设计可以完全相同,但要记得做完事是3个数据表
CREATE TABLE `你的数据库名`.`city_data` (
`id` INT(11) NOT NULL AUTO_INCREMENT ,
`text` VARCHAR(255) NOT NULL ,
`value` VARCHAR(255) NOT NULL ,
`parent_code` VARCHAR(255) NOT NULL ,
`code` VARCHAR(255) NOT NULL , PRIMARY KEY (`id`)
);
ThinkPHP后端控制器
文件处理
将下载的data.json文件放在网站根目录下的随意文件夹内,我这边改名为city-china.json;
处理完成后可以将initCityData()在页面返回的JSON字符串保存下来,不再经过数据库
数据库在处理完JSON文件后的功能就是为前端所选的code匹配地名
public function execSaveCityData()
{
$file = json_decode(file_get_contents('./Uploads/documents/city-china.json'),true);
foreach ($file as $k => $v) {
// 处理数据,对齐到数据库列表
$data = array(
'code' => $v['code'],
'text' => $v['name'],
'value' => $v['code'],
'parent_code' => $v['parent_code']
);
// 后四位为0 省/直辖市
if (substr($v['code'],2,4)=='0000'){
unset($data['parent_code']);
M('province_data')->add($data);
// parent_id后4位为0 直辖市/市
}elseif (substr($v['parent_code'],2,4) == '0000'){
M('city_data')->add($data);
// parent_id后2位为0 区/县
}elseif (substr($v['parent_code'],4,2) == '00'){
M('country_data')->add($data);
}
}
}
public function initCityData()
{
if (IS_POST){
// 获取第一层 省/直辖市 的列表
$cityData = M('province_data')
->field('id,text,value,code')
->order('code asc')
->select();
foreach ($cityData as $k => $v) {
// 获取第二层 市 的列表,绑定到相关联的 省/直辖市
$cityData[$k]['children'] = M('city_data')
->field('id,text,value,code,parent_code')
->where(array('parent_code' => $v['code']))
->order('code asc')
->select();
// 获取第三层 区/县 的列表,绑定到相关联的 市
foreach ($cityData[$k]['children'] as $kk => $vv) {
$cityData[$k]['children'][$kk]['children'] = M('country_data')
->field('id,text,value,code,parent_code')
->where(array('parent_code' => $vv['code']))
->order('code asc')
->select();
}
}
// 返回已经处理完毕的 三级联动数据
$this->ajaxReturn(array('city-china' => $cityData));
}
}
// 提交地址处理 省市区/县 方法
public function subAddress()
{
if (IS_POST){
$data = I('post.');
// 取前2位补0满6位,即是所选区/县的省/直辖市
$data['s_province'] = M('province_data')
->where(array('code' => substr($data['province'],0,2) . '0000'))
->getField('text');
// 取前4位补0满6位,即是所选区/县的市/直辖市
$data['s_city'] = M('city_data')
->where(array('code' => substr($data['province'],0,4) . '00'))
->getField('text');
// 直接查询区/县的code
$data['s_country'] = M('country_data')
->where(array('code' => $data['province']))
->getField('text');
// 其它业务代码
// ……
}
}
// 这个是确认地址选择功能没有问题,保存返回的JSON文件字符串
// 使用postman或者在浏览器内获取,浏览器需要屏蔽掉 if (IS_POST)
// 我这边将保存后的JSON文件命名为area_data.json
public function area_data()
{
if (IS_POST){
$this->ajaxReturn(json_decode(file_get_contents('./Uploads/documents/area_data.json'),true));
}
}
uni-app部分代码
注意要在HBuilder X项目内导入uni-data-picker插件,导入并编辑后,如果不显示请重新编译一下
<template>
<view>
<uni-data-picker
:localdata="localData"
placeholder="请选择居住地址"
v-model="address"
>
</uni-data-picker>
</view>
</template>
<script>
export default {
data() {
return {
localData: [],
// 最终保存的是区/县的code
address: ''
}
},
onLoad() {
uni.request({
// 这里是举例的接口地址,请修改为自己的网站
url: 'https://yourapi.com/Home/Controller/initCityData',
method: 'POST',
dataType: 'json',
success: (res) => {
console.log(res.data);
this.localData = res.data['city-china'];
}
});
},
methods: {
}
}
</script>
<style>
</style>
微信小程序截图: