为什么要做
人的一生中三个终极的哲学问题:
- 早饭吃什么
- 中饭吃什么
- 晚饭吃什么
这个问题不知道困扰了多少像我一样的哲学家(不要脸),每天工作到一半,就在思考这哲学问题。鲁迅说过:
不知道每天吃什么的人跟咸鱼有什么区别 !
于是,为了不当咸鱼,秉着要当就要当最最香的烤鱼,呸,要当就当最靓的鲤鱼的信念下,就有了让程序帮我选今天吃什么的想法。下面说下具体的实现过程及原理。
咸鱼翻身记-实现
实现的过程不复杂,主要是利用高德地图的api获取商家数据,然后再对数据做进一步的处理。
实现原理
利用高德地图的定位功能找到自己所处位置,然后通过搜索附近商家功能,搜集到附近一定范围内的商家的信息,然后随机挑选一家餐饮店,完成咸鱼翻身把歌唱。
实现准备
- 需要去高德开放平台,申请使用权限,然后去控制台新建应用,申请使用的key,目前我使用的是免费版,每天有3万次的调用限制,不过对于我这个玩具应用来说,已经足够了,具体的申请过程就不再赘述了。
- 一颗宁可饿死都不做咸鱼的心
实现过程
通过查阅高德地图的资料,找到需要配置的参数,了解相关参数的含义以及可配置范围。
实现当前定位
需要调用高德地图的api,在页面中引入,一定要在head标签中引入,不然会报错
然后在vue.config.js中添加配置
module.exports = {
configureWebpack: {
externals: {
AMap: 'AMap'
}
}
};
这样就完成插件的引入了,开始定位,获取到自己当前所处位置的经度纬度。
// 获取当前位置
getLocation() {
const that = this;
AMap.plugin('AMap.Geolocation', () => {
var geolocation = new AMap.Geolocation({
// 是否使用高精度定位,默认:true
enableHighAccuracy: true,
timeout: 10000,
});
geolocation.getCurrentPosition();
AMap.event.addListener(geolocation, 'complete', (data) => {
// console.log('纬度:', data.position.lat);
// console.log('经度:', data.position.lng);
that.lat = data.position.lat;
that.lng = data.position.lng;
// 查询店铺信息
this.getData();
});
AMap.event.addListener(geolocation, 'error', (err) => {
console.log(err);
console.log('获取定位失败');
});
});
},
高德地图的定位在默认情况下,PC 端优先使用精确 IP 定位,IP定位失败后使用浏览器定位;手机端优先使用浏览器定位,失败后使用IP定位。这里要注意的是,由于Chrome、IOS10等已不再支持非安全域的浏览器定位请求,需要将站点升级到https才能保证定位的精确度。
获取店铺信息
完成定位后需要拼接请求的api来获取到商家数据。
// 获取附近店铺信息
getData() {
const url = `https://restapi.amap.com/v3/place/around?这里跟具体的参数信息,参数配置可查高德文档`;
axios(url)
.then((res) => {
// console.log(res.data.pois);
this.fullShopData = res.data.pois;
})
.catch((err) => {
console.log(err);
console.log('获取店铺信息失败');
});
},
然后获取随机数据。
随机抽取店铺
通过获取到店铺信息的数组的长度,然后在 [0-数组长度)之间生成一个随机数,这个随机数就是当前所有店铺信息中被选中的天之骄子,也就是我们今天要去吃饭的店铺。
// 随机抽取一家店铺
randomShop() {
if (!this.fullShopData || this.fullShopData.length === 0) {
// console.log('附近无店铺或者获取店铺数据失败');
this.$Notice.info({
title: '附近无店铺信息,吃点正常的东西吧!',
});
return false;
}
const total = this.fullShopData.length; //数据长度
const randomIndex = this.random(0, total); // 随机数组下标
this.shopName = this.fullShopData[randomIndex].name; //店名
this.distance = this.fullShopData[randomIndex].distance; //距离
this.address = this.fullShopData[randomIndex].address; //地址
this.isChose = true;
},
这样,一个最小可用的版本已经做好了。但是有时候自己又有点想法,不想做程序的奴隶,于是就需要对随机的范围进行更加精确的配置。
配置项开发
配置项主要有对类别,搜索半径,关键词的配置,具体没什么好说的,主要是对接口参数的重新赋值,这里拿一个数据联动的例子说一下,在选择想要吃的餐馆类别中,需要选中一个大类,再对他的子类进行挑选。这里的分类是基于高德地图的 POI分类编码,进行分类的,根据以上的需求信息,构造一个符合需求的数据结构。
{
name: '咖啡厅',
value: '050500',
types: [
{
name: '星巴克咖啡',
value: '050501'
},
{
name: '上岛咖啡',
value: '050502'
},
{
name: 'Pacific Coffee Company',
value: '050503'
},
{
name: '巴黎咖啡店',
value: '050504'
}
]
},
然后通过监测第一个大类的变动,获取到当前的选中项的value,然后再跟所有的大类数据进行筛选甄别,找到当前项的types,再把当前项的types作为子类的数据来源。
// 筛选大类
selectFirstType(val) {
// 筛选出当前选中项的数据,方便取子项目
const result = this.typeList.filter((item) => item.value === val.value);
this.restaurantList = result[0].types;
this.apiOption.types = val.value;
this.disableChose = false;
},
项目部署
项目是通过netlify部署的,netlify非常适合快速部署一些静态网站,只需要把自己build好的dist包上传至netlify上的个人主页,再配置下域名,就能完成发布部署,非常轻量,可配置项也特别多。这是这个项目的线上版本 https://createforyou.netlify.app/#/
咸鱼翻身记-最后
突然又想到一个场景,当可爱的程序猿小张跟女生小莉出去约会的时候。
程序猿小张: 你想吃什么?
女生小莉:随便。
如果小张有选择困难症,听到随便两个字,心中是啥状态?所以这个时候你就可以发挥你的程序猿本色,现场给他撸一个随机选择程序,然后吃饭的时候跟她讲你撸程序的过程,我相信,你们一定会度过一个快乐的时光的。
光棍节快乐,赶紧跑,小命要紧(狗头)!
源码在这 Gayhub , 最后附上效果图