diff --git a/app/app.json b/app/app.json index 2695222..c0e8771 100644 --- a/app/app.json +++ b/app/app.json @@ -1,12 +1,12 @@ { "pages": [ "pages/order/show", + "pages/order/quasi", "pages/order/list", "pages/index/index", "pages/address/list", "pages/address/add", "pages/address/select", - "pages/order/quasi", "pages/shop/show", "pages/mine/mine", "pages/index/address", diff --git a/app/app.wxss b/app/app.wxss index 33c79ed..9ead761 100644 --- a/app/app.wxss +++ b/app/app.wxss @@ -23,6 +23,7 @@ page { } .trangle { + position: relative; padding-right: 15px; } diff --git a/app/images/Shop-icon.png b/app/images/Shop-icon.png deleted file mode 100644 index 2aae60d..0000000 Binary files a/app/images/Shop-icon.png and /dev/null differ diff --git a/app/images/chat_phone_normal.png b/app/images/chat_phone_normal.png new file mode 100644 index 0000000..c9e2f74 Binary files /dev/null and b/app/images/chat_phone_normal.png differ diff --git a/app/images/icon_hongbao.png b/app/images/icon_hongbao.png new file mode 100644 index 0000000..c2daf33 Binary files /dev/null and b/app/images/icon_hongbao.png differ diff --git a/app/images/icon_jian.png b/app/images/icon_jian.png new file mode 100644 index 0000000..012b44e Binary files /dev/null and b/app/images/icon_jian.png differ diff --git a/app/images/shop-512.png b/app/images/shop-512.png new file mode 100644 index 0000000..421d2de Binary files /dev/null and b/app/images/shop-512.png differ diff --git a/app/pages/index/index.js b/app/pages/index/index.js index fb33cb1..a97db55 100644 --- a/app/pages/index/index.js +++ b/app/pages/index/index.js @@ -1,19 +1,5 @@ //index.js //获取应用实例 - -function countdown(that) { - var second = that.data.second - if (second <= 0) { - return - } - var time = setTimeout(function () { - console.log(second) - that.setData({ - second: second - 1 - }); - countdown(that); - }, 1000) -} var app = getApp() Page({ data: { diff --git a/app/pages/order/constant.js b/app/pages/order/constant.js index 4a851a4..d100c10 100644 --- a/app/pages/order/constant.js +++ b/app/pages/order/constant.js @@ -6,4 +6,4 @@ export const ORDER_STATES = { "5": '订单已取消', "6": '退款中', "7": '已退款' -} \ No newline at end of file +} diff --git a/app/pages/order/quasi.wxml b/app/pages/order/quasi.wxml index 31f1560..565be2a 100644 --- a/app/pages/order/quasi.wxml +++ b/app/pages/order/quasi.wxml @@ -27,7 +27,7 @@ - + {{info.seller_name}} @@ -52,7 +52,9 @@ - 商城优惠 + + 商城优惠 + -¥{{info.cut_money}} @@ -63,8 +65,8 @@ 总计¥{{info.order_price}} 优惠¥{{info.cut_money}} - 实付 - ¥{{info.pay_price}} + + 实付 ¥{{info.pay_price}} @@ -74,9 +76,10 @@ 已优惠¥{{info.cut_money}} - 待支付 ¥{{info.pay_price}} + 待支付 + ¥{{info.pay_price}} - \ No newline at end of file diff --git a/app/pages/order/quasi.wxss b/app/pages/order/quasi.wxss index 2e68e15..61be79d 100644 --- a/app/pages/order/quasi.wxss +++ b/app/pages/order/quasi.wxss @@ -26,8 +26,8 @@ .quasi-goods__img { margin-top: -2px; - width: 20px; - height: 20px; + width: 18px; + height: 18px; vertical-align: middle; } @@ -48,6 +48,13 @@ flex: 2; } +.quasi-goods__item-name-icon { + margin: -2px 5px 0 0; + height: 21px; + width: 21px; + vertical-align: middle; +} + .quasi-goods__item-name_grey { color: #999; } diff --git a/app/pages/order/show.js b/app/pages/order/show.js index 4fca748..fcf3e3a 100644 --- a/app/pages/order/show.js +++ b/app/pages/order/show.js @@ -1,41 +1,54 @@ // pages/order/show.js +import Countdown from '../../utils/countdown' +import { countdownFormat } from '../../utils/util' Page({ data: { + activeNavIndex: 1, + tabNavs: ['订单状态', '订单详情'], + statusImgs: { + '1': '/images/status/order_status_money_icon_current@2x.png', + '2': '/images/status/order_status_shop_icon_current@2x.png', + '3': '/images/status/order_status_rider_icon_current@2x.png', + '4': '/images/status/order_status_service_icon_current@2x.png', + '5': '/images/status/order_status_service_icon_fail_current@2x.png', + '6': '/images/status/order_status_service_icon_fail_current@2x.png', + '7': '/images/status/order_status_service_icon_fail_current@2x.png' + }, info: { - "order_id": "1370", - "order_no": "2017042815510158201158862546", - "day_sn": "1", + "order_id": "1375", + "order_no": "2017050316304632448020041071", + "day_sn": "4", "seller_id": "2", "user_id": "4", - "state": "5", - "add_time": "1493365861", - "order_price": "42.98", - "pay_price": "34.98", - "goods_price": "22.98", + "state": "3", + "add_time": "1493800246", + "order_price": "30.00", + "pay_price": "22.00", + "goods_price": "20.00", "cut_money": "8.00", "coupon_money": "0.00", - "packing_fee": "2.00", - "delivery_fee": "18.00", + "packing_fee": "0.00", + "delivery_fee": "10.00", "receiver": "test4", - "receiver_addr": "龙华大厦", - "receiver_gps": "120.69101,28.002974", - "receiver_phone": "13000000005", - "receive_time": "1493369461", - "distance": "7.177", - "remark": null, + "receiver_addr": "电商大厦", + "receiver_gps": "120.737561,27.979617", + "receiver_phone": "13000000004", + "receive_time": "1493803846", + "distance": "1.707", + "remark": "", "is_reviews": "0", "is_delete": "0", "delivery_order_id": "0", - "title": "鸡腿饭(大)", + "title": "鸡翅饭", "receiver_city": "330300", - "take_time": null, + "take_time": "1493800254", "remind_time": "0", - "pay_type": null, + "pay_type": "3", "sys_settle_no": null, "settle_no": null, "commision": "0.00", "user_coupon_id": null, - "real_delivery_fee": "18.00", + "real_delivery_fee": "10.00", "cut_delivery_fee": "0.00", "service_money": "0.00", "seller_name": "鲜极道", @@ -43,46 +56,53 @@ Page({ "delivery_phone": "13906641410", "goods": [ { - "goods_id": "29", - "sub_id": "50", + "goods_id": "32", + "sub_id": "0", "seller_id": "2", - "detail": "鸡腿饭 xx", - "sales": "46", + "detail": "鸡翅饭 xx", + "sales": "43", "praise": "0", "state": "1", - "commision": "3.00", - "goods_name": "鸡腿饭(大)", - "price": "22.98", - "packing_fee": "2.00", - "stock": "74", + "commision": null, + "goods_name": "鸡翅饭", + "price": "20.00", + "packing_fee": "0.00", + "stock": "54", "is_delete": "0", - "pic_url": "http://test.storesystem.cn/Uploadfile/Img/seller_goods/1461034075146103407535640.jpg", + "pic_url": null, "num": "1", - "price_sum": "22.98" + "price_sum": "20.00" } ], "expire_time": 0, "left_time": 0, "flow": [ { - "time": "1493365861", + "time": "1493800246", "state": "1", "status": "订单提交成功,待支付", "remark": "" }, { - "time": "1493366164", - "state": "5", - "status": "订单已取消", + "time": "1493800252", + "state": "2", + "status": "支付成功,等待商家接单", + "remark": "" + }, + { + "time": "1493800254", + "state": "3", + "status": "商家已接单", "remark": "" } ], + "run_order_id": "6408", "localphone": "13906641410" - } - + }, }, onLoad: function (options) { // 页面初始化 options为页面跳转所带来的参数 + this.initCountdown(287) }, onReady: function () { // 页面渲染完成 @@ -95,5 +115,34 @@ Page({ }, onUnload: function () { // 页面关闭 + if (this.countdown) { + this.countdown.stop() + } + }, + tabChange(e) { + var {current} = e.detail + this.setData({ + activeNavIndex: current + }) + }, + navChange(e) { + var {id} = e.currentTarget + this.setData({ + activeNavIndex: id + }) + }, + + initCountdown(count) { + this.setData({ + count + }) + var countdown = new Countdown(this, 'count') + countdown.start((count) => { + this.setData({ + countLabel: countdownFormat(count) + }) + }) + this.countdown = countdown } + }) \ No newline at end of file diff --git a/app/pages/order/show.wxml b/app/pages/order/show.wxml index c629335..cfeacac 100644 --- a/app/pages/order/show.wxml +++ b/app/pages/order/show.wxml @@ -2,19 +2,141 @@ - + 订单状态 - - 订单详情 + + - + - + + + {{item.status}} + + {{item.time}} + + + + 支付剩余时间 + {{countLabel}} + + + 取消订单 + 立即付款 + - - 详情 + + 订单详情 + + + + + {{info.seller_name}} + + + 爱跑腿专送 + + + + + {{item.goods_name}} + x{{item.num}} + ¥{{item.price_sum}} + + + + + 餐盒费 + + ¥{{info.packing_fee}} + + + 配送费 + + ¥{{info.delivery_fee}} + + + + + + 商城优惠 + + + -¥{{info.cut_money}} + + + + + + 总计¥{{info.order_price}} 优惠¥{{info.cut_money}} + + + + 实付 ¥{{info.pay_price}} + + + + + + 配送信息 + + + + 期望时间 + + 立即配送 + + + + 配送地址 + + + + {{info.receiver}} {{info.receiver_phone}} + + + {{info.receiver_addr}} + + + + + + 配送服务 + + + 爱跑腿专送 + + + + 订单信息 + + + + 订单号码 + + + {{info.order_no}} + + + + + 订单时间 + + + {{info.add_time}} + + + + + 支付方式 + + + 在线支付 + + + \ No newline at end of file diff --git a/app/pages/order/show.wxss b/app/pages/order/show.wxss index f74402d..590a846 100644 --- a/app/pages/order/show.wxss +++ b/app/pages/order/show.wxss @@ -1,4 +1,5 @@ /* pages/order/show.wxss */ +@import './quasi.wxss'; .tab { display: flex; @@ -8,6 +9,7 @@ } .tab__navbar { + position: relative; display: flex; color: #999; border-bottom: 1rpx solid #e8e8e8; @@ -33,3 +35,112 @@ .tab-swiper { flex: 1; } + +.tab__swiper-item { + position: absolute; + overflow: auto; +} + + +/* flow-list */ +.flow-item { + position: relative; + margin-left: 50px; + padding: 10px 0; +} + +.flow-item:not(:first-child) { + border-top: 1rpx solid #e8e8e8; +} + +.flow-item::before { + content: ''; + position: absolute; + left: -25px; + top: 50%; + width: 5px; + height: 5px; + background-color: #ff5801; + border-radius: 50%; + transform: translate(-50%, -50%); +} + +.flow-item:not(:last-child)::after { + content: ''; + position: absolute; + left: -25px; + top: 50%; + height: 100%; + border-left: 2rpx solid #ff5801; + transform: translateX(-50%); +} + +.flow-item__time { + position: absolute; + top: 10px; + right: 10px; + color: #999; + font-size: 0.8em; +} + +.flow-item__img { + position: absolute; + top: 50%; + left: -25px; + width:20px; + height: 20px; + border: 5px solid #fff; + transform: translate(-50%, -50%); + z-index: 1; +} + + +/* actionbar*/ +.actionbar { + display: flex; + position: absolute; + left: 0; + bottom: 0; + height: 50px; + width: 100%; + border-top: 1rpx solid #e8e8e8; +} + +.actionbar-btn_action { + flex: 1; + line-height: 50px; + text-align: center; +} + +.actionbar-btn_primary { + background-color: #ff5801; + color: #fff; +} + +/* order-show_left-time*/ +.order-show__left-time { + position: absolute; + bottom: 60px; + left: 10px; + font-size: 0.8em; +} + +.phone { + position: absolute; + top: 5px; + right: 8px; +} +.phone__icon { + width: 26px; + height: 26px; +} + + +.tab__swiper-item_detail { + background-color: #f8f8f8; +} + +.weui-cell__hd { + min-width: 5em; + color: #999; +} \ No newline at end of file diff --git a/app/utils/WxValidate.js b/app/utils/WxValidate.js new file mode 100644 index 0000000..82497bf --- /dev/null +++ b/app/utils/WxValidate.js @@ -0,0 +1,378 @@ +/** + * 创建验证字段的工厂函数 + * + * @param {Object} rules 验证字段的规则 + * @param {Object} messages 验证字段的提示信息 + * + */ +class WxValidate { + constructor(rules = {}, messages = {}) { + Object.assign(this, { + rules, + messages, + }) + this.__init() + } + + /** + * __init + */ + __init() { + this.__initMethods() + this.__initDefaults() + this.__initErrorList() + } + + /** + * 初始化错误信息 + */ + __initErrorList() { + this.errorList = [] + } + + /** + * 初始化默认提示信息 + */ + __initDefaults() { + this.defaults = { + messages: { + required: '这是必填字段。', + email: '请输入有效的电子邮件地址。', + tel: '请输入11位的手机号码。', + url: '请输入有效的网址。', + date: '请输入有效的日期。', + dateISO: '请输入有效的日期(ISO),例如:2009-06-23,1998/01/22。', + number: '请输入有效的数字。', + digits: '只能输入数字。', + idcard: '请输入18位的有效身份证。', + equalTo: this.formatTpl('输入值必须和 {0} 相同。'), + contains: this.formatTpl('输入值必须包含 {0}。'), + minlength: this.formatTpl('最少要输入 {0} 个字符。'), + maxlength: this.formatTpl('最多可以输入 {0} 个字符。'), + rangelength: this.formatTpl('请输入长度在 {0} 到 {1} 之间的字符。'), + min: this.formatTpl('请输入不小于 {0} 的数值。'), + max: this.formatTpl('请输入不大于 {0} 的数值。'), + range: this.formatTpl('请输入范围在 {0} 到 {1} 之间的数值。'), + } + } + } + + /** + * 初始化默认验证方法 + */ + __initMethods() { + const that = this + that.methods = { + /** + * 验证必填元素 + */ + required(value, param) { + if (!that.depend(param)) { + return 'dependency-mismatch' + } + return value.length > 0 + }, + /** + * 验证电子邮箱格式 + */ + email(value) { + return that.optional(value) || /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/.test(value) + }, + /** + * 验证手机格式 + */ + tel(value) { + return that.optional(value) || /^1[34578]\d{9}$/.test(value) + }, + /** + * 验证URL格式 + */ + url(value) { + return that.optional(value) || /^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})).?)(?::\d{2,5})?(?:[/?#]\S*)?$/i.test(value) + }, + /** + * 验证日期格式 + */ + date(value) { + return that.optional(value) || !/Invalid|NaN/.test(new Date(value).toString()) + }, + /** + * 验证ISO类型的日期格式 + */ + dateISO(value) { + return that.optional(value) || /^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$/.test(value) + }, + /** + * 验证十进制数字 + */ + number(value) { + return that.optional(value) || /^(?:-?\d+|-?\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test(value) + }, + /** + * 验证整数 + */ + digits(value) { + return that.optional(value) || /^\d+$/.test(value) + }, + /** + * 验证身份证号码 + */ + idcard(value) { + return that.optional(value) || /^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/.test(value) + }, + /** + * 验证两个输入框的内容是否相同 + */ + equalTo(value, param) { + return that.optional(value) || value === that.scope.detail.value[param] + }, + /** + * 验证是否包含某个值 + */ + contains(value, param) { + return that.optional(value) || value.indexOf(param) >= 0 + }, + /** + * 验证最小长度 + */ + minlength(value, param) { + return that.optional(value) || value.length >= param + }, + /** + * 验证最大长度 + */ + maxlength(value, param) { + return that.optional(value) || value.length <= param + }, + /** + * 验证一个长度范围[min, max] + */ + rangelength(value, param) { + return that.optional(value) || (value.length >= param[0] && value.length <= param[1]) + }, + /** + * 验证最小值 + */ + min(value, param) { + return that.optional(value) || value >= param + }, + /** + * 验证最大值 + */ + max(value, param) { + return that.optional(value) || value <= param + }, + /** + * 验证一个值范围[min, max] + */ + range(value, param) { + return that.optional(value) || (value >= param[0] && value <= param[1]) + }, + } + } + + /** + * 添加自定义验证方法 + * @param {String} name 方法名 + * @param {Function} method 函数体,接收两个参数(value, param),value表示元素的值,param表示参数 + * @param {String} message 提示信息 + */ + addMethod(name, method, message) { + this.methods[name] = method + this.defaults.messages[name] = message !== undefined ? message : this.defaults.messages[name] + } + + /** + * 判断验证方法是否存在 + */ + isValidMethod(value) { + let methods = [] + for(let method in this.methods) { + if (method && typeof this.methods[method] === 'function') { + methods.push(method) + } + } + return methods.indexOf(value) !== -1 + } + + /** + * 格式化提示信息模板 + */ + formatTpl(source, params) { + const that = this + if (arguments.length === 1) { + return function() { + let args = Array.from(arguments) + args.unshift(source) + return that.formatTpl.apply(this, args) + } + } + if (params === undefined) { + return source + } + if (arguments.length > 2 && params.constructor !== Array) { + params = Array.from(arguments).slice(1) + } + if (params.constructor !== Array) { + params = [ params ] + } + params.forEach(function(n, i) { + source = source.replace(new RegExp("\\{" + i + "\\}", "g"), function() { + return n + }) + }) + return source + } + + /** + * 判断规则依赖是否存在 + */ + depend(param) { + switch(typeof param) { + case 'boolean': + param = param + break + case 'string': + param = !!param.length + break + case 'function': + param = param() + default: + param = !0 + } + return param + } + + /** + * 判断输入值是否为空 + */ + optional(value) { + return !this.methods.required(value) && 'dependency-mismatch' + } + + /** + * 获取自定义字段的提示信息 + * @param {String} param 字段名 + * @param {Object} rule 规则 + */ + customMessage(param, rule) { + const params = this.messages[param] + const isObject = typeof params === 'object' + if (params && isObject) return params[rule.method] + } + + /** + * 获取某个指定字段的提示信息 + * @param {String} param 字段名 + * @param {Object} rule 规则 + */ + defaultMessage(param, rule) { + let message = this.customMessage(param, rule) || this.defaults.messages[rule.method] + let type = typeof message + + if (type === 'undefined') { + message = `Warning: No message defined for ${rule.method}.` + } else if (type === 'function') { + message = message.call(this, rule.parameters) + } + + return message + } + + /** + * 缓存错误信息 + * @param {String} param 字段名 + * @param {Object} rule 规则 + * @param {String} value 元素的值 + */ + formatTplAndAdd(param, rule, value) { + let msg = this.defaultMessage(param, rule) + + this.errorList.push({ + param: param, + msg: msg, + value: value, + }) + } + + /** + * 验证某个指定字段的规则 + * @param {String} param 字段名 + * @param {Object} rules 规则 + * @param {Object} event 表单数据对象 + */ + checkParam(param, rules, event) { + + // 缓存表单数据对象 + this.scope = event + + // 缓存字段对应的值 + const data = event.detail.value + const value = data[param] || '' + + // 遍历某个指定字段的所有规则,依次验证规则,否则缓存错误信息 + for(let method in rules) { + + // 判断验证方法是否存在 + if (this.isValidMethod(method)) { + + // 缓存规则的属性及值 + const rule = { + method: method, + parameters: rules[method] + } + + // 调用验证方法 + const result = this.methods[method](value, rule.parameters) + + // 若result返回值为dependency-mismatch,则说明该字段的值为空或非必填字段 + if (result === 'dependency-mismatch') { + continue + } + + // 判断是否通过验证,否则缓存错误信息,跳出循环 + if (!result) { + this.formatTplAndAdd(param, rule, value) + break + } + } + } + } + + /** + * 验证所有字段的规则,返回验证是否通过 + * @param {Object} event 表单数据对象 + */ + checkForm(event) { + this.errorList = [] + + for (let param in this.rules) { + this.checkParam(param, this.rules[param], event) + } + + return this.valid() + } + + /** + * 返回验证是否通过 + */ + valid() { + return this.size() === 0 + } + + /** + * 返回错误信息的个数 + */ + size() { + return this.errorList.length + } + + /** + * 返回所有错误信息 + */ + validationErrors() { + return this.errorList + } +} + +export default WxValidate \ No newline at end of file diff --git a/app/utils/coordtransform.js b/app/utils/coordtransform.js new file mode 100644 index 0000000..be1a7d4 --- /dev/null +++ b/app/utils/coordtransform.js @@ -0,0 +1,153 @@ +/** + * Created by Wandergis on 2015/7/8. + * 提供了百度坐标(BD09)、国测局坐标(火星坐标,GCJ02)、和WGS84坐标系之间的转换 + */ +//UMD魔法代码 +// if the module has no dependencies, the above pattern can be simplified to +(function (root, factory) { + if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + define([], factory); + } else if (typeof module === 'object' && module.exports) { + // Node. Does not work with strict CommonJS, but + // only CommonJS-like environments that support module.exports, + // like Node. + module.exports = factory(); + } else { + // Browser globals (root is window) + root.coordtransform = factory(); + } +}(this, function () { + //定义一些常量 + var x_PI = 3.14159265358979324 * 3000.0 / 180.0; + var PI = 3.1415926535897932384626; + var a = 6378245.0; + var ee = 0.00669342162296594323; + /** + * 百度坐标系 (BD-09) 与 火星坐标系 (GCJ-02)的转换 + * 即 百度 转 谷歌、高德 + * @param bd_lon + * @param bd_lat + * @returns {*[]} + */ + var bd09togcj02 = function bd09togcj02(bd_lon, bd_lat) { + var bd_lon = +bd_lon; + var bd_lat = +bd_lat; + var x = bd_lon - 0.0065; + var y = bd_lat - 0.006; + var z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * x_PI); + var theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_PI); + var gg_lng = z * Math.cos(theta); + var gg_lat = z * Math.sin(theta); + return [gg_lng, gg_lat] + }; + + /** + * 火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的转换 + * 即谷歌、高德 转 百度 + * @param lng + * @param lat + * @returns {*[]} + */ + var gcj02tobd09 = function gcj02tobd09(lng, lat) { + var lat = +lat; + var lng = +lng; + var z = Math.sqrt(lng * lng + lat * lat) + 0.00002 * Math.sin(lat * x_PI); + var theta = Math.atan2(lat, lng) + 0.000003 * Math.cos(lng * x_PI); + var bd_lng = z * Math.cos(theta) + 0.0065; + var bd_lat = z * Math.sin(theta) + 0.006; + return [bd_lng, bd_lat] + }; + + /** + * WGS84转GCj02 + * @param lng + * @param lat + * @returns {*[]} + */ + var wgs84togcj02 = function wgs84togcj02(lng, lat) { + var lat = +lat; + var lng = +lng; + if (out_of_china(lng, lat)) { + return [lng, lat] + } else { + var dlat = transformlat(lng - 105.0, lat - 35.0); + var dlng = transformlng(lng - 105.0, lat - 35.0); + var radlat = lat / 180.0 * PI; + var magic = Math.sin(radlat); + magic = 1 - ee * magic * magic; + var sqrtmagic = Math.sqrt(magic); + dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * PI); + dlng = (dlng * 180.0) / (a / sqrtmagic * Math.cos(radlat) * PI); + var mglat = lat + dlat; + var mglng = lng + dlng; + return [mglng, mglat] + } + }; + + /** + * GCJ02 转换为 WGS84 + * @param lng + * @param lat + * @returns {*[]} + */ + var gcj02towgs84 = function gcj02towgs84(lng, lat) { + var lat = +lat; + var lng = +lng; + if (out_of_china(lng, lat)) { + return [lng, lat] + } else { + var dlat = transformlat(lng - 105.0, lat - 35.0); + var dlng = transformlng(lng - 105.0, lat - 35.0); + var radlat = lat / 180.0 * PI; + var magic = Math.sin(radlat); + magic = 1 - ee * magic * magic; + var sqrtmagic = Math.sqrt(magic); + dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * PI); + dlng = (dlng * 180.0) / (a / sqrtmagic * Math.cos(radlat) * PI); + var mglat = lat + dlat; + var mglng = lng + dlng; + return [lng * 2 - mglng, lat * 2 - mglat] + } + }; + + var transformlat = function transformlat(lng, lat) { + var lat = +lat; + var lng = +lng; + var ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * Math.sqrt(Math.abs(lng)); + ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0; + ret += (20.0 * Math.sin(lat * PI) + 40.0 * Math.sin(lat / 3.0 * PI)) * 2.0 / 3.0; + ret += (160.0 * Math.sin(lat / 12.0 * PI) + 320 * Math.sin(lat * PI / 30.0)) * 2.0 / 3.0; + return ret + }; + + var transformlng = function transformlng(lng, lat) { + var lat = +lat; + var lng = +lng; + var ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * Math.sqrt(Math.abs(lng)); + ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0; + ret += (20.0 * Math.sin(lng * PI) + 40.0 * Math.sin(lng / 3.0 * PI)) * 2.0 / 3.0; + ret += (150.0 * Math.sin(lng / 12.0 * PI) + 300.0 * Math.sin(lng / 30.0 * PI)) * 2.0 / 3.0; + return ret + }; + + /** + * 判断是否在国内,不在国内则不做偏移 + * @param lng + * @param lat + * @returns {boolean} + */ + var out_of_china = function out_of_china(lng, lat) { + var lat = +lat; + var lng = +lng; + // 纬度3.86~53.55,经度73.66~135.05 + return !(lng > 73.66 && lng < 135.05 && lat > 3.86 && lat < 53.55); + }; + + return { + bd09togcj02: bd09togcj02, + gcj02tobd09: gcj02tobd09, + wgs84togcj02: wgs84togcj02, + gcj02towgs84: gcj02towgs84 + } +})); diff --git a/app/utils/countdown.js b/app/utils/countdown.js new file mode 100644 index 0000000..fb78c56 --- /dev/null +++ b/app/utils/countdown.js @@ -0,0 +1,26 @@ +export default class Countdown { + constructor(page, prop) { + this.page = page + this.prop = prop + } + + start(cb) { + var that = this; + var {page, prop} = that + var second = page.data[prop] + if (second <= 0) { + return + } + cb && cb(second) + that.timer = setTimeout(function () { + page.setData({ + [prop]: second - 1 + }); + that.start(cb); + }, 1000) + } + + stop() { + clearTimeout(this.timer) + } +} \ No newline at end of file diff --git a/app/utils/qqmap-wx-jssdk.min.js b/app/utils/qqmap-wx-jssdk.min.js new file mode 100644 index 0000000..3323249 --- /dev/null +++ b/app/utils/qqmap-wx-jssdk.min.js @@ -0,0 +1,2 @@ +var _createClass=function(){function a(e,c){for(var b=0;b=l[i]&&i(0===i?9:1)&&(i+=1),d[n](t,i)[a].replace("%s",t)}function r(e,n){return n=n?t(n):new Date,(n-t(e))/1e3}function i(t){for(var e=1,n=0,r=Math.abs(t);t>=l[n]&&n1&&(n+="s"),[t+" "+n+" ago","in "+t+" "+n]},zh_CN:function(t,e){if(0===e)return["刚刚","片刻后"];var n=s[parseInt(e/2)];return[t+n+"前",t+n+"后"]}},l=[60,60,24,7,365/7/12,12],h=6,p="datetime";return u.register=function(t,e){d[t]=e},u}); \ No newline at end of file diff --git a/app/utils/util.js b/app/utils/util.js index c5cccf3..dfc8ca1 100644 --- a/app/utils/util.js +++ b/app/utils/util.js @@ -1,21 +1,179 @@ -function formatTime(date) { - var year = date.getFullYear() - var month = date.getMonth() + 1 - var day = date.getDate() +'use strict'; +import timeago from './timeago.min' +import QQMapWX from './qqmap-wx-jssdk.min' +import { gcj02tobd09 } from './coordtransform' +// import { host } from '../config' - var hour = date.getHours() - var minute = date.getMinutes() - var second = date.getSeconds() +const qqmap = new QQMapWX({ + key: 'FPOBZ-UT2K2-ZFYUC-CX67E-IOOYS-7XFQ6' +}); - - return [year, month, day].map(formatNumber).join('/') + ' ' + [hour, minute, second].map(formatNumber).join(':') +function resolveAdInfo(adInfo) { + const {city, district, adcode} = adInfo + return { + city, district, + district_id: adcode, + city_id: adcode.replace(/\d{2}$/, '00') + } } -function formatNumber(n) { - n = n.toString() - return n[1] ? n : '0' + n +// 解析地址 +export function reverseGeocoder(options) { + const { + location, success, complete + } = options + qqmap.reverseGeocoder({ + location, + success: function (res) { + var address = resolveAdInfo(res.result.ad_info) + success && success(address) + }, + fail: function (err) { + console.log(err) + }, + complete + }) } -module.exports = { - formatTime: formatTime +// 获取当前地理位置 +export function getCurrentAddress(options) { + const { + success, complete + } = options + wx.getLocation({ + type: 'gcj02', + success(res) { + getAddressFromLocation({ + location: { + latitude: res.latitude, + longitude: res.longitude, + }, + success, complete + }) + } + }) } + +// 根据坐标获取地址信息 +export function getAddressFromLocation(options) { + const {location, success} = options + getPois({ + location, + success(pois) { + var poi = pois[0] + if (poi) { + var address = Object.assign({ + address_name: poi.title, + location, + }, resolveAdInfo(poi.ad_info)) + + success && success(address) + } + } + }) +} + +// 获取兴趣点 +export function getPois(options) { + const { + location, success, complete + } = options + qqmap.reverseGeocoder({ + location, + get_poi: 1, + success: function (res) { + success && success(res.result.pois) + }, + fail: function (err) { + console.log(err) + }, + complete + }) +} + +export function getPrevPage() { + const pages = getCurrentPages() + return pages[pages.length - 2] +} + +export function fetch(options) { + wx.request({ + url: `https://${host}/${options.url}`, + data: Object.assign(options.data, { + 'app_v': 'ipaotui_mini' + }), + method: options.method || 'POST', + header: { + 'content-type': 'application/x-www-form-urlencoded' + }, + success: function (res) { + const data = res.data + if (data.State == 'Success') { + options.success && options.success(data.data) + } else { + alert(data.info) + options.error && options.error(data.info) + } + options.complete && options.complete() + } + }) +} + +// 提示框 +export function alert(content, callback) { + wx.showModal({ + title: '提示', + content: content, + showCancel: false, + success: callback + }) +} +// 确认框 +export function confirm(options) { + const { + content, confirmText, + ok, + } = options + wx.showModal({ + content, + confirmText, + cancelText: '关闭', + success(res) { + if (res.confirm) { + ok && ok() + } + } + }) +} + +// 加载提示 +export function showLoading() { + wx.showToast({ + icon: 'loading', + duration: 10000, + title: '加载中...', + mask: true, + }) +} +export function hideLoading() { + wx.hideToast() +} + +// 时间格式化 +export function datetimeFormat(unix_timestamp) { + return new timeago().format(new Date(unix_timestamp * 1000), 'zh_CN'); +} + +// 坐标格式化 +export function coordFormat(location) { + // gcj02 转 bd09 + return gcj02tobd09(location.longitude, location.latitude).join(',') +} + +// 倒计时格式化 +export function countdownFormat(count) { + var seconds = count % 60 + count = Math.floor(count / 60) + var minutes = count % 60 + return `${minutes}分钟${seconds}秒` +} \ No newline at end of file