Commit c56295540476b922f4c59f7dec1fab6c120f12f7

Authored by wangfan
1 parent 6f8d9f38

预定地图

... ... @@ -12,7 +12,7 @@
"pages/customer/list",
"pages/customer/remind",
"pages/me/index",
"pages/reservr/index",
"pages/reserve/index",
"pages/me/setting",
"pages/me/list",
"pages/book/b_addnew",
... ... @@ -36,10 +36,10 @@
"borderStyle": "",
"list": [
{
"pagePath": "pages/reservr/index",
"pagePath": "pages/reserve/index",
"text": "订座",
"iconPath": "pages/image/tabicon-reservr.png",
"selectedIconPath": "pages/image/tabicon-reservr-checked.png"
"iconPath": "pages/image/tabicon-reserve.png",
"selectedIconPath": "pages/image/tabicon-reserve-checked.png"
},
{
"pagePath": "pages/customer/list",
... ...
// components/reserve/seller-box/seller-box.js
Component({
/**
* 组件的属性列表
*/
properties: {
seller:{
type:Object,
value:{}
}
},
/**
* 组件的初始数据
*/
data: {
hasShow:false,
},
/**
* 组件的方法列表
*/
methods: {
show(){
this.setData({
hasShow:true,
})
},
hide(){
this.setData({
hasShow:false,
})
this.triggerEvent('event',{type:'hide'});
}
}
})
... ...
{
"component": true,
"usingComponents": {}
}
\ No newline at end of file
... ...
<!--components/showModal/showModal.wxml-->
<cover-view class="mask flex-vr" hidden="{{!hasShow}}" bindtap="hide">
<cover-view class="showModal">
<cover-view class="header">
{{seller.seller_name}}
</cover-view>
<cover-view class="body">{{opt.body}}</cover-view>
<cover-view class="footer flex-cc">
<button class="button-none cancel" plain wx:if="{{opt.cancelText}}"
bindtap="tapButton" data-type="cancel"
style="color:{{opt.cancelColor}};">{{opt.cancelText}}</button>
<button class="button-none" plain
bindtap="tapButton" data-type="confirm"
style="color:{{opt.confirmColor}};">{{opt.confirmText}}</button>
</cover-view>
</cover-view>
</cover-view>
... ...
/* components/reserve/seller-box/seller-box.wxss */
@import "../../../app.wxss";
.mask{
position: fixed;
width: 100%;
height: 100%;
background-color: rgba(0,0,0,.5);
top:0;
left: 0;
}
.showModal{
width: 90%;
background-color: #fff;
padding: 20rpx 5% 0 5%;
}
.showModal .header{
font-size: 40rpx;
line-height: 120rpx;
height: 120rpx;
}
.showModal .body{
font-size: 30rpx;
margin-bottom: 30rpx;
}
.footer{
border-top: 2rpx solid #ccc;
background-color: #fff;
width: 90%;
}
.footer .button-none{
line-height: 120rpx;
height: 120rpx;
border-width: 0;
}
.footer .button-none.cancel{
border-right: 2rpx solid #ccc !important;
}
\ No newline at end of file
... ...
// components/showModal/showModal.js
import util from '../../utils/util'
const properties={
cancelText:{type:String,value:''},
cancelColor:{type:String,value:'#000'},
confirmText:{type:String,value:'确认'},
confirmColor:{type:String,value:'#393'},
header:{type:String,value:'确认信息'},
body:{type:String,value:'确认信息'},
};
Component({
/**
* 组件的属性列表
*/
properties: properties,
/**
* 组件的初始数据
*/
data: {
hasShow:false,
},
attached(){
let opt={};
Object.keys(properties).forEach((k)=>{
opt[k]=this.data[k]
})
this.setData({
opt:opt
})
},
/**
* 组件的方法列表
*/
methods: {
options(obj){
let opt=this.data.opt;
this.setData({
opt:{
...opt,
...obj
}
})
return this;
},
show(){
console.log(this.data.opt)
this.setData({
hasShow:true,
})
},
tapButton(e){
this.triggerEvent('showModal',{type:util.attr(e,'type')})
this.hide();
},
hide(){
this.setData({
hasShow:false,
})
}
}
})
... ...
{
"component": true,
"usingComponents": {}
}
\ No newline at end of file
... ...
<!--components/showModal/showModal.wxml-->
<cover-view class="mask flex-vc" hidden="{{!hasShow}}">
<cover-view class="showModal">
<cover-view class="header">
{{opt.header}}
</cover-view>
<cover-view class="body">{{opt.body}}</cover-view>
</cover-view>
<cover-view class="footer flex-cc">
<button class="button-none cancel" plain wx:if="{{opt.cancelText}}"
bindtap="tapButton" data-type="cancel"
style="color:{{opt.cancelColor}};">{{opt.cancelText}}</button>
<button class="button-none" plain
bindtap="tapButton" data-type="confirm"
style="color:{{opt.confirmColor}};">{{opt.confirmText}}</button>
</cover-view>
</cover-view>
... ...
/* components/showModal/showModal.wxss */
@import "../../app.wxss";
.mask{
position: fixed;
width: 100%;
height: 100%;
background-color: rgba(0,0,0,.5);
top:0;
left: 0;
}
.showModal{
width: 80%;
background-color: #fff;
padding: 20rpx 5% 0 5%;
}
.showModal .header{
font-size: 40rpx;
line-height: 120rpx;
height: 120rpx;
}
.showModal .body{
font-size: 30rpx;
margin-bottom: 30rpx;
}
.footer{
border-top: 2rpx solid #ccc;
background-color: #fff;
width: 90%;
}
.footer .button-none{
line-height: 120rpx;
height: 120rpx;
border-width: 0;
}
.footer .button-none.cancel{
border-right: 2rpx solid #ccc !important;
}
\ No newline at end of file
... ...
... ... @@ -43,6 +43,7 @@ Component({
this.setData({
hasShare:true
})
},
share(e){
console.log('userinfo-share',e);
... ...
// pages/reservr/index.js
import util from '../../utils/util';
import App from '../../utils/api';
const {regeneratorRuntime} = global
import QQMapWX from '../../utils/qqmap-wx-jssdk'
Page({
/**
* 页面的初始数据
*/
data: {
map:{
latitude: 23.099994,
longitude: 113.324520,
scale:18,
height:300,
},
markers: [{
iconPath: "/pages/image/ding.d.png",
id: 0,
latitude: 23.099994,
longitude: 113.324520,
width: 50,
height: 50
}],
seller:{},
},
qqmapsdk:null,
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
this.qqmapsdk=new QQMapWX({
key: 'SDEBZ-I74W4-QLGUX-XXYXU-HIR23-3QFBJ'
});
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
this.getPos();
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function () {
},
getPos(){
this._getPos().then(res=>{
console.log('wx.getLocation.then',res);
let map=this.data.map;
map.latitude=res.latitude;
map.longitude=res.longitude;
map.height=getApp().system.windowHeight
this.setData({
map:map,
})
this.getMarkers();
}).catch(()=>{
this.selectComponent('#showModal').options({
header:'定位失败',
body:'需要地理位置授权'
}).show();
})
},
_getPos(){
return new Promise((success,fail)=>{
wx.getLocation({
type:'gcj02',
success:(res)=>{
success(res)
},
fail:(res)=>{
fail(res)
},
complete:(res)=>{
console.log('wx.getLocation',res)
}
});
})
},
showModal(e){
wx.openSetting()
},
regionchange(e){
//console.log(e)
},
mapUpdated(e){
//console.log('mapUpdated',e)
},
markertap(e){
console.log(e)
let seller_id=e.markerId;
this.setData({
seller:{
id:seller_id,
seller_name:'商户名名称'+seller_id,
seller_addr:'商户地址'+seller_id,
seller_phone:'商户电话'+seller_id,
}
})
this.selectComponent('#seller-box').show();
wx.hideTabBar();
},
getMarkers(){
let map=this.data.map;
let markers=[];
for(var i=1;i<50;i++){
markers.push({
id: i,
iconPath: "/pages/image/ding.png",
latitude: parseFloat(map.latitude) + Math.random()*(parseInt(Math.random()*10)%2==0?-1:1)/500,
longitude: parseFloat(map.longitude) +Math.random()*(parseInt(Math.random()*10)%2==0?-1:1)/500,
width: 24,
height: 30,
title:'店铺名称t'+i,
// callout:{
// content:'店铺名称cc'+i,
// color:'#f00',
// fontSize:30,
// borderRadius:5,
// borderWidth:1,
// borderColor:'#f00',
// bgColor:'#fff',
// padding:5,
// display:'BYCLICK',//BYCLICK,ALWAYS
// textAlign:'center',
// },
label:{
content:'店铺名称lc'+i,
color:'#353535',
fontSize:13,
anchorX:-50,
anchorY:1,
borderWidth:1,
borderColor:'#B4B0B0',
borderRadius:20,
bgColor:'#fff',
padding:5,
textAlign:'center',
},
})
}
this.setData({
markers:markers,
})
},
sellerBoxEvent(e){
wx.showTabBar();
}
})
\ No newline at end of file
... ...
... ... @@ -4,6 +4,8 @@
"navigationBarTitleText":"订个座儿",
"usingComponents": {
"formids":"/components/formids/formids",
"nav":"/components/nav/nav"
"nav":"/components/nav/nav",
"showModal":"/components/showModal/showModal",
"seller-box":"/components/reserve/seller-box/seller-box"
}
}
\ No newline at end of file
... ...
<!--pages/reservr/index.wxml-->
<view class="page">
<view class="flex-vc map">
<map id="map" longitude="{{map.longitude}}" latitude="{{map.latitude}}" scale="{{map.scale}}"
markers="{{markers}}"
bindmarkertap="markertap"
bindregionchange="regionchange"
bindupdated="mapUpdated"
show-location
enable-3D
enable-zoom
enable-scroll
enable-rotate
show-compass
style="width: 100%; height: {{map.height}}px;"></map>
</view>
</view>
<showModal id="showModal" confirmText="去授权" bindshowModal="showModal"></showModal>
<seller-box id="seller-box" seller="{{seller}}" bindevent="sellerBoxEvent"></seller-box>
... ...
/* pages/reservr/index.wxss */
.page{
width: 100%;
margin: 0 0 0;
color:#353535;
}
.map{
}
\ No newline at end of file
... ...
// pages/reservr/index.js
Page({
/**
* 页面的初始数据
*/
data: {
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function () {
}
})
\ No newline at end of file
<!--pages/reservr/index.wxml-->
<nav hasHome>订个座儿</nav>
<view class="page">
<view class="flex-vc empry">
<image src="http://qn.colorcun.com/custom/lite/image/empty-order.png"></image>
<view class="Medium">正在预备上线</view>
</view>
</view>
/* pages/reservr/index.wxss */
.page{
width: 90%;
margin: 30rpx 5% 0;
color:#353535;
}
.empry{
font-size: 34rpx;
}
.empry image{
width:384rpx;
height: 296rpx;
margin-bottom: 100rpx;
margin-top: 176rpx;
}
\ No newline at end of file
{
"description": "项目配置文件。",
"setting": {
"urlCheck": true,
"urlCheck": false,
"es6": true,
"postcss": true,
"minified": true,
... ... @@ -30,7 +30,7 @@
"list": []
},
"miniprogram": {
"current": 6,
"current": 18,
"list": [
{
"id": 0,
... ... @@ -169,6 +169,18 @@
"pathName": "pages/book/b_addnew",
"query": "id=51",
"scene": "1001"
},
{
"id": -1,
"name": "pages/reserve/index 在线订座",
"pathName": "pages/reserve/index",
"query": "",
"scene": "1044",
"shareInfo": {
"groupName": "测试模拟群1",
"shareName": "8DEbIRpK4pa9mH_QY2vU4ZUKYPuI97WoQ4BQoFej-Q8@cr4dev",
"shareKey": "PZhnqMlY2TnRuHhATyGeSamVmBQUDXXr_WtjRSddeeFK17UAiOP-HNOdhxiEN7PFub5S1DjAeUl0IXOdW-VDqg~~"
}
}
]
}
... ...
/**
* 微信小程序JavaScriptSDK
*
* @version 1.0
* @date 2017-01-10
* @author jaysonzhou@tencent.com
*/
var ERROR_CONF = {
KEY_ERR: 311,
KEY_ERR_MSG: 'key格式错误',
PARAM_ERR: 310,
PARAM_ERR_MSG: '请求参数信息有误',
SYSTEM_ERR: 600,
SYSTEM_ERR_MSG: '系统错误',
WX_ERR_CODE: 1000,
WX_OK_CODE: 200
};
var BASE_URL = 'https://apis.map.qq.com/ws/';
var URL_SEARCH = BASE_URL + 'place/v1/search';
var URL_SUGGESTION = BASE_URL + 'place/v1/suggestion';
var URL_GET_GEOCODER = BASE_URL + 'geocoder/v1/';
var URL_CITY_LIST = BASE_URL + 'district/v1/list';
var URL_AREA_LIST = BASE_URL + 'district/v1/getchildren';
var URL_DISTANCE = BASE_URL + 'distance/v1/';
var Utils = {
/**
* 得到终点query字符串
* @param {Array|String} 检索数据
*/
location2query(data) {
if (typeof data == 'string') {
return data;
}
var query = '';
for (var i = 0; i < data.length; i++) {
var d = data[i];
if (!!query) {
query += ';';
}
if (d.location) {
query = query + d.location.lat + ',' + d.location.lng;
}
if (d.latitude && d.longitude) {
query = query + d.latitude + ',' + d.longitude;
}
}
return query;
},
/**
* 使用微信接口进行定位
*/
getWXLocation(success, fail, complete) {
wx.getLocation({
type: 'gcj02',
success: success,
fail: fail,
complete: complete
});
},
/**
* 获取location参数
*/
getLocationParam(location) {
if (typeof location == 'string') {
var locationArr = location.split(',');
if (locationArr.length === 2) {
location = {
latitude: location.split(',')[0],
longitude: location.split(',')[1]
};
} else {
location = {};
}
}
return location;
},
/**
* 回调函数默认处理
*/
polyfillParam(param) {
param.success = param.success || function () { };
param.fail = param.fail || function () { };
param.complete = param.complete || function () { };
},
/**
* 验证param对应的key值是否为空
*
* @param {Object} param 接口参数
* @param {String} key 对应参数的key
*/
checkParamKeyEmpty(param, key) {
if (!param[key]) {
var errconf = this.buildErrorConfig(ERROR_CONF.PARAM_ERR, ERROR_CONF.PARAM_ERR_MSG + key +'参数格式有误');
param.fail(errconf);
param.complete(errconf);
return true;
}
return false;
},
/**
* 验证参数中是否存在检索词keyword
*
* @param {Object} param 接口参数
*/
checkKeyword(param){
return !this.checkParamKeyEmpty(param, 'keyword');
},
/**
* 验证location值
*
* @param {Object} param 接口参数
*/
checkLocation(param) {
var location = this.getLocationParam(param.location);
if (!location || !location.latitude || !location.longitude) {
var errconf = this.buildErrorConfig(ERROR_CONF.PARAM_ERR, ERROR_CONF.PARAM_ERR_MSG + ' location参数格式有误')
param.fail(errconf);
param.complete(errconf);
return false;
}
return true;
},
/**
* 构造错误数据结构
* @param {Number} errCode 错误码
* @param {Number} errMsg 错误描述
*/
buildErrorConfig(errCode, errMsg) {
return {
status: errCode,
message: errMsg
};
},
/**
* 构造微信请求参数,公共属性处理
*
* @param {Object} param 接口参数
* @param {Object} param 配置项
*/
buildWxRequestConfig(param, options) {
var that = this;
options.header = { "content-type": "application/json" };
options.method = 'GET';
options.success = function (res) {
var data = res.data;
if (data.status === 0) {
param.success(data);
} else {
param.fail(data);
}
};
options.fail = function (res) {
res.statusCode = ERROR_CONF.WX_ERR_CODE;
param.fail(that.buildErrorConfig(ERROR_CONF.WX_ERR_CODE, result.errMsg));
};
options.complete = function (res) {
var statusCode = +res.statusCode;
switch(statusCode) {
case ERROR_CONF.WX_ERR_CODE: {
param.complete(that.buildErrorConfig(ERROR_CONF.WX_ERR_CODE, res.errMsg));
break;
}
case ERROR_CONF.WX_OK_CODE: {
var data = res.data;
if (data.status === 0) {
param.complete(data);
} else {
param.complete(that.buildErrorConfig(data.status, data.message));
}
break;
}
default:{
param.complete(that.buildErrorConfig(ERROR_CONF.SYSTEM_ERR, ERROR_CONF.SYSTEM_ERR_MSG));
}
}
}
return options;
},
/**
* 处理用户参数是否传入坐标进行不同的处理
*/
locationProcess(param, locationsuccess, locationfail, locationcomplete) {
var that = this;
locationfail = locationfail || function (res) {
res.statusCode = ERROR_CONF.WX_ERR_CODE;
param.fail(that.buildErrorConfig(ERROR_CONF.WX_ERR_CODE, res.errMsg));
};
locationcomplete = locationcomplete || function (res) {
if (res.statusCode == ERROR_CONF.WX_ERR_CODE) {
param.complete(that.buildErrorConfig(ERROR_CONF.WX_ERR_CODE, res.errMsg));
}
};
if (!param.location) {
that.getWXLocation(locationsuccess, locationfail, locationcomplete);
} else if (that.checkLocation(param)) {
var location = Utils.getLocationParam(param.location);
locationsuccess(location);
}
}
}
class QQMapWX {
/**
* 构造函数
*
* @param {Object} options 接口参数,key 为必选参数
*/
constructor(options) {
if (!options.key) {
throw Error('key值不能为空');
}
this.key = options.key;
}
/**
* POI周边检索
*
* @param {Object} options 接口参数对象
*
* 参数对象结构可以参考
* @see http://lbs.qq.com/webservice_v1/guide-search.html
*/
search(options) {
var that = this;
options = options || {};
Utils.polyfillParam(options);
if (!Utils.checkKeyword(options)) {
return;
}
var requestParam = {
keyword: options.keyword,
orderby: options.orderby || '_distance',
page_size: options.page_size || 10,
page_index: options.page_index || 1,
output: 'json',
key: that.key
};
if (options.address_format) {
requestParam.address_format = options.address_format;
}
if (options.filter) {
requestParam.filter = options.filter;
}
var distance = options.distance || "1000";
var auto_extend = options.auto_extend || 1;
var locationsuccess = function (result) {
requestParam.boundary = "nearby(" + result.latitude + "," + result.longitude + "," + distance + "," + auto_extend +")";
wx.request(Utils.buildWxRequestConfig(options, {
url: URL_SEARCH,
data: requestParam
}));
}
Utils.locationProcess(options, locationsuccess);
}
/**
* sug模糊检索
*
* @param {Object} options 接口参数对象
*
* 参数对象结构可以参考
* http://lbs.qq.com/webservice_v1/guide-suggestion.html
*/
getSuggestion(options) {
var that = this;
options = options || {};
Utils.polyfillParam(options);
if (!Utils.checkKeyword(options)) {
return;
}
var requestParam = {
keyword: options.keyword,
region: options.region || '全国',
region_fix: options.region_fix || 0,
policy: options.policy || 0,
output: 'json',
key: that.key
};
wx.request(Utils.buildWxRequestConfig(options, {
url: URL_SUGGESTION,
data: requestParam
}));
}
/**
* 逆地址解析
*
* @param {Object} options 接口参数对象
*
* 请求参数结构可以参考
* http://lbs.qq.com/webservice_v1/guide-gcoder.html
*/
reverseGeocoder(options) {
var that = this;
options = options || {};
Utils.polyfillParam(options);
var requestParam = {
coord_type: options.coord_type || 5,
get_poi: options.get_poi || 0,
output: 'json',
key: that.key
};
if (options.poi_options) {
requestParam.poi_options = options.poi_options
}
var locationsuccess = function (result) {
requestParam.location = result.latitude + ',' + result.longitude;
wx.request(Utils.buildWxRequestConfig(options, {
url: URL_GET_GEOCODER,
data: requestParam
}));
};
Utils.locationProcess(options, locationsuccess);
}
/**
* 地址解析
*
* @param {Object} options 接口参数对象
*
* 请求参数结构可以参考
* http://lbs.qq.com/webservice_v1/guide-geocoder.html
*/
geocoder(options) {
var that = this;
options = options || {};
Utils.polyfillParam(options);
if (Utils.checkParamKeyEmpty(options, 'address')) {
return;
}
var requestParam = {
address: options.address,
output: 'json',
key: that.key
};
wx.request(Utils.buildWxRequestConfig(options, {
url: URL_GET_GEOCODER,
data: requestParam
}));
}
/**
* 获取城市列表
*
* @param {Object} options 接口参数对象
*
* 请求参数结构可以参考
* http://lbs.qq.com/webservice_v1/guide-region.html
*/
getCityList(options) {
var that = this;
options = options || {};
Utils.polyfillParam(options);
var requestParam = {
output: 'json',
key: that.key
};
wx.request(Utils.buildWxRequestConfig(options, {
url: URL_CITY_LIST,
data: requestParam
}));
}
/**
* 获取对应城市ID的区县列表
*
* @param {Object} options 接口参数对象
*
* 请求参数结构可以参考
* http://lbs.qq.com/webservice_v1/guide-region.html
*/
getDistrictByCityId(options) {
var that = this;
options = options || {};
Utils.polyfillParam(options);
if (Utils.checkParamKeyEmpty(options, 'id')) {
return;
}
var requestParam = {
id: options.id || '',
output: 'json',
key: that.key
};
wx.request(Utils.buildWxRequestConfig(options, {
url: URL_AREA_LIST,
data: requestParam
}));
}
/**
* 用于单起点到多终点的路线距离(非直线距离)计算:
* 支持两种距离计算方式:步行和驾车。
* 起点到终点最大限制直线距离10公里。
*
* @param {Object} options 接口参数对象
*
* 请求参数结构可以参考
* http://lbs.qq.com/webservice_v1/guide-distance.html
*/
calculateDistance(options) {
var that = this;
options = options || {};
Utils.polyfillParam(options);
if (Utils.checkParamKeyEmpty(options, 'to')) {
return;
}
var requestParam = {
mode: options.mode || 'walking',
to: Utils.location2query(options.to),
output: 'json',
key: that.key
};
var locationsuccess = function (result) {
requestParam.from = result.latitude + ',' + result.longitude;
wx.request(Utils.buildWxRequestConfig(options, {
url: URL_DISTANCE,
data: requestParam
}));
}
if (options.from) {
options.location = options.from;
}
Utils.locationProcess(options, locationsuccess);
}
}
module.exports = QQMapWX;
\ No newline at end of file
... ...