订单详情

This commit is contained in:
Kiyan 2017-05-04 13:08:03 +08:00
parent c68b9d3a26
commit 87d9148977
20 changed files with 1079 additions and 82 deletions

View File

@ -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",

View File

@ -23,6 +23,7 @@ page {
}
.trangle {
position: relative;
padding-right: 15px;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

BIN
app/images/icon_hongbao.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 699 B

BIN
app/images/icon_jian.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 749 B

BIN
app/images/shop-512.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@ -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: {

View File

@ -6,4 +6,4 @@ export const ORDER_STATES = {
"5": '订单已取消',
"6": '退款中',
"7": '已退款'
}
}

View File

@ -27,7 +27,7 @@
</view>
<view class="quasi-goods">
<view class="quasi-goods__hd">
<image class="quasi-goods__img" src="/images/Shop-icon.png"></image>
<image class="quasi-goods__img" src="/images/shop-512.png"></image>
{{info.seller_name}}
</view>
<view class="quasi-goods__bd">
@ -52,7 +52,9 @@
</view>
<view class="quasi-goods__list">
<view class="quasi-goods__item">
<view class="quasi-goods__item-name quasi-goods__item-name_grey">商城优惠</view>
<view class="quasi-goods__item-name quasi-goods__item-name_grey">
<image class="quasi-goods__item-name-icon" src="/images/icon_jian.png"></image>商城优惠
</view>
<view class="quasi-goods__item-num"></view>
<view class="quasi-goods__item-price">-¥{{info.cut_money}}</view>
</view>
@ -63,8 +65,8 @@
总计¥{{info.order_price}} 优惠¥{{info.cut_money}}
</view>
<view class="quasi-goods__item-num"></view>
<view class="quasi-goods__item-price">实付
<text class="primary-color">¥{{info.pay_price}}</text>
<view class="quasi-goods__item-price primary-color">
实付 ¥{{info.pay_price}}
</view>
</view>
</view>
@ -74,9 +76,10 @@
<view class="quasi-actions">
<view class="quasi-actions__cut">已优惠¥{{info.cut_money}}</view>
<view class="quasi-actions__pay">
待支付 <text class="primary-color">¥{{info.pay_price}}</text>
待支付
<text class="primary-color">¥{{info.pay_price}}</text>
</view>
<button class="weui-btn menu-cart__btn" type="primary" >
<button class="weui-btn menu-cart__btn" type="primary">
提交订单
</button>
</view>

View File

@ -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;
}

View File

@ -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
}
})

View File

@ -2,19 +2,141 @@
<!--pages/order/show.wxml-->
<view class="order-show-tab tab">
<view class="tab__navbar">
<view class="tab__navbar-item tab__navbar-item_active">
<view bindtap="navChange" id="{{index}}" wx:for="{{tabNavs}}" wx:key="{{index}}" class="tab__navbar-item {{index == activeNavIndex? 'tab__navbar-item_active': ''}} ">
订单状态
</view>
<view class="tab__navbar-item">
订单详情
<view wx:if="{{info.localphone}}" class="phone">
<image class="phone__icon" src="/images/chat_phone_normal.png"></image>
</view>
</view>
<swiper class="tab-swiper" autoplay="{{false}}">
<swiper bindchange="tabChange" current="{{activeNavIndex}}" class="tab-swiper" autoplay="{{false}}">
<swiper-item class="tab__swiper-item">
<view class="classname"></view>
<view class="flow-list">
<view wx:for="{{info.flow}}" wx:key="{{index}}" class="flow-item">
{{item.status}}
<image wx:if="{{item.state == info.state}}" src="{{statusImgs[item.state]}}" class="flow-item__img"></image>
<view class="flow-item__time">{{item.time}}</view>
</view>
</view>
<view wx:if="{{count > 0}}" class="order-show__left-time">
支付剩余时间
<text class="primary-color">{{countLabel}}</text>
</view>
<view class="actionbar">
<view class="actionbar-btn actionbar-btn_action">取消订单</view>
<view class="actionbar-btn actionbar-btn_action actionbar-btn_primary">立即付款</view>
</view>
</swiper-item>
<swiper-item class="tab__swiper-item">
详情
<swiper-item class="tab__swiper-item tab__swiper-item_detail">
<view class="weui-cells__title">订单详情</view>
<view class="quasi-goods">
<view class="quasi-goods__hd weui-flex">
<navigator url="url" class=" trangle">
<image class="quasi-goods__img" src="/images/shop-512.png"></image>
{{info.seller_name}}
</navigator>
<view class=" weui-flex__item"></view>
<view class="grey-color">爱跑腿专送</view>
</view>
<view class="quasi-goods__bd">
<view class="quasi-goods__list">
<view wx:for="{{info.goods}}" wx:key="{{index}}" class="quasi-goods__item">
<view class="quasi-goods__item-name">{{item.goods_name}}</view>
<view class="quasi-goods__item-num">x{{item.num}}</view>
<view class="quasi-goods__item-price">¥{{item.price_sum}}</view>
</view>
</view>
<view class="quasi-goods__list">
<view class="quasi-goods__item">
<view class="quasi-goods__item-name">餐盒费</view>
<view class="quasi-goods__item-num"></view>
<view class="quasi-goods__item-price">¥{{info.packing_fee}}</view>
</view>
<view class="quasi-goods__item">
<view class="quasi-goods__item-name">配送费</view>
<view class="quasi-goods__item-num"></view>
<view class="quasi-goods__item-price">¥{{info.delivery_fee}}</view>
</view>
</view>
<view class="quasi-goods__list">
<view class="quasi-goods__item">
<view class="quasi-goods__item-name quasi-goods__item-name_grey">
<image class="quasi-goods__item-name-icon" src="/images/icon_jian.png"></image>商城优惠
</view>
<view class="quasi-goods__item-num"></view>
<view class="quasi-goods__item-price">-¥{{info.cut_money}}</view>
</view>
</view>
<view class="quasi-goods__list">
<view class="quasi-goods__item">
<view class="quasi-goods__item-name quasi-goods__item-name_grey">
总计¥{{info.order_price}} 优惠¥{{info.cut_money}}
</view>
<view class="quasi-goods__item-num"></view>
<view class="quasi-goods__item-price primary-color">
实付 ¥{{info.pay_price}}
</view>
</view>
</view>
</view>
</view>
<view class="weui-cells__title">配送信息</view>
<view class="weui-cells weui-cells_after-title">
<view class="weui-cell">
<view class="weui-cell__hd">
期望时间
</view>
<view class="weui-cell__bd">立即配送</view>
</view>
<view class="weui-cell">
<view class="weui-cell__hd">
配送地址
</view>
<view class="weui-cell__bd">
<view class="classname">
{{info.receiver}} {{info.receiver_phone}}
</view>
<view class="classname">
{{info.receiver_addr}}
</view>
</view>
</view>
<view class="weui-cell">
<view class="weui-cell__hd">
配送服务
</view>
<view class="weui-cell__bd">
爱跑腿专送
</view>
</view>
</view>
<view class="weui-cells__title">订单信息</view>
<view class="weui-cells weui-cells_after-title">
<view class="weui-cell">
<view class="weui-cell__hd">
订单号码
</view>
<view class="weui-cell__bd">
{{info.order_no}}
</view>
</view>
<view class="weui-cell">
<view class="weui-cell__hd">
订单时间
</view>
<view class="weui-cell__bd">
{{info.add_time}}
</view>
</view>
<view class="weui-cell">
<view class="weui-cell__hd">
支付方式
</view>
<view class="weui-cell__bd">
在线支付
</view>
</view>
</view>
</swiper-item>
</swiper>
</view>

