Comming

百度小程序省市区三级联动终极版

之前的那篇百度小程序三级联动的博客自认为写得不够好,比较偏理论,基本在讲picker组件中的各个参数的意思;这篇是在上一篇的基础上对三级联动重写了一遍,实现的效果要比上一篇好,还支持用户点击编辑收获地址的时候input框内显示省市区地址。

上篇的三级联动的省市区数据都是通过发送请求获取的,本篇的三级联动的数据都是使用本地文件里面的数据,具体看下面代码。

// 导入验证js
const app = getApp();
import WxValidate from "../../utils/WxValidate";
import { axios } from "../../utils/request";
import region from "../../utils/region";
import {
  setAddressList,
  getAddressList,
  setProvinceList,
  getProvinceList
} from "../../utils/storage";
import { showToast } from "../../utils/index";
Page({
  data: {
    multiIndex: [0, 0, 0], // 默认的下标    [省、市、区]
    step: 0, // 默认显示请选择
    // 设置默认收货地址按钮选中状态
    value: ""
  },
  onLoad() {
    // console.log("openid: ", app.globalData.openid);
    // 初始化表单验证规则
    this.initValidate();
    // 获取省的数据
    this.getProvince();
  },
  // 提交表单
  formSubmit(e) {
    if (this.data.step == 0) {
      swan.showToast({
        title: "请选择收货城市",
        icon: "none",
        duration: 4000,
        mask: false
      });
      return;
    }
    let params = e.detail.value;
    // console.log(params);
    // 省的名字
    let DeliveryName = this.data.provinceList[params["receivingAddress"][0]]
      .name;
    // 市的名字
    let CityName = this.data.cityList[params["receivingAddress"][1]].name;
    // 区的名字
    let storeName = this.data.storeList[params["receivingAddress"][2]].name;
    // 如果市和区名称相同就只市的名称
    let DeliveryAddress;
    (CityName == storeName) ? DeliveryAddress = DeliveryName + CityName : DeliveryAddress = DeliveryName + CityName + storeName;
    // console.log("DeliveryAddress是不是undefined", DeliveryAddress + params.CustomArea);
    // console.log("DeliveryAddress是不是undefined", DeliveryAddress + params.CustomArea);
    let storeNumber = params["receivingAddress"][2];
    let storeCode = this.data.storeList[storeNumber].code;
    if (!this.WxValidate.checkForm(params)) {
      //表单元素验证不通过,此处给出相应提示
      let error = this.WxValidate.errorList[0];
      this.showToast(error);
      return false;
    } else {
      // 构建请求数据结构
      let addressObj = {
        openid: app.globalData.openid,
        Name: params.Name,
        phone: params.phone,
        IsDefault: this.data.value,
        // 详细地址
        CustomArea: params.CustomArea,
        // 省市区+详细地址
        DeliveryAddress: DeliveryAddress + params.CustomArea,
        RegionCode: storeCode
      };
      // console.log("跳啊: ", addressObj);
      axios({
        url: "/api/Account/AddAddress",
        method: "POST",
        data: addressObj
      }, true)
        .then(res => {
          if (res.data.IsSuccess) {
            // 发送请求获取服务器数据库中最新的收货地址列表数据
            // app.getAddressList();
            // 直接存储新的数据
            setAddressList(res.data.ResultObject);
            // 跳转到我的收获地址页面
            swan.navigateBack({
              // url: "/pages/address/address",
              delta: 1,
              success: res => {
                // 添加成功
                showToast("添加收货地址成功");
              },
              fail: () => {
                // console.log("跳转失败,请重试!");
              }
            });
            let shopcar = res.data.ResultObject
            for (let i = 0, len = shopcar.length; i < len; i++) {
              if (shopcar[i].IsDefaultDelivery) {
                let currentMyress = {
                  name: shopcar[i].DeliveryConsignee, //地址名字
                  phone: shopcar[i].ConsigneePhone2, //地址电话
                  deliveryAddress: shopcar[i].DeliveryAddress, //地址
                  deliveryId: shopcar[i].DeliveryId, //地址id
                  IsDefaultDelivery: shopcar[i].IsDefaultDelivery//是否默认地址
                }
                swan.setStorageSync('currentMyress', currentMyress);
              }
            }


          } else {
            // 添加失败
            showToast(res.data.Msg);
          }
        })
        .catch(error => {
          // console.log(error);
        });
    }
  },
  // checkedbox状态改变
  checkboxChange(e) {
    const { value } = e.detail;
    // value是一个数组,如果length不等于0说明选中了
    value.length != 0
      ? this.setData({ value: "true" })
      : this.setData({ value: "false" });
  },

  /* 表单验证函数 */
  initValidate() {
    let rules = {
      Name: {
        required: true,
        maxlength: 10
      },
      phone: {
        required: true,
        tel: true
      },
      CustomArea: {
        required: true
      },
      receivingAddress: {
        required: true
      }
      /*       receivingAddressValue: {
        required: true
      } */
    };

    let message = {
      Name: {
        required: "请输入姓名",
        rangelength: "请输入2~4个汉字"
      },
      phone: {
        required: "请输入11位手机号码",
        tel: "请输入正确的手机号码"
      },
      CustomArea: {
        required: "请输入详细地址"
      },
      receivingAddress: {
        required: "请选择收货地区"
      },
      receivingAddressValue: {
        required: "必须选择收货地区"
      }
    };
    //实例化当前的验证规则和提示消息
    this.WxValidate = new WxValidate(rules, message);
  },

  // 错误消息提示框
  showToast(error) {
    swan.showToast({
      title: error.msg,
      icon: "none",
      duration: 2000,
      mask: false
    });
  },
  // 获取省的数据
  getProvince() {
    // 从本地的省市区文件中获取省数据
    let data = region.province;
    data.splice(31, 4);
    let provinceList = [...data]; // 将返回的数据放在一个数组里面,现在的数据结构是一个数组对象
    let provinceArr = data.map(item => {
      return item.name;
    });
    this.setData({
      multiArray: [provinceArr, [], []], // 更新三维数组
      provinceList, // 省原始数据
      provinceArr // 省级所有名称
    });
    let defaultCode = this.data.provinceList[0].code;
    this.setData({
      currentProviceKey: defaultCode // 保存当前省级的key(也就是code)
    });
    this.getCity(defaultCode); // 通过省级的code获取当前省级下面的市级数据
  },

  getCity(code) {
    // 获取市级的数据
    this.setData({
      currentProviceKey: code // 保存当前选择的市级code
    });
    // 先找到接收的code对应的市级数据
    let data = region.city.filter(item => {
      if (item.parentId == code) {
        return true;
      }
    });
    let cityList = [...data[0].list];
    let cityArr = [...data[0].list].map(item => {
      return item.name;
    })
    this.setData({
      multiArray: [this.data.provinceArr, cityArr, []], // 更新三维数组
      cityList, // 保存下市级所有数据
      cityArr
    });
    // console.log(this.data.multiArray);
    let defaultCode = this.data.cityList[0].code; // 用第一个code获取区数据
    this.setData({
      currentCityKey: defaultCode // 存下当前选择的城市的key
    });
    this.getStore(defaultCode);
  },

  getStore(code) {
    this.setData({
      // 获取区级数据
      currentCityKey: code // 更新当前选择的市级Key
    });
    let data = region.area.filter(item => {
      if (item.parentId == code) {
        return true;
      }
    });
    // console.log("store Data: ", data);
    let storeList = [...data[0].list];
    let storeArr = [...data[0].list].map(item => {
      return item.name;
    })
    // console.log("区数据 >", storeArr);
    this.setData({
      multiArray: [this.data.provinceArr, this.data.cityArr, storeArr], // 重新赋值三级数组
      storeList, // 保存区级原始数据
      storeArr
    });
  },

  columnchange(e) {
    // 滚动选择器触发的事件
    let column = e.detail.column; // column表示改变了第几列(下标从0开始)
    let value = e.detail.value; // value的值表示变更值得下标
    let multiIndex = JSON.parse(JSON.stringify(this.data.multiIndex));
    multiIndex[column] = e.detail.value; // 第几列改变了就是对应multiIndex的第几个,更新他
    switch (
    column // 处理不同的逻辑
    ) {
      case 0: // 第一列更改 就是省级的更改
        let currentProviceKey = this.data.provinceList[e.detail.value].code; // 重新赋值省级编号
        if (currentProviceKey != this.data.currentProviceKey) {
          // 判断当前key是不是正真的更新
          this.getCity(currentProviceKey); // 获取当前key下面的市级数据
        }
        multiIndex[1] = 0; // 将市默认选择第1个
        this.setData(multiIndex); // 更新数据
        break;

      case 1: // 市发生变化
        let currentCityKey = this.data.cityList[e.detail.value].code;
        // let currentCityParentCode = this.data.cityList[e.detail.value].ParentCode;
        if (currentCityKey != this.data.currentCityKey) {
          this.getStore(currentCityKey); // 获取区
        }
        multiIndex[2] = 0; // 区默认选择第一个
        this.setData(multiIndex); // 更新数据
        break;
    }
  },
  pickchange(e) {
    // console.log("value改变了...", e.detail.value);
    this.setData({
      step: 1, // 更新用于是否默认显示地区的状态值
      multiIndex: e.detail.value
    });
  }
});
addAddress.js

 

const app = getApp();
// 导入验证js
import WxValidate from "../../utils/WxValidate";
import { axios } from "../../utils/request";
import {
  getUserInfo,
  setUserInfo,
  setAddressList,
  getAddressList
} from "../../utils/storage";
import region from "../../utils/region";

Page({
  data: {
    multiArray: [], // 三维数组数据
    multiIndex: [0, 0, 0], // 默认的下标    [省、市、区]
    step: 0, // 默认显示请选择
    // 设置默认收货地址按钮选中状态
    value: "",
    DeliveryId: "",
    detailAddressInfo: {}
  },
  onLoad(params) {
    // 获取传递过来的数据并赋值
    const { DeliveryId } = params;
    this.setData({
      DeliveryId
    });
    this.getDetailAddressInfo();

    // 初始化表单验证规则
    this.initValidate();
    // 获取省的数据
  },
  // 提交表单
  formSubmit(e) {
    /*     if(this.data.step == 0){
      swan.showToast({
        title: '请选择收货城市',
        icon: "none",
        duration: 4000,
        mask: false
      });
      return;
    } */
    let params = e.detail.value;
    // 省的名字
    let DeliveryName = this.data.provinceList[params["receivingAddress"][0]].name;
    // 市的名字
    let CityName = this.data.cityList[params["receivingAddress"][1]].name;
    // 区的名字
    let storeName = this.data.storeList[params["receivingAddress"][2]].name;
    let DeliveryAddress;
    (CityName == storeName) ? DeliveryAddress = DeliveryName + CityName : DeliveryAddress = DeliveryName + CityName + storeName;
    let storeNumber = params["receivingAddress"][2];
    let storeCode = this.data.storeList[storeNumber].code;
    let DeliveryId = this.data.DeliveryId;
    if (!this.WxValidate.checkForm(params)) {
      //表单元素验证不通过,此处给出相应提示
      let error = this.WxValidate.errorList[0];
      this.showToast(error);
      return false;
    } else {
      // 构建请求数据结构
      let addressObj = {
        openid: app.globalData.openid,
        Name: params.Name,
        phone: params.phone,
        IsDefault: this.data.value,
        // 详细地址
        CustomArea: params.CustomArea,
        // 省市区+详细地址
        DeliveryAddress: DeliveryAddress + params.CustomArea,
        RegionCode: storeCode,
        DeliveryId
      };
      axios({
        url: "/api/Account/UpdateDelivery",
        method: "POST",
        data: addressObj
      })
        .then(res => {
          if (res.data.IsSuccess) {
            // 获取数据库最新数据
            app.getAddressList();
            // 跳转到我的收获地址页面
            swan.navigateBack({
              url: "/pages/address/address",
              delta: 1,
              success: res => {
                // 添加成功
                swan.showToast({
                  title: "修改收货地址成功",
                  icon: "none",
                  duration: 2000,
                  mask: false
                });
              },
              fail: () => {
                // console.log("跳转失败,请重试!");
              }
            });
          } else {
            // 添加失败
            this.showToast(res.data.Msg);
          }
        })
        .catch(error => {
          // console.log(error);
        });
    }
  },
  // checkedbox状态改变
  checkboxChange(e) {
    const { value } = e.detail;
    // value是一个数组,如果length不等于0说明选中了
    value.length != 0
      ? this.setData({ value: "true" })
      : this.setData({ value: "false" });
  },

  /* 表单验证函数 */
  initValidate() {
    let rules = {
      Name: {
        required: true,
        maxlength: 10
      },
      phone: {
        required: true,
        tel: true
      },
      CustomArea: {
        required: true
      },
      receivingAddress: {
        required: true
      }
    };

    let message = {
      Name: {
        required: "请输入姓名",
        rangelength: "请输入2~4个汉字个汉字"
      },
      phone: {
        required: "请输入11位手机号码",
        tel: "请输入正确的手机号码"
      },
      CustomArea: {
        required: "请输入详细地址"
      },
      receivingAddress: {
        required: "请选择收货地区"
      }
    };
    //实例化当前的验证规则和提示消息
    this.WxValidate = new WxValidate(rules, message);
  },

  // 错误消息提示框
  showToast(error) {
    swan.showToast({
      title: error.msg,
      icon: "none",
      duration: 4000,
      mask: false
    });
  },
  // 获取省的数据
  getProvince() {
    let data = region.province;
    data.splice(31, 4);
    let provinceList = [...data]; // 将返回的数据放在一个数组里面,现在的数据结构是一个数组对象
    let provinceArr = data.map(item => item.name); // 获取数据里面的value值,只用数据的名称
    this.setData({
      multiArray: [provinceArr, [], []], // 更新三维数组
      provinceList, // 省原始数据
      provinceArr // 省级所有名称
    });
    let defaultCode = this.data.provinceList[this.data.multiIndex[0]].code; // 使用第一项当做参数获取市级数据
    this.setData({
      currentProviceKey: defaultCode // 保存当前省级的key(也就是AreaCode)
    });
    this.getCity(defaultCode); // 通过省级的AreaCode获取当前省级下面的市级数据
  },

  getCity(code) {
    // 获取市级的数据
    this.setData({
      currentProviceKey: code // 保存当前选择的市级code
    });
    let data = region.city.filter(item => {
      if (item.parentId == code) {
        return true;
      }
    });
    let cityList = [...data[0].list];
    let cityArr = [...data[0].list].map(item => {
      return item.name;
    });
    this.setData({
      multiArray: [this.data.provinceArr, cityArr, []], // 更新三维数组
      cityArr, // 保存下市级所有名称
      cityList // 保存下市级所有数据
    });
    let defaultCode = this.data.cityList[this.data.multiIndex[1]].code; // 用第一个code获取区数据
    this.setData({
      currentCityKey: defaultCode // 存下当前选择的城市的key
    });
    // 通过市级的AreaCode获取当前市级下面的区级数据
    this.getStore(defaultCode);
  },

  getStore(code) {
    // 获取区级数据
    this.setData({
      currentCityKey: code // 更新当前选择的市级Key
    });
    // 处理直辖市和特殊的区,获取区的时候使用市的code   如果不是直辖市就通过市级的AreaCode获取当前市级下面的区级数据
    let data = region.area.filter(item => {
      if (item.parentId == code) {
        return true;
      }
    });
    let storeList = [...data[0].list];
    let storeArr = [...data[0].list].map(item => {
      return item.name;
    });
    this.setData({
      multiArray: [this.data.provinceArr, this.data.cityArr, storeArr], // 重新赋值三级数组
      storeList, // 保存区级原始数据
      storeArr // 保存区级名称
    });
  },

  columnchange(e) {
    // 滚动选择器触发的事件
    let column = e.detail.column; // column表示改变了第几列(下标从0开始)
    let value = e.detail.value; // value的值表示变更值得下标
    let multiIndex = JSON.parse(JSON.stringify(this.data.multiIndex));
    multiIndex[column] = e.detail.value; // 第几列改变了就是对应multiIndex的第几个,更新他
    switch (
      column // 处理不同的逻辑
    ) {
      case 0: // 第一列更改 就是省级的更改
        let currentProviceKey = this.data.provinceList[e.detail.value].code; // 重新赋值省级编号
        if (currentProviceKey != this.data.currentProviceKey) {
          // 判断当前key是不是正真的更新
          this.getCity(currentProviceKey); // 获取当前key下面的市级数据
        }
        multiIndex[1] = 0; // 将市默认选择第1个
        this.setData({ multiIndex }); // 更新数据
        break;

      case 1: // 市发生变化
        let currentCityKey = this.data.cityList[e.detail.value].code;
        if (currentCityKey != this.data.currentCityKey) {
          this.getStore(currentCityKey); // 获取区
        }
        multiIndex[2] = 0; // 区默认选择第一个
        this.setData({ multiIndex }); // 更新数据
        break;
    }
  },
  pickchange(e) {
    this.setData({
      step: 1, // 更新用于是否默认显示地区的状态值
      multiIndex: e.detail.value
    });
  },

  // 根据DeliveryId发请求获取收货地址详细信息
  getDetailAddressInfo() {
    const DeliveryId = this.data.DeliveryId;
    // 减少HTTP请求,降低渲染时间
    if (!this.data.detailAddressInfo.DeliveryId) {
      axios({
        url: "/api/Account/GetDeliveryById",
        method: "POST",
        data: {
          openid: app.globalData.openid,
          deliveryId: DeliveryId
        }
      })
        .then(res => {
          if (res.data.IsSuccess) {
            let detailAddressInfo = res.data.ResultObject;
            this.setData({
              detailAddressInfo
            });
            this.getDetailAddressInfoMethod();
          } else {
            swan.showToast({
              title: res.data.Msg,
              icon: "none",
              duration: 3000,
              mask: false
            });
          }
        })
        .catch(error => {
          // console.log(error);
        });
    }else {
      this.getDetailAddressInfoMethod();
    }
  },
  getDetailAddressInfoMethod() {
    let RegionCode = this.data.detailAddressInfo.RegionCode;
    // // 通过截取RegionCode查找省市级
    let code = RegionCode.slice(0, 2) + "0000";
    let provinceIndex = region.province.findIndex(item => item.code == code);

    // // 获取市的数据
    let cityCode = RegionCode.slice(0, 4) + "00";
    let cityName = region.city.filter(item => {
      return item.list.find(item2 => {
        return item2.code == cityCode;
      });
    });
    let cityIndex = cityName[0].list.findIndex(item => item.code == cityCode);

    // // 获取区的数据
    let storeCode = RegionCode;
    let storeName = region.area.filter(item => {
      return item.list.find(item2 => {
        return item2.code == storeCode;
      });
    });
    let storeIndex = storeName[0].list.findIndex(
      item => item.code == storeCode
    );
    this.setData(
      {
        multiIndex: [provinceIndex, cityIndex, storeIndex]
      },
      () => {
        this.getProvince();
      }
    );

    // 备份
    // let RegionCode = this.data.detailAddressInfo.RegionCode;
    // // 通过截取RegionCode查找省市级
    // let code = RegionCode.slice(0,2) + '0000';
    // let provinceName = region.province.filter(item=>{
    // return item.code == code;
    // });
    // provinceName = provinceName[0].name
    // // 获取市的数据
    // let cityCode = RegionCode.slice(0,4) + '00';
    // let cityName = region.city.filter(item=>{
    //   return item.list.find(item2=>{
    //     return item2.code == cityCode;
    //   });
    // })
    // cityName = cityName[0].list.filter(item=>{
    //   return item.code == cityCode;
    // })
    // cityName = cityName[0].name;
    // // 获取区的数据
    // let storeCode = RegionCode;
    // let storeName = region.area.filter(item=>{
    //   return item.list.find(item2=>{
    //     return item2.code == storeCode;
    //   });
    // })
    // storeName = storeName[0].list.filter(item=>{
    //   return item.code == storeCode;
    // })
    // storeName = storeName[0].name;
    // this.setData({
    //   multiArray: [[provinceName], [cityName], [storeName]]
    // })
  },
  pickClick(e) {
    this.getProvince();
  },
  pickCancel(e) {
    this.getDetailAddressInfo();
  }
});
editAddress.js

 

 编辑收获地址时获取当前地址的省市区的操作步骤是:

1.发请求拿到当前地址的信息,里面会包含一个regionCode,就是区的编号

2.通过对区的编号进行字符串截取得到市和省的编号,然后做把市很省的编号在文件里面做匹配,通过findIndex()函数找到当前对象所在数组中的下表

3.在初始函数 getDetailAddressInfoMethod中将上面三个编号所在数组对象中的index拿出来setData更新到multiIndex中即可

 

posted @ 2019-11-28 14:52  Sauron831  阅读(677)  评论(0编辑  收藏  举报