微信小程序开发(四)公司营业网点列表

wxml 部分

本页面的功能是从云数据库中获取公司网点的名称、地址、经纬度信息、电话等,并将其展示到前端页面。wxml 部分没有太多复杂的场景,只是简单的样式堆砌,附代码:

<view class="container">
	<view class='address-item' wx:for="{{newArray}}" wx:key="index">
		<view class='address-text'>
			<text class='address-text-title'>{{item.name}}<text class='address-text-distance'> -- 距离{{item.distance}}km</text></text>
			<text class='address-text-subtitle'>{{item.address}}</text>
		</view>
		
		<view class='img-container' bindtap="onCallingTapped" data-id="{{item._id}}">
			<image class='img' src='../../images/mypage_companies_phone.svg'></image>
		</view>

		<view class='img-container' bindtap="onLocatingTapped" data-id="{{item._id}}">
			<image class='img' src='../../images/mypage_companies_location.svg'></image>
		</view>
	</view>
</view>

js 部分

第一步需要先从云数据库中取出所有数据并存入 data 字段的数组中。代码如下:

// 获取公司列表
getData: function() {
	return new Promise((resolve, reject) => {
		this.getListCount().then(res => {
			let count = res
			let list = []
			for (let i = 0; i < count; i += 20) {
				this.getListIndexSkip(i).then(res => {
					list = list.concat(res)
					if (list.length == count) 
						resolve(list)
				})
			}
		})
	})
},

// 获取公司列表长度
getListCount: function() {
	return new Promise((resolve, reject) => {
		db.collection('Mypage_Companies').count().then(res => {
			resolve(res.total)
		})
	})
},

// 从第skip个位置开始获取20个列表记录
getListIndexSkip: function(skip) {
	return new Promise((resolve, reject) => {
		db.collection('Mypage_Companies').skip(skip).get().then(res => {
			resolve(res.data)
		})
	})
},

需要注意的是,这里的 db.collection().get() 是异步调用的方法,所以如果希望获取到所有数据之后再执行计算或者排序,就得用 awake 关键字或者 Promise 风格来写代码。此处我采用的是 Promise 方法,因为小程序默认不支持 awake,除非开启增强编译。Promise 方法用 resolve 来返回需要返回的内容,会等到 resolve 中的变量已经生成完全后再返回到调用处,这样我们就通过循环获取到了数据库中的所有公司记录。

第二步是计算当前位置到每个网点的地理距离:

// 计算距离并根据距离排序
calculateDistanceAndSort: function(objectArray) {
	var that = this;
	wx.getLocation({
		type: 'gcj02',
		success: function(res) {
			for (var i = 0; i < objectArray.length; i++) {
				objectArray[i].distance = Number(that.distance(res.latitude, res.longitude, objectArray[i].location.latitude, objectArray[i].location.longitude))
			}
			that.setData({
				objectArray: objectArray
			})
			that.newArray()
		}
	})
},

// 由经纬度计算两点之间的距离,la为纬度latitude缩写,lo为经度longitude的缩写
distance: function(la1, lo1, la2, lo2) {
      var La1 = la1 * Math.PI / 180.0;
      var La2 = la2 * Math.PI / 180.0;
      var La3 = La1 - La2;
      var Lb3 = lo1 * Math.PI / 180.0 - lo2 * Math.PI / 180.0;

      var s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(La3 / 2), 2) + Math.cos(La1) * Math.cos(La2) * Math.pow(Math.sin(Lb3 / 2), 2)));
      s = s * 6378.137;
      s = Math.round(s * 10000) / 10000;
      s = s.toFixed(2);
      return s;
},

这里借助了一个计算地球上两个经纬度之间距离的函数,从云数据库中取出来经纬度信息后拿进来算一算,再把算出来的结果赋给数组中对应公司的 distance 属性,然后调用 newArray() 方法根据距离远近进行排序,排序算法不再赘述。

最后一步是绑定电话和定位两个事件:

// 处理电话事件
onCallingTapped: function(e) {
	let id = e.currentTarget.dataset.id
	db.collection('Mypage_Companies').doc(id).get().then(res => {
		let phone = res.data.phone
		wx.showModal({
			title: '提示',
			content: '拨打电话:' + phone + '?',
			success: function(res) {
				if (res.confirm) {
					wx.makePhoneCall({
						phoneNumber: phone
					})
			  	}
			}
		})
	})
},

// 处理定位事件
onLocatingTapped: function(e) {
	let id = e.currentTarget.dataset.id
	db.collection('Mypage_Companies').doc(id).get().then(res => {
		let latitude = res.data.location.latitude
		let longitude = res.data.location.longitude
		let name = res.data.name
		let address = res.data.address
			wx.getLocation({
			success: function(res) {
				wx.openLocation({
					latitude: latitude,
					longitude: longitude,
					scale: 26,
					name: name,
					address: address
				})
			}
		})
	})
}

wx.showModal() 方法可以弹出提示框让用户选择是否打电话,wx.makePhoneCall 方法可以直接跳转到拨号页。wx.getLocation() 获取当前用户的地理位置,然后调用 wx.openLocation(),其中的参数是当前用户选择的网点的经纬度和名称地址等信息。

posted @ 2021-01-14 14:22  老鼠司令  阅读(217)  评论(0编辑  收藏  举报