View File

@ -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;
}

378
app/utils/WxValidate.js Normal file
View File

@ -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-231998/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

153
app/utils/coordtransform.js Normal file
View File

@ -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
}
}));

26
app/utils/countdown.js Normal file
View File

@ -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)
}
}

2
app/utils/qqmap-wx-jssdk.min.js vendored Normal file

File diff suppressed because one or more lines are too long

1
app/utils/timeago.min.js vendored Normal file
View File

@ -0,0 +1 @@
!function(t,e){"object"==typeof module&&module.exports?module.exports=e(t):t.timeago=e(t)}("undefined"!=typeof window?window:this,function(){function t(t){return t instanceof Date?t:isNaN(t)?/^\d+$/.test(t)?new Date(e(t)):(t=(t||"").trim().replace(/\.\d+/,"").replace(/-/,"/").replace(/-/,"/").replace(/(\d)T(\d)/,"$1 $2").replace(/Z/," UTC").replace(/([\+\-]\d\d)\:?(\d\d)/," $1$2"),new Date(t)):new Date(e(t))}function e(t){return parseInt(t)}function n(t,n,r){n=d[n]?n:d[r]?r:"en";var i=0,a=t<0?1:0;for(t=Math.abs(t);t>=l[i]&&i<h;i++)t/=l[i];return t=e(t),i*=2,t>(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]&&n<h;n++)t/=l[n],e*=l[n];return r%=e,r=r?e-r:e,Math.ceil(r)}function a(t){return t.dataset.timeago?t.dataset.timeago:t.getAttribute?t.getAttribute(p):t.attr?t.attr(p):void 0}function o(t,e){function o(a,c,f,s){var d=r(c,t);a.innerHTML=n(d,f,e),u["k"+s]=setTimeout(function(){o(a,c,f,s)},Math.min(1e3*i(d),2147483647))}var u={};return e||(e="en"),this.format=function(i,a){return n(r(i,t),a,e)},this.render=function(t,e){void 0===t.length&&(t=[t]);for(var n=0;n<t.length;n++)o(t[n],a(t[n]),e,++c)},this.cancel=function(){for(var t in u)clearTimeout(u[t]);u={}},this.setLocale=function(t){e=t},this}function u(t,e){return new o(t,e)}var c=0,f="second_minute_hour_day_week_month_year".split("_"),s="秒_分钟_小时_天_周_月_年".split("_"),d={en:function(t,e){if(0===e)return["just now","right now"];var n=f[parseInt(e/2)];return t>1&&(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});

View File

@ -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}`
}