zhanghui il y a 2 ans
Parent
commit
b29db4cc10

+ 3 - 1
common/js/api.js

@@ -2,9 +2,11 @@
 import login from "../js/login.js";
 import user from "../js/user.js";
 import service from "../js/service.js";
+import qqMap from "../js/qqMap.js";
 
 export default {
 	login,
 	user,
-	service
+	service,
+	qqMap
 }

+ 9 - 1
common/js/login.js

@@ -9,5 +9,13 @@ export default {
 			method: 'POST',
 			data: param
 		})
+	},
+
+	//退出登录
+	logout() {
+		return request({
+			url: '/auth/logout',
+			method: 'DELETE'
+		})
 	}
-}
+}

+ 27 - 0
common/js/qqMap.js

@@ -0,0 +1,27 @@
+import QQMapWX from '../js/qqmap/qqmap-wx-jssdk.js'
+
+// 腾讯地图经纬度转中文地址
+
+export default{
+    getAddress (lng, lat) {
+        return new Promise((resove, reject) => {
+            const qqmapsdk = new QQMapWX({
+                key: 'ZEHBZ-5C4WQ-C3K5N-BTP4J-TRMJO-63BVC',
+            })
+            qqmapsdk.reverseGeocoder({
+                location: {
+                    longitude: lng,
+                    latitude: lat,
+                },
+                success: (res) => {
+                    resove(res)
+                },
+                fail: (e) => {
+                    reject(e)
+
+                },
+            })
+        })
+    }
+}
+

+ 1137 - 0
common/js/qqmap/myqqmap-sdk.js

@@ -0,0 +1,1137 @@
+var vm = ''
+
+/**
+ * 这里是重写部分
+ */
+var wx = {
+    request(obj){
+        obj.data.output = 'jsonp'
+        vm.$jsonp(obj.url,obj.data)
+            .then(json => {
+                if(json.status == 0){
+                    obj.success(json)
+                }else {
+                    obj.fail(json)
+                }
+            })
+            .catch(err => {
+                obj.fail(err)
+            })
+    }
+}
+
+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 URL_DIRECTION = BASE_URL + 'direction/v1/';
+var MODE = {
+    driving: 'driving',
+    transit: 'transit'
+};
+var EARTH_RADIUS = 6378136.49;
+var Utils = {
+    /**
+     * md5加密方法
+     * 版权所有©2011 Sebastian Tschan,https://blueimp.net
+     */
+    safeAdd(x, y) {
+        var lsw = (x & 0xffff) + (y & 0xffff);
+        var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
+        return (msw << 16) | (lsw & 0xffff);
+    },
+    bitRotateLeft(num, cnt) {
+        return (num << cnt) | (num >>> (32 - cnt));
+    },
+    md5cmn(q, a, b, x, s, t) {
+        return this.safeAdd(this.bitRotateLeft(this.safeAdd(this.safeAdd(a, q), this.safeAdd(x, t)), s), b);
+    },
+    md5ff(a, b, c, d, x, s, t) {
+        return this.md5cmn((b & c) | (~b & d), a, b, x, s, t);
+    },
+    md5gg(a, b, c, d, x, s, t) {
+        return this.md5cmn((b & d) | (c & ~d), a, b, x, s, t);
+    },
+    md5hh(a, b, c, d, x, s, t) {
+        return this.md5cmn(b ^ c ^ d, a, b, x, s, t);
+    },
+    md5ii(a, b, c, d, x, s, t) {
+        return this.md5cmn(c ^ (b | ~d), a, b, x, s, t);
+    },
+    binlMD5(x, len) {
+        /* append padding */
+        x[len >> 5] |= 0x80 << (len % 32);
+        x[((len + 64) >>> 9 << 4) + 14] = len;
+        var i;
+        var olda;
+        var oldb;
+        var oldc;
+        var oldd;
+        var a = 1732584193;
+        var b = -271733879;
+        var c = -1732584194;
+        var d = 271733878;
+
+        for (i = 0; i < x.length; i += 16) {
+            olda = a;
+            oldb = b;
+            oldc = c;
+            oldd = d;
+
+            a = this.md5ff(a, b, c, d, x[i], 7, -680876936);
+            d = this.md5ff(d, a, b, c, x[i + 1], 12, -389564586);
+            c = this.md5ff(c, d, a, b, x[i + 2], 17, 606105819);
+            b = this.md5ff(b, c, d, a, x[i + 3], 22, -1044525330);
+            a = this.md5ff(a, b, c, d, x[i + 4], 7, -176418897);
+            d = this.md5ff(d, a, b, c, x[i + 5], 12, 1200080426);
+            c = this.md5ff(c, d, a, b, x[i + 6], 17, -1473231341);
+            b = this.md5ff(b, c, d, a, x[i + 7], 22, -45705983);
+            a = this.md5ff(a, b, c, d, x[i + 8], 7, 1770035416);
+            d = this.md5ff(d, a, b, c, x[i + 9], 12, -1958414417);
+            c = this.md5ff(c, d, a, b, x[i + 10], 17, -42063);
+            b = this.md5ff(b, c, d, a, x[i + 11], 22, -1990404162);
+            a = this.md5ff(a, b, c, d, x[i + 12], 7, 1804603682);
+            d = this.md5ff(d, a, b, c, x[i + 13], 12, -40341101);
+            c = this.md5ff(c, d, a, b, x[i + 14], 17, -1502002290);
+            b = this.md5ff(b, c, d, a, x[i + 15], 22, 1236535329);
+
+            a = this.md5gg(a, b, c, d, x[i + 1], 5, -165796510);
+            d = this.md5gg(d, a, b, c, x[i + 6], 9, -1069501632);
+            c = this.md5gg(c, d, a, b, x[i + 11], 14, 643717713);
+            b = this.md5gg(b, c, d, a, x[i], 20, -373897302);
+            a = this.md5gg(a, b, c, d, x[i + 5], 5, -701558691);
+            d = this.md5gg(d, a, b, c, x[i + 10], 9, 38016083);
+            c = this.md5gg(c, d, a, b, x[i + 15], 14, -660478335);
+            b = this.md5gg(b, c, d, a, x[i + 4], 20, -405537848);
+            a = this.md5gg(a, b, c, d, x[i + 9], 5, 568446438);
+            d = this.md5gg(d, a, b, c, x[i + 14], 9, -1019803690);
+            c = this.md5gg(c, d, a, b, x[i + 3], 14, -187363961);
+            b = this.md5gg(b, c, d, a, x[i + 8], 20, 1163531501);
+            a = this.md5gg(a, b, c, d, x[i + 13], 5, -1444681467);
+            d = this.md5gg(d, a, b, c, x[i + 2], 9, -51403784);
+            c = this.md5gg(c, d, a, b, x[i + 7], 14, 1735328473);
+            b = this.md5gg(b, c, d, a, x[i + 12], 20, -1926607734);
+
+            a = this.md5hh(a, b, c, d, x[i + 5], 4, -378558);
+            d = this.md5hh(d, a, b, c, x[i + 8], 11, -2022574463);
+            c = this.md5hh(c, d, a, b, x[i + 11], 16, 1839030562);
+            b = this.md5hh(b, c, d, a, x[i + 14], 23, -35309556);
+            a = this.md5hh(a, b, c, d, x[i + 1], 4, -1530992060);
+            d = this.md5hh(d, a, b, c, x[i + 4], 11, 1272893353);
+            c = this.md5hh(c, d, a, b, x[i + 7], 16, -155497632);
+            b = this.md5hh(b, c, d, a, x[i + 10], 23, -1094730640);
+            a = this.md5hh(a, b, c, d, x[i + 13], 4, 681279174);
+            d = this.md5hh(d, a, b, c, x[i], 11, -358537222);
+            c = this.md5hh(c, d, a, b, x[i + 3], 16, -722521979);
+            b = this.md5hh(b, c, d, a, x[i + 6], 23, 76029189);
+            a = this.md5hh(a, b, c, d, x[i + 9], 4, -640364487);
+            d = this.md5hh(d, a, b, c, x[i + 12], 11, -421815835);
+            c = this.md5hh(c, d, a, b, x[i + 15], 16, 530742520);
+            b = this.md5hh(b, c, d, a, x[i + 2], 23, -995338651);
+
+            a = this.md5ii(a, b, c, d, x[i], 6, -198630844);
+            d = this.md5ii(d, a, b, c, x[i + 7], 10, 1126891415);
+            c = this.md5ii(c, d, a, b, x[i + 14], 15, -1416354905);
+            b = this.md5ii(b, c, d, a, x[i + 5], 21, -57434055);
+            a = this.md5ii(a, b, c, d, x[i + 12], 6, 1700485571);
+            d = this.md5ii(d, a, b, c, x[i + 3], 10, -1894986606);
+            c = this.md5ii(c, d, a, b, x[i + 10], 15, -1051523);
+            b = this.md5ii(b, c, d, a, x[i + 1], 21, -2054922799);
+            a = this.md5ii(a, b, c, d, x[i + 8], 6, 1873313359);
+            d = this.md5ii(d, a, b, c, x[i + 15], 10, -30611744);
+            c = this.md5ii(c, d, a, b, x[i + 6], 15, -1560198380);
+            b = this.md5ii(b, c, d, a, x[i + 13], 21, 1309151649);
+            a = this.md5ii(a, b, c, d, x[i + 4], 6, -145523070);
+            d = this.md5ii(d, a, b, c, x[i + 11], 10, -1120210379);
+            c = this.md5ii(c, d, a, b, x[i + 2], 15, 718787259);
+            b = this.md5ii(b, c, d, a, x[i + 9], 21, -343485551);
+
+            a = this.safeAdd(a, olda);
+            b = this.safeAdd(b, oldb);
+            c = this.safeAdd(c, oldc);
+            d = this.safeAdd(d, oldd);
+        }
+        return [a, b, c, d];
+    },
+    binl2rstr(input) {
+        var i;
+        var output = '';
+        var length32 = input.length * 32;
+        for (i = 0; i < length32; i += 8) {
+            output += String.fromCharCode((input[i >> 5] >>> (i % 32)) & 0xff);
+        }
+        return output;
+    },
+    rstr2binl(input) {
+        var i;
+        var output = [];
+        output[(input.length >> 2) - 1] = undefined;
+        for (i = 0; i < output.length; i += 1) {
+            output[i] = 0;
+        }
+        var length8 = input.length * 8;
+        for (i = 0; i < length8; i += 8) {
+            output[i >> 5] |= (input.charCodeAt(i / 8) & 0xff) << (i % 32);
+        }
+        return output;
+    },
+    rstrMD5(s) {
+        return this.binl2rstr(this.binlMD5(this.rstr2binl(s), s.length * 8));
+    },
+    rstrHMACMD5(key, data) {
+        var i;
+        var bkey = this.rstr2binl(key);
+        var ipad = [];
+        var opad = [];
+        var hash;
+        ipad[15] = opad[15] = undefined;
+        if (bkey.length > 16) {
+            bkey = this.binlMD5(bkey, key.length * 8);
+        }
+        for (i = 0; i < 16; i += 1) {
+            ipad[i] = bkey[i] ^ 0x36363636;
+            opad[i] = bkey[i] ^ 0x5c5c5c5c;
+        }
+        hash = this.binlMD5(ipad.concat(this.rstr2binl(data)), 512 + data.length * 8);
+        return this.binl2rstr(this.binlMD5(opad.concat(hash), 512 + 128));
+    },
+    rstr2hex(input) {
+        var hexTab = '0123456789abcdef';
+        var output = '';
+        var x;
+        var i;
+        for (i = 0; i < input.length; i += 1) {
+            x = input.charCodeAt(i);
+            output += hexTab.charAt((x >>> 4) & 0x0f) + hexTab.charAt(x & 0x0f);
+        }
+        return output;
+    },
+    str2rstrUTF8(input) {
+        return unescape(encodeURIComponent(input));
+    },
+    rawMD5(s) {
+        return this.rstrMD5(this.str2rstrUTF8(s));
+    },
+    hexMD5(s) {
+        return this.rstr2hex(this.rawMD5(s));
+    },
+    rawHMACMD5(k, d) {
+        return this.rstrHMACMD5(this.str2rstrUTF8(k), str2rstrUTF8(d));
+    },
+    hexHMACMD5(k, d) {
+        return this.rstr2hex(this.rawHMACMD5(k, d));
+    },
+
+    md5(string, key, raw) {
+        if (!key) {
+            if (!raw) {
+                return this.hexMD5(string);
+            }
+            return this.rawMD5(string);
+        }
+        if (!raw) {
+            return this.hexHMACMD5(key, string);
+        }
+        return this.rawHMACMD5(key, string);
+    },
+    /**
+     * 得到md5加密后的sig参数
+     * @param {Object} requestParam 接口参数
+     * @param {String} sk签名字符串
+     * @param {String} featrue 方法名
+     * @return 返回加密后的sig参数
+     */
+    getSig(requestParam, sk, feature, mode) {
+        var sig = null;
+        var requestArr = [];
+        Object.keys(requestParam).sort().forEach(function(key){
+            requestArr.push(key + '=' + requestParam[key]);
+        });
+        if (feature == 'search') {
+            sig = '/ws/place/v1/search?' + requestArr.join('&') + sk;
+        }
+        if (feature == 'suggest') {
+            sig = '/ws/place/v1/suggestion?' + requestArr.join('&') + sk;
+        }
+        if (feature == 'reverseGeocoder') {
+            sig = '/ws/geocoder/v1/?' + requestArr.join('&') + sk;
+        }
+        if (feature == 'geocoder') {
+            sig = '/ws/geocoder/v1/?' + requestArr.join('&') + sk;
+        }
+        if (feature == 'getCityList') {
+            sig = '/ws/district/v1/list?' + requestArr.join('&') + sk;
+        }
+        if (feature == 'getDistrictByCityId') {
+            sig = '/ws/district/v1/getchildren?' + requestArr.join('&') + sk;
+        }
+        if (feature == 'calculateDistance') {
+            sig = '/ws/distance/v1/?' + requestArr.join('&') + sk;
+        }
+        if (feature == 'direction') {
+            sig = '/ws/direction/v1/' + mode + '?' + requestArr.join('&') + sk;
+        }
+        sig = this.md5(sig);
+        return sig;
+    },
+    /**
+     * 得到终点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;
+    },
+
+    /**
+     * 计算角度
+     */
+    rad(d) {
+        return d * Math.PI / 180.0;
+    },
+    /**
+     * 处理终点location数组
+     * @return 返回终点数组
+     */
+    getEndLocation(location){
+        var to = location.split(';');
+        var endLocation = [];
+        for (var i = 0; i < to.length; i++) {
+            endLocation.push({
+                lat: parseFloat(to[i].split(',')[0]),
+                lng: parseFloat(to[i].split(',')[1])
+            })
+        }
+        return endLocation;
+    },
+
+    /**
+     * 计算两点间直线距离
+     * @param a 表示纬度差
+     * @param b 表示经度差
+     * @return 返回的是距离,单位m
+     */
+    getDistance(latFrom, lngFrom, latTo, lngTo) {
+        var radLatFrom = this.rad(latFrom);
+        var radLatTo = this.rad(latTo);
+        var a = radLatFrom - radLatTo;
+        var b = this.rad(lngFrom) - this.rad(lngTo);
+        var distance = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(radLatFrom) * Math.cos(radLatTo) * Math.pow(Math.sin(b / 2), 2)));
+        distance = distance * EARTH_RADIUS;
+        distance = Math.round(distance * 10000) / 10000;
+        return parseFloat(distance.toFixed(0));
+    },
+    /**
+     * 使用微信接口进行定位
+     */
+    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 {String} feature 功能名称
+     * search 地点搜索
+     * suggest关键词提示
+     * reverseGeocoder逆地址解析
+     * geocoder地址解析
+     * getCityList获取城市列表:父集
+     * getDistrictByCityId获取区县列表:子集
+     * calculateDistance距离计算
+     * @param {Object} param 接口参数
+     * @param {Object} data 数据
+     */
+    handleData(param,data,feature){
+        if (feature == 'search') {
+            var searchResult = data.data;
+            var searchSimplify = [];
+            for (var i = 0; i < searchResult.length; i++) {
+                searchSimplify.push({
+                    id: searchResult[i].id || null,
+                    title: searchResult[i].title || null,
+                    latitude: searchResult[i].location && searchResult[i].location.lat || null,
+                    longitude: searchResult[i].location && searchResult[i].location.lng || null,
+                    address: searchResult[i].address || null,
+                    category: searchResult[i].category || null,
+                    tel: searchResult[i].tel || null,
+                    adcode: searchResult[i].ad_info && searchResult[i].ad_info.adcode || null,
+                    city: searchResult[i].ad_info && searchResult[i].ad_info.city || null,
+                    district: searchResult[i].ad_info && searchResult[i].ad_info.district || null,
+                    province: searchResult[i].ad_info && searchResult[i].ad_info.province || null
+                })
+            }
+            param.success(data, {
+                searchResult: searchResult,
+                searchSimplify: searchSimplify
+            })
+        } else if (feature == 'suggest') {
+            var suggestResult = data.data;
+            var suggestSimplify = [];
+            for (var i = 0; i < suggestResult.length; i++) {
+                suggestSimplify.push({
+                    adcode: suggestResult[i].adcode || null,
+                    address: suggestResult[i].address || null,
+                    category: suggestResult[i].category || null,
+                    city: suggestResult[i].city || null,
+                    district: suggestResult[i].district || null,
+                    id: suggestResult[i].id || null,
+                    latitude: suggestResult[i].location && suggestResult[i].location.lat || null,
+                    longitude: suggestResult[i].location && suggestResult[i].location.lng || null,
+                    province: suggestResult[i].province || null,
+                    title: suggestResult[i].title || null,
+                    type: suggestResult[i].type || null
+                })
+            }
+            param.success(data, {
+                suggestResult: suggestResult,
+                suggestSimplify: suggestSimplify
+            })
+        } else if (feature == 'reverseGeocoder') {
+            var reverseGeocoderResult = data.result;
+            var reverseGeocoderSimplify = {
+                address: reverseGeocoderResult.address || null,
+                latitude: reverseGeocoderResult.location && reverseGeocoderResult.location.lat || null,
+                longitude: reverseGeocoderResult.location && reverseGeocoderResult.location.lng || null,
+                adcode: reverseGeocoderResult.ad_info && reverseGeocoderResult.ad_info.adcode || null,
+                city: reverseGeocoderResult.address_component && reverseGeocoderResult.address_component.city || null,
+                district: reverseGeocoderResult.address_component && reverseGeocoderResult.address_component.district || null,
+                nation: reverseGeocoderResult.address_component && reverseGeocoderResult.address_component.nation || null,
+                province: reverseGeocoderResult.address_component && reverseGeocoderResult.address_component.province || null,
+                street: reverseGeocoderResult.address_component && reverseGeocoderResult.address_component.street || null,
+                street_number: reverseGeocoderResult.address_component && reverseGeocoderResult.address_component.street_number || null,
+                recommend: reverseGeocoderResult.formatted_addresses && reverseGeocoderResult.formatted_addresses.recommend || null,
+                rough: reverseGeocoderResult.formatted_addresses && reverseGeocoderResult.formatted_addresses.rough || null
+            };
+            if (reverseGeocoderResult.pois) {//判断是否返回周边poi
+                var pois = reverseGeocoderResult.pois;
+                var poisSimplify = [];
+                for (var i = 0;i < pois.length;i++) {
+                    poisSimplify.push({
+                        id: pois[i].id || null,
+                        title: pois[i].title || null,
+                        latitude: pois[i].location && pois[i].location.lat || null,
+                        longitude: pois[i].location && pois[i].location.lng || null,
+                        address: pois[i].address || null,
+                        category: pois[i].category || null,
+                        adcode: pois[i].ad_info && pois[i].ad_info.adcode || null,
+                        city: pois[i].ad_info && pois[i].ad_info.city || null,
+                        district: pois[i].ad_info && pois[i].ad_info.district || null,
+                        province: pois[i].ad_info && pois[i].ad_info.province || null
+                    })
+                }
+                param.success(data,{
+                    reverseGeocoderResult: reverseGeocoderResult,
+                    reverseGeocoderSimplify: reverseGeocoderSimplify,
+                    pois: pois,
+                    poisSimplify: poisSimplify
+                })
+            } else {
+                param.success(data, {
+                    reverseGeocoderResult: reverseGeocoderResult,
+                    reverseGeocoderSimplify: reverseGeocoderSimplify
+                })
+            }
+        } else if (feature == 'geocoder') {
+            var geocoderResult = data.result;
+            var geocoderSimplify = {
+                title: geocoderResult.title || null,
+                latitude: geocoderResult.location && geocoderResult.location.lat || null,
+                longitude: geocoderResult.location && geocoderResult.location.lng || null,
+                adcode: geocoderResult.ad_info && geocoderResult.ad_info.adcode || null,
+                province: geocoderResult.address_components && geocoderResult.address_components.province || null,
+                city: geocoderResult.address_components && geocoderResult.address_components.city || null,
+                district: geocoderResult.address_components && geocoderResult.address_components.district || null,
+                street: geocoderResult.address_components && geocoderResult.address_components.street || null,
+                street_number: geocoderResult.address_components && geocoderResult.address_components.street_number || null,
+                level: geocoderResult.level || null
+            };
+            param.success(data,{
+                geocoderResult: geocoderResult,
+                geocoderSimplify: geocoderSimplify
+            });
+        } else if (feature == 'getCityList') {
+            var provinceResult = data.result[0];
+            var cityResult = data.result[1];
+            var districtResult = data.result[2];
+            param.success(data,{
+                provinceResult: provinceResult,
+                cityResult: cityResult,
+                districtResult: districtResult
+            });
+        } else if (feature == 'getDistrictByCityId') {
+            var districtByCity = data.result[0];
+            param.success(data, districtByCity);
+        } else if (feature == 'calculateDistance') {
+            var calculateDistanceResult = data.result.elements;
+            var distance = [];
+            for (var i = 0; i < calculateDistanceResult.length; i++){
+                distance.push(calculateDistanceResult[i].distance);
+            }
+            param.success(data, {
+                calculateDistanceResult: calculateDistanceResult,
+                distance: distance
+            });
+        } else if (feature == 'direction') {
+            var direction = data.result.routes;
+            param.success(data,direction);
+        } else {
+            param.success(data);
+        }
+    },
+
+    /**
+     * 构造微信请求参数,公共属性处理
+     *
+     * @param {Object} param 接口参数
+     * @param {Object} param 配置项
+     * @param {String} feature 方法名
+     */
+    buildWxRequestConfig(param, options, feature) {
+        var that = this;
+        options.header = { "content-type": "application/json" };
+        options.method = 'GET';
+        options.success = function (res) {
+            var data = res;
+            if (data.status === 0) {
+                that.handleData(param, data, feature);
+            } else {
+                param.fail(data);
+            }
+        };
+        options.fail = function (res) {
+            res.statusCode = ERROR_CONF.WX_ERR_CODE;
+            param.fail(that.buildErrorConfig(ERROR_CONF.WX_ERR_CODE, res.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值不能为空');
+        }
+        vm = options.vm
+        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 region = null;
+        var rectangle = null;
+
+        //判断城市限定参数
+        if (options.region) {
+            region = options.region;
+        }
+
+        //矩形限定坐标(暂时只支持字符串格式)
+        if (options.rectangle) {
+            rectangle = options.rectangle;
+        }
+
+        var locationsuccess = function (result) {
+            if (region && !rectangle) {
+                //城市限定参数拼接
+                requestParam.boundary = "region(" + region + "," + auto_extend + "," + result.latitude + "," + result.longitude + ")";
+                if (options.sig) {
+                    requestParam.sig = Utils.getSig(requestParam, options.sig, 'search');
+                }
+            } else if (rectangle && !region) {
+                //矩形搜索
+                requestParam.boundary = "rectangle(" + rectangle + ")";
+                if (options.sig) {
+                    requestParam.sig = Utils.getSig(requestParam, options.sig, 'search');
+                }
+            } else {
+                requestParam.boundary = "nearby(" + result.latitude + "," + result.longitude + "," + distance + "," + auto_extend + ")";
+                if (options.sig) {
+                    requestParam.sig = Utils.getSig(requestParam, options.sig, 'search');
+                }
+            }
+            wx.request(Utils.buildWxRequestConfig(options, {
+                url: URL_SEARCH,
+                data: requestParam
+            }, 'search'));
+        };
+        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,
+            page_size: options.page_size || 10,//控制显示条数
+            page_index: options.page_index || 1,//控制页数
+            get_subpois : options.get_subpois || 0,//返回子地点
+            output: 'json',
+            key: that.key
+        };
+        //长地址
+        if (options.address_format) {
+            requestParam.address_format = options.address_format;
+        }
+        //过滤
+        if (options.filter) {
+            requestParam.filter = options.filter;
+        }
+        //排序
+        if (options.location) {
+            var locationsuccess = function (result) {
+                requestParam.location = result.latitude + ',' + result.longitude;
+                if (options.sig) {
+                    requestParam.sig = Utils.getSig(requestParam, options.sig, 'suggest');
+                }
+                wx.request(Utils.buildWxRequestConfig(options, {
+                    url: URL_SUGGESTION,
+                    data: requestParam
+                }, "suggest"));
+            };
+            Utils.locationProcess(options, locationsuccess);
+        } else {
+            if (options.sig) {
+                requestParam.sig = Utils.getSig(requestParam, options.sig, 'suggest');
+            }
+            wx.request(Utils.buildWxRequestConfig(options, {
+                url: URL_SUGGESTION,
+                data: requestParam
+            }, "suggest"));
+        }
+    };
+
+    /**
+     * 逆地址解析
+     *
+     * @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;
+            if (options.sig) {
+                requestParam.sig = Utils.getSig(requestParam, options.sig, 'reverseGeocoder');
+            }
+            wx.request(Utils.buildWxRequestConfig(options, {
+                url: URL_GET_GEOCODER,
+                data: requestParam
+            }, 'reverseGeocoder'));
+        };
+        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
+        };
+
+        //城市限定
+        if (options.region) {
+            requestParam.region = options.region;
+        }
+
+        if (options.sig) {
+            requestParam.sig = Utils.getSig(requestParam, options.sig, 'geocoder');
+        }
+
+        wx.request(Utils.buildWxRequestConfig(options, {
+            url: URL_GET_GEOCODER,
+            data: requestParam
+        },'geocoder'));
+    };
+
+
+    /**
+     * 获取城市列表
+     *
+     * @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
+        };
+
+        if (options.sig) {
+            requestParam.sig = Utils.getSig(requestParam, options.sig, 'getCityList');
+        }
+
+        wx.request(Utils.buildWxRequestConfig(options, {
+            url: URL_CITY_LIST,
+            data: requestParam
+        },'getCityList'));
+    };
+
+    /**
+     * 获取对应城市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
+        };
+
+        if (options.sig) {
+            requestParam.sig = Utils.getSig(requestParam, options.sig, 'getDistrictByCityId');
+        }
+
+        wx.request(Utils.buildWxRequestConfig(options, {
+            url: URL_AREA_LIST,
+            data: requestParam
+        },'getDistrictByCityId'));
+    };
+
+    /**
+     * 用于单起点到多终点的路线距离(非直线距离)计算:
+     * 支持两种距离计算方式:步行和驾车。
+     * 起点到终点最大限制直线距离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
+        };
+
+        if (options.from) {
+            options.location = options.from;
+        }
+
+        //计算直线距离
+        if(requestParam.mode == 'straight'){
+            var locationsuccess = function (result) {
+                var locationTo = Utils.getEndLocation(requestParam.to);//处理终点坐标
+                var data = {
+                    message:"query ok",
+                    result:{
+                        elements:[]
+                    },
+                    status:0
+                };
+                for (var i = 0; i < locationTo.length; i++) {
+                    data.result.elements.push({//将坐标存入
+                        distance: Utils.getDistance(result.latitude, result.longitude, locationTo[i].lat, locationTo[i].lng),
+                        duration:0,
+                        from:{
+                            lat: result.latitude,
+                            lng:result.longitude
+                        },
+                        to:{
+                            lat: locationTo[i].lat,
+                            lng: locationTo[i].lng
+                        }
+                    });
+                }
+                var calculateResult = data.result.elements;
+                var distanceResult = [];
+                for (var i = 0; i < calculateResult.length; i++) {
+                    distanceResult.push(calculateResult[i].distance);
+                }
+                return options.success(data,{
+                    calculateResult: calculateResult,
+                    distanceResult: distanceResult
+                });
+            };
+
+            Utils.locationProcess(options, locationsuccess);
+        } else {
+            var locationsuccess = function (result) {
+                requestParam.from = result.latitude + ',' + result.longitude;
+                if (options.sig) {
+                    requestParam.sig = Utils.getSig(requestParam, options.sig, 'calculateDistance');
+                }
+                wx.request(Utils.buildWxRequestConfig(options, {
+                    url: URL_DISTANCE,
+                    data: requestParam
+                },'calculateDistance'));
+            };
+
+            Utils.locationProcess(options, locationsuccess);
+        }
+    };
+
+    /**
+     * 路线规划:
+     *
+     * @param {Object} options 接口参数对象
+     *
+     * 请求参数结构可以参考
+     * https://lbs.qq.com/webservice_v1/guide-road.html
+     */
+    direction(options) {
+        var that = this;
+        options = options || {};
+        Utils.polyfillParam(options);
+
+        if (Utils.checkParamKeyEmpty(options, 'to')) {
+            return;
+        }
+
+        var requestParam = {
+            output: 'json',
+            key: that.key
+        };
+
+        //to格式处理
+        if (typeof options.to == 'string') {
+            requestParam.to = options.to;
+        } else {
+            requestParam.to = options.to.latitude + ',' + options.to.longitude;
+        }
+        //初始化局部请求域名
+        var SET_URL_DIRECTION = null;
+        //设置默认mode属性
+        options.mode = options.mode || MODE.driving;
+
+        //设置请求域名
+        SET_URL_DIRECTION = URL_DIRECTION + options.mode;
+
+        if (options.from) {
+            options.location = options.from;
+        }
+
+        if (options.mode == MODE.driving) {
+            if (options.from_poi) {
+                requestParam.from_poi = options.from_poi;
+            }
+            if (options.heading) {
+                requestParam.heading = options.heading;
+            }
+            if (options.speed) {
+                requestParam.speed = options.speed;
+            }
+            if (options.accuracy) {
+                requestParam.accuracy = options.accuracy;
+            }
+            if (options.road_type) {
+                requestParam.road_type = options.road_type;
+            }
+            if (options.to_poi) {
+                requestParam.to_poi = options.to_poi;
+            }
+            if (options.from_track) {
+                requestParam.from_track = options.from_track;
+            }
+            if (options.waypoints) {
+                requestParam.waypoints = options.waypoints;
+            }
+            if (options.policy) {
+                requestParam.policy = options.policy;
+            }
+            if (options.plate_number) {
+                requestParam.plate_number = options.plate_number;
+            }
+        }
+
+        if (options.mode == MODE.transit) {
+            if (options.departure_time) {
+                requestParam.departure_time = options.departure_time;
+            }
+            if (options.policy) {
+                requestParam.policy = options.policy;
+            }
+        }
+
+        var locationsuccess = function (result) {
+            requestParam.from = result.latitude + ',' + result.longitude;
+            if (options.sig) {
+                requestParam.sig = Utils.getSig(requestParam, options.sig, 'direction',options.mode);
+            }
+            wx.request(Utils.buildWxRequestConfig(options, {
+                url: SET_URL_DIRECTION,
+                data: requestParam
+            }, 'direction'));
+        };
+
+        Utils.locationProcess(options, locationsuccess);
+    }
+};
+
+module.exports = QQMapWX;

+ 1122 - 0
common/js/qqmap/qqmap-wx-jssdk.js

@@ -0,0 +1,1122 @@
+/**
+ * 微信小程序JavaScriptSDK
+ * 
+ * @version 1.2
+ * @date 2019-03-06
+ */
+
+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 URL_DIRECTION = BASE_URL + 'direction/v1/';
+var MODE = {
+  driving: 'driving',
+  transit: 'transit'
+};
+var EARTH_RADIUS = 6378136.49;
+var Utils = {
+  /**
+  * md5加密方法
+  * 版权所有©2011 Sebastian Tschan,https://blueimp.net
+  */
+  safeAdd(x, y) {
+    var lsw = (x & 0xffff) + (y & 0xffff);
+    var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
+    return (msw << 16) | (lsw & 0xffff);
+  },
+  bitRotateLeft(num, cnt) {
+    return (num << cnt) | (num >>> (32 - cnt));
+  },
+  md5cmn(q, a, b, x, s, t) {
+    return this.safeAdd(this.bitRotateLeft(this.safeAdd(this.safeAdd(a, q), this.safeAdd(x, t)), s), b);
+  },
+  md5ff(a, b, c, d, x, s, t) {
+    return this.md5cmn((b & c) | (~b & d), a, b, x, s, t);
+  },
+  md5gg(a, b, c, d, x, s, t) {
+    return this.md5cmn((b & d) | (c & ~d), a, b, x, s, t);
+  },
+  md5hh(a, b, c, d, x, s, t) {
+    return this.md5cmn(b ^ c ^ d, a, b, x, s, t);
+  },
+  md5ii(a, b, c, d, x, s, t) {
+    return this.md5cmn(c ^ (b | ~d), a, b, x, s, t);
+  },
+  binlMD5(x, len) {
+    /* append padding */
+    x[len >> 5] |= 0x80 << (len % 32);
+    x[((len + 64) >>> 9 << 4) + 14] = len;
+
+    var i;
+    var olda;
+    var oldb;
+    var oldc;
+    var oldd;
+    var a = 1732584193;
+    var b = -271733879;
+    var c = -1732584194;
+    var d = 271733878;
+
+    for (i = 0; i < x.length; i += 16) {
+      olda = a;
+      oldb = b;
+      oldc = c;
+      oldd = d;
+
+      a = this.md5ff(a, b, c, d, x[i], 7, -680876936);
+      d = this.md5ff(d, a, b, c, x[i + 1], 12, -389564586);
+      c = this.md5ff(c, d, a, b, x[i + 2], 17, 606105819);
+      b = this.md5ff(b, c, d, a, x[i + 3], 22, -1044525330);
+      a = this.md5ff(a, b, c, d, x[i + 4], 7, -176418897);
+      d = this.md5ff(d, a, b, c, x[i + 5], 12, 1200080426);
+      c = this.md5ff(c, d, a, b, x[i + 6], 17, -1473231341);
+      b = this.md5ff(b, c, d, a, x[i + 7], 22, -45705983);
+      a = this.md5ff(a, b, c, d, x[i + 8], 7, 1770035416);
+      d = this.md5ff(d, a, b, c, x[i + 9], 12, -1958414417);
+      c = this.md5ff(c, d, a, b, x[i + 10], 17, -42063);
+      b = this.md5ff(b, c, d, a, x[i + 11], 22, -1990404162);
+      a = this.md5ff(a, b, c, d, x[i + 12], 7, 1804603682);
+      d = this.md5ff(d, a, b, c, x[i + 13], 12, -40341101);
+      c = this.md5ff(c, d, a, b, x[i + 14], 17, -1502002290);
+      b = this.md5ff(b, c, d, a, x[i + 15], 22, 1236535329);
+
+      a = this.md5gg(a, b, c, d, x[i + 1], 5, -165796510);
+      d = this.md5gg(d, a, b, c, x[i + 6], 9, -1069501632);
+      c = this.md5gg(c, d, a, b, x[i + 11], 14, 643717713);
+      b = this.md5gg(b, c, d, a, x[i], 20, -373897302);
+      a = this.md5gg(a, b, c, d, x[i + 5], 5, -701558691);
+      d = this.md5gg(d, a, b, c, x[i + 10], 9, 38016083);
+      c = this.md5gg(c, d, a, b, x[i + 15], 14, -660478335);
+      b = this.md5gg(b, c, d, a, x[i + 4], 20, -405537848);
+      a = this.md5gg(a, b, c, d, x[i + 9], 5, 568446438);
+      d = this.md5gg(d, a, b, c, x[i + 14], 9, -1019803690);
+      c = this.md5gg(c, d, a, b, x[i + 3], 14, -187363961);
+      b = this.md5gg(b, c, d, a, x[i + 8], 20, 1163531501);
+      a = this.md5gg(a, b, c, d, x[i + 13], 5, -1444681467);
+      d = this.md5gg(d, a, b, c, x[i + 2], 9, -51403784);
+      c = this.md5gg(c, d, a, b, x[i + 7], 14, 1735328473);
+      b = this.md5gg(b, c, d, a, x[i + 12], 20, -1926607734);
+
+      a = this.md5hh(a, b, c, d, x[i + 5], 4, -378558);
+      d = this.md5hh(d, a, b, c, x[i + 8], 11, -2022574463);
+      c = this.md5hh(c, d, a, b, x[i + 11], 16, 1839030562);
+      b = this.md5hh(b, c, d, a, x[i + 14], 23, -35309556);
+      a = this.md5hh(a, b, c, d, x[i + 1], 4, -1530992060);
+      d = this.md5hh(d, a, b, c, x[i + 4], 11, 1272893353);
+      c = this.md5hh(c, d, a, b, x[i + 7], 16, -155497632);
+      b = this.md5hh(b, c, d, a, x[i + 10], 23, -1094730640);
+      a = this.md5hh(a, b, c, d, x[i + 13], 4, 681279174);
+      d = this.md5hh(d, a, b, c, x[i], 11, -358537222);
+      c = this.md5hh(c, d, a, b, x[i + 3], 16, -722521979);
+      b = this.md5hh(b, c, d, a, x[i + 6], 23, 76029189);
+      a = this.md5hh(a, b, c, d, x[i + 9], 4, -640364487);
+      d = this.md5hh(d, a, b, c, x[i + 12], 11, -421815835);
+      c = this.md5hh(c, d, a, b, x[i + 15], 16, 530742520);
+      b = this.md5hh(b, c, d, a, x[i + 2], 23, -995338651);
+
+      a = this.md5ii(a, b, c, d, x[i], 6, -198630844);
+      d = this.md5ii(d, a, b, c, x[i + 7], 10, 1126891415);
+      c = this.md5ii(c, d, a, b, x[i + 14], 15, -1416354905);
+      b = this.md5ii(b, c, d, a, x[i + 5], 21, -57434055);
+      a = this.md5ii(a, b, c, d, x[i + 12], 6, 1700485571);
+      d = this.md5ii(d, a, b, c, x[i + 3], 10, -1894986606);
+      c = this.md5ii(c, d, a, b, x[i + 10], 15, -1051523);
+      b = this.md5ii(b, c, d, a, x[i + 1], 21, -2054922799);
+      a = this.md5ii(a, b, c, d, x[i + 8], 6, 1873313359);
+      d = this.md5ii(d, a, b, c, x[i + 15], 10, -30611744);
+      c = this.md5ii(c, d, a, b, x[i + 6], 15, -1560198380);
+      b = this.md5ii(b, c, d, a, x[i + 13], 21, 1309151649);
+      a = this.md5ii(a, b, c, d, x[i + 4], 6, -145523070);
+      d = this.md5ii(d, a, b, c, x[i + 11], 10, -1120210379);
+      c = this.md5ii(c, d, a, b, x[i + 2], 15, 718787259);
+      b = this.md5ii(b, c, d, a, x[i + 9], 21, -343485551);
+
+      a = this.safeAdd(a, olda);
+      b = this.safeAdd(b, oldb);
+      c = this.safeAdd(c, oldc);
+      d = this.safeAdd(d, oldd);
+    }
+    return [a, b, c, d];
+  },
+  binl2rstr(input) {
+    var i;
+    var output = '';
+    var length32 = input.length * 32;
+    for (i = 0; i < length32; i += 8) {
+      output += String.fromCharCode((input[i >> 5] >>> (i % 32)) & 0xff);
+    }
+    return output;
+  },
+  rstr2binl(input) {
+    var i;
+    var output = [];
+    output[(input.length >> 2) - 1] = undefined;
+    for (i = 0; i < output.length; i += 1) {
+      output[i] = 0;
+    }
+    var length8 = input.length * 8;
+    for (i = 0; i < length8; i += 8) {
+      output[i >> 5] |= (input.charCodeAt(i / 8) & 0xff) << (i % 32);
+    }
+    return output;
+  },
+  rstrMD5(s) {
+    return this.binl2rstr(this.binlMD5(this.rstr2binl(s), s.length * 8));
+  },
+  rstrHMACMD5(key, data) {
+    var i;
+    var bkey = this.rstr2binl(key);
+    var ipad = [];
+    var opad = [];
+    var hash;
+    ipad[15] = opad[15] = undefined;
+    if (bkey.length > 16) {
+      bkey = this.binlMD5(bkey, key.length * 8);
+    }
+    for (i = 0; i < 16; i += 1) {
+      ipad[i] = bkey[i] ^ 0x36363636;
+      opad[i] = bkey[i] ^ 0x5c5c5c5c;
+    }
+    hash = this.binlMD5(ipad.concat(this.rstr2binl(data)), 512 + data.length * 8);
+    return this.binl2rstr(this.binlMD5(opad.concat(hash), 512 + 128));
+  },
+  rstr2hex(input) {
+    var hexTab = '0123456789abcdef';
+    var output = '';
+    var x;
+    var i;
+    for (i = 0; i < input.length; i += 1) {
+      x = input.charCodeAt(i);
+      output += hexTab.charAt((x >>> 4) & 0x0f) + hexTab.charAt(x & 0x0f);
+    }
+    return output;
+  },
+  str2rstrUTF8(input) {
+    return unescape(encodeURIComponent(input));
+  },
+  rawMD5(s) {
+    return this.rstrMD5(this.str2rstrUTF8(s));
+  },
+  hexMD5(s) {
+    return this.rstr2hex(this.rawMD5(s));
+  },
+  rawHMACMD5(k, d) {
+    return this.rstrHMACMD5(this.str2rstrUTF8(k), str2rstrUTF8(d));
+  },
+  hexHMACMD5(k, d) {
+    return this.rstr2hex(this.rawHMACMD5(k, d));
+  },
+
+  md5(string, key, raw) {
+    if (!key) {
+      if (!raw) {
+        return this.hexMD5(string);
+      }
+      return this.rawMD5(string);
+    }
+    if (!raw) {
+      return this.hexHMACMD5(key, string);
+    }
+    return this.rawHMACMD5(key, string);
+  },
+  /**
+   * 得到md5加密后的sig参数
+   * @param {Object} requestParam 接口参数
+   * @param {String} sk签名字符串
+   * @param {String} featrue 方法名
+   * @return 返回加密后的sig参数
+   */
+  getSig(requestParam, sk, feature, mode) {
+    var sig = null;
+    var requestArr = [];
+    Object.keys(requestParam).sort().forEach(function(key){
+      requestArr.push(key + '=' + requestParam[key]);
+    });
+    if (feature == 'search') {
+      sig = '/ws/place/v1/search?' + requestArr.join('&') + sk;
+    }
+    if (feature == 'suggest') {
+      sig = '/ws/place/v1/suggestion?' + requestArr.join('&') + sk;
+    }
+    if (feature == 'reverseGeocoder') {
+      sig = '/ws/geocoder/v1/?' + requestArr.join('&') + sk;
+    }
+    if (feature == 'geocoder') {
+      sig = '/ws/geocoder/v1/?' + requestArr.join('&') + sk;
+    }
+    if (feature == 'getCityList') {
+      sig = '/ws/district/v1/list?' + requestArr.join('&') + sk;
+    }
+    if (feature == 'getDistrictByCityId') {
+      sig = '/ws/district/v1/getchildren?' + requestArr.join('&') + sk;
+    }
+    if (feature == 'calculateDistance') {
+      sig = '/ws/distance/v1/?' + requestArr.join('&') + sk;
+    }
+    if (feature == 'direction') {
+      sig = '/ws/direction/v1/' + mode + '?' + requestArr.join('&') + sk;
+    }
+    sig = this.md5(sig);
+    return sig;
+  },
+    /**
+     * 得到终点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;
+    },
+
+    /**
+     * 计算角度
+     */
+    rad(d) {
+      return d * Math.PI / 180.0;
+    },  
+    /**
+     * 处理终点location数组
+     * @return 返回终点数组
+     */
+    getEndLocation(location){
+      var to = location.split(';');
+      var endLocation = [];
+      for (var i = 0; i < to.length; i++) {
+        endLocation.push({
+          lat: parseFloat(to[i].split(',')[0]),
+          lng: parseFloat(to[i].split(',')[1])
+        })
+      }
+      return endLocation;
+    },
+
+    /**
+     * 计算两点间直线距离
+     * @param a 表示纬度差
+     * @param b 表示经度差
+     * @return 返回的是距离,单位m
+     */
+    getDistance(latFrom, lngFrom, latTo, lngTo) {
+      var radLatFrom = this.rad(latFrom);
+      var radLatTo = this.rad(latTo);
+      var a = radLatFrom - radLatTo;
+      var b = this.rad(lngFrom) - this.rad(lngTo);
+      var distance = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(radLatFrom) * Math.cos(radLatTo) * Math.pow(Math.sin(b / 2), 2)));
+      distance = distance * EARTH_RADIUS;
+      distance = Math.round(distance * 10000) / 10000;
+      return parseFloat(distance.toFixed(0));
+    },
+    /**
+     * 使用微信接口进行定位
+     */
+    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 {String} feature 功能名称
+     * search 地点搜索
+     * suggest关键词提示
+     * reverseGeocoder逆地址解析
+     * geocoder地址解析
+     * getCityList获取城市列表:父集
+     * getDistrictByCityId获取区县列表:子集
+     * calculateDistance距离计算
+     * @param {Object} param 接口参数
+     * @param {Object} data 数据
+     */
+    handleData(param,data,feature){
+      if (feature == 'search') {
+        var searchResult = data.data;
+        var searchSimplify = [];
+        for (var i = 0; i < searchResult.length; i++) {
+          searchSimplify.push({
+            id: searchResult[i].id || null,
+            title: searchResult[i].title || null,
+            latitude: searchResult[i].location && searchResult[i].location.lat || null,
+            longitude: searchResult[i].location && searchResult[i].location.lng || null,
+            address: searchResult[i].address || null,
+            category: searchResult[i].category || null,
+            tel: searchResult[i].tel || null,
+            adcode: searchResult[i].ad_info && searchResult[i].ad_info.adcode || null,
+            city: searchResult[i].ad_info && searchResult[i].ad_info.city || null,
+            district: searchResult[i].ad_info && searchResult[i].ad_info.district || null,
+            province: searchResult[i].ad_info && searchResult[i].ad_info.province || null
+          })
+        }
+        param.success(data, {
+          searchResult: searchResult,
+          searchSimplify: searchSimplify
+        })
+      } else if (feature == 'suggest') {
+        var suggestResult = data.data;
+        var suggestSimplify = [];
+        for (var i = 0; i < suggestResult.length; i++) {
+          suggestSimplify.push({
+            adcode: suggestResult[i].adcode || null,
+            address: suggestResult[i].address || null,
+            category: suggestResult[i].category || null,
+            city: suggestResult[i].city || null,
+            district: suggestResult[i].district || null,
+            id: suggestResult[i].id || null,
+            latitude: suggestResult[i].location && suggestResult[i].location.lat || null,
+            longitude: suggestResult[i].location && suggestResult[i].location.lng || null,
+            province: suggestResult[i].province || null,
+            title: suggestResult[i].title || null,
+            type: suggestResult[i].type || null
+          })
+        }
+        param.success(data, {
+          suggestResult: suggestResult,
+          suggestSimplify: suggestSimplify
+          })
+      } else if (feature == 'reverseGeocoder') {
+        var reverseGeocoderResult = data.result;
+        var reverseGeocoderSimplify = {
+          address: reverseGeocoderResult.address || null,
+          latitude: reverseGeocoderResult.location && reverseGeocoderResult.location.lat || null,
+          longitude: reverseGeocoderResult.location && reverseGeocoderResult.location.lng || null,
+          adcode: reverseGeocoderResult.ad_info && reverseGeocoderResult.ad_info.adcode || null,
+          city: reverseGeocoderResult.address_component && reverseGeocoderResult.address_component.city || null,
+          district: reverseGeocoderResult.address_component && reverseGeocoderResult.address_component.district || null,
+          nation: reverseGeocoderResult.address_component && reverseGeocoderResult.address_component.nation || null,
+          province: reverseGeocoderResult.address_component && reverseGeocoderResult.address_component.province || null,
+          street: reverseGeocoderResult.address_component && reverseGeocoderResult.address_component.street || null,
+          street_number: reverseGeocoderResult.address_component && reverseGeocoderResult.address_component.street_number || null,
+          recommend: reverseGeocoderResult.formatted_addresses && reverseGeocoderResult.formatted_addresses.recommend || null,
+          rough: reverseGeocoderResult.formatted_addresses && reverseGeocoderResult.formatted_addresses.rough || null
+        };
+        if (reverseGeocoderResult.pois) {//判断是否返回周边poi
+          var pois = reverseGeocoderResult.pois;
+          var poisSimplify = [];
+          for (var i = 0;i < pois.length;i++) {
+            poisSimplify.push({
+              id: pois[i].id || null,
+              title: pois[i].title || null,
+              latitude: pois[i].location && pois[i].location.lat || null,
+              longitude: pois[i].location && pois[i].location.lng || null,
+              address: pois[i].address || null,
+              category: pois[i].category || null,
+              adcode: pois[i].ad_info && pois[i].ad_info.adcode || null,
+              city: pois[i].ad_info && pois[i].ad_info.city || null,
+              district: pois[i].ad_info && pois[i].ad_info.district || null,
+              province: pois[i].ad_info && pois[i].ad_info.province || null
+            })
+          }
+          param.success(data,{
+            reverseGeocoderResult: reverseGeocoderResult,
+            reverseGeocoderSimplify: reverseGeocoderSimplify,
+            pois: pois,
+            poisSimplify: poisSimplify
+          })
+        } else {
+          param.success(data, {
+            reverseGeocoderResult: reverseGeocoderResult,
+            reverseGeocoderSimplify: reverseGeocoderSimplify
+          })
+        }
+      } else if (feature == 'geocoder') {
+        var geocoderResult = data.result;
+        var geocoderSimplify = {
+          title: geocoderResult.title || null,
+          latitude: geocoderResult.location && geocoderResult.location.lat || null,
+          longitude: geocoderResult.location && geocoderResult.location.lng || null,
+          adcode: geocoderResult.ad_info && geocoderResult.ad_info.adcode || null,
+          province: geocoderResult.address_components && geocoderResult.address_components.province || null,
+          city: geocoderResult.address_components && geocoderResult.address_components.city || null,
+          district: geocoderResult.address_components && geocoderResult.address_components.district || null,
+          street: geocoderResult.address_components && geocoderResult.address_components.street || null,
+          street_number: geocoderResult.address_components && geocoderResult.address_components.street_number || null,
+          level: geocoderResult.level || null
+        };
+        param.success(data,{
+          geocoderResult: geocoderResult,
+          geocoderSimplify: geocoderSimplify
+        });
+      } else if (feature == 'getCityList') {
+        var provinceResult = data.result[0];
+        var cityResult = data.result[1];
+        var districtResult = data.result[2];
+        param.success(data,{
+          provinceResult: provinceResult,
+          cityResult: cityResult,
+          districtResult: districtResult
+        });
+      } else if (feature == 'getDistrictByCityId') {
+        var districtByCity = data.result[0];
+        param.success(data, districtByCity);
+      } else if (feature == 'calculateDistance') {
+        var calculateDistanceResult = data.result.elements;  
+        var distance = [];
+        for (var i = 0; i < calculateDistanceResult.length; i++){
+          distance.push(calculateDistanceResult[i].distance);
+        }   
+        param.success(data, {
+          calculateDistanceResult: calculateDistanceResult,
+          distance: distance
+          });
+      } else if (feature == 'direction') {
+        var direction = data.result.routes;
+        param.success(data,direction);
+      } else {
+        param.success(data);
+      }
+    },
+
+    /**
+     * 构造微信请求参数,公共属性处理
+     * 
+     * @param {Object} param 接口参数
+     * @param {Object} param 配置项
+     * @param {String} feature 方法名
+     */
+    buildWxRequestConfig(param, options, feature) {
+        var that = this;
+        options.header = { "content-type": "application/json" };
+        options.method = 'GET';
+        options.success = function (res) {
+            var data = res.data;
+            if (data.status === 0) {
+              that.handleData(param, data, feature);
+            } else {
+                param.fail(data);
+            }
+        };
+        options.fail = function (res) {
+            res.statusCode = ERROR_CONF.WX_ERR_CODE;
+            param.fail(that.buildErrorConfig(ERROR_CONF.WX_ERR_CODE, res.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 region = null;
+        var rectangle = null;
+
+        //判断城市限定参数
+        if (options.region) {
+          region = options.region;
+        }
+
+        //矩形限定坐标(暂时只支持字符串格式)
+        if (options.rectangle) {
+          rectangle = options.rectangle;
+        }
+
+        var locationsuccess = function (result) {        
+          if (region && !rectangle) {
+            //城市限定参数拼接
+            requestParam.boundary = "region(" + region + "," + auto_extend + "," + result.latitude + "," + result.longitude + ")";
+            if (options.sig) {
+              requestParam.sig = Utils.getSig(requestParam, options.sig, 'search');
+            }
+          } else if (rectangle && !region) {
+            //矩形搜索
+            requestParam.boundary = "rectangle(" + rectangle + ")";
+            if (options.sig) {
+              requestParam.sig = Utils.getSig(requestParam, options.sig, 'search');
+            }
+            } else {
+              requestParam.boundary = "nearby(" + result.latitude + "," + result.longitude + "," + distance + "," + auto_extend + ")";
+            if (options.sig) {
+              requestParam.sig = Utils.getSig(requestParam, options.sig, 'search');
+            }
+            }            
+            wx.request(Utils.buildWxRequestConfig(options, {
+                url: URL_SEARCH,
+                data: requestParam
+            }, 'search'));
+        };
+        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,
+            page_size: options.page_size || 10,//控制显示条数
+            page_index: options.page_index || 1,//控制页数
+            get_subpois : options.get_subpois || 0,//返回子地点
+            output: 'json',
+            key: that.key
+        };
+        //长地址
+        if (options.address_format) {
+          requestParam.address_format = options.address_format;
+        }
+        //过滤
+        if (options.filter) {
+          requestParam.filter = options.filter;
+        }
+        //排序
+        if (options.location) {
+          var locationsuccess = function (result) {
+            requestParam.location = result.latitude + ',' + result.longitude;
+            if (options.sig) {
+              requestParam.sig = Utils.getSig(requestParam, options.sig, 'suggest');
+            }
+            wx.request(Utils.buildWxRequestConfig(options, {
+              url: URL_SUGGESTION,
+              data: requestParam
+            }, "suggest"));      
+          };
+          Utils.locationProcess(options, locationsuccess);
+        } else {
+          if (options.sig) {
+            requestParam.sig = Utils.getSig(requestParam, options.sig, 'suggest');
+          }
+          wx.request(Utils.buildWxRequestConfig(options, {
+            url: URL_SUGGESTION,
+            data: requestParam
+          }, "suggest"));      
+        }        
+    };
+
+    /**
+     * 逆地址解析
+     *
+     * @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;
+          if (options.sig) {
+            requestParam.sig = Utils.getSig(requestParam, options.sig, 'reverseGeocoder');
+          }
+            wx.request(Utils.buildWxRequestConfig(options, {
+                url: URL_GET_GEOCODER,
+                data: requestParam
+            }, 'reverseGeocoder'));
+        };
+        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
+        };
+
+        //城市限定
+        if (options.region) {
+          requestParam.region = options.region;
+        }
+
+        if (options.sig) {
+          requestParam.sig = Utils.getSig(requestParam, options.sig, 'geocoder');
+        }
+
+        wx.request(Utils.buildWxRequestConfig(options, {
+            url: URL_GET_GEOCODER,
+            data: requestParam
+        },'geocoder'));
+    };
+
+
+    /**
+     * 获取城市列表
+     *
+     * @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
+        };
+
+        if (options.sig) {
+          requestParam.sig = Utils.getSig(requestParam, options.sig, 'getCityList');
+        }
+
+        wx.request(Utils.buildWxRequestConfig(options, {
+            url: URL_CITY_LIST,
+            data: requestParam
+        },'getCityList'));
+    };
+
+    /**
+     * 获取对应城市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
+        };
+
+        if (options.sig) {
+          requestParam.sig = Utils.getSig(requestParam, options.sig, 'getDistrictByCityId');
+        }
+
+        wx.request(Utils.buildWxRequestConfig(options, {
+            url: URL_AREA_LIST,
+            data: requestParam
+        },'getDistrictByCityId'));
+    };
+
+    /**
+     * 用于单起点到多终点的路线距离(非直线距离)计算:
+     * 支持两种距离计算方式:步行和驾车。
+     * 起点到终点最大限制直线距离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
+        };
+
+        if (options.from) {
+          options.location = options.from;
+        }
+
+        //计算直线距离
+        if(requestParam.mode == 'straight'){        
+          var locationsuccess = function (result) {
+            var locationTo = Utils.getEndLocation(requestParam.to);//处理终点坐标
+            var data = {
+              message:"query ok",
+              result:{
+                elements:[]
+              },
+              status:0
+            };
+            for (var i = 0; i < locationTo.length; i++) {
+              data.result.elements.push({//将坐标存入
+                distance: Utils.getDistance(result.latitude, result.longitude, locationTo[i].lat, locationTo[i].lng),
+                duration:0,
+                from:{
+                  lat: result.latitude,
+                  lng:result.longitude
+                },
+                to:{
+                  lat: locationTo[i].lat,
+                  lng: locationTo[i].lng
+                }
+              });            
+            }
+            var calculateResult = data.result.elements;
+            var distanceResult = [];
+            for (var i = 0; i < calculateResult.length; i++) {
+              distanceResult.push(calculateResult[i].distance);
+            }  
+            return options.success(data,{
+              calculateResult: calculateResult,
+              distanceResult: distanceResult
+            });
+          };
+          
+          Utils.locationProcess(options, locationsuccess);
+        } else {
+          var locationsuccess = function (result) {
+            requestParam.from = result.latitude + ',' + result.longitude;
+            if (options.sig) {
+              requestParam.sig = Utils.getSig(requestParam, options.sig, 'calculateDistance');
+            }
+            wx.request(Utils.buildWxRequestConfig(options, {
+              url: URL_DISTANCE,
+              data: requestParam
+            },'calculateDistance'));
+          };
+
+          Utils.locationProcess(options, locationsuccess);
+        }      
+    };
+
+  /**
+   * 路线规划:
+   * 
+   * @param {Object} options 接口参数对象
+   * 
+   * 请求参数结构可以参考
+   * https://lbs.qq.com/webservice_v1/guide-road.html
+   */
+  direction(options) {
+    var that = this;
+    options = options || {};
+    Utils.polyfillParam(options);
+
+    if (Utils.checkParamKeyEmpty(options, 'to')) {
+      return;
+    }
+
+    var requestParam = {
+      output: 'json',
+      key: that.key
+    };
+
+    //to格式处理
+    if (typeof options.to == 'string') {
+      requestParam.to = options.to;
+    } else {
+      requestParam.to = options.to.latitude + ',' + options.to.longitude;
+    }
+    //初始化局部请求域名
+    var SET_URL_DIRECTION = null;
+    //设置默认mode属性
+    options.mode = options.mode || MODE.driving;
+
+    //设置请求域名
+    SET_URL_DIRECTION = URL_DIRECTION + options.mode;
+
+    if (options.from) {
+      options.location = options.from;
+    }
+
+    if (options.mode == MODE.driving) {
+      if (options.from_poi) {
+        requestParam.from_poi = options.from_poi;
+      }
+      if (options.heading) {
+        requestParam.heading = options.heading;
+      }
+      if (options.speed) {
+        requestParam.speed = options.speed;
+      }
+      if (options.accuracy) {
+        requestParam.accuracy = options.accuracy;
+      }
+      if (options.road_type) {
+        requestParam.road_type = options.road_type;
+      }
+      if (options.to_poi) {
+        requestParam.to_poi = options.to_poi;
+      }
+      if (options.from_track) {
+        requestParam.from_track = options.from_track;
+      }
+      if (options.waypoints) {
+        requestParam.waypoints = options.waypoints;
+      }
+      if (options.policy) {
+        requestParam.policy = options.policy;
+      }
+      if (options.plate_number) {
+        requestParam.plate_number = options.plate_number;
+      }
+    }
+
+    if (options.mode == MODE.transit) {
+      if (options.departure_time) {
+        requestParam.departure_time = options.departure_time;
+      }
+      if (options.policy) {
+        requestParam.policy = options.policy;
+      }
+    } 
+
+    var locationsuccess = function (result) {
+      requestParam.from = result.latitude + ',' + result.longitude;
+      if (options.sig) {
+        requestParam.sig = Utils.getSig(requestParam, options.sig, 'direction',options.mode);
+      }
+      wx.request(Utils.buildWxRequestConfig(options, {
+        url: SET_URL_DIRECTION,
+        data: requestParam
+      }, 'direction'));
+    };
+
+    Utils.locationProcess(options, locationsuccess);
+  }
+};
+
+module.exports = QQMapWX;

+ 5 - 8
common/js/request.js

@@ -5,14 +5,11 @@ function service(options = {}) {
 	// 判断本地是否存在token,如果存在则带上请求头
 	let access_token = uni.getStorageSync('accessToken')
 	let refresh_token = uni.getStorageSync('refresh_token')
-	if(options.header&&options.header['content-type']){
-		options.header['Authorization'] ='Bearer '+ access_token
-	}else {
-		options.header = {
-			'Authorization': 'Bearer '+ access_token,
-			'content-type':'application/json'
-		};
-	}
+
+	options.header = {
+		'Authorization': 'Bearer '+ access_token,
+		'content-type':'application/json'
+	};
 
 	// resolved是返回成功数据,rejected返回错误数据
 	return new Promise((resolved, rejected) => {

+ 59 - 2
common/js/service.js

@@ -51,7 +51,7 @@ export default {
             data:param
         })
     },
-    //结算
+    //待服务的订单
     list(param) {
         return request({
             url: '/business/tech/wait/list',
@@ -67,6 +67,63 @@ export default {
             method: 'GET',
             data:param
         })
-    }
+    },
+
+    //服务项目列表
+    serviceProjectList(param) {
+        return request({
+            url: '/business/tech/serviceProject/list',
+            method: 'GET',
+            data:param
+        })
+    },
+    //添加服务项目
+    addServiceProject(param) {
+        return request({
+            url: '/business/tech/addServiceProject',
+            method: 'POST',
+            data:param
+        })
+    },
+
+    // get请求 根据门店、排班日期查询技师
+    getServicePerson(param) {
+        return request({
+            url: '/store/uniapp/work-person-ist/'+param.storeId,
+            method: 'GET'
+        })
+    },
+
+    // 移交
+    handover(param) {
+        return request({
+            url: '/business/tech/handover',
+            method: 'POST'
+        })
+    },
+    // 报道打卡
+    clockIn(param) {
+        return request({
+            url: '/business/tech/clockIn?storeId='+param.storeId + '&longitude=' + param.longitude + '&latitude=' + param.latitude,
+            method: 'POST'
+        })
+    },
+    // 切换服务对象
+    switchServiceObject(param) {
+        return request({
+            url: '/business/tech/switchServiceObject?orderServiceId='+param.orderServiceId+'&serviceObjectId='+param.serviceObjectId,
+            method: 'POST'
+        })
+    },
+    // 获取服务对象列表
+    getServiceObjectList(param) {
+        return request({
+            url: '/business/tech/getServiceObjectList',
+            method: 'GET',
+            data:param
+        })
+    },
+
+
 
 }

+ 8 - 1
main.js

@@ -5,6 +5,13 @@ import './uni.promisify.adaptor'
 import api from './common/js/api'
 import env from './common/js/env.js';
 
+// #ifdef H5
+// 提交前需要注释  本地调试使用 使用vconsole
+const vconsole = require('vconsole')
+Vue.prototype.$vconsole = new vconsole()
+// #endif
+import {VueJsonp} from 'vue-jsonp'
+Vue.use(VueJsonp)
 import uView from "uview-ui";
 Vue.use(uView);
 Vue.config.productionTip = false
@@ -14,4 +21,4 @@ App.mpType = 'app'
 const app = new Vue({
 	...App
 })
-app.$mount()
+app.$mount()

+ 87 - 80
manifest.json

@@ -1,81 +1,88 @@
 {
-    "name" : "娇骄儿技师端",
-    "appid" : "__UNI__5ADCEDA",
-    "description" : "",
-    "versionName" : "1.0.0",
-    "versionCode" : "100",
-    "transformPx" : false,
-    /* 5+App特有相关 */
-    "app-plus" : {
-        "usingComponents" : true,
-        "nvueStyleCompiler" : "uni-app",
-        "compilerVersion" : 3,
-        "splashscreen" : {
-            "alwaysShowBeforeRender" : true,
-            "waiting" : true,
-            "autoclose" : true,
-            "delay" : 0
-        },
-        /* 模块配置 */
-        "modules" : {},
-        /* 应用发布信息 */
-        "distribute" : {
-            /* android打包配置 */
-            "android" : {
-                "permissions" : [
-                    "<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
-                    "<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
-                    "<uses-permission android:name=\"android.permission.VIBRATE\"/>",
-                    "<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
-                    "<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
-                    "<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
-                    "<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
-                    "<uses-permission android:name=\"android.permission.CAMERA\"/>",
-                    "<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
-                    "<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
-                    "<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
-                    "<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
-                    "<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
-                    "<uses-feature android:name=\"android.hardware.camera\"/>",
-                    "<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
-                ]
-            },
-            /* ios打包配置 */
-            "ios" : {},
-            /* SDK配置 */
-            "sdkConfigs" : {}
-        }
-    },
-    /* 快应用特有相关 */
-    "quickapp" : {},
-    /* 小程序特有相关 */
-    "mp-weixin" : {
-        "appid" : "",
-        "setting" : {
-            "urlCheck" : false
-        },
-        "usingComponents" : true
-    },
-    "mp-alipay" : {
-        "usingComponents" : true
-    },
-    "mp-baidu" : {
-        "usingComponents" : true
-    },
-    "mp-toutiao" : {
-        "usingComponents" : true
-    },
-    "uniStatistics" : {
-        "enable" : false
-    },
-    "vueVersion" : "2",
-    "h5" : {
-        "router" : {
-            "mode" : "hash",
-            "base" : "./"
-        },
-        "devServer" : {
-            "https" : false
-        }
-    }
-}
+	"name": "娇骄儿技师端",
+	"appid": "__UNI__5ADCEDA",
+	"description": "",
+	"versionName": "1.0.0",
+	"versionCode": "100",
+	"transformPx": false,
+	/* 5+App特有相关 */
+	"app-plus": {
+		"usingComponents": true,
+		"nvueStyleCompiler": "uni-app",
+		"compilerVersion": 3,
+		"splashscreen": {
+			"alwaysShowBeforeRender": true,
+			"waiting": true,
+			"autoclose": true,
+			"delay": 0
+		},
+		/* 模块配置 */
+		"modules": {},
+		/* 应用发布信息 */
+		"distribute": {
+			/* android打包配置 */
+			"android": {
+				"permissions": [
+					"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
+					"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
+					"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
+					"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
+					"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
+					"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
+					"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
+					"<uses-permission android:name=\"android.permission.CAMERA\"/>",
+					"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
+					"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
+					"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
+					"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
+					"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
+					"<uses-feature android:name=\"android.hardware.camera\"/>",
+					"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
+				]
+			},
+			/* ios打包配置 */
+			"ios": {},
+			/* SDK配置 */
+			"sdkConfigs": {}
+		}
+	},
+	/* 快应用特有相关 */
+	"quickapp": {},
+	/* 小程序特有相关 */
+	"mp-weixin": {
+		"appid": "",
+		"setting": {
+			"urlCheck": false
+		},
+		"usingComponents": true
+	},
+	"mp-alipay": {
+		"usingComponents": true
+	},
+	"mp-baidu": {
+		"usingComponents": true
+	},
+	"mp-toutiao": {
+		"usingComponents": true
+	},
+	"uniStatistics": {
+		"enable": false
+	},
+	"vueVersion": "2",
+	"h5": {
+		"router": {
+			"mode": "hash",
+			"base": "./"
+		},
+		"devServer": {
+			"https": false
+		},
+		"sdkConfigs": {
+			"maps": {
+				"qqmap": {
+					"key": "ZIABZ-543WB-747UM-JL5Y7-NDS4E-HWB4M"
+				}
+			}
+		}
+	}
+}

+ 98 - 1
package-lock.json

@@ -5,9 +5,46 @@
   "packages": {
     "": {
       "dependencies": {
-        "uview-ui": "^2.0.36"
+        "uview-ui": "^2.0.36",
+        "vconsole": "^3.15.1",
+        "vue-jsonp": "^2.0.0"
       }
     },
+    "node_modules/@babel/runtime": {
+      "version": "7.23.6",
+      "resolved": "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.23.6.tgz",
+      "integrity": "sha512-zHd0eUrf5GZoOWVCXp6koAKQTfZV07eit6bGPmJgnZdnSAvvZee6zniW2XMF7Cmc4ISOOnPy3QaSiIJGJkVEDQ==",
+      "dependencies": {
+        "regenerator-runtime": "^0.14.0"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/copy-text-to-clipboard": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmmirror.com/copy-text-to-clipboard/-/copy-text-to-clipboard-3.2.0.tgz",
+      "integrity": "sha512-RnJFp1XR/LOBDckxTib5Qjr/PMfkatD0MUCQgdpqS8MdKiNUzBjAQBEN6oUy+jW7LI93BBG3DtMB2KOOKpGs2Q==",
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/core-js": {
+      "version": "3.34.0",
+      "resolved": "https://registry.npmmirror.com/core-js/-/core-js-3.34.0.tgz",
+      "integrity": "sha512-aDdvlDder8QmY91H88GzNi9EtQi2TjvQhpCX6B1v/dAZHU1AuLgHvRh54RiOerpEhEW46Tkf+vgAViB/CWC0ag==",
+      "hasInstallScript": true
+    },
+    "node_modules/mutation-observer": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmmirror.com/mutation-observer/-/mutation-observer-1.0.3.tgz",
+      "integrity": "sha512-M/O/4rF2h776hV7qGMZUH3utZLO/jK7p8rnNgGkjKUw8zCGjRQPxB8z6+5l8+VjRUQ3dNYu4vjqXYLr+U8ZVNA=="
+    },
+    "node_modules/regenerator-runtime": {
+      "version": "0.14.1",
+      "resolved": "https://registry.npmmirror.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
+      "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw=="
+    },
     "node_modules/uview-ui": {
       "version": "2.0.36",
       "resolved": "https://registry.npmmirror.com/uview-ui/-/uview-ui-2.0.36.tgz",
@@ -15,13 +52,73 @@
       "engines": {
         "HBuilderX": "^3.1.0"
       }
+    },
+    "node_modules/vconsole": {
+      "version": "3.15.1",
+      "resolved": "https://registry.npmmirror.com/vconsole/-/vconsole-3.15.1.tgz",
+      "integrity": "sha512-KH8XLdrq9T5YHJO/ixrjivHfmF2PC2CdVoK6RWZB4yftMykYIaXY1mxZYAic70vADM54kpMQF+dYmvl5NRNy1g==",
+      "dependencies": {
+        "@babel/runtime": "^7.17.2",
+        "copy-text-to-clipboard": "^3.0.1",
+        "core-js": "^3.11.0",
+        "mutation-observer": "^1.0.3"
+      }
+    },
+    "node_modules/vue-jsonp": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/vue-jsonp/-/vue-jsonp-2.0.0.tgz",
+      "integrity": "sha512-Mzd9GNeuKP5hHFDWZNMWOsCuMILSkA6jo2l4A02wheFz3qqBzH7aSEFTey1BRCZCLizlaf1EqJ5YUtF392KspA=="
     }
   },
   "dependencies": {
+    "@babel/runtime": {
+      "version": "7.23.6",
+      "resolved": "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.23.6.tgz",
+      "integrity": "sha512-zHd0eUrf5GZoOWVCXp6koAKQTfZV07eit6bGPmJgnZdnSAvvZee6zniW2XMF7Cmc4ISOOnPy3QaSiIJGJkVEDQ==",
+      "requires": {
+        "regenerator-runtime": "^0.14.0"
+      }
+    },
+    "copy-text-to-clipboard": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmmirror.com/copy-text-to-clipboard/-/copy-text-to-clipboard-3.2.0.tgz",
+      "integrity": "sha512-RnJFp1XR/LOBDckxTib5Qjr/PMfkatD0MUCQgdpqS8MdKiNUzBjAQBEN6oUy+jW7LI93BBG3DtMB2KOOKpGs2Q=="
+    },
+    "core-js": {
+      "version": "3.34.0",
+      "resolved": "https://registry.npmmirror.com/core-js/-/core-js-3.34.0.tgz",
+      "integrity": "sha512-aDdvlDder8QmY91H88GzNi9EtQi2TjvQhpCX6B1v/dAZHU1AuLgHvRh54RiOerpEhEW46Tkf+vgAViB/CWC0ag=="
+    },
+    "mutation-observer": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmmirror.com/mutation-observer/-/mutation-observer-1.0.3.tgz",
+      "integrity": "sha512-M/O/4rF2h776hV7qGMZUH3utZLO/jK7p8rnNgGkjKUw8zCGjRQPxB8z6+5l8+VjRUQ3dNYu4vjqXYLr+U8ZVNA=="
+    },
+    "regenerator-runtime": {
+      "version": "0.14.1",
+      "resolved": "https://registry.npmmirror.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
+      "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw=="
+    },
     "uview-ui": {
       "version": "2.0.36",
       "resolved": "https://registry.npmmirror.com/uview-ui/-/uview-ui-2.0.36.tgz",
       "integrity": "sha512-ASSZT6M8w3GTO1eFPbsgEFV0U5UujK+8pTNr+MSUbRNcRMC1u63DDTLJVeArV91kWM0bfAexK3SK9pnTqF9TtA=="
+    },
+    "vconsole": {
+      "version": "3.15.1",
+      "resolved": "https://registry.npmmirror.com/vconsole/-/vconsole-3.15.1.tgz",
+      "integrity": "sha512-KH8XLdrq9T5YHJO/ixrjivHfmF2PC2CdVoK6RWZB4yftMykYIaXY1mxZYAic70vADM54kpMQF+dYmvl5NRNy1g==",
+      "requires": {
+        "@babel/runtime": "^7.17.2",
+        "copy-text-to-clipboard": "^3.0.1",
+        "core-js": "^3.11.0",
+        "mutation-observer": "^1.0.3"
+      }
+    },
+    "vue-jsonp": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/vue-jsonp/-/vue-jsonp-2.0.0.tgz",
+      "integrity": "sha512-Mzd9GNeuKP5hHFDWZNMWOsCuMILSkA6jo2l4A02wheFz3qqBzH7aSEFTey1BRCZCLizlaf1EqJ5YUtF392KspA=="
     }
   }
 }

+ 3 - 1
package.json

@@ -1,5 +1,7 @@
 {
   "dependencies": {
-    "uview-ui": "^2.0.36"
+    "uview-ui": "^2.0.36",
+    "vconsole": "^3.15.1",
+    "vue-jsonp": "^2.0.0"
   }
 }

+ 9 - 1
pages.json

@@ -29,7 +29,15 @@
 			"path" : "pages/scanCode/scanCode",
 			"style" :
 			{
-				"navigationBarTitleText" : "扫码",
+				"navigationStyle": "custom",
+				"enablePullDownRefresh" : false
+			}
+		},
+		{
+			"path" : "pages/userInfo/userInfo",
+			"style" :
+			{
+				"navigationStyle": "custom",
 				"enablePullDownRefresh" : false
 			}
 		}

+ 198 - 10
pages/index/index.rpx.css

@@ -3,12 +3,13 @@
     background-repeat:no-repeat;
     background-size:100% ;
     background-color: #f7f7f7;
-    padding: 32rpx;
+    padding: 0 32rpx;
 }
 .tuni{
     height: 160rpx;
     border-radius: 24rpx;
     background: #ffffff;
+    margin-top: 34rpx;
 }
 .profile{
     width: 112rpx;
@@ -146,11 +147,11 @@
     color: #333333;
 }
 .key1{
-    height: 44rpx;
+    height: 60rpx;
     font-size: 28rpx;
     font-weight: 400;
     color: #333333;
-    line-height: 44rpx;
+    line-height: 60rpx;
 }
 .leftBord{
     border-left: 2px solid #DDDDDD;
@@ -158,11 +159,11 @@
     margin-left: 30rpx;
 }
 .value1{
-    height: 52rpx;
+    height: 60rpx;
     font-size: 36rpx;
     font-weight: bold;
     color: #ED569F;
-    line-height: 52rpx;
+    line-height: 60rpx;
 }
 .value2{
     height: 44rpx;
@@ -186,18 +187,36 @@
 .tag1 text{
     margin-left: 10rpx;
 }
+.itemViewOut{
+    width: 638rpx;
+    margin-left: 24rpx;
+    padding: 24rpx 0;
+    border-top: 2rpx dashed #E7E7E7;
+}
+.itemViewOut:first-child{
+   border: none;
+}
 .itemView{
     width: 592rpx;
-    margin-top: 24rpx;
 }
 .item{
     margin-top: 16rpx;
 }
+.statusDesc{
+    font-size: 28rpx;
+    font-weight: 400;
+    color: #FFAF36;
+}
+.statusDesc1{
+    font-size: 28rpx;
+    font-weight: 400;
+    color: #CCCCCC;
+}
 .grid{
     width: 622rpx;
     height: 136rpx;
     margin-top: 40rpx;
-    border-top: 2rpx dashed #111111;
+    border-top: 2rpx dashed #E7E7E7;
     padding-top: 40rpx;
 }
 .grid-text{
@@ -229,8 +248,8 @@
     margin-top: 40rpx;
 }
 .dataNull{
-    width: 300rpx;
-    height: 300rpx;
+    width: 280rpx;
+    height: 280rpx;
     margin-top: 100rpx;
 }
 .dataNullText{
@@ -239,7 +258,176 @@
     color: #999999;
     margin-top: 24rpx;
 }
+.addService{
+    width: 750rpx;
+    height: 724rpx;
+    background: #FFFFFF;
+    border-radius: 24rpx 24rpx 0rpx 0rpx;
+    padding-top: 24rpx;
+}
+.popupTitle{
+    height: 44rpx;
+    font-size: 32rpx;
+    font-weight: 600;
+    color: #333333;
+    line-height: 44rpx;
+    margin-left: 34rpx;
+}
+.scrollY{
+    height: 504rpx;
+    margin-top: 34rpx;
+    margin-bottom: 24rpx;
+}
+.serviceItem{
+    width: 686rpx;
+    height: 152rpx;
+    background: #FAFAFA;
+    border-radius: 8rpx;
+    margin-left: 32rpx;
+    margin-top: 24rpx;
+    position: relative;
+}
+.vImage{
+    position: absolute;
+    top: 0;
+    right: 0;
+    width: 32rpx;
+    height: 32rpx;
+}
+.serviceItem:first-child{
+    margin-top: 0rpx;
+}
+.serviceName{
+    font-size: 32rpx;
+    font-weight: 600;
+    color: #111111;
+    margin-left: 24rpx;
+    padding-top: 24rpx;
+}
+.servicePrice{
+    margin-top: 16rpx;
+    margin-left: 24rpx;
+}
+.servicePriceKey{
+    height: 40rpx;
+    font-size: 24rpx;
+    font-weight: 400;
+    color: #999999;
+    line-height: 40rpx;
+}
+.servicePricePrice {
+    height: 40rpx;
+    font-size: 24rpx;
+    font-weight: 400;
+    color: #ED569F;
+    line-height: 40rpx;
+}
+.cancelButton{
+    width: 332rpx;
+    height: 80rpx;
+    background: #F5F5F5;
+    border-radius: 54rpx;
+    text-align: center;
+    line-height: 80rpx;
+    font-size: 28rpx;
+    font-weight: 400;
+    color: #666666;
+}
+.confirmButton{
+    width: 332rpx;
+    height: 80rpx;
+    background: #FFE05C;
+    border-radius: 54rpx;
+    text-align: center;
+    line-height: 80rpx;
+    font-size: 28rpx;
+    font-weight: 400;
+    color: #333333;
+}
 
+.teachItem{
+    width: 686rpx;
+    height: 228rpx;
+    background: #FAFAFA;
+    border-radius: 16rpx;
+    position: relative;
+    margin-left: 32rpx;
+    margin-top: 24rpx;
+}
+.teachItem:first-child{
+    margin-top: 0rpx;
+}
+.teachImage{
+    width: 180rpx;
+    height: 180rpx;
+    border-radius: 8rpx;
+    margin-top: 24rpx;
+    margin-left: 24rpx;
+}
+.teachMsg{
+    margin-left: 24rpx;
+}
+.techName{
+    height: 48rpx;
+    font-size: 32rpx;
+    font-weight: 600;
+    color: #111111;
+    line-height: 48rpx;
+    margin-top: 62rpx;
+}
+.teachTag{
 
+    height: 44rpx;
+    font-size: 20rpx;
+    font-weight: 400;
+    color: #333333;
+    line-height: 44rpx;
 
-
+    padding: 0 24rpx;
+    margin-left: 16rpx;
+    margin-top: 62rpx;
+    background: #FFF6CE;
+    border-radius: 8rpx;
+    border: 2rpx solid #FFE05C;
+}
+.declaration{
+    height: 40rpx;
+    font-size: 24rpx;
+    font-weight: 400;
+    color: #999999;
+    line-height: 40rpx;
+    margin-top: 16rpx;
+}
+.vBackGround{
+    background: rgba(255,224,92,0.1);
+    border: 4rpx solid #FFE05C;
+    box-sizing: border-box;
+}
+.objectItem{
+    width: 686rpx;
+    height: 160rpx;
+    background: #FAFAFA;
+    border-radius: 16rpx;
+    margin-left: 32rpx;
+    position: relative;
+    margin-top: 24rpx;
+}
+.objectItem:first-child{
+    margin-top: 0rpx;
+}
+.objectImage{
+    width: 108rpx;
+    height: 108rpx;
+    border-radius: 56rpx;
+    border: 2rpx solid #FFFFFF;
+    margin-top: 24rpx;
+    margin-left: 24rpx;
+}
+.objectName{
+    height: 160rpx;
+    font-size: 32rpx;
+    font-weight: 600;
+    color: #111111;
+    line-height: 160rpx;
+    margin-left: 24rpx;
+}

+ 433 - 189
pages/index/index.vue

@@ -1,280 +1,524 @@
 <template>
 	<view class="page">
+		<uni-nav-bar  :fixed="true" background-color="#FFE05C" :border="false" :statusBar="true"  title="首页" />
+		<view class="flex-row tuni">
+			<image class="profile" :src="userInfo.avatar || '/static/logo.png'"></image>
+			<view class="tuniMsg flex-col">
+				<text class="name">{{userInfo.nickName}}</text>
+				<view class="flex-row dizi">
+					<u-icon name="/static/index/dizi.png" size="18"></u-icon>
+					<text>{{storeName || '请先报道打卡'}}</text>
+				</view>
+			</view>
+			<view class="flex-col " @click="userScanCode">
+				<view class="flex-row justify-center dakaIcon">
+					<u-icon name="/static/index/saoma.png" size="25"></u-icon>
+				</view>
+				<view class="flex-row justify-center dakaText">
+					<text>报道打卡</text>
+				</view>
+			</view>
+		</view>
 
-					<view class="flex-row tuni">
-						<image class="profile" :src="userInfo.avatar"></image>
-						<view class="tuniMsg flex-col">
-							<text class="name">{{userInfo.nickName}}</text>
-							<view class="flex-row dizi">
-								<u-icon name="/static/index/dizi.png" size="18"></u-icon>
-								<text>{{storeName}}</text>
-							</view>
-						</view>
-						<view class="flex-col " @click="userScanCode">
-							<view class="flex-row justify-center dakaIcon">
-								<u-icon name="/static/index/saoma.png" size="25"></u-icon>
-							</view>
-							<view class="flex-row justify-center dakaText">
-								<text>报道打卡</text>
+
+		<view class="flex-row justify-center">
+			<view class="tab flex-row">
+				<view class="tabs" :class="{selectTabs: tabIndex === 0}" @click="clickTab(0)">
+					<text>服务中</text>
+				</view>
+				<view class="tabs" :class="{selectTabs: tabIndex === 1}" @click="clickTab(1)">
+					<text>待服务</text>
+				</view>
+			</view>
+		</view>
+
+		<view v-if="tabIndex === 0" class="flex-row justify-center">
+			<view class="serviceMsg " v-if="currService">
+				<view class="flex-row serviceInfo ">
+					<image class="serviceProfile" :src="currService.avatar || '/static/logo.png'"></image>
+					<view class="flex-col justify-end">
+						<view class="flex-row">
+							<text class="servicename">{{currService.serviceObjectName}}</text>
+							<view class="flex-row justify-center tag" @click="openSelectServiceObjectPopup">
+								<text>切换</text>
+								<u-icon name="/static/index/qiehuan.png" size="18"></u-icon>
 							</view>
 						</view>
 					</view>
+				</view>
+				<view :style="{'height':'110rpx'}"></view>
+				<view class="flex-row justify-center " v-if="currService.balanceFlag">
 
-
-		<view class="flex-row justify-center">
-					<view class="tab flex-row">
-						<view class="tabs" :class="{selectTabs: tabIndex === 0}" @click="clickTab(0)">
-							<text>服务中</text>
+					<view class="flex-row hintView">
+						<view class="hint">
+							<text>!</text>
 						</view>
-						<view class="tabs" :class="{selectTabs: tabIndex === 1}"  @click="clickTab(1)">
-							<text>待服务</text>
+						<view class="hintCentent">
+							<text>娇宝的余额已不足,请提醒充值~</text>
 						</view>
 					</view>
 				</view>
-
-				<view v-if="tabIndex === 0" class="flex-row justify-center">
-						<view class="serviceMsg " v-if="currService">
-							<view class="flex-row serviceInfo ">
-								<image class="serviceProfile" :src="currService.avatar"></image>
-								<view class="flex-col justify-end">
-									<view class="flex-row" >
-										<text class="servicename">{{currService.serviceObjectName}}</text>
-										<view class="flex-row justify-center tag">
-											<text>切换</text>
-											<u-icon name="/static/index/qiehuan.png" size="18"></u-icon>
-										</view>
-									</view>
+				<view class="flex-col ">
+					<view class="flex-row justify-center itemViewOut " v-for="(item,index) in currService.childList" :key="index">
+						<view class="flex-col itemView " >
+							<view class="flex-row justify-between item">
+								<view class="flex-row">
+									<u-icon name="/static/index/jiandao.png" size="20"></u-icon>
+									<text class="key">服务项目:</text>
+									<text class="value">{{item.serviceProject}}</text>
 								</view>
-							</view>
-							<view :style="{'height':'110rpx'}"></view>
-							<view class="flex-row justify-center ">
-
-								<view class="flex-row hintView">
-										<view class="hint">
-											<text>!</text>
-										</view>
-									<view class="hintCentent" v-if="currService.balanceFlag">
-										<text>娇宝的余额已不足,请提醒充值~</text>
-									</view>
+								<view class="flex-row statusDesc" :class="item.status ?'statusDesc':'statusDesc1'">
+									<text>{{item.statusDesc}}</text>
 								</view>
 							</view>
-							<view class="flex-row justify-center ">
-								<view class="flex-col itemView">
-									<view class="flex-row item">
-										<u-icon name="/static/index/jiandao.png" size="20"></u-icon>
-										<text class="key">服务项目:</text>
-										<text class="value">{{currService.serviceProject}}</text>
-									</view>
-									<view class="flex-row item">
-										<u-icon name="/static/index/riqi.png" size="20"></u-icon>
-										<text class="key">服务日期:</text>
-										<text class="value">{{currService.date}}</text>
-									</view>
-									<view class="flex-row  item">
-										<view class="flex-row">
-											<u-icon name="/static/index/aixin.png" size="20"></u-icon>
-											<text class="key">服务人员:</text>
-											<text class="value">{{currService.serviceUserName}}</text>
-										</view>
-										<view class="flex-row leftBord">
-											<text class="key">预约费用:</text>
-											<text class="value2">¥{{currService.bookingFee}}</text>
-										</view>
-									</view>
-
-									<view class="flex-row item">
-										<view class="flex-row">
-											<u-icon name="/static/index/shiduan.png" size="20"></u-icon>
-											<text class="key">服务时段:</text>
-											<text class="value">{{currService.time}}</text>
-										</view>
-										<view class="flex-row leftBord">
-											<text class="key">服务费用:</text>
-											<text class="value2">¥{{currService.serviceFee}}</text>
-										</view>
-									</view>
-
-
-								</view>
+							<view class="flex-row item">
+								<u-icon name="/static/index/riqi.png" size="20"></u-icon>
+								<text class="key">服务日期:</text>
+								<text class="value">{{item.serviceDate}}</text>
 							</view>
-							<view class="flex-row justify-center">
-								<view class="flex-col itemView">
-									<view class="flex-row justify-between">
-
-										<view class="flex-col justify-center">
-											<view class="flex-row">
-												<text class="key1">服务总金额:</text>
-												<text class="value1">¥{{currService.serviceFee + currService.bookingFee}}</text>
-											</view>
-										</view>
-										<view class="flex-row justify-center tag1" v-if="currService.isSettle == 0" @click="settle">
-											<u-icon name="/static/index/qianbao.png" size="18"></u-icon>
-											<text>去结算</text>
-										</view>
-									</view>
+							<view class="flex-row  item">
+								<view class="flex-row">
+									<u-icon name="/static/index/aixin.png" size="20"></u-icon>
+									<text class="key">服务人员:</text>
+									<text class="value">{{item.serviceUserName}}</text>
 								</view>
 							</view>
 
-							<view class="flex-row justify-center">
-								<view class="flex-row justify-around grid">
-										<view>
-											<u-icon name="/static/index/jiaojieban.png" size="40"></u-icon>
-											<text class="grid-text">服务交接</text>
-										</view>
-										<view>
-											<u-icon name="/static/index/jiandao.png" size="40"></u-icon>
-											<text class="grid-text">添加服务</text>
-										</view>
-										<view @click="next">
-											<u-icon name="/static/index/xiayige.png" size="40"></u-icon>
-											<text class="grid-text">下一位</text>
-										</view>
-										<view @click="takePlace">
-											<u-icon name="/static/index/yijiuwei.png" size="40"></u-icon>
-											<text class="grid-text">已就位</text>
-										</view>
+							<view class="flex-row item">
+								<view class="flex-row">
+									<u-icon name="/static/index/shiduan.png" size="20"></u-icon>
+									<text class="key">服务时段:</text>
+									<text class="value">{{item.time}}</text>
+								</view>
+								<view class="flex-row leftBord">
+									<text class="key">服务费用:</text>
+									<text class="value2">¥{{item.serviceFee}}</text>
 								</view>
 							</view>
+						</view>
+					</view>
+				</view>
+				<view class="flex-row justify-center">
+					<view class="flex-col itemView">
+						<view class="flex-row justify-between">
 
-							<view class="flex-row justify-center start" @click="start" v-if="currService.status == 1">
-								<text>开始服务</text>
+							<view class="flex-col justify-center">
+								<view class="flex-row">
+									<text class="key1">服务总金额:</text>
+									<text class="value1">¥{{currService.serviceFee}}</text>
+								</view>
 							</view>
-							<view class="flex-row justify-center start" @click="end" v-if="currService.status == 6">
-								<text>开始结束</text>
+							<view class="flex-row justify-center tag1" v-if="currService.isSettle == 0" @click="settle">
+								<u-icon name="/static/index/qianbao.png" size="18"></u-icon>
+								<text>去结算</text>
 							</view>
+						</view>
 					</view>
+				</view>
 
-					<view class="flex-col" :style="{'height':sysHeight}" v-else>
-						<view class="flex-row justify-center">
-							<image class="dataNull" src="/static/index/dataNull.png"></image>
+				<view class="flex-row justify-center">
+					<view class="flex-row justify-around grid">
+						<view @click="connect">
+							<u-icon name="/static/index/jiaojieban.png" size="40"></u-icon>
+							<text class="grid-text">服务交接</text>
+						</view>
+						<view @click="addService">
+							<u-icon name="/static/index/jiandao.png" size="40"></u-icon>
+							<text class="grid-text">添加服务</text>
+						</view>
+						<view @click="next">
+							<u-icon name="/static/index/xiayige.png" size="40"></u-icon>
+							<text class="grid-text">下一位</text>
+						</view>
+						<view @click="takePlace">
+							<u-icon name="/static/index/yijiuwei.png" size="40"></u-icon>
+							<text class="grid-text">已就位</text>
 						</view>
-						<view class="flex-row justify-center dataNullText">
-							<text>暂无服务项目</text>
+					</view>
+				</view>
+
+
+
+				<view class="flex-row justify-center start" @click="start" v-if="currService.status == 1">
+					<text>开始服务</text>
+				</view>
+				<view class="flex-row justify-center start" @click="end" v-if="currService.status == 6">
+					<text>结束服务</text>
+				</view>
+			</view>
+
+			<view class="flex-col" :style="{'height':sysHeight}" v-else>
+				<view class="flex-row justify-center">
+					<image class="dataNull" src="/static/index/dataNull.png"></image>
+				</view>
+				<view class="flex-row justify-center dataNullText">
+					<text>暂无服务项目</text>
+				</view>
+			</view>
+		</view>
+		<view v-if="tabIndex === 1" :style="{'height':sysHeight}">
+			<mescroll-item :i="0" :index="0" :height="sysHeight">
+			</mescroll-item>
+		</view>
+
+		<uni-popup ref="addServicePopup" @change="popupChange" type="bottom">
+			<view class="addService">
+
+				<view class="popupTitle">
+					<text>添加服务项目</text>
+				</view>
+
+				<scroll-view class="scrollY" scroll-y>
+					<view class="serviceItem" :class="{'vBackGround': serviceProjectListIndex === index}" v-for="(item,index) in serviceProjectList" :key="index" @click="serviceProjectListIndex = index">
+						<view class="serviceName">
+							<text>{{item.serviceName}}</text>
+						</view>
+						<view class="flex-row servicePrice">
+							<u-icon name="rmb-circle" color="#666666"></u-icon>
+							<text class="servicePriceKey">预约费用:</text>
+							<text class="servicePricePrice">¥{{item.standardPrice}}</text>
+						</view>
+						<image v-if="serviceProjectListIndex === index" class="vImage" src="/static/index/xuanzhong.png"></image>
+					</view>
+				</scroll-view>
+
+				<view class="flex-row justify-around">
+					<view class="cancelButton" @click="closeAddServicePopup">
+						<text>取消</text>
+					</view>
+					<view class="confirmButton" @click="addServiceProject">
+						<text>确定</text>
+					</view>
+				</view>
+			</view>
+		</uni-popup>
+		<uni-popup ref="connectPopup" @change="popupChange" type="bottom">
+			<view class="addService">
+
+				<view class="popupTitle">
+					<text>选择交接人员</text>
+				</view>
+
+				<scroll-view class="scrollY" scroll-y>
+					<view class="flex-row teachItem" :class="{'vBackGround': servicePersonListIndex === index}" v-for="(item,index) in servicePersonList" :key="index"  @click="servicePersonListIndex = index">
+						<image class="teachImage" src="/static/index/dataNull.png"></image>
+						<view class="flex-col teachMsg ">
+							<view class="flex-row">
+								<text class="techName">{{item.personName}}</text>
+								<view v-if="i<2" class="teachTag" v-for="(iter,i) in item.postList" :key="i">
+									<text>{{iter.levelName}}</text>
+								</view>
+							</view>
+							<text class="declaration">优质服务,从我做起</text>
+						</view>
+						<image v-if="servicePersonListIndex === index" class="vImage" src="/static/index/xuanzhong.png"></image>
+					</view>
+				</scroll-view>
+
+				<view class="flex-row justify-around">
+					<view class="cancelButton" @click="closeConnectPopup">
+						<text>取消</text>
+					</view>
+					<view class="confirmButton" @click="handover">
+						<text>确定</text>
+					</view>
+				</view>
+			</view>
+		</uni-popup>
+		<uni-popup ref="selectServiceObjectPopup" @change="popupChange" type="bottom">
+			<view class="addService">
+
+				<view class="popupTitle">
+					<text>切换服务对象</text>
+				</view>
+
+				<scroll-view class="scrollY" scroll-y>
+					<view class="flex-row objectItem" :class="{'vBackGround': selectServiceObjectIndex === index}" v-for="(item,index) in selectServiceObjectList" :key="index"  @click="selectServiceObjectIndex = index">
+						<image class="objectImage" :src="item.facePhoto || '/static/index/dataNull.png'"></image>
+						<view class="flex-col objectName ">
+							<text>{{item.nickName}}</text>
 						</view>
+						<image v-if="servicePersonListIndex === index" class="vImage" src="/static/index/xuanzhong.png"></image>
 					</view>
-		       </view>
-			<view v-if="tabIndex === 1" :style="{'height':sysHeight}">
-				<mescroll-item :i="0" :index="0" :height="sysHeight">
-				</mescroll-item>
+				</scroll-view>
+
+				<view class="flex-row justify-around">
+					<view class="cancelButton" @click="closeSelectServiceObjectPopup">
+						<text>取消</text>
+					</view>
+					<view class="confirmButton" @click="switchServiceObject">
+						<text>确定</text>
+					</view>
+				</view>
 			</view>
+		</uni-popup>
 	</view>
 </template>
 
 <script>
 	import MescrollItem from "./module/mescrollUni-item.vue";
+	import QQMapWX from '../../common/js/qqmap/myqqmap-sdk.js'
 	export default {
 		components: {
 			MescrollItem
 		},
 		data() {
 			return {
-				tabIndex:0,
-				sysHeight:'',
-				group1: [
-					{thumb: '/static/my/idcard.png', title: '个人信息', rightText: '', to: '/myPages/aboutOur/index'}
-				],
-				readerHeight:'',
-				readerWidth:'',
-				userInfo:{},
-				storeId:'1710635498257108993',
-				storeName:'娇骄儿白云店',
-				currService:{},
+				selectServiceObjectList:[],
+				selectServiceObjectIndex:-1,
+				servicePersonList:[],
+				servicePersonListIndex:-1,
+				serviceProjectList:[],
+				serviceProjectListIndex:-1,
+				tabIndex: 0,
+				sysHeight: '',
+				readerHeight: '',
+				readerWidth: '',
+				userInfo: {},
+				storeId: '1710635498257108993',
+				storeName: '娇骄儿白云店',
+				currService: null,
+				qqMap:new QQMapWX({key: 'ZIABZ-543WB-747UM-JL5Y7-NDS4E-HWB4M',vm: this})
+
 			}
 		},
-		onLoad(){
+		onLoad() {
 			let sysInfo = uni.getSystemInfoSync()
-			this.sysHeight = sysInfo.windowHeight - (sysInfo.windowWidth/750) * 354  + 'px'
-			this.readerHeight=sysInfo.windowHeight + 'px'
-			this.readerWidth=sysInfo.windowWidth + 'px'
-			console.log(this.sysHeight)
-
-			 uni.getLocation({
-				 success:(e)=>{
-					 console.log(e)
-				 }
-			 })
-			uni.setStorageSync('storeId',this.storeId)
-		},
-		onShow(){
-			//退款成功后,刷新列表监听事件
-			uni.$off('scancode')
-			uni.$on('scancode',this.scancode)
+			this.sysHeight = sysInfo.windowHeight - (sysInfo.windowWidth / 750) * 400 + 'px'
+			this.readerHeight = sysInfo.windowHeight + 'px'
+			this.readerWidth = sysInfo.windowWidth + 'px'
+			this.storeId = uni.getStorageSync('storeId')
+			this.storeName = uni.getStorageSync('storeName')
 			this.getUserInfo()
-			this.currServiceInfo()
+			// this.currServiceInfo()
+
+
+		},
+		onShow() {
 		},
 		methods: {
-			takePlace(){
-				this.$api.service.takePlace({
-					orderServiceId:this.currService.orderServiceId
+			openSelectServiceObjectPopup(){
+				this.$api.service.getServiceObjectList({
+					orderServiceId:this.currService.orderServiceId,
+				}).then(res=>{
+					this.selectServiceObjectList= res.data.data
+					uni.hideTabBar()
+					this.$refs.selectServiceObjectPopup.open()
+				})
+			},
+
+			closeSelectServiceObjectPopup(){
+				this.serviceProjectListIndex = -1
+				this.$refs.selectServiceObjectPopup.close()
+			},
+			switchServiceObject(){
+				if (this.selectServiceObjectIndex === -1){
+					uni.showToast({
+						icon: 'none',
+						duration: 2000,
+						title: '请选择服务对象'
+					});
+					return
+				}
+				this.$api.service.switchServiceObject({
+					orderServiceId:this.currService.orderServiceId,
+					serviceObjectId:this.selectServiceObjectList[this.selectServiceObjectIndex].id
 				}).then(res=>{
 					this.currServiceInfo()
+					this.closeSelectServiceObjectPopup()
 				})
 			},
 
-			settle(){
-				this.$api.service.settle({
-					orderServiceId:this.currService.orderServiceId
+			addService() {
+
+				this.$api.service.serviceProjectList().then(res=>{
+					this.serviceProjectList= res.data.data
+					uni.hideTabBar()
+					this.$refs.addServicePopup.open()
+				})
+			},
+
+			closeAddServicePopup(){
+				this.serviceProjectListIndex = -1
+				this.$refs.addServicePopup.close()
+			},
+			addServiceProject(){
+				if (this.serviceProjectListIndex === -1){
+					uni.showToast({
+						icon: 'none',
+						duration: 2000,
+						title: '请选择服务项目'
+					});
+					return
+				}
+				this.$api.service.addServiceProject(
+						{
+							orderServiceId:this.currService.orderServiceId,
+							serviceProjectId:this.serviceProjectList[this.serviceProjectListIndex].id
+						}
+				).then(res=>{
+					uni.showToast({
+						icon: 'none',
+						duration: 2000,
+						title: '添加成功'
+					});
+					this.currServiceInfo()
+					this.closeAddServicePopup()
+				})
+			},
+
+			popupChange(e) {
+				if (!e.show) {
+					uni.showTabBar()
+				}
+			},
+			connect() {
+
+				this.$api.service.getServicePerson({storeId:this.storeId}).then((res) => {
+					this.servicePersonList = res.data.data;
+					uni.hideTabBar()
+					this.$refs.connectPopup.open()
+				})
+			},
+			closeConnectPopup(){
+				this.servicePersonListIndex = -1
+				this.$refs.connectPopup.close()
+			},
+			handover(){
+				if (this.servicePersonListIndex === -1){
+					uni.showToast({
+						icon: 'none',
+						duration: 2000,
+						title: '请选择服务技师'
+					});
+					return
+				}
+				this.$api.service.handover({
+					orderServiceId:this.currService.orderServiceId,
+					serviceUserId:this.servicePersonList[this.servicePersonListIndex].personId
 				}).then(res=>{
+					this.closeConnectPopup()
+					this.closeAddServicePopup()
+				})
+
+			},
+
+			takePlace() {
+				this.$api.service.takePlace({
+					orderServiceId: this.currService.orderServiceId
+				}).then(res => {
 					this.currServiceInfo()
 				})
 			},
-			start(){
+
+			settle() {
+				this.$api.service.settle({
+					orderServiceId: this.currService.orderServiceId
+				}).then(res => {
+					this.currServiceInfo()
+				})
+			},
+			start() {
 				this.$api.service.start({
-					orderServiceId:this.currService.orderServiceId
-				}).then(res=>{
+					orderServiceId: this.currService.orderServiceId
+				}).then(res => {
 					this.currServiceInfo()
 				})
 			},
 
-			end(){
+			end() {
 				this.$api.service.end({
-					orderServiceId:this.currService.orderServiceId
-				}).then(res=>{
+					orderServiceId: this.currService.orderServiceId
+				}).then(res => {
 					this.currServiceInfo()
 				})
 			},
 
-			next(){
+			next() {
 				this.$api.service.next({
-					orderServiceId:this.currService.orderServiceId
-				}).then(res=>{
+					orderServiceId: this.currService.orderServiceId
+				}).then(res => {
 					this.currServiceInfo()
 				})
 
 			},
 
-			currServiceInfo(){
-				this.$api.service.currServiceInfo({storeId:this.storeId}).then(res=>{
+			currServiceInfo() {
+				if (this.storeId === '' || this.storeId === null){
+					return
+				}
+				this.$api.service.currServiceInfo({
+					storeId: this.storeId
+				}).then(res => {
 					console.log(res.data.data)
 					this.currService = res.data.data
+					this.currService.avatar=this.currService.avatar.replace(/^http:/, "https:")
+					let serviceFee = 0
+					res.data.data.childList.forEach(item=>{
+						serviceFee += item.serviceFee *1
+					})
+					this.currService.serviceFee = serviceFee.toFixed(2)
 				})
 
 			},
 
-			getUserInfo(){
-				this.$api.user.getUserInfo().then(res=>{
+			getUserInfo() {
+				this.$api.user.getUserInfo().then(res => {
 					this.userInfo = res.data.data.user
+					uni.setStorageSync('userInfo', this.userInfo )
 				})
 			},
 
-			userScanCode(){
+			userScanCode() {
+				let that = this
 				uni.navigateTo({
-					url:'/pages/scanCode/scanCode'
-				})
-			},
+					url: '/pages/scanCode/scanCode',
+					events: {
+						getScancode: function(data) {
+							that.storeId = JSON.parse(data).storeId
+							that.storeName = JSON.parse(data).storeName
+							uni.setStorageSync('storeId', that.storeId)
+							uni.setStorageSync('storeName', that.storeName)
 
-			scancode(e){
-				console.log(e)
-				this.$u.toast(e)
-			},
+							console.log('++++++++++getScancode+++++++++++++',that.storeId,that.storeName)
+
+							uni.getLocation({
+								type: 'gcj02',
+								success: (e) => {
+									console.log('++++++++++getLocation++success+++++++++++',e.longitude,e.latitude)
+									let param ={
+										storeId:that.storeId,
+										longitude:e.longitude,
+										latitude:e.latitude
+									}
+									that.qqMap.reverseGeocoder({
+										location: {
+											latitude: e.latitude,
+											longitude: e.longitude
+										},
+										success: function(res1){
+											console.log('+++++++++++++++++地址信息++++++++++++++++++++++++',res1)
+										}
+									})
+									that.$api.service.clockIn(param).then(res=>{
+										that.currServiceInfo()
+									})
+								},
+								fail:(err) =>{
+									console.log('++++++++++getLocation++fail+++++++++++',err)
+								}
+							})
 
 
-			clickTab(e){
+						},
+					}
+				})
+			},
+			clickTab(e) {
 				this.tabIndex = e
-				if (e===0){
+				if (e === 0) {
 					this.currServiceInfo()
 				}
-
 			},
 
 		}

+ 16 - 19
pages/index/module/mescrollUni-item.vue

@@ -8,19 +8,19 @@
 	<mescroll-uni :ref="'mescrollRef' + i" @init="mescrollInit" :height="height" :down="downOption" @down="downCallback"
 		:up="upOption" @up="upCallback" @emptyclick="emptyClick">
 
-		<view class="listItem flex-row justify-between " v-for="(item,index) in list" :key="index">
-			<view class="flex-row">
-				<image class="listItemProfile" :src="item.avatar"></image>
-				<text class="listItemName">{{item.serviceObjectName}}</text>
-			</view>
-			<view class="flex-row">
-				<u-icon name="/static/index/shiduan.png" size="20"></u-icon>
-				<text class="listItemkey">服务时段:</text>
-				<text class="listItemValue">{{item.time}}</text>
+		<view class="flex-col ">
+			<view class="listItem flex-row justify-between " v-for="(item,index) in list" :key="index">
+				<view class="flex-row">
+					<image class="listItemProfile" :src="item.avatar"></image>
+					<text class="listItemName">{{item.serviceObjectName}}</text>
+				</view>
+				<view class="flex-row">
+					<u-icon name="/static/index/shiduan.png" size="20"></u-icon>
+					<text class="listItemkey">服务时段:</text>
+					<text class="listItemValue">{{item.time}}</text>
+				</view>
 			</view>
 		</view>
-
-
 	</mescroll-uni>
 </template>
 
@@ -101,22 +101,19 @@
 			/*上拉加载的回调: 其中page.num:当前页 从1开始, page.size:每页数据条数,默认10 */
 			upCallback(page) {
 
-				let status = this.index
-				if (this.index === 3){
-					status = 4
-				}
-
 				//联网加载数据
 				let storeId = uni.getStorageSync('storeId')
-				console.log('storeId:',storeId)
+				if (storeId === '' || storeId === null){
+					storeId = '1710635498257108993'
+				}
 				this.$api.service.list({
 					storeId:storeId
 				}).then((res) => {
 					//联网成功的回调,隐藏下拉刷新和上拉加载的状态;
-					this.mescroll.endSuccess(res.data.data.length, res.data.data.length === 10);
+					this.mescroll.endSuccess(res.data.rows.length, res.data.rows.length === 10);
 					//设置列表数据
 					if (page.num === 1) this.list = []; //如果是第一页需手动制空列表
-					this.list = this.list.concat(res.data.data); //追加新数据
+					this.list = this.list.concat(res.data.rows); //追加新数据
 					console.log(this.list)
 				}).catch((err) => {
 					//联网失败, 结束加载

+ 3 - 0
pages/login/login.vue

@@ -1,5 +1,6 @@
 <template>
 	<view class="page">
+		<uni-nav-bar  :fixed="true" background-color="#FFE05C" :border="false" :statusBar="true"  title="登录" />
 		<view class="logTitle">
 			<view class="welcome">
 				<text>HI,您好!</text>
@@ -74,6 +75,8 @@
 				this.$refs.uForm.validate().then(res => {
 					this.$api.login.techLogin(this.form).then(res => {
 						uni.setStorageSync('accessToken', res.data.data.access_token)
+						uni.removeStorageSync('storeId');
+						uni.removeStorageSync('storeName');
 						uni.switchTab({
 							url: "/pages/index/index"
 						})

+ 3 - 2
pages/my/index.rpx.css

@@ -1,13 +1,14 @@
 .page{
-    background-image:url('/static/my/bg1.png');
+    background-image:url('https://wine.gzzzyd.com/tech/static/my/bg1.png');
     background-repeat:no-repeat;
     background-size:100% 30%;
     background-color: #f7f7f7;
-    padding: 32rpx;
+    padding: 0 32rpx;
 }
 .useInfo{
     width: 686rpx;
     height: 152rpx;
+    margin-top: 32rpx;
 }
 
 .profileView{

+ 23 - 12
pages/my/my.vue

@@ -1,16 +1,16 @@
 <template>
 	<view class="page" :style="{'height':sysHeight}">
-
+		<uni-nav-bar  :fixed="true" background-color="#FFE05C" :border="false" :statusBar="true"   title="我的" />
 			<view class="useInfo  flex-row">
-				<view class="profileView">
-					<image class="profile" :src="userInfo.avatar"></image>
+				<view class="profileView" @click="goUserInfo">
+					<image class="profile" :src="userInfo.avatar  || '/static/logo.png'"></image>
 				</view>
 				<view class="usermsg flex-col">
 					<view class="name">
-						<text>{{userInfo.nickName}}</text>
+						<text @click="goUserInfo">{{userInfo.nickName}}</text>
 					</view>
 					<view class="other flex-row">
-						<text>脱离老师脱离老师脱离老师脱离</text>
+						<text @click="goUserInfo">{{userInfo.phonenumber}}</text>
 						<u-icon name="arrow-right" color="#333333" size="18"></u-icon>
 					</view>
 				</view>
@@ -25,10 +25,10 @@
 							<u-icon name="/static/my/fuwuNmber.png" size="28"></u-icon>
 						</view>
 						<view class="flex-row justify-center statisticsKey">
-							<text>服务次数(次)</text>
+							<text>服务次数(次)</text>
 						</view>
 						<view class="flex-row justify-center statisticsValue">
-							<text>{{staticsData.serviceTotal}}</text>
+							<text>{{staticsData.serviceTotal || 0}}</text>
 						</view>
 					</view>
 					<view class="statisticsItem flex-col ">
@@ -36,10 +36,10 @@
 							<u-icon name="/static/my/fuwuTimeLong.png" size="28"></u-icon>
 						</view>
 						<view class="flex-row justify-center statisticsKey">
-							<text>服务时长(分)</text>
+							<text>总服务金额(元)</text>
 						</view>
 						<view class="flex-row justify-center statisticsValue">
-							<text>{{staticsData.avgServiceTime}}</text>
+							<text>{{staticsData.avgServiceTime || 0}}</text>
 						</view>
 					</view>
 				</view>
@@ -57,24 +57,35 @@
 	export default {
 		data() {
 			return {
+				storeId:'',
 				userInfo:'',
 				staticsData:'',
 				sysHeight:'',
 				group1: [
-					{thumb: '/static/my/idcard.png', title: '个人信息', rightText: '', to: '/myPages/aboutOur/index'}
+					{thumb: '/static/my/idcard.png', title: '个人信息', rightText: '', to: '/pages/userInfo/userInfo'}
 				],
 			}
 		},
 		onLoad(){
+
 			let sysInfo = uni.getSystemInfoSync()
 			this.sysHeight = sysInfo.windowHeight + 'px'
 			console.log(this.sysHeight)
 		},
-		show(){
+		onShow(){
+			this.storeId = uni.getStorageSync('storeId')
 			this.getUserInfo()
-			this.statics()
+			if (!(this.storeId === '' || this.storeId === null)){
+				this.statics()
+			}
 		},
+
 		methods: {
+			goUserInfo(){
+				uni.navigateTo({
+					url: '/pages/userInfo/userInfo'
+				})
+			},
 
 			getUserInfo(){
 				this.$api.user.getUserInfo().then(res=>{

+ 20 - 2
pages/scanCode/scanCode.vue

@@ -1,5 +1,6 @@
 <template>
 	<view>
+		<uni-nav-bar  :fixed="true" background-color="#FFE05C" :border="false" :statusBar="true"  left-icon="left" title="扫码" @clickLeft="back" />
 		<mumu-get-qrcode @success='qrcodeSucess' @error="qrcodeError"></mumu-get-qrcode>
 	</view>
 </template>
@@ -15,12 +16,29 @@
 			return {
 
 			}
+		},
+		onLoad(){
+
 		},
 		methods: {
+			back() {
+				uni.navigateBack({
+					delta: 1
+				})
+			},
 			qrcodeSucess(data) {
 
-				uni.$emit('scancode',data)
-				uni.navigateBack()
+				uni.showToast({
+					title: '扫码成功'
+				})
+				const eventChannel = this.getOpenerEventChannel();
+				eventChannel.emit('getScancode', data);
+				setTimeout(()=>{
+					uni.navigateBack({
+						delta: 1
+					});
+				},2000)
+
 			},
 			qrcodeError(err) {
 				console.log(err)

+ 64 - 0
pages/userInfo/index.rpx.css

@@ -0,0 +1,64 @@
+.page{
+    height: 100vh;
+    background: #F9F9F9;
+    padding: 0 32rpx;
+}
+.outView{
+    background: #FFFFFF;
+    border-radius: 15rpx;
+    padding: 0 24rpx;
+    margin-top: 24rpx;
+}
+.photoView{
+    width: 100rpx;
+    height: 100rpx;
+    border-radius: 50rpx;
+    padding: 0;
+    margin: 30rpx 0;
+}
+
+
+.photoImage{
+    width: 100rpx;
+    height: 100rpx;
+}
+.key{
+    font-size: 28rpx;
+    font-family: PingFangSC-Regular, PingFang SC;
+    font-weight: 400;
+    color: #333333;
+    line-height: 44rpx;
+}
+.bordBot{
+    border-bottom: 1px solid #F7F7F7;
+}
+.nikeName{
+    font-size: 28rpx;
+    font-family: PingFangSC-Regular, PingFang SC;
+    font-weight: 400;
+    color: #999999;
+    margin: 28rpx 28rpx 28rpx 0;
+    text-align: right;
+}
+.groupItemContent{
+    font-size: 24rpx;
+    font-family: PingFangSC-Regular, PingFang SC;
+    font-weight: 400;
+    color: #999999;
+    margin: 30rpx 0;
+}
+.updateButton{
+    margin-top: 60rpx;
+    border-radius: 40rpx;
+    background: #FFE05C;
+    font-size: 30rpx;
+}
+.updateButton:after{
+    border: none;
+}
+.picker{
+    width: 300rpx;
+}
+.logoutButton{
+    margin-top: 100rpx;
+}

+ 100 - 0
pages/userInfo/userInfo.vue

@@ -0,0 +1,100 @@
+<template>
+	<view class="page">
+		<uni-nav-bar  :fixed="true" background-color="#FFE05C" :border="false" :statusBar="true"  left-icon="left" title="个人信息" @clickLeft="back" />
+
+		<view class="outView">
+
+			<form>
+
+				<view class="flex-row justify-between bordBot" >
+					<view class="key flex-col justify-center ">
+						<text>头像</text>
+					</view>
+					<view class="photoView">
+						<image class="photoImage" :src="userInfo.selfPhotoUrl || '/static/logo.png'"></image>
+					</view>
+				</view>
+
+				<view class="flex-row justify-between bordBot" >
+					<view class="key flex-col justify-center ">
+						<text>姓名</text>
+					</view>
+					<view class="nikeName flex-col justify-center">
+						<input disabled type="nickname" name="nickname" v-model="userInfo.nickName"   placeholder="请输入昵称"/>
+					</view>
+				</view>
+
+				<view class="flex-row justify-between bordBot" >
+					<view class="key flex-col justify-center ">
+						<text>性别</text>
+					</view>
+						<view class="flex-row justify-end groupItemContent">
+							<text v-if="userInfo.sex == 0">男</text>
+							<text v-else-if="userInfo.sex == 1">女</text>
+							<text v-else-if="userInfo.sex == 2">未知</text>
+							<text v-else>请选择性别</text>
+<!--							<u-icon name="arrow-right" color="#666" size="18"></u-icon>-->
+						</view>
+				</view>
+
+				<view class="flex-row justify-between bordBot" >
+					<view class="key flex-col justify-center ">
+						<text>手机号</text>
+					</view>
+					<view class="flex-row justify-end groupItemContent" @click="settingTelphone">
+						<text>{{userInfo.phonenumber? userInfo.phonenumber : '' }}</text>
+<!--						<u-icon name="arrow-right" color="#666" size="18"></u-icon>-->
+					</view>
+				</view>
+			</form>
+		</view>
+		<u-button class="logoutButton" type="error" text="退出登录" @click="logout"></u-button>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				photoUrl:'',
+				userInfo: {},
+				genderIndex:0,
+				genderList: [{gender:'男',id:'0'},
+					{gender:'女',id:'1'},
+					{gender:'未知',id:'2'}],
+			};
+		},
+		mounted() {
+		},
+		onShow() {
+
+
+			// 用户信息
+			this.userInfo = uni.getStorageSync('userInfo')
+
+			console.log(this.userInfo)
+
+
+		},
+		methods: {
+			back() {
+				uni.navigateBack({
+					delta: 1
+				})
+			},
+			logout(){
+				this.$api.login.logout().then(res=>{
+					uni.clearStorageSync();
+					uni.navigateTo({
+						url:'/pages/login/login'
+					})
+				})
+			}
+
+		}
+	};
+</script>
+
+<style lang="scss">
+	@import './index.rpx.css';
+</style>

BIN
static/images/icon-arrow-close.png


BIN
static/images/icon-arrow-left.png


BIN
static/index/xuanzhong.png


+ 4 - 0
uni_modules/uni-icons/changelog.md

@@ -1,3 +1,7 @@
+## 2.0.8(2023-12-14)
+- 修复 项目未使用 ts 情况下,打包报错的bug
+## 2.0.7(2023-12-14)
+- 修复 size 属性为 string 时,不加单位导致尺寸异常的bug
 ## 2.0.6(2023-12-11)
 - 优化 兼容老版本icon类型,如 top ,bottom 等
 ## 2.0.5(2023-12-11)

+ 6 - 4
uni_modules/uni-icons/components/uni-icons/uni-icons.uvue

@@ -49,11 +49,13 @@
 				return ''
 			},
 			iconSize() : string {
-				if (typeof this.size == 'string') {
-					return '' + this.size
+				const size = this.size
+				if (typeof size == 'string') {
+					const reg = /^[0-9]*$/g
+					return reg.test(size as string) ? '' + size + 'px' : '' + size;
+					// return '' + this.size
 				}
-				const size = this.size as number
-				return this.getFontSize(size)
+				return this.getFontSize(size as number)
 			},
 			styleObj() : UTSJSONObject {
 				if (this.fontFamily !== '') {

+ 11 - 9
uni_modules/uni-icons/components/uni-icons/uni-icons.vue

@@ -10,7 +10,13 @@
 </template>
 
 <script>
-	import { fontData } from './uniicons_file.ts';
+	import { fontData } from './uniicons_file_vue.js';
+
+	const getVal = (val) => {
+		const reg = /^[0-9]*$/g
+		return (typeof val === 'number' || reg.test(val)) ? val + 'px' : val;
+	}
+
 	// #ifdef APP-NVUE
 	var domModule = weex.requireModule('dom');
 	import iconUrl from './uniicons.ttf'
@@ -57,7 +63,7 @@
 		},
 		data() {
 			return {
-				icons: fontData 
+				icons: fontData
 			}
 		},
 		computed: {
@@ -68,12 +74,8 @@
 				}
 				return ''
 			},
-			iconSize()  {
-				if (typeof this.size == 'string') {
-					return this.size
-				}
-				const size = this.size
-				return size + 'px'
+			iconSize() {
+				return getVal(this.size)
 			},
 			styleObj() {
 				if (this.fontFamily !== '') {
@@ -105,4 +107,4 @@
 		text-decoration: none;
 		text-align: center;
 	}
-</style>
+</style>

+ 649 - 0
uni_modules/uni-icons/components/uni-icons/uniicons_file_vue.js

@@ -0,0 +1,649 @@
+
+export const fontData = [
+  {
+    "font_class": "arrow-down",
+    "unicode": "\ue6be"
+  },
+  {
+    "font_class": "arrow-left",
+    "unicode": "\ue6bc"
+  },
+  {
+    "font_class": "arrow-right",
+    "unicode": "\ue6bb"
+  },
+  {
+    "font_class": "arrow-up",
+    "unicode": "\ue6bd"
+  },
+  {
+    "font_class": "auth",
+    "unicode": "\ue6ab"
+  },
+  {
+    "font_class": "auth-filled",
+    "unicode": "\ue6cc"
+  },
+  {
+    "font_class": "back",
+    "unicode": "\ue6b9"
+  },
+  {
+    "font_class": "bars",
+    "unicode": "\ue627"
+  },
+  {
+    "font_class": "calendar",
+    "unicode": "\ue6a0"
+  },
+  {
+    "font_class": "calendar-filled",
+    "unicode": "\ue6c0"
+  },
+  {
+    "font_class": "camera",
+    "unicode": "\ue65a"
+  },
+  {
+    "font_class": "camera-filled",
+    "unicode": "\ue658"
+  },
+  {
+    "font_class": "cart",
+    "unicode": "\ue631"
+  },
+  {
+    "font_class": "cart-filled",
+    "unicode": "\ue6d0"
+  },
+  {
+    "font_class": "chat",
+    "unicode": "\ue65d"
+  },
+  {
+    "font_class": "chat-filled",
+    "unicode": "\ue659"
+  },
+  {
+    "font_class": "chatboxes",
+    "unicode": "\ue696"
+  },
+  {
+    "font_class": "chatboxes-filled",
+    "unicode": "\ue692"
+  },
+  {
+    "font_class": "chatbubble",
+    "unicode": "\ue697"
+  },
+  {
+    "font_class": "chatbubble-filled",
+    "unicode": "\ue694"
+  },
+  {
+    "font_class": "checkbox",
+    "unicode": "\ue62b"
+  },
+  {
+    "font_class": "checkbox-filled",
+    "unicode": "\ue62c"
+  },
+  {
+    "font_class": "checkmarkempty",
+    "unicode": "\ue65c"
+  },
+  {
+    "font_class": "circle",
+    "unicode": "\ue65b"
+  },
+  {
+    "font_class": "circle-filled",
+    "unicode": "\ue65e"
+  },
+  {
+    "font_class": "clear",
+    "unicode": "\ue66d"
+  },
+  {
+    "font_class": "close",
+    "unicode": "\ue673"
+  },
+  {
+    "font_class": "closeempty",
+    "unicode": "\ue66c"
+  },
+  {
+    "font_class": "cloud-download",
+    "unicode": "\ue647"
+  },
+  {
+    "font_class": "cloud-download-filled",
+    "unicode": "\ue646"
+  },
+  {
+    "font_class": "cloud-upload",
+    "unicode": "\ue645"
+  },
+  {
+    "font_class": "cloud-upload-filled",
+    "unicode": "\ue648"
+  },
+  {
+    "font_class": "color",
+    "unicode": "\ue6cf"
+  },
+  {
+    "font_class": "color-filled",
+    "unicode": "\ue6c9"
+  },
+  {
+    "font_class": "compose",
+    "unicode": "\ue67f"
+  },
+  {
+    "font_class": "contact",
+    "unicode": "\ue693"
+  },
+  {
+    "font_class": "contact-filled",
+    "unicode": "\ue695"
+  },
+  {
+    "font_class": "down",
+    "unicode": "\ue6b8"
+  },
+	{
+	  "font_class": "bottom",
+	  "unicode": "\ue6b8"
+	},
+  {
+    "font_class": "download",
+    "unicode": "\ue68d"
+  },
+  {
+    "font_class": "download-filled",
+    "unicode": "\ue681"
+  },
+  {
+    "font_class": "email",
+    "unicode": "\ue69e"
+  },
+  {
+    "font_class": "email-filled",
+    "unicode": "\ue69a"
+  },
+  {
+    "font_class": "eye",
+    "unicode": "\ue651"
+  },
+  {
+    "font_class": "eye-filled",
+    "unicode": "\ue66a"
+  },
+  {
+    "font_class": "eye-slash",
+    "unicode": "\ue6b3"
+  },
+  {
+    "font_class": "eye-slash-filled",
+    "unicode": "\ue6b4"
+  },
+  {
+    "font_class": "fire",
+    "unicode": "\ue6a1"
+  },
+  {
+    "font_class": "fire-filled",
+    "unicode": "\ue6c5"
+  },
+  {
+    "font_class": "flag",
+    "unicode": "\ue65f"
+  },
+  {
+    "font_class": "flag-filled",
+    "unicode": "\ue660"
+  },
+  {
+    "font_class": "folder-add",
+    "unicode": "\ue6a9"
+  },
+  {
+    "font_class": "folder-add-filled",
+    "unicode": "\ue6c8"
+  },
+  {
+    "font_class": "font",
+    "unicode": "\ue6a3"
+  },
+  {
+    "font_class": "forward",
+    "unicode": "\ue6ba"
+  },
+  {
+    "font_class": "gear",
+    "unicode": "\ue664"
+  },
+  {
+    "font_class": "gear-filled",
+    "unicode": "\ue661"
+  },
+  {
+    "font_class": "gift",
+    "unicode": "\ue6a4"
+  },
+  {
+    "font_class": "gift-filled",
+    "unicode": "\ue6c4"
+  },
+  {
+    "font_class": "hand-down",
+    "unicode": "\ue63d"
+  },
+  {
+    "font_class": "hand-down-filled",
+    "unicode": "\ue63c"
+  },
+  {
+    "font_class": "hand-up",
+    "unicode": "\ue63f"
+  },
+  {
+    "font_class": "hand-up-filled",
+    "unicode": "\ue63e"
+  },
+  {
+    "font_class": "headphones",
+    "unicode": "\ue630"
+  },
+  {
+    "font_class": "heart",
+    "unicode": "\ue639"
+  },
+  {
+    "font_class": "heart-filled",
+    "unicode": "\ue641"
+  },
+  {
+    "font_class": "help",
+    "unicode": "\ue679"
+  },
+  {
+    "font_class": "help-filled",
+    "unicode": "\ue674"
+  },
+  {
+    "font_class": "home",
+    "unicode": "\ue662"
+  },
+  {
+    "font_class": "home-filled",
+    "unicode": "\ue663"
+  },
+  {
+    "font_class": "image",
+    "unicode": "\ue670"
+  },
+  {
+    "font_class": "image-filled",
+    "unicode": "\ue678"
+  },
+  {
+    "font_class": "images",
+    "unicode": "\ue650"
+  },
+  {
+    "font_class": "images-filled",
+    "unicode": "\ue64b"
+  },
+  {
+    "font_class": "info",
+    "unicode": "\ue669"
+  },
+  {
+    "font_class": "info-filled",
+    "unicode": "\ue649"
+  },
+  {
+    "font_class": "left",
+    "unicode": "\ue6b7"
+  },
+  {
+    "font_class": "link",
+    "unicode": "\ue6a5"
+  },
+  {
+    "font_class": "list",
+    "unicode": "\ue644"
+  },
+  {
+    "font_class": "location",
+    "unicode": "\ue6ae"
+  },
+  {
+    "font_class": "location-filled",
+    "unicode": "\ue6af"
+  },
+  {
+    "font_class": "locked",
+    "unicode": "\ue66b"
+  },
+  {
+    "font_class": "locked-filled",
+    "unicode": "\ue668"
+  },
+  {
+    "font_class": "loop",
+    "unicode": "\ue633"
+  },
+  {
+    "font_class": "mail-open",
+    "unicode": "\ue643"
+  },
+  {
+    "font_class": "mail-open-filled",
+    "unicode": "\ue63a"
+  },
+  {
+    "font_class": "map",
+    "unicode": "\ue667"
+  },
+  {
+    "font_class": "map-filled",
+    "unicode": "\ue666"
+  },
+  {
+    "font_class": "map-pin",
+    "unicode": "\ue6ad"
+  },
+  {
+    "font_class": "map-pin-ellipse",
+    "unicode": "\ue6ac"
+  },
+  {
+    "font_class": "medal",
+    "unicode": "\ue6a2"
+  },
+  {
+    "font_class": "medal-filled",
+    "unicode": "\ue6c3"
+  },
+  {
+    "font_class": "mic",
+    "unicode": "\ue671"
+  },
+  {
+    "font_class": "mic-filled",
+    "unicode": "\ue677"
+  },
+  {
+    "font_class": "micoff",
+    "unicode": "\ue67e"
+  },
+  {
+    "font_class": "micoff-filled",
+    "unicode": "\ue6b0"
+  },
+  {
+    "font_class": "minus",
+    "unicode": "\ue66f"
+  },
+  {
+    "font_class": "minus-filled",
+    "unicode": "\ue67d"
+  },
+  {
+    "font_class": "more",
+    "unicode": "\ue64d"
+  },
+  {
+    "font_class": "more-filled",
+    "unicode": "\ue64e"
+  },
+  {
+    "font_class": "navigate",
+    "unicode": "\ue66e"
+  },
+  {
+    "font_class": "navigate-filled",
+    "unicode": "\ue67a"
+  },
+  {
+    "font_class": "notification",
+    "unicode": "\ue6a6"
+  },
+  {
+    "font_class": "notification-filled",
+    "unicode": "\ue6c1"
+  },
+  {
+    "font_class": "paperclip",
+    "unicode": "\ue652"
+  },
+  {
+    "font_class": "paperplane",
+    "unicode": "\ue672"
+  },
+  {
+    "font_class": "paperplane-filled",
+    "unicode": "\ue675"
+  },
+  {
+    "font_class": "person",
+    "unicode": "\ue699"
+  },
+  {
+    "font_class": "person-filled",
+    "unicode": "\ue69d"
+  },
+  {
+    "font_class": "personadd",
+    "unicode": "\ue69f"
+  },
+  {
+    "font_class": "personadd-filled",
+    "unicode": "\ue698"
+  },
+  {
+    "font_class": "personadd-filled-copy",
+    "unicode": "\ue6d1"
+  },
+  {
+    "font_class": "phone",
+    "unicode": "\ue69c"
+  },
+  {
+    "font_class": "phone-filled",
+    "unicode": "\ue69b"
+  },
+  {
+    "font_class": "plus",
+    "unicode": "\ue676"
+  },
+  {
+    "font_class": "plus-filled",
+    "unicode": "\ue6c7"
+  },
+  {
+    "font_class": "plusempty",
+    "unicode": "\ue67b"
+  },
+  {
+    "font_class": "pulldown",
+    "unicode": "\ue632"
+  },
+  {
+    "font_class": "pyq",
+    "unicode": "\ue682"
+  },
+  {
+    "font_class": "qq",
+    "unicode": "\ue680"
+  },
+  {
+    "font_class": "redo",
+    "unicode": "\ue64a"
+  },
+  {
+    "font_class": "redo-filled",
+    "unicode": "\ue655"
+  },
+  {
+    "font_class": "refresh",
+    "unicode": "\ue657"
+  },
+  {
+    "font_class": "refresh-filled",
+    "unicode": "\ue656"
+  },
+  {
+    "font_class": "refreshempty",
+    "unicode": "\ue6bf"
+  },
+  {
+    "font_class": "reload",
+    "unicode": "\ue6b2"
+  },
+  {
+    "font_class": "right",
+    "unicode": "\ue6b5"
+  },
+  {
+    "font_class": "scan",
+    "unicode": "\ue62a"
+  },
+  {
+    "font_class": "search",
+    "unicode": "\ue654"
+  },
+  {
+    "font_class": "settings",
+    "unicode": "\ue653"
+  },
+  {
+    "font_class": "settings-filled",
+    "unicode": "\ue6ce"
+  },
+  {
+    "font_class": "shop",
+    "unicode": "\ue62f"
+  },
+  {
+    "font_class": "shop-filled",
+    "unicode": "\ue6cd"
+  },
+  {
+    "font_class": "smallcircle",
+    "unicode": "\ue67c"
+  },
+  {
+    "font_class": "smallcircle-filled",
+    "unicode": "\ue665"
+  },
+  {
+    "font_class": "sound",
+    "unicode": "\ue684"
+  },
+  {
+    "font_class": "sound-filled",
+    "unicode": "\ue686"
+  },
+  {
+    "font_class": "spinner-cycle",
+    "unicode": "\ue68a"
+  },
+  {
+    "font_class": "staff",
+    "unicode": "\ue6a7"
+  },
+  {
+    "font_class": "staff-filled",
+    "unicode": "\ue6cb"
+  },
+  {
+    "font_class": "star",
+    "unicode": "\ue688"
+  },
+  {
+    "font_class": "star-filled",
+    "unicode": "\ue68f"
+  },
+  {
+    "font_class": "starhalf",
+    "unicode": "\ue683"
+  },
+  {
+    "font_class": "trash",
+    "unicode": "\ue687"
+  },
+  {
+    "font_class": "trash-filled",
+    "unicode": "\ue685"
+  },
+  {
+    "font_class": "tune",
+    "unicode": "\ue6aa"
+  },
+  {
+    "font_class": "tune-filled",
+    "unicode": "\ue6ca"
+  },
+  {
+    "font_class": "undo",
+    "unicode": "\ue64f"
+  },
+  {
+    "font_class": "undo-filled",
+    "unicode": "\ue64c"
+  },
+  {
+    "font_class": "up",
+    "unicode": "\ue6b6"
+  },
+	{
+	  "font_class": "top",
+	  "unicode": "\ue6b6"
+	},
+  {
+    "font_class": "upload",
+    "unicode": "\ue690"
+  },
+  {
+    "font_class": "upload-filled",
+    "unicode": "\ue68e"
+  },
+  {
+    "font_class": "videocam",
+    "unicode": "\ue68c"
+  },
+  {
+    "font_class": "videocam-filled",
+    "unicode": "\ue689"
+  },
+  {
+    "font_class": "vip",
+    "unicode": "\ue6a8"
+  },
+  {
+    "font_class": "vip-filled",
+    "unicode": "\ue6c6"
+  },
+  {
+    "font_class": "wallet",
+    "unicode": "\ue6b1"
+  },
+  {
+    "font_class": "wallet-filled",
+    "unicode": "\ue6c2"
+  },
+  {
+    "font_class": "weibo",
+    "unicode": "\ue68b"
+  },
+  {
+    "font_class": "weixin",
+    "unicode": "\ue691"
+  }
+]
+
+// export const fontData = JSON.parse<IconsDataItem>(fontDataJson)

+ 1 - 1
uni_modules/uni-icons/package.json

@@ -1,7 +1,7 @@
 {
   "id": "uni-icons",
   "displayName": "uni-icons 图标",
-  "version": "2.0.6",
+  "version": "2.0.8",
   "description": "图标组件,用于展示移动端常见的图标,可自定义颜色、大小。",
   "keywords": [
     "uni-ui",

+ 51 - 0
uni_modules/uni-nav-bar/changelog.md

@@ -0,0 +1,51 @@
+## 1.3.11(2023-03-29)
+- 修复 自定义状态栏高度闪动BUG
+## 1.3.10(2023-03-29)
+- 修复 暗黑模式下边线颜色错误的bug
+## 1.3.9(2022-10-13)
+- 修复 条件编译错误的bug
+## 1.3.8(2022-10-12)
+- 修复 nvue 环境 fixed 为 true 的情况下,无法置顶的 bug
+## 1.3.7(2022-08-11)
+- 修复 nvue 环境下 fixed 为 true 的情况下,无法置顶的 bug
+## 1.3.6(2022-06-30)
+- 修复 组件示例中插槽用法无法显示内容的bug
+## 1.3.5(2022-05-24)
+- 新增 stat 属性 ,可开启统计title 上报 ,仅使用了title 属性且项目开启了uni统计生效
+## 1.3.4(2022-01-24)
+- 更新 组件示例
+## 1.3.3(2022-01-24)
+- 新增 left-width/right-width属性 ,可修改左右两侧的宽度
+## 1.3.2(2022-01-18)
+- 修复 在vue下,标题不垂直居中的bug
+## 1.3.1(2022-01-18)
+- 修复 height 属性类型错误
+## 1.3.0(2022-01-18)
+- 新增 height 属性,可修改组件高度
+- 新增 dark 属性可可开启暗黑模式
+- 优化 标题字数过多显示省略号
+- 优化 插槽,插入内容可完全覆盖
+## 1.2.1(2022-01-10)
+- 修复 color 属性不生效的bug
+## 1.2.0(2021-11-19)
+- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
+- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-nav-bar](https://uniapp.dcloud.io/component/uniui/uni-nav-bar)
+## 1.1.0(2021-07-30)
+- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
+## 1.0.11(2021-05-12)
+- 新增 组件示例地址
+## 1.0.10(2021-04-30)
+- 修复 在nvue下fixed为true,宽度不能撑满的Bug
+## 1.0.9(2021-04-21)
+- 优化 添加依赖 uni-icons, 导入后自动下载依赖
+## 1.0.8(2021-04-14)
+- uni-ui 修复 uni-nav-bar 当 fixed 属性为 true 时铺不满屏幕的 bug
+
+## 1.0.7(2021-02-25)
+- 修复 easycom 下,找不到 uni-status-bar 的bug
+
+## 1.0.6(2021-02-05)
+- 优化 组件引用关系,通过uni_modules引用组件
+
+## 1.0.5(2021-02-05)
+- 调整为uni_modules目录规范

+ 357 - 0
uni_modules/uni-nav-bar/components/uni-nav-bar/uni-nav-bar.vue

@@ -0,0 +1,357 @@
+<template>
+	<view class="uni-navbar" :class="{'uni-dark':dark, 'uni-nvue-fixed': fixed}">
+		<view class="uni-navbar__content" :class="{ 'uni-navbar--fixed': fixed, 'uni-navbar--shadow': shadow, 'uni-navbar--border': border }"
+			:style="{ 'background-color': themeBgColor, 'border-bottom-color':themeColor }" >
+			<status-bar v-if="statusBar" />
+			<view :style="{ color: themeColor,backgroundColor: themeBgColor ,height:navbarHeight}"
+				class="uni-navbar__header">
+				<view @tap="onClickLeft" class="uni-navbar__header-btns uni-navbar__header-btns-left"
+					:style="{width:leftIconWidth}">
+					<slot name="left">
+						<view class="uni-navbar__content_view" v-if="leftIcon.length > 0">
+							<uni-icons :color="themeColor" :type="leftIcon" size="20" />
+						</view>
+						<view :class="{ 'uni-navbar-btn-icon-left': !leftIcon.length > 0 }" class="uni-navbar-btn-text"
+							v-if="leftText.length">
+							<text :style="{ color: themeColor, fontSize: '12px' }">{{ leftText }}</text>
+						</view>
+					</slot>
+				</view>
+				<view class="uni-navbar__header-container " @tap="onClickTitle">
+					<slot>
+						<view class="uni-navbar__header-container-inner" v-if="title.length>0">
+							<text class="uni-nav-bar-text uni-ellipsis-1"
+								:style="{color: themeColor }">{{ title }}</text>
+						</view>
+					</slot>
+				</view>
+				<view @click="onClickRight" class="uni-navbar__header-btns uni-navbar__header-btns-right"
+					:style="{width:rightIconWidth}">
+					<slot name="right">
+						<view v-if="rightIcon.length">
+							<uni-icons :color="themeColor" :type="rightIcon" size="22" />
+						</view>
+						<view class="uni-navbar-btn-text" v-if="rightText.length && !rightIcon.length">
+							<text class="uni-nav-bar-right-text" :style="{ color: themeColor}">{{ rightText }}</text>
+						</view>
+					</slot>
+				</view>
+			</view>
+		</view>
+		<!-- #ifndef APP-NVUE -->
+		<view class="uni-navbar__placeholder" v-if="fixed">
+			<status-bar v-if="statusBar" />
+			<view class="uni-navbar__placeholder-view" :style="{ height:navbarHeight}" />
+		</view>
+		<!-- #endif -->
+	</view>
+</template>
+
+<script>
+	import statusBar from "./uni-status-bar.vue";
+	const getVal = (val) => typeof val === 'number' ? val + 'px' : val;
+
+	/**
+	 * 
+	 * 
+	 * NavBar 自定义导航栏
+	 * @description 导航栏组件,主要用于头部导航
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=52
+	 * @property {Boolean} dark 开启黑暗模式
+	 * @property {String} title 标题文字
+	 * @property {String} leftText 左侧按钮文本
+	 * @property {String} rightText 右侧按钮文本
+	 * @property {String} leftIcon 左侧按钮图标(图标类型参考 [Icon 图标](http://ext.dcloud.net.cn/plugin?id=28) type 属性)
+	 * @property {String} rightIcon 右侧按钮图标(图标类型参考 [Icon 图标](http://ext.dcloud.net.cn/plugin?id=28) type 属性)
+	 * @property {String} color 图标和文字颜色
+	 * @property {String} backgroundColor 导航栏背景颜色
+	 * @property {Boolean} fixed = [true|false] 是否固定顶部
+	 * @property {Boolean} statusBar = [true|false] 是否包含状态栏
+	 * @property {Boolean} shadow = [true|false] 导航栏下是否有阴影
+	 * @property {Boolean} stat 是否开启统计标题上报
+	 * @event {Function} clickLeft 左侧按钮点击时触发
+	 * @event {Function} clickRight 右侧按钮点击时触发
+	 * @event {Function} clickTitle 中间标题点击时触发
+	 */
+	export default {
+		name: "UniNavBar",
+		components: {
+			statusBar
+		},
+		emits: ['clickLeft', 'clickRight', 'clickTitle'],
+		props: {
+			dark: {
+				type: Boolean,
+				default: false
+			},
+			title: {
+				type: String,
+				default: ""
+			},
+			leftText: {
+				type: String,
+				default: ""
+			},
+			rightText: {
+				type: String,
+				default: ""
+			},
+			leftIcon: {
+				type: String,
+				default: ""
+			},
+			rightIcon: {
+				type: String,
+				default: ""
+			},
+			fixed: {
+				type: [Boolean, String],
+				default: false
+			},
+			color: {
+				type: String,
+				default: ""
+			},
+			backgroundColor: {
+				type: String,
+				default: ""
+			},
+			statusBar: {
+				type: [Boolean, String],
+				default: false
+			},
+			shadow: {
+				type: [Boolean, String],
+				default: false
+			},
+			border: {
+				type: [Boolean, String],
+				default: true
+			},
+			height: {
+				type: [Number, String],
+				default: 44
+			},
+			leftWidth: {
+				type: [Number, String],
+				default: 60
+			},
+			rightWidth: {
+				type: [Number, String],
+				default: 60
+			},
+			stat: {
+				type: [Boolean, String],
+				default: ''
+			}
+		},
+		computed: {
+			themeBgColor() {
+				if (this.dark) {
+					// 默认值
+					if (this.backgroundColor) {
+						return this.backgroundColor
+					} else {
+						return this.dark ? '#333' : '#FFF'
+					}
+				}
+				return this.backgroundColor || '#FFF'
+			},
+			themeColor() {
+				if (this.dark) {
+					// 默认值
+					if (this.color) {
+						return this.color
+					} else {
+						return this.dark ? '#fff' : '#333'
+					}
+				}
+				return this.color || '#333'
+			},
+			navbarHeight() {
+				return getVal(this.height)
+			},
+			leftIconWidth() {
+				return getVal(this.leftWidth)
+			},
+			rightIconWidth() {
+				return getVal(this.rightWidth)
+			}
+		},
+		mounted() {
+			if (uni.report && this.stat && this.title !== '') {
+				uni.report('title', this.title)
+			}
+		},
+		methods: {
+			onClickLeft() {
+				this.$emit("clickLeft");
+			},
+			onClickRight() {
+				this.$emit("clickRight");
+			},
+			onClickTitle() {
+				this.$emit("clickTitle");
+			}
+		}
+	};
+</script>
+
+<style lang="scss" scoped>
+	$nav-height: 44px;
+
+	.uni-nvue-fixed {
+		/* #ifdef APP-NVUE */
+		position: sticky;
+		/* #endif */
+	}
+	.uni-navbar {
+		// box-sizing: border-box;
+	}
+
+	.uni-nav-bar-text {
+		/* #ifdef APP-PLUS */
+		font-size: 34rpx;
+		/* #endif */
+		/* #ifndef APP-PLUS */
+		font-size: 14px;
+		/* #endif */
+	}
+
+	.uni-nav-bar-right-text {
+		font-size: 12px;
+	}
+
+	.uni-navbar__content {
+		position: relative;
+		// background-color: #fff;
+		// box-sizing: border-box;
+		background-color: transparent;
+	}
+
+	.uni-navbar__content_view {
+		// box-sizing: border-box;
+	}
+
+	.uni-navbar-btn-text {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: column;
+		justify-content: flex-start;
+		align-items: center;
+		line-height: 12px;
+	}
+
+	.uni-navbar__header {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		padding: 0 10px;
+		flex-direction: row;
+		height: $nav-height;
+		font-size: 12px;
+	}
+
+	.uni-navbar__header-btns {
+		/* #ifndef APP-NVUE */
+		overflow: hidden;
+		display: flex;
+		/* #endif */
+		flex-wrap: nowrap;
+		flex-direction: row;
+		width: 120rpx;
+		// padding: 0 6px;
+		justify-content: center;
+		align-items: center;
+		/* #ifdef H5 */
+		cursor: pointer;
+		/* #endif */
+	}
+
+	.uni-navbar__header-btns-left {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		width: 120rpx;
+		justify-content: flex-start;
+		align-items: center;
+	}
+
+	.uni-navbar__header-btns-right {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		// width: 150rpx;
+		// padding-right: 30rpx;
+		justify-content: flex-end;
+		align-items: center;
+	}
+
+	.uni-navbar__header-container {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex: 1;
+		padding: 0 10px;
+		overflow: hidden;
+	}
+
+	.uni-navbar__header-container-inner {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex: 1;
+		flex-direction: row;
+		align-items: center;
+		justify-content: center;
+		font-size: 12px;
+		overflow: hidden;
+		// box-sizing: border-box;
+	}
+
+
+	.uni-navbar__placeholder-view {
+		height: $nav-height;
+	}
+
+	.uni-navbar--fixed {
+		position: fixed;
+		z-index: 998;
+		/* #ifdef H5 */
+		left: var(--window-left);
+		right: var(--window-right);
+		/* #endif */
+		/* #ifndef H5 */
+		left: 0;
+		right: 0;
+		/* #endif */
+
+	}
+
+	.uni-navbar--shadow {
+		box-shadow: 0 1px 6px #ccc;
+	}
+
+	.uni-navbar--border {
+		border-bottom-width: 1rpx;
+		border-bottom-style: solid;
+		border-bottom-color: #eee;
+	}
+
+	.uni-ellipsis-1 {
+		overflow: hidden;
+		/* #ifndef APP-NVUE */
+		white-space: nowrap;
+		text-overflow: ellipsis;
+		/* #endif */
+		/* #ifdef APP-NVUE */
+		lines: 1;
+		text-overflow: ellipsis;
+		/* #endif */
+	}
+
+	// 暗主题配置
+	.uni-dark {}
+</style>

+ 24 - 0
uni_modules/uni-nav-bar/components/uni-nav-bar/uni-status-bar.vue

@@ -0,0 +1,24 @@
+<template>
+	<view :style="{ height: statusBarHeight }" class="uni-status-bar">
+		<slot />
+	</view>
+</template>
+
+<script>
+	export default {
+		name: 'UniStatusBar',
+		data() {
+			return {
+				statusBarHeight: uni.getSystemInfoSync().statusBarHeight + 'px'
+			}
+		}
+	}
+</script>
+
+<style lang="scss" >
+	.uni-status-bar {
+		// width: 750rpx;
+		height: 20px;
+		// height: var(--status-bar-height);
+	}
+</style>

+ 86 - 0
uni_modules/uni-nav-bar/package.json

@@ -0,0 +1,86 @@
+{
+  "id": "uni-nav-bar",
+  "displayName": "uni-nav-bar 自定义导航栏",
+  "version": "1.3.11",
+  "description": "自定义导航栏组件,主要用于头部导航。",
+  "keywords": [
+    "uni-ui",
+    "导航",
+    "导航栏",
+    "自定义导航栏"
+],
+  "repository": "https://github.com/dcloudio/uni-ui",
+  "engines": {
+    "HBuilderX": ""
+  },
+  "directories": {
+    "example": "../../temps/example_temps"
+  },
+"dcloudext": {
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "无",
+      "permissions": "无"
+    },
+    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
+    "type": "component-vue"
+  },
+  "uni_modules": {
+    "dependencies": [
+			"uni-scss",
+			"uni-icons"
+		],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y"
+      },
+      "client": {
+        "App": {
+          "app-vue": "y",
+          "app-nvue": "y"
+        },
+        "H5-mobile": {
+          "Safari": "y",
+          "Android Browser": "y",
+          "微信浏览器(Android)": "y",
+          "QQ浏览器(Android)": "y"
+        },
+        "H5-pc": {
+          "Chrome": "y",
+          "IE": "y",
+          "Edge": "y",
+          "Firefox": "y",
+          "Safari": "y"
+        },
+        "小程序": {
+          "微信": "y",
+          "阿里": "y",
+          "百度": "y",
+          "字节跳动": "y",
+          "QQ": "y"
+        },
+        "快应用": {
+          "华为": "u",
+          "联盟": "u"
+        },
+        "Vue": {
+            "vue2": "y",
+            "vue3": "y"
+        }
+      }
+    }
+  }
+}

+ 15 - 0
uni_modules/uni-nav-bar/readme.md

@@ -0,0 +1,15 @@
+
+
+## NavBar 导航栏
+> **组件名:uni-nav-bar**
+> 代码块: `uNavBar`
+
+导航栏组件,主要用于头部导航。
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-nav-bar)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 
+
+
+
+
+