diff --git a/.gitignore b/.gitignore
index 6704566..f13be61 100644
--- a/.gitignore
+++ b/.gitignore
@@ -102,3 +102,8 @@ dist
# TernJS port file
.tern-port
+
+# settings
+miniprogram/settings/settings.pro.js
+# cloud dev settings
+cloudfunctions/main/settings.js
\ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..f5906c3
--- /dev/null
+++ b/README.md
@@ -0,0 +1,30 @@
+# mini_shop
+
+### 配置文件说明
+
+`const settings = {
+ app_id: '', // 微信小程序appid
+ app_secret: '' // 微信小程序appsecret,
+ enviroment: 'pro' // 当前环境,
+ cloudenv: 'cake-dev-rlbcr' // 云开发环境名称,
+ HomePage: '/pages/home/home' // 首页路径,
+ // tabs页面
+ TAB_URLS: [
+ '/pages/home/home',
+ '/pages/me/me',
+ '/pages/goods/goods',
+ ],
+ // 主题颜色
+ Theme: {
+ BgColor: '#d9262f',
+ lightColor: '#F0f0f2',
+ lightColor2: '#f4f4f2',
+ blueColor: '#7dd3da',
+ redColor: '#e67774',
+ greenColor: '#8dbb6a'
+ },
+ // 提示信息固定时间(短)
+ shortTipDuration: 2000,
+ // 提示信息固定时间(长)
+ longTipDuration: 4000
+};`
\ No newline at end of file
diff --git a/cloudfunctions/main/address.js b/cloudfunctions/main/address.js
new file mode 100644
index 0000000..8970cc1
--- /dev/null
+++ b/cloudfunctions/main/address.js
@@ -0,0 +1,149 @@
+const db = require('./db')
+
+const queryAddress = async (event, wxContext, user) => {
+ return {
+ status: true,
+ message: 'ok',
+ data: {
+ entities: user.address
+ }
+ }
+}
+
+const getAddress = async (event, wxContext, user) => {
+ for (let item of user.address) {
+ if (item.id == event.addressId) {
+ return {
+ status: true,
+ message: 'ok',
+ data: {
+ entity: item
+ }
+ }
+ }
+ }
+ return {
+ status: false,
+ message: 'address_not_found'
+ }
+
+}
+
+const saveAddress = async (event, wxContext, user) => {
+ let result = null
+ for (let i = 0; i < user.address.length; i++) {
+ if (user.address[i].id == event.addressId) {
+ user.address[i] = event.address
+ try {
+ result = await db.collection('user').doc(user._id).update({
+ data: {
+ address: user.address
+ }
+ })
+ } catch (e) {
+ console.error(e)
+ }
+ if (!result) {
+ return {
+ status: false,
+ message: 'update_address_error'
+ }
+ } else {
+ return {
+ status: true,
+ message: 'ok'
+ }
+ }
+
+ }
+ }
+ return {
+ status: false,
+ message: 'address_not_found'
+ }
+}
+
+
+const deleteAddress = async (event, wxContext, user) => {
+ let result = null
+ for (let i = 0; i < user.address.length; i++) {
+ if (user.address[i].id == event.addressId) {
+ user.address.splice(i, 1)
+ try {
+ result = await db.collection('user').doc(user._id).update({
+ data: {
+ address: user.address
+ }
+ })
+ } catch (e) {
+ console.error(e)
+ }
+ if (!result) {
+ return {
+ status: false,
+ message: 'update_address_error'
+ }
+ } else {
+ return {
+ status: true,
+ message: 'ok'
+ }
+ }
+
+ }
+ }
+ return {
+ status: false,
+ message: 'address_not_found'
+ }
+}
+
+const setDefaultAddress = async (event, wxContext, user) => {
+ let result = null
+ let index = null
+ for (let i = 0; i < user.address.length; i++) {
+ if (user.address[i].id == event.addressId) {
+ user.address[i].isDefault = true
+ index = i
+ } else {
+ user.address[i].isDefault = false
+ }
+ }
+
+ if (index === null) {
+ return {
+ status: false,
+ message: 'address_not_found'
+ }
+ }
+
+ try {
+ result = await db.collection('user').doc(user._id).update({
+ data: {
+ address: user.address
+ }
+ })
+ } catch (e) {
+ console.error(e)
+ }
+ if (!result) {
+ return {
+ status: false,
+ message: 'setdefault_address_error'
+ }
+ } else {
+ return {
+ status: true,
+ message: 'ok'
+ }
+ }
+}
+
+
+module.exports = {
+ queryAddress: queryAddress,
+ getAddress: getAddres,
+ saveAddress: saveAddress,
+ deleteAddress: deleteAddress,
+ setDefaultAddress: setDefaultAddress
+}
diff --git a/cloudfunctions/main/admin_funcs.js b/cloudfunctions/main/admin_funcs.js
new file mode 100644
index 0000000..a8ea460
--- /dev/null
+++ b/cloudfunctions/main/admin_funcs.js
@@ -0,0 +1,617 @@
+const cloud = require('wx-server-sdk')
+const db = require('./db')
+const constant = require('./constant')
+const moment = require('moment')
+
+const _ = db.command
+
+async function getOrder(orderId) {
+ let order = await db.collection('order').doc(orderId).get()
+ console.log('order:', order)
+ if (order && order.errMsg == 'document.get:ok' && order.data && order.data.is_enable) {
+ return order
+ }
+}
+
+
+// 搜索用户
+const getUsers = async (event, wxContext, user) => {
+ console.log(user)
+ let result = null
+ let page = event.page || 1;
+ page = parseInt(page)
+ let page_size = event.page_size || 20;
+ page_size = parseInt(page_size)
+ let skip = (page - 1) * page_size
+ try {
+ if (event.search_text) {
+ result = await db.collection('user').orderBy('create_at', 'desc').where(_.or([{ _id: _.eq(event.search_text) }, { nickName: _.eq(event.search_text) }, { realName: _.eq(event.search_text) }, { mobile_phone: _.eq(event.search_text) }])).where({ is_enable: true }).skip(skip).limit(page_size).get()
+ } else {
+ result = await db.collection('user').orderBy('update_at', 'desc').where({ is_enable: true }).skip(skip).limit(page_size).get()
+ }
+
+ console.log('result:', result)
+ } catch (e) {
+ console.error(e)
+ }
+ if (!result) {
+ return {
+ status: false,
+ message: 'get_users_error'
+ }
+ }
+ return {
+ status: true,
+ message: 'ok',
+ data: {
+ entities: result.data,
+ page: page,
+ page_size: page_size
+ }
+ }
+}
+
+
+// 搜索用户
+const getUserOrders = async (event, wxContext, user) => {
+ console.log(user)
+ console.log('event:', event)
+ let result = null
+ try {
+ if (event.user_id) {
+ result = await db.collection('order').orderBy('create_at', 'desc').where({ openid: event.user_id, is_enable: true }).get()
+ } else if (event.orderid) {
+ result = await db.collection('order').orderBy('create_at', 'desc').where({ is_enable: true, _id: event.orderid }).get()
+ } else if (event.start_at && !event.start_at) {
+ var start_at = moment(event.start_at).toDate()
+ result = await db.collection('order').orderBy('create_at', 'desc').where({ is_enable: true, create_at: _.gte(start_at) }).get()
+ } else if (event.end_at && !event.end_at) {
+ var end_at = moment(event.end_at).toDate()
+ result = await db.collection('order').orderBy('create_at', 'desc').where({ is_enable: true, create_at: _.lte(end_at) }).get()
+ } else if (event.start_at && event.end_at) {
+ var start_at = moment(event.start_at).toDate()
+ var end_at = moment(event.end_at).toDate()
+ console.log('start', start_at)
+ console.log('end', end_at)
+ result = await db.collection('order').orderBy('create_at', 'desc').where({ is_enable: true, create_at: _.and(_.gte(start_at), _.lt(end_at)) }).get()
+ } else {
+ result = await db.collection('order').orderBy('create_at', 'desc').where({ is_enable: true }).get()
+ }
+
+ console.log('result:', result)
+ } catch (e) {
+ console.error(e)
+ }
+ if (!result) {
+ return {
+ status: false,
+ message: 'get_user_orders_error'
+ }
+ }
+ return {
+ status: true,
+ message: 'ok',
+ data: {
+ entities: result.data
+ }
+ }
+}
+
+
+// 是否是管理员
+const getIsAdmin = async (event, wxContext, user) => {
+ let admin = await db.collection('admin').doc(user._id)
+ if (admin && admin.errMsg == 'document.get:ok' && admin.data) {
+ return {
+ status: true,
+ message: 'ok',
+ data: {
+ entity: admin.data
+ }
+ }
+ } else {
+ return {
+ status: false,
+ message: 'not_admin'
+ }
+ }
+}
+
+
+// 修改订单地址
+const updateOrderAddress = async (event, wxContext, user) => {
+ let result = null
+ try {
+ result = await getOrder(event.orderId)
+ console.log('result:', result)
+ } catch (e) {
+ console.error(e)
+ }
+
+ if (!result || !result.data) {
+ return {
+ status: false,
+ message: 'order_not_found'
+ }
+ }
+
+ if (!event.addressInfo.cityName || !event.addressInfo.detailInfo || !event.addressInfo.provinceName || !event.addressInfo.telNumber || !event.addressInfo.userName) {
+ return {
+ status: false,
+ message: 'addressInfo_detail_error'
+ }
+ }
+
+ let updateResult = null
+ try {
+ updateResult = await db.collection('order').doc(event.orderId).update({
+ data: {
+ addressInfo: event.addressInfo,
+ admin_update_at: new Date()
+ }
+ })
+ if (updateResult.stats && updateResult.stats.updated !== 1) {
+ return {
+ status: false,
+ message: 'order_not_found_when_update'
+ }
+ }
+ } catch (e) {
+ console.error(e)
+ }
+
+ result = await getOrder(event.orderId)
+
+ return {
+ status: true,
+ message: 'ok',
+ data: {
+ entity: result.data
+ }
+ }
+}
+
+
+// 修改订单状态
+const updateOrderStatus = async (event, wxContext, user) => {
+
+ let result = null
+ try {
+ result = await getOrder(event.orderId)
+ console.log('result:', result)
+ } catch (e) {
+ console.error(e)
+ }
+
+ if (!result || !result.data) {
+ return {
+ status: false,
+ message: 'order_not_found'
+ }
+ }
+
+ if (!constant.PayStatus[event.status]) {
+ return {
+ status: false,
+ message: 'pay_status_error'
+ }
+ }
+
+
+ let updateResult = null
+ try {
+ updateResult = await db.collection('order').doc(event.orderId).update({
+ data: {
+ status: event.status,
+ admin_update_at: new Date()
+ }
+ })
+ if (updateResult.stats && updateResult.stats.updated !== 1) {
+ return {
+ status: false,
+ message: 'order_not_found_when_update_order_status'
+ }
+ }
+ } catch (e) {
+ console.error(e)
+ }
+
+ result = await getOrder(event.orderId)
+
+ return {
+ status: true,
+ message: 'ok',
+ data: {
+ entities: result.data
+ }
+ }
+
+}
+
+// 修改发货状态
+const updateDeliveryStatus = async (event, wxContext, user) => {
+
+ let result = null
+ try {
+ result = await getOrder(event.orderId)
+ console.log('result:', result)
+ } catch (e) {
+ console.error(e)
+ }
+
+ if (!result || !result.data) {
+ return {
+ status: false,
+ message: 'order_not_found'
+ }
+ }
+
+ if (!constant.DeliveryStatus[event.status]) {
+ return {
+ status: false,
+ message: 'delivery_status_error'
+ }
+ }
+
+ let updateResult = null
+ try {
+ let updateData = {
+ delivery_status: event.status,
+ admin_update_at: new Date()
+ }
+
+ if (event.status == 'shipping' || event.status == 'delivering') {
+ updateData.deliveryInfo = event.deliveryInfo
+ }
+
+ updateResult = await db.collection('order').doc(event.orderId).update({
+ data: updateData
+ })
+ if (updateResult.stats && updateResult.stats.updated !== 1) {
+ return {
+ status: false,
+ message: 'order_not_found_when_update_delivery_status'
+ }
+ }
+ } catch (e) {
+ console.error(e)
+ }
+
+ result = await getOrder(event.orderId)
+
+ return {
+ status: true,
+ message: 'ok',
+ data: {
+ entities: result.data
+ }
+ }
+}
+
+// 修改订单金额
+const updateOrderTotal = async (event, wxContext, user) => {
+
+ if (!event.total) {
+ return {
+ status: false,
+ message: 'total_required'
+ }
+ }
+
+ let result = null
+ try {
+ result = await getOrder(event.orderId)
+ console.log('result:', result)
+ } catch (e) {
+ console.error(e)
+ }
+
+ if (!result || !result.data) {
+ return {
+ status: false,
+ message: 'order_not_found'
+ }
+ }
+
+ let order = result.data;
+ console.log('user:', user)
+ let total = parseFloat(event.total)
+ console.log('total:', total)
+ let order_total = parseFloat(order.orderInfo.total)
+ console.log('order_total:', order_total)
+ let balance = parseFloat(user.balance)
+ let difference = total - order_total
+
+ if ((balance + difference) < 0) {
+ return {
+ status: false,
+ message: 'update_order_total_error'
+ }
+ }
+
+ let updateLogs = order.updateLogs || []
+ updateLogs.push({
+ total: total,
+ order_total: order_total,
+ balance: user.balance,
+ user_id: user._id,
+ create_at: new Date()
+ })
+
+ let orderInfo = order.orderInfo
+ orderInfo.total = total
+
+ let updateResult = null
+ try {
+ let updateData = {
+ admin_update_at: new Date(),
+ updateLogs: updateLogs,
+ amount: total,
+ orderInfo: orderInfo
+ }
+
+ updateResult = await db.collection('order').doc(event.orderId).update({
+ data: updateData
+ })
+ if (updateResult.stats && updateResult.stats.updated !== 1) {
+ return {
+ status: false,
+ message: 'order_not_found_when_update_total'
+ }
+ }
+ } catch (e) {
+ console.error(e)
+ }
+
+ let updateBalanceResult = null
+ console.log('difference:', difference)
+ try {
+ updateBalanceResult = await db.collection('user').doc(order.openid).update({
+ data: {
+ balance: db.command.inc(-difference),
+ update_at: new Date(),
+ update_by: user._id
+ }
+ })
+ console.log('updateBalanceResult:', updateBalanceResult)
+ } catch (e) {
+ console.error(e)
+ }
+ if (!updateBalanceResult || updateBalanceResult.errMsg !== 'document.update:ok') {
+ return {
+ status: false,
+ message: 'update_balance_error_when_update_total'
+ }
+ }
+
+ result = await getOrder(event.orderId)
+
+ return {
+ status: true,
+ message: 'ok',
+ data: {
+ entities: result.data
+ }
+ }
+
+
+}
+
+// 修改订单备注
+const updateOrderRemarks = async (event, wxContext, user) => {
+
+ if (!event.remarks && !event.admin_remarks) {
+ return {
+ status: false,
+ message: 'remarks_required'
+ }
+ }
+
+ let result = null
+ try {
+ result = await getOrder(event.orderId)
+ console.log('result:', result)
+ } catch (e) {
+ console.error(e)
+ }
+
+ if (!result || !result.data) {
+ return {
+ status: false,
+ message: 'order_not_found'
+ }
+ }
+
+ let updateResult = null
+ try {
+
+ updateResult = await db.collection('order').doc(event.orderId).update({
+ data: {
+ admin_remarks: event.admin_remarks,
+ remarks: event.remarks,
+ admin_update_at: new Date()
+ }
+ })
+ if (updateResult.stats && updateResult.stats.updated !== 1) {
+ return {
+ status: false,
+ message: 'order_not_found_when_update_delivery_status'
+ }
+ }
+ } catch (e) {
+ console.error(e)
+ }
+
+ result = await getOrder(event.orderId)
+
+ return {
+ status: true,
+ message: 'ok',
+ data: {
+ entities: result.data
+ }
+ }
+
+}
+
+
+
+// 取消订单
+const cancelOrder = async (event, wxContext, user) => {
+
+ let result = null
+ try {
+ result = await getOrder(event.orderId)
+ console.log('result:', result)
+ } catch (e) {
+ console.error(e)
+ }
+
+ if (!result || !result.data) {
+ return {
+ status: false,
+ message: 'order_not_found'
+ }
+ }
+
+ let order = result.data;
+
+ let updateResult = null
+ try {
+ let updateData = {
+ is_cancel: true,
+ admin_update_at: new Date()
+ }
+
+ if (event.refund_amount){
+ status: 'refund'
+ }
+ if (parseFloat(event.refund_amount) > parseFloat(order.total)) {
+ return {
+ status: false,
+ message: 'refund_amount_error'
+ }
+ }
+
+ updateData.refund_amount = event.refund_amount
+
+ updateResult = await db.collection('order').doc(event.orderId).update({
+ data: updateData
+ })
+ if (updateResult.stats && updateResult.stats.updated !== 1) {
+ return {
+ status: false,
+ message: 'order_not_found_when_cancel'
+ }
+ }
+ } catch (e) {
+ console.error(e)
+ }
+
+
+ if (event.refund_amount) {
+ let updateUserResult = null
+ try {
+ updateUserResult = await db.collection('user').doc(order.openid).update({
+ data: {
+ balance: db.command.inc(parseFloat(event.refund_amount))
+ }
+ })
+ console.log('updateUserResult:', updateUserResult)
+ } catch (e) {
+ console.error(e)
+ }
+ if (!updateUserResult || updateUserResult.errMsg !== 'document.update:ok') {
+ return {
+ status: false,
+ message: 'update_balance_error_when_cancel_order'
+ }
+ }
+ }
+
+ result = await getOrder(event.orderId)
+
+ return {
+ status: true,
+ message: 'ok',
+ data: {
+ entities: result.data
+ }
+ }
+
+}
+
+
+
+
+// 增加管理员推送的token
+const increasePushToken = async (event, wxContext, user) => {
+ let result = null
+ let expire_date = moment().subtract(7, 'days').toDate()
+ try {
+ result = await db.collection('admin_push_token').where({ user_id: user._id, create_at: _.lte(expire_date) }).remove()
+ console.log('result:', result)
+ } catch (e) {
+ console.error(e)
+ }
+
+ try {
+ let record = {
+ user_id: user._id,
+ token: event.token,
+ create_at: new Date()
+ }
+ console.log(record)
+ result = await db.collection('admin_push_token').add({ data: record})
+ }catch(e) {
+ console.error(e)
+ result = null
+ }
+ console.log(result)
+ if (!result || result.errMsg !== 'collection.add:ok') {
+ return {
+ status: false,
+ message: 'fail_to_increase_admin_token'
+ }
+ }
+
+ try {
+ result = await db.collection('admin_push_token').where({ user_id: user._id }).count()
+ console.log('result:', result)
+ } catch (e) {
+ console.error(e)
+ result = null
+ }
+
+
+ if (!result || result.errMsg !== 'collection.count:ok') {
+ return {
+ status: false,
+ message: 'fail_to_get_admin_token_count'
+ }
+ }
+
+ return {
+ status: true,
+ data: {
+ total: result.total
+ },
+ message: 'ok'
+ }
+
+}
+
+
+
+
+module.exports = {
+ getUsers: getUsers,
+ getUserOrders: getUserOrders,
+ updateOrderAddress: updateOrderAddress,
+ updateOrderStatus: updateOrderStatus,
+ updateDeliveryStatus: updateDeliveryStatus,
+ updateOrderTotal: updateOrderTotal,
+ updateOrderRemarks: updateOrderRemarks,
+ cancelOrder: cancelOrder,
+ increasePushToken: increasePushToken
+}
diff --git a/cloudfunctions/main/config.json b/cloudfunctions/main/config.json
new file mode 100644
index 0000000..407d539
--- /dev/null
+++ b/cloudfunctions/main/config.json
@@ -0,0 +1,21 @@
+{
+ "permissions": {
+ "openapi": [
+ "wxacode.get",
+ "templateMessage.send",
+ "logistics.getAllDelivery"
+ ]
+ },
+ "triggers": [
+ {
+ "name": "wechat_triggers.update_access_token",
+ "type": "timer",
+ "config": "0 */5 * * * * *"
+ },
+ {
+ "name": "wechat_triggers.send_notification",
+ "type": "timer",
+ "config": "0 */2 * * * * *"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/cloudfunctions/main/constant.js b/cloudfunctions/main/constant.js
new file mode 100644
index 0000000..0281e47
--- /dev/null
+++ b/cloudfunctions/main/constant.js
@@ -0,0 +1,24 @@
+const PayStatus = {
+ 'submit': 'submit',
+ 'pay': 'pay',
+ 'received': 'received',
+ 'refund': 'refund',
+ 'complete': 'complete'
+}
+const PayType = {
+ 'pay': 'pay',
+ 'deposit': 'deposit'
+}
+
+const DeliveryStatus = {
+ 'preparing': 'preparing',
+ 'shipping': 'shipping',
+ 'delivering': 'delivering',
+ 'received': 'received'
+}
+
+module.exports = {
+ PayType: PayType,
+ PayStatus: PayStatus,
+ DeliveryStatus: DeliveryStatus
+}
\ No newline at end of file
diff --git a/cloudfunctions/main/db.js b/cloudfunctions/main/db.js
new file mode 100644
index 0000000..add5010
--- /dev/null
+++ b/cloudfunctions/main/db.js
@@ -0,0 +1,12 @@
+const settings = require('./settings')
+
+const cloud = require('wx-server-sdk')
+cloud.init({
+ env: settings.cloudenv
+})
+const db = cloud.database()
+
+
+
+module.exports = db
+
diff --git a/cloudfunctions/main/deposit.js b/cloudfunctions/main/deposit.js
new file mode 100644
index 0000000..577d65b
--- /dev/null
+++ b/cloudfunctions/main/deposit.js
@@ -0,0 +1,248 @@
+
+const cloud = require('wx-server-sdk')
+const db = require('./db')
+const cryptoMO = require('crypto');
+const request = require('request');
+const xml2js = require('xml2js');
+const uuid = require('./uuid.js')
+const constant = require('./constant')
+const shortid = require('./utils/shortid')
+const settings = require('./settings')
+const wechat = settings.wechat
+
+function non_str_random() {
+ return new uuid.UUID();
+}
+
+function create_deposit_orderid(length) {
+ let s = shortid(length)
+ return `D${s}`
+}
+
+function bodyData(wechat, payBody, nonce_str, openid, out_trade_no, total_fee, sign) {
+ return `
+ ${wechat.appid}
+ ${payBody}
+ ${wechat.mch_id}
+ ${nonce_str}
+ ${openid}
+ ${wechat.notify_url}
+ ${out_trade_no}
+ ${wechat.ip}
+ ${total_fee}
+ JSAPI
+ ${sign.toUpperCase()}
+ `
+}
+
+
+const wxPaymentSubmit = async (data) => {
+ let result = await new Promise((resolve, reject) => {
+ request({ url: wechat.url, method: 'POST', body: data.body }, (err, res, body) => {
+ const xmlParser = new xml2js.Parser({ explicitArray: false, ignoreAttrs: true })
+ console.log(err)
+ console.log(res)
+ xmlParser.parseString(body, (err, res) => {
+ var prepay_id = res.xml.prepay_id;
+ var str = `appId=${data.appid}&nonceStr=${data.non_str}&package=prepay_id=${prepay_id}&signType=MD5&timeStamp=${data.timestamp}&key=${data.key}`;
+ var paySign = cryptoMO.createHash('md5').update(str).digest('hex');
+ resolve({ status: true, data: { timeStamp: data.timestamp, nonceStr: data.non_str, package: `prepay_id=${prepay_id}`, paySign: paySign, outTradeNo: data.out_trade_no, signType: 'MD5' } });
+ })
+ })
+ })
+ return result
+}
+
+
+const deposit = async (event, wxContext, user) => {
+ console.log('event:', event)
+ console.log('user', user)
+
+ let cardResult = null
+ try {
+ cardResult = await db.collection('deposit_card').doc(event.cardId).get()
+ console.log('cardResult:', cardResult)
+ } catch (e) {
+ console.error(e)
+ }
+ if (!cardResult || cardResult.errMsg !== 'document.get:ok') {
+ return {
+ status: false,
+ message: 'card_not_found'
+ }
+ }
+ console.log('card:', cardResult.data)
+ console.log('cardId:', cardResult.data._id)
+ let balance = 0;
+ if (user.balance !== undefined || user.balance !== null) {
+ balance = user.balance
+ }
+
+ const out_trade_no = create_deposit_orderid(5)
+ const non_str = non_str_random().id;
+ console.log('non_str:', non_str)
+ console.log(non_str.length)
+ var payBody = `Deposit-${cardResult.data.real_value}-${event.cardId}`;
+ var total_fee = parseInt(parseFloat(cardResult.data.value) * 100)
+ // var total_fee = 1
+ var str = `appid=${wechat.appid}&body=${payBody}&mch_id=${wechat.mch_id}&nonce_str=${non_str}¬ify_url=${wechat.notify_url}&openid=${wxContext.OPENID}&out_trade_no=${out_trade_no}&spbill_create_ip=${wechat.ip}&total_fee=${total_fee}&trade_type=JSAPI&key=${wechat.key}`;
+ console.log({ 'str': str })
+ var sign = cryptoMO.createHash('md5').update(str).digest('hex');
+ console.log('sign:', sign)
+ var temp_body_data = bodyData(wechat, payBody, non_str, wxContext.OPENID, out_trade_no, total_fee, sign);
+ console.log({ xml: temp_body_data })
+
+ var payData = {
+ body: temp_body_data,
+ appid: wechat.appid,
+ non_str: non_str,
+ out_trade_no: out_trade_no,
+ key: wechat.key,
+ timestamp: new Date().getTime().toString()
+ }
+
+ let depositSubmitResult = await wxPaymentSubmit(payData)
+
+ if (!depositSubmitResult.status) {
+ return {
+ status: false,
+ message: 'paysubmit_error'
+ }
+ }
+
+ let order = {
+ orderNo: out_trade_no,
+ userName: user.nickName,
+ mobile_phone: user.mobile_phone,
+ is_admin_notified: false,
+ orderInfo: {
+ total: cardResult.data.real_value,
+ count: 1,
+ entities: [
+ {
+ id: cardResult.data._id,
+ name: cardResult.data.name,
+ name_en: cardResult.data.name_en,
+ price: cardResult.data.real_value,
+ display_price: cardResult.data.value,
+ count: 1,
+ total: cardResult.data.real_value,
+ display_total: cardResult.data.value,
+ cover: cardResult.data.image
+ }
+ ]
+ },
+ create_at: new Date(),
+ update_at: new Date(),
+ is_enable: true,
+ openid: user._id,
+ unionid: user.unionid,
+ status: constant.PayStatus.submit,
+ amount: cardResult.data.real_value,
+ type: constant.PayType.deposit
+ // balance: balance + parseFloat(cardResult.data.real_value)
+ }
+ console.log('orderInfo:', order)
+
+
+
+ let orderResult = null
+ try {
+ orderResult = await db.collection('order').add({
+ data: order
+ })
+ console.log('orderResult:', orderResult)
+ } catch (e) {
+ console.error(e)
+ }
+ if (!orderResult) {
+ return {
+ status: false,
+ message: 'create_deposit_order_error'
+ }
+ }
+
+
+ return {
+ status: true,
+ message: 'ok',
+ data: {
+ orderNo: out_trade_no,
+ payData: depositSubmitResult.data
+ }
+ }
+}
+
+
+async function depositSuccess(event, wxContext, user) {
+
+ let orderResult = null
+ try {
+ orderResult = await db.collection('order').where({ orderNo: event.orderNo }).limit(1).get()
+ console.log('orderResult:', orderResult)
+ } catch (e) {
+ console.error(e)
+ }
+ if (!orderResult || !orderResult.data || orderResult.data.length !== 1) {
+ return {
+ status: false,
+ message: 'get_deposit_order_error'
+ }
+ }
+ orderResult = orderResult.data[0]
+ if (orderResult.status !== constant.PayStatus.submit) {
+ return {
+ status: false,
+ message: 'deposit_order_status_error'
+ }
+ }
+
+ let updateOrderStatusRes = null
+ try {
+ updateOrderStatusRes = await db.collection('order').doc(orderResult._id).update({
+ data: {
+ balance: db.command.inc(parseFloat(orderResult.orderInfo.total)),
+ status: constant.PayStatus.complete
+ }
+ })
+ console.log('updateOrderStatusRes:', updateOrderStatusRes)
+ } catch (e) {
+ console.error(e)
+ }
+ if (!updateOrderStatusRes || updateOrderStatusRes.errMsg !== 'document.update:ok') {
+ return {
+ status: false,
+ message: 'update_order_status_error'
+ }
+ }
+
+ let depositResult = null
+ try {
+ depositResult = await db.collection('user').doc(wxContext.OPENID).update({
+ data: {
+ balance: db.command.inc(parseFloat(orderResult.orderInfo.total)),
+ update_at: new Date()
+ }
+ })
+ console.log('depositResult:', depositResult)
+ } catch (e) {
+ console.error(e)
+ }
+ if (!depositResult || depositResult.errMsg !== 'document.update:ok') {
+ return {
+ status: false,
+ message: 'update_balance_error'
+ }
+ }
+ return {
+ status: true,
+ message: 'ok'
+ }
+}
+
+
+
+module.exports = {
+ deposit: deposit,
+ depositSuccess: depositSuccess
+}
diff --git a/cloudfunctions/main/goods.js b/cloudfunctions/main/goods.js
new file mode 100644
index 0000000..ef161f5
--- /dev/null
+++ b/cloudfunctions/main/goods.js
@@ -0,0 +1,25 @@
+const db = require('./db')
+
+const getGoods = async (event, wxContext) => {
+ try {
+ const result = await db.collection('goods').where({ is_enable: true }).get()
+ return {
+ status: true,
+ data: {
+ entities: result.data
+ }
+ }
+ } catch (e) {
+ console.error(e)
+ return {
+ status: false,
+ message: e.message
+ }
+ }
+
+}
+
+
+module.exports = {
+ getGoods: getGoods
+}
diff --git a/cloudfunctions/main/index.js b/cloudfunctions/main/index.js
new file mode 100644
index 0000000..49df35d
--- /dev/null
+++ b/cloudfunctions/main/index.js
@@ -0,0 +1,365 @@
+const db = require('./db')
+const userAPI = require('./user')
+const orderAPI = require('./orders')
+const loginAPI = require('./login')
+const registAPI = require('./regist')
+const goodsAPI = require('./goods')
+const depositAPI = require('./deposit')
+const payAPI = require('./pay')
+const adminAPI = require('./admin_funcs')
+const wechat_triggers = require('./wechat_triggers')
+const constant = require('./constant')
+const cloud = require('wx-server-sdk')
+
+
+const getCards = async () => {
+ let cards = []
+ try {
+ const result = await db.collection('deposit_card').where({ is_enable: true }).get()
+ cards = result.data
+ } catch (e) {
+ console.error(e)
+ return {
+ status: false,
+ message: e.message
+ }
+ }
+
+ try {
+ const result = await db.collection('slide').where({ is_enable: true }).get()
+ return {
+ status: true,
+ data: {
+ entities: cards,
+ images: result.data
+ }
+ }
+ } catch (e) {
+ console.error(e)
+ return {
+ status: false,
+ message: e.message
+ }
+ }
+}
+
+
+
+
+
+const getUser = async (openid) => {
+ try {
+ return await db.collection('user').doc(openid).get()
+ } catch (e) {
+ // console.error(e)
+ return null
+ }
+}
+
+
+const getAdmin = async (openid) => {
+ let result = null
+ try {
+ result = await db.collection('admin').where({ user_id: openid, is_enable: true }).get()
+ } catch (e) {
+ // console.error(e)
+ return null
+ }
+ console.log(result)
+ if (result && result.errMsg == 'collection.get:ok' && result.data) {
+ return result.data[0]
+ }
+ return null
+}
+
+
+const getProfile = async (event, wxContext, user) => {
+
+
+ let data = {
+ status: true,
+ data: {
+ user: {
+ id: user._id,
+ avatar: user.avatar,
+ balance: user.balance,
+ nickName: user.nickName,
+ realName: user.realName,
+ status: user.status,
+ gender: user.gender,
+ birthday: user.birthday,
+ address: user.address,
+ update_at: user.update_at,
+ create_at: user.create_at
+ }
+ }
+ }
+
+ let result = await db.collection('admin').where({ user_id: user._id }).limit(1).get()
+ console.log(result)
+ if (result && result.errMsg == 'collection.get:ok' && result.data && result.data.length === 1) {
+ if (result.data[0].is_enable) {
+ data.data.admin = {
+ id: result.data[0]._id,
+ name: result.data[0].name
+ }
+ }
+ }
+
+ return data
+}
+
+
+
+
+// 云函数入口函数
+exports.main = async (event, context) => {
+ console.log('event:', event)
+ console.log(context)
+ const wxContext = cloud.getWXContext()
+ if (event.Type == 'Timer' && event.TriggerName.startsWith('wechat_triggers.update_access_token')) {
+ let triggerResult = await wechat_triggers.update_access_token(event, wxContext)
+ console.log(triggerResult)
+ return
+ } else if (event.Type == 'Timer' && event.TriggerName.startsWith('wechat_triggers.send_notification')) {
+ let notificationResult = await wechat_triggers.send_notification(event, wxContext)
+ console.log(notificationResult)
+ return
+ }
+
+
+ let user = await getUser(wxContext.OPENID)
+ switch (event.apiName) {
+ case 'getCards':
+ return await getCards()
+ case 'depositAPI.deposit':
+ if (!user || user.errMsg !== 'document.get:ok') {
+ return {
+ status: false,
+ message: 'user_not_found'
+ }
+ }
+ return await depositAPI.deposit(event, wxContext, user.data)
+ case 'depositAPI.depositSuccess':
+ if (!user || user.errMsg !== 'document.get:ok') {
+ return {
+ status: false,
+ message: 'user_not_found'
+ }
+ }
+ return await depositAPI.depositSuccess(event, wxContext, user.data)
+ case 'payAPI.orderPay':
+ if (!user || user.errMsg !== 'document.get:ok') {
+ return {
+ status: false,
+ message: 'user_not_found'
+ }
+ }
+ return await payAPI.orderPay(event, wxContext, user.data)
+ case 'getProfile':
+ if (!user || user.errMsg !== 'document.get:ok') {
+ return {
+ status: false,
+ message: 'user_not_found'
+ }
+ }
+ return await getProfile(event, wxContext, user.data)
+ case 'userAPI.updateBirthday':
+ if (!user || user.errMsg !== 'document.get:ok') {
+ return {
+ status: false,
+ message: 'user_not_found'
+ }
+ }
+ return await userAPI.updateBirthday(event, wxContext, user.data)
+ case 'userAPI.updateUserName':
+ if (!user || user.errMsg !== 'document.get:ok') {
+ return {
+ status: false,
+ message: 'user_not_found'
+ }
+ }
+ return await userAPI.updateUserName(event, wxContext, user.data)
+ case 'userAPI.updateGender':
+ if (!user || user.errMsg !== 'document.get:ok') {
+ return {
+ status: false,
+ message: 'user_not_found'
+ }
+ }
+ return await userAPI.updateGender(event, wxContext, user.data)
+ case 'userAPI.updateAddress':
+ if (!user || user.errMsg !== 'document.get:ok') {
+ return {
+ status: false,
+ message: 'user_not_found'
+ }
+ }
+ return await userAPI.updateAddress(event, wxContext, user.data)
+ case 'orderAPI.getOrders':
+ if (!user || user.errMsg !== 'document.get:ok') {
+ return {
+ status: false,
+ message: 'user_not_found'
+ }
+ }
+ return await orderAPI.getOrders(event, wxContext, user.data)
+
+ // admin API start
+ case 'adminAPI.getUsers':
+ if (!user || user.errMsg !== 'document.get:ok') {
+ return {
+ status: false,
+ message: 'user_not_found'
+ }
+ }
+
+ var admin = await getAdmin(wxContext.OPENID)
+ if (!admin || !admin._id) {
+ return {
+ status: false,
+ message: 'admin_required'
+ }
+ }
+
+ return await adminAPI.getUsers(event, wxContext, user.data)
+ case 'adminAPI.getUserOrders':
+ if (!user || user.errMsg !== 'document.get:ok') {
+ return {
+ status: false,
+ message: 'user_not_found'
+ }
+ }
+
+ var admin = await getAdmin(wxContext.OPENID)
+ if (!admin || !admin._id) {
+ return {
+ status: false,
+ message: 'admin_required'
+ }
+ }
+ return await adminAPI.getUserOrders(event, wxContext, user.data)
+ case 'adminAPI.updateOrderAddress':
+ if (!user || user.errMsg !== 'document.get:ok') {
+ return {
+ status: false,
+ message: 'user_not_found'
+ }
+ }
+ var admin = await getAdmin(wxContext.OPENID)
+ if (!admin || !admin._id) {
+ return {
+ status: false,
+ message: 'admin_required'
+ }
+ }
+ return await adminAPI.updateOrderAddress(event, wxContext, user.data)
+ case 'adminAPI.updateOrderStatus':
+ if (!user || user.errMsg !== 'document.get:ok') {
+ return {
+ status: false,
+ message: 'user_not_found'
+ }
+ }
+ var admin = await getAdmin(wxContext.OPENID)
+ if (!admin || !admin._id) {
+ return {
+ status: false,
+ message: 'admin_required'
+ }
+ }
+ return await adminAPI.updateOrderStatus(event, wxContext, user.data)
+ case 'adminAPI.updateDeliveryStatus':
+ if (!user || user.errMsg !== 'document.get:ok') {
+ return {
+ status: false,
+ message: 'user_not_found'
+ }
+ }
+ var admin = await getAdmin(wxContext.OPENID)
+ if (!admin || !admin._id) {
+ return {
+ status: false,
+ message: 'admin_required'
+ }
+ }
+ return await adminAPI.updateDeliveryStatus(event, wxContext, user.data)
+ case 'adminAPI.updateOrderTotal':
+ if (!user || user.errMsg !== 'document.get:ok') {
+ return {
+ status: false,
+ message: 'user_not_found'
+ }
+ }
+ var admin = await getAdmin(wxContext.OPENID)
+ if (!admin || !admin._id) {
+ return {
+ status: false,
+ message: 'admin_required'
+ }
+ }
+ return await adminAPI.updateOrderTotal(event, wxContext, user.data)
+ case 'adminAPI.updateOrderRemarks':
+ if (!user || user.errMsg !== 'document.get:ok') {
+ return {
+ status: false,
+ message: 'user_not_found'
+ }
+ }
+ var admin = await getAdmin(wxContext.OPENID)
+ if (!admin || !admin._id) {
+ return {
+ status: false,
+ message: 'admin_required'
+ }
+ }
+ return await adminAPI.updateOrderRemarks(event, wxContext, user.data)
+ case 'adminAPI.cancelOrder':
+ if (!user || user.errMsg !== 'document.get:ok') {
+ return {
+ status: false,
+ message: 'user_not_found'
+ }
+ }
+ var admin = await getAdmin(wxContext.OPENID)
+ if (!admin || !admin._id) {
+ return {
+ status: false,
+ message: 'admin_required'
+ }
+ }
+ return await adminAPI.cancelOrder(event, wxContext, user.data)
+
+ case 'adminAPI.increasePushToken':
+ if (!user || user.errMsg !== 'document.get:ok') {
+ return {
+ status: false,
+ message: 'user_not_found'
+ }
+ }
+ var admin = await getAdmin(wxContext.OPENID)
+ if (!admin || !admin._id) {
+ return {
+ status: false,
+ message: 'admin_required'
+ }
+ }
+ return await adminAPI.increasePushToken(event, wxContext, user.data)
+
+ // admin api end
+
+ case 'loginAPI.login':
+ return await loginAPI.login(event, wxContext)
+ case 'registAPI.regist':
+ return await registAPI.regist(event, wxContext)
+ case 'registAPI.registByCloudID':
+ return await registAPI.registByCloudID(event, wxContext)
+ case 'goodsAPI.getGoods':
+ return await goodsAPI.getGoods(event, wxContext)
+ default:
+ return {
+ status: false,
+ message: 'api_not_found'
+ }
+ }
+}
\ No newline at end of file
diff --git a/cloudfunctions/main/login.js b/cloudfunctions/main/login.js
new file mode 100644
index 0000000..ad96f75
--- /dev/null
+++ b/cloudfunctions/main/login.js
@@ -0,0 +1,101 @@
+const cloud = require('wx-server-sdk')
+const db = require('./db')
+
+
+const getUser = async (openid) => {
+ try {
+ return await db.collection('user').doc(openid).get()
+ } catch (e) {
+ // console.error(e)
+ return null
+ }
+}
+
+
+
+const createUser = async (openid, unionid, nickName, gender, avatar, balance = 0, inviteBy = null, inviteFrom = null, userinfo = {}) => {
+ try {
+ return await db.collection('user').add({
+ data: {
+ _id: openid,
+ unionid: unionid,
+ gender: gender,
+ nickName: nickName,
+ avatar: avatar,
+ raw: userinfo,
+ mobile_phone: "",
+ balance: balance,
+ inviteBy: inviteBy,
+ inviteFrom: inviteFrom,
+ status: 'regist',
+ is_enable: true
+ }
+ })
+ } catch (e) {
+ // console.error(e)
+ return null
+ }
+}
+
+const login = async (event, wxContext) => {
+ const result = await getUser(wxContext.OPENID)
+ console.log('getUser:')
+ console.log(result)
+ if (!result) {
+ const userInfo = event.userinfo
+ const createResult = await createUser(
+ wxContext.OPENID,
+ wxContext.UNIONID,
+ userInfo.nickName,
+ userInfo.gender,
+ userInfo.avatarUrl,
+ 0,
+ event.inviteBy || null,
+ event.inviteFrom || null,
+ userInfo
+ )
+ if (!createResult) {
+ return {
+ status: false,
+ message: 'fail_create_user'
+ }
+ } else {
+ return {
+ status: true,
+ message: 'ok',
+ data: {
+ registed: false,
+ nextpage: '/pages/regist/regist',
+ openid: wxContext.OPENID
+ }
+ }
+ }
+ } else {
+ if (result.data.mobile_phone) {
+ return {
+ status: true,
+ message: 'ok',
+ data: {
+ registed: true,
+ nextpage: '/pages/home/home',
+ openid: wxContext.OPENID
+ }
+ }
+ } else {
+ return {
+ status: true,
+ message: 'ok',
+ data: {
+ registed: false,
+ nextpage: '/pages/regist/regist',
+ openid: wxContext.OPENID
+ }
+ }
+ }
+ }
+}
+
+
+module.exports = {
+ login: login
+}
diff --git a/cloudfunctions/main/orders.js b/cloudfunctions/main/orders.js
new file mode 100644
index 0000000..59b0d56
--- /dev/null
+++ b/cloudfunctions/main/orders.js
@@ -0,0 +1,30 @@
+const cloud = require('wx-server-sdk')
+const db = require('./db')
+
+const getOrders = async (event, wxContext, user) => {
+ console.log(user)
+ let result = null
+ try {
+ result = await db.collection('order').orderBy('create_at', 'desc').where({ openid: user._id, is_enable: true }).get()
+ console.log('result:', result)
+ } catch (e) {
+ console.error(e)
+ }
+ if (!result) {
+ return {
+ status: false,
+ message: 'get_orders_error'
+ }
+ }
+ return {
+ status: true,
+ message: 'ok',
+ data: {
+ entities: result.data
+ }
+ }
+}
+
+module.exports = {
+ getOrders: getOrders
+}
diff --git a/cloudfunctions/main/package-lock.json b/cloudfunctions/main/package-lock.json
new file mode 100644
index 0000000..c2fd216
--- /dev/null
+++ b/cloudfunctions/main/package-lock.json
@@ -0,0 +1,603 @@
+{
+ "name": "deposit",
+ "version": "1.0.0",
+ "lockfileVersion": 1,
+ "requires": true,
+ "dependencies": {
+ "@cloudbase/database": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/@cloudbase/database/-/database-0.1.1.tgz",
+ "integrity": "sha512-r6tSlzrDKvu27K9tlQYG6qFphw3ZmGECuch7J2ZKW93iLlqpaBVQdy5kBNKZkpjxrpVw9cZKoC2+k0wMqaTWtQ==",
+ "requires": {
+ "bson": "^4.0.2"
+ }
+ },
+ "@protobufjs/aspromise": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz",
+ "integrity": "sha1-m4sMxmPWaafY9vXQiToU00jzD78="
+ },
+ "@protobufjs/base64": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz",
+ "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg=="
+ },
+ "@protobufjs/codegen": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz",
+ "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg=="
+ },
+ "@protobufjs/eventemitter": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz",
+ "integrity": "sha1-NVy8mLr61ZePntCV85diHx0Ga3A="
+ },
+ "@protobufjs/fetch": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz",
+ "integrity": "sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=",
+ "requires": {
+ "@protobufjs/aspromise": "^1.1.1",
+ "@protobufjs/inquire": "^1.1.0"
+ }
+ },
+ "@protobufjs/float": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz",
+ "integrity": "sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E="
+ },
+ "@protobufjs/inquire": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz",
+ "integrity": "sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik="
+ },
+ "@protobufjs/path": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz",
+ "integrity": "sha1-bMKyDFya1q0NzP0hynZz2Nf79o0="
+ },
+ "@protobufjs/pool": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz",
+ "integrity": "sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q="
+ },
+ "@protobufjs/utf8": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz",
+ "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA="
+ },
+ "@types/long": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.0.tgz",
+ "integrity": "sha512-1w52Nyx4Gq47uuu0EVcsHBxZFJgurQ+rTKS3qMHxR1GY2T8c2AJYd6vZoZ9q1rupaDjU0yT+Jc2XTyXkjeMA+Q=="
+ },
+ "@types/node": {
+ "version": "10.14.13",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-10.14.13.tgz",
+ "integrity": "sha512-yN/FNNW1UYsRR1wwAoyOwqvDuLDtVXnaJTZ898XIw/Q5cCaeVAlVwvsmXLX5PuiScBYwZsZU4JYSHB3TvfdwvQ=="
+ },
+ "ajv": {
+ "version": "6.10.2",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz",
+ "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==",
+ "requires": {
+ "fast-deep-equal": "^2.0.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ }
+ },
+ "asn1": {
+ "version": "0.2.4",
+ "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
+ "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==",
+ "requires": {
+ "safer-buffer": "~2.1.0"
+ }
+ },
+ "assert-plus": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+ "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU="
+ },
+ "asynckit": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+ "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
+ },
+ "aws-sign2": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
+ "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg="
+ },
+ "aws4": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz",
+ "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ=="
+ },
+ "axios": {
+ "version": "0.19.0",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.0.tgz",
+ "integrity": "sha512-1uvKqKQta3KBxIz14F2v06AEHZ/dIoeKfbTRkK1E5oqjDnuEerLmYTgJB5AiQZHJcljpg1TuRzdjDR06qNk0DQ==",
+ "requires": {
+ "follow-redirects": "1.5.10",
+ "is-buffer": "^2.0.2"
+ }
+ },
+ "base64-js": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz",
+ "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw=="
+ },
+ "bcrypt-pbkdf": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
+ "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
+ "requires": {
+ "tweetnacl": "^0.14.3"
+ }
+ },
+ "bson": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/bson/-/bson-4.0.2.tgz",
+ "integrity": "sha512-rBdCxMBCg2aR420e1oKUejjcuPZLTibA7zEhWAlliFWEwzuBCC9Dkp5r7VFFIQB2t1WVsvTbohry575mc7Xw5A==",
+ "requires": {
+ "buffer": "^5.1.0",
+ "long": "^4.0.0"
+ }
+ },
+ "buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.2.1.tgz",
+ "integrity": "sha512-c+Ko0loDaFfuPWiL02ls9Xd3GO3cPVmUobQ6t3rXNUk304u6hGq+8N/kFi+QEIKhzK3uwolVhLzszmfLmMLnqg==",
+ "requires": {
+ "base64-js": "^1.0.2",
+ "ieee754": "^1.1.4"
+ }
+ },
+ "caseless": {
+ "version": "0.12.0",
+ "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
+ "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw="
+ },
+ "combined-stream": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+ "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+ "requires": {
+ "delayed-stream": "~1.0.0"
+ }
+ },
+ "core-util-is": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
+ "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
+ },
+ "crypto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/crypto/-/crypto-1.0.1.tgz",
+ "integrity": "sha512-VxBKmeNcqQdiUQUW2Tzq0t377b54N2bMtXO/qiLa+6eRRmmC4qT3D4OnTGoT/U6O9aklQ/jTwbOtRMTTY8G0Ig=="
+ },
+ "dashdash": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
+ "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
+ "requires": {
+ "assert-plus": "^1.0.0"
+ }
+ },
+ "debug": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+ "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "delayed-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+ "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
+ },
+ "ecc-jsbn": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
+ "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
+ "requires": {
+ "jsbn": "~0.1.0",
+ "safer-buffer": "^2.1.0"
+ }
+ },
+ "extend": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
+ "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
+ },
+ "extsprintf": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
+ "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU="
+ },
+ "fast-deep-equal": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz",
+ "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk="
+ },
+ "fast-json-stable-stringify": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz",
+ "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I="
+ },
+ "follow-redirects": {
+ "version": "1.5.10",
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz",
+ "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==",
+ "requires": {
+ "debug": "=3.1.0"
+ }
+ },
+ "forever-agent": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
+ "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE="
+ },
+ "form-data": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
+ "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
+ "requires": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.6",
+ "mime-types": "^2.1.12"
+ }
+ },
+ "function-bind": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
+ },
+ "getpass": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
+ "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
+ "requires": {
+ "assert-plus": "^1.0.0"
+ }
+ },
+ "har-schema": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
+ "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI="
+ },
+ "har-validator": {
+ "version": "5.1.3",
+ "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz",
+ "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==",
+ "requires": {
+ "ajv": "^6.5.5",
+ "har-schema": "^2.0.0"
+ }
+ },
+ "has": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
+ "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+ "requires": {
+ "function-bind": "^1.1.1"
+ }
+ },
+ "http-signature": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
+ "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
+ "requires": {
+ "assert-plus": "^1.0.0",
+ "jsprim": "^1.2.2",
+ "sshpk": "^1.7.0"
+ }
+ },
+ "ieee754": {
+ "version": "1.1.13",
+ "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz",
+ "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg=="
+ },
+ "is-buffer": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz",
+ "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A=="
+ },
+ "is-regex": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz",
+ "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=",
+ "requires": {
+ "has": "^1.0.1"
+ }
+ },
+ "is-typedarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
+ "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo="
+ },
+ "isstream": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
+ "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo="
+ },
+ "jsbn": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
+ "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM="
+ },
+ "json-schema": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
+ "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM="
+ },
+ "json-schema-traverse": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="
+ },
+ "json-stringify-safe": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
+ "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus="
+ },
+ "jsprim": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
+ "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
+ "requires": {
+ "assert-plus": "1.0.0",
+ "extsprintf": "1.3.0",
+ "json-schema": "0.2.3",
+ "verror": "1.10.0"
+ }
+ },
+ "lodash.merge": {
+ "version": "4.6.2",
+ "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
+ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="
+ },
+ "long": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz",
+ "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA=="
+ },
+ "mime-db": {
+ "version": "1.40.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz",
+ "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA=="
+ },
+ "mime-types": {
+ "version": "2.1.24",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz",
+ "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==",
+ "requires": {
+ "mime-db": "1.40.0"
+ }
+ },
+ "moment": {
+ "version": "2.24.0",
+ "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz",
+ "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg=="
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+ },
+ "oauth-sign": {
+ "version": "0.9.0",
+ "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
+ "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ=="
+ },
+ "performance-now": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
+ "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns="
+ },
+ "protobufjs": {
+ "version": "6.8.8",
+ "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.8.8.tgz",
+ "integrity": "sha512-AAmHtD5pXgZfi7GMpllpO3q1Xw1OYldr+dMUlAnffGTAhqkg72WdmSY71uKBF/JuyiKs8psYbtKrhi0ASCD8qw==",
+ "requires": {
+ "@protobufjs/aspromise": "^1.1.2",
+ "@protobufjs/base64": "^1.1.2",
+ "@protobufjs/codegen": "^2.0.4",
+ "@protobufjs/eventemitter": "^1.1.0",
+ "@protobufjs/fetch": "^1.1.0",
+ "@protobufjs/float": "^1.0.2",
+ "@protobufjs/inquire": "^1.1.0",
+ "@protobufjs/path": "^1.1.2",
+ "@protobufjs/pool": "^1.1.0",
+ "@protobufjs/utf8": "^1.1.0",
+ "@types/long": "^4.0.0",
+ "@types/node": "^10.1.0",
+ "long": "^4.0.0"
+ }
+ },
+ "psl": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/psl/-/psl-1.2.0.tgz",
+ "integrity": "sha512-GEn74ZffufCmkDDLNcl3uuyF/aSD6exEyh1v/ZSdAomB82t6G9hzJVRx0jBmLDW+VfZqks3aScmMw9DszwUalA=="
+ },
+ "punycode": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
+ "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A=="
+ },
+ "qs": {
+ "version": "6.5.2",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
+ "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA=="
+ },
+ "request": {
+ "version": "2.88.0",
+ "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz",
+ "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==",
+ "requires": {
+ "aws-sign2": "~0.7.0",
+ "aws4": "^1.8.0",
+ "caseless": "~0.12.0",
+ "combined-stream": "~1.0.6",
+ "extend": "~3.0.2",
+ "forever-agent": "~0.6.1",
+ "form-data": "~2.3.2",
+ "har-validator": "~5.1.0",
+ "http-signature": "~1.2.0",
+ "is-typedarray": "~1.0.0",
+ "isstream": "~0.1.2",
+ "json-stringify-safe": "~5.0.1",
+ "mime-types": "~2.1.19",
+ "oauth-sign": "~0.9.0",
+ "performance-now": "^2.1.0",
+ "qs": "~6.5.2",
+ "safe-buffer": "^5.1.2",
+ "tough-cookie": "~2.4.3",
+ "tunnel-agent": "^0.6.0",
+ "uuid": "^3.3.2"
+ }
+ },
+ "safe-buffer": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz",
+ "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg=="
+ },
+ "safer-buffer": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
+ },
+ "sax": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
+ "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw=="
+ },
+ "sshpk": {
+ "version": "1.16.1",
+ "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz",
+ "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==",
+ "requires": {
+ "asn1": "~0.2.3",
+ "assert-plus": "^1.0.0",
+ "bcrypt-pbkdf": "^1.0.0",
+ "dashdash": "^1.12.0",
+ "ecc-jsbn": "~0.1.1",
+ "getpass": "^0.1.1",
+ "jsbn": "~0.1.0",
+ "safer-buffer": "^2.0.2",
+ "tweetnacl": "~0.14.0"
+ }
+ },
+ "tcb-admin-node": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/tcb-admin-node/-/tcb-admin-node-1.9.0.tgz",
+ "integrity": "sha512-TYoBo66CEIIw1QzgK4Jq43G45zvBE6ZB35LbDV8wwLQvg6CiZHlmOTVZkgj2YZ8O87ELi+ZE3UBVNZM3nFa6lQ==",
+ "requires": {
+ "@cloudbase/database": "0.1.1",
+ "is-regex": "^1.0.4",
+ "lodash.merge": "^4.6.1",
+ "request": "^2.87.0",
+ "xml2js": "^0.4.19"
+ }
+ },
+ "tough-cookie": {
+ "version": "2.4.3",
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz",
+ "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==",
+ "requires": {
+ "psl": "^1.1.24",
+ "punycode": "^1.4.1"
+ },
+ "dependencies": {
+ "punycode": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
+ "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4="
+ }
+ }
+ },
+ "tslib": {
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz",
+ "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ=="
+ },
+ "tunnel-agent": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
+ "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
+ "requires": {
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "tweetnacl": {
+ "version": "0.14.5",
+ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
+ "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q="
+ },
+ "uri-js": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz",
+ "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==",
+ "requires": {
+ "punycode": "^2.1.0"
+ }
+ },
+ "uuid": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz",
+ "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA=="
+ },
+ "verror": {
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
+ "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
+ "requires": {
+ "assert-plus": "^1.0.0",
+ "core-util-is": "1.0.2",
+ "extsprintf": "^1.2.0"
+ }
+ },
+ "wx-server-sdk": {
+ "version": "0.8.1",
+ "resolved": "https://registry.npmjs.org/wx-server-sdk/-/wx-server-sdk-0.8.1.tgz",
+ "integrity": "sha512-mE7O3E7GtRhqk1ukWw2+NiykaO5DaJYiMFCeHrwvekYTVL5Z2nFXnSrUx6nPg/vZ7LWWQbCgQlGOygBjj2+hkQ==",
+ "requires": {
+ "protobufjs": "6.8.8",
+ "tcb-admin-node": "1.9.0",
+ "tslib": "^1.9.3"
+ }
+ },
+ "xml2js": {
+ "version": "0.4.19",
+ "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz",
+ "integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==",
+ "requires": {
+ "sax": ">=0.6.0",
+ "xmlbuilder": "~9.0.1"
+ }
+ },
+ "xmlbuilder": {
+ "version": "9.0.7",
+ "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz",
+ "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0="
+ },
+ "xmlreader": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/xmlreader/-/xmlreader-0.2.3.tgz",
+ "integrity": "sha1-hldutdV5Wabe5+0os8vRw1Wdy5A=",
+ "requires": {
+ "sax": "~0.5.2"
+ },
+ "dependencies": {
+ "sax": {
+ "version": "0.5.8",
+ "resolved": "https://registry.npmjs.org/sax/-/sax-0.5.8.tgz",
+ "integrity": "sha1-1HLbIo6zMcJQaw6MFVJK25OdEsE="
+ }
+ }
+ }
+ }
+}
diff --git a/cloudfunctions/main/package.json b/cloudfunctions/main/package.json
new file mode 100644
index 0000000..f7d1cd3
--- /dev/null
+++ b/cloudfunctions/main/package.json
@@ -0,0 +1,20 @@
+{
+ "name": "deposit",
+ "version": "1.0.0",
+ "description": "",
+ "main": "index.js",
+ "scripts": {
+ "test": "echo \"Error: no test specified\" && exit 1"
+ },
+ "author": "",
+ "license": "ISC",
+ "dependencies": {
+ "axios": "^0.19.0",
+ "crypto": "^1.0.1",
+ "moment": "^2.24.0",
+ "request": "^2.88.0",
+ "wx-server-sdk": "^0.8.1",
+ "xml2js": "^0.4.19",
+ "xmlreader": "^0.2.3"
+ }
+}
diff --git a/cloudfunctions/main/pay.js b/cloudfunctions/main/pay.js
new file mode 100644
index 0000000..7a59bd4
--- /dev/null
+++ b/cloudfunctions/main/pay.js
@@ -0,0 +1,193 @@
+
+const cloud = require('wx-server-sdk')
+const db = require('./db')
+const constant = require('./constant')
+const shortid = require('./utils/shortid')
+
+
+function checkOrder(orderInfo) {
+ // todo: add order verifiy function
+ return true
+}
+
+
+function create_pay_orderid(length) {
+ let s = shortid(length)
+ return `P${s}`
+}
+
+
+const orderPay = async (event, wxContext, user) => {
+ let orderInfo = event.orderInfo
+
+ // 校验订单数据
+ let checkResult = checkOrder(orderInfo)
+ if (!checkResult) {
+ return {
+ status: false,
+ message: 'order_info_error'
+ }
+ }
+
+ // 校验用户余额
+ console.log('user.balance:', user.balance)
+ console.log('orderInfo.total:', orderInfo.total)
+ let balance;
+ if (user.balance !== undefined && user.balance !== null) {
+ balance = user.balance
+ }
+ if (balance < parseFloat(orderInfo.total)) {
+ return {
+ status: false,
+ message: 'user_balance_error'
+ }
+ }
+ let orderNo = event.orderNo
+ let balanceAfter = balance - parseFloat(orderInfo.total);
+ if (!orderNo) {
+ let orderNo = create_pay_orderid(5)
+ let order = {
+ orderNo: orderNo,
+ orderInfo: orderInfo,
+ create_at: new Date(),
+ update_at: new Date(),
+ is_enable: true,
+ openid: user._id,
+ userName: user.nickName,
+ mobile_phone: user.mobile_phone,
+ unionid: user.unionid,
+ status: constant.PayStatus.submit,
+ amount: orderInfo.total,
+ type: constant.PayType.pay,
+ balance: balance - parseFloat(orderInfo.total),
+ is_admin_notified: false
+
+ }
+
+ let orderResult = null
+ try {
+ orderResult = await db.collection('order').add({
+ data: order
+ })
+ console.log('orderResult:', orderResult)
+ } catch (e) {
+ console.error(e)
+ }
+ if (!orderResult) {
+ return {
+ status: false,
+ message: 'create_order_error'
+ }
+ }
+
+ let buyResult = null
+ console.log('user:', user._id)
+ try {
+ buyResult = await db.collection('user').doc(user._id).update({
+ data: {
+ balance: db.command.inc(-parseFloat(orderInfo.total))
+ }
+ })
+ console.log('buyResult:', buyResult)
+ } catch (e) {
+ console.error(e)
+ }
+ if (!buyResult) {
+ return {
+ status: false,
+ message: 'update_balance_error'
+ }
+ }
+
+ let payResult = null
+ try {
+ payResult = await db.collection('order').doc(orderResult._id).update({
+ data: {
+ status: constant.PayStatus.pay,
+ update: new Date()
+ }
+ })
+ console.log('payResult:', payResult)
+ } catch (e) {
+ console.error(e)
+ }
+ if (!payResult) {
+ return {
+ status: false,
+ message: 'pay_order_error'
+ }
+ }
+ } else {
+ let orderResult = null
+ try {
+ orderResult = await db.collection('order').get({orderNo: orderNo}).limit(1).get()
+ console.log('orderResult:', orderResult)
+ } catch (e) {
+ console.error(e)
+ }
+ if (!orderResult) {
+ return {
+ status: false,
+ message: 'orderno_not_found'
+ }
+ }
+
+ if (orderResult.status !== constant.PayStatus.submit) {
+ return {
+ status: false,
+ message: 'submit_order_status_error'
+ }
+ }
+
+ let buyResult = null
+ try {
+ buyResult = await db.collection('user').doc(user.openid).update({
+ data: {
+ balance: db.command.inc(-parseInt(orderInfo.total)),
+ update_at: new Date()
+ }
+ })
+ console.log('buyResult:', buyResult)
+ } catch (e) {
+ console.error(e)
+ }
+ if (!buyResult) {
+ return {
+ status: false,
+ message: 'update_balance_error'
+ }
+ }
+
+ let payResult = null
+ try {
+ payResult = await db.collection('order').doc(orderResult._id).update({
+ data: {
+ status: constant.PayStatus.pay,
+ update: new Date()
+ }
+ })
+ console.log('payResult:', payResult)
+ } catch (e) {
+ console.error(e)
+ }
+ if (!payResult) {
+ return {
+ status: false,
+ message: 'pay_order_error'
+ }
+ }
+ }
+ return {
+ status: true,
+ message: 'ok',
+ data: {
+ orderNo: orderNo,
+ }
+ }
+}
+
+
+
+module.exports = {
+ orderPay: orderPay
+}
diff --git a/cloudfunctions/main/regist.js b/cloudfunctions/main/regist.js
new file mode 100644
index 0000000..3239192
--- /dev/null
+++ b/cloudfunctions/main/regist.js
@@ -0,0 +1,133 @@
+const cloud = require('wx-server-sdk')
+const db = require('./db')
+const WXBizDataCrypt = require('./utils/WXBizDataCrypt')
+const settings = require('./settings')
+
+const getUser = async (openid) => {
+ try {
+ return await db.collection('user').doc(openid).get()
+ } catch (e) {
+ // console.error(e)
+ return null
+ }
+}
+
+
+const updateUserMobilePhone = async (openid, mobile_phone) => {
+ try {
+ return await db.collection('user').doc(openid).update({
+ data: {
+ mobile_phone: mobile_phone,
+ update_at: new Date()
+ }
+ })
+ } catch (e) {
+ // console.error(e)
+ return null
+ }
+}
+
+// 云函数入口函数
+const regist = async (event, wxContext) => {
+ console.log('regist:')
+ console.log(event)
+ console.log(wxContext)
+
+ // var pc = new WXBizDataCrypt(appId, sessionKey)
+
+ // var data = pc.decryptData(encryptedData, iv)
+
+
+ const openid = wxContext.OPENID
+ // const mobile_phone = event.mobile_phone.data.phoneNumber
+ var pc = new WXBizDataCrypt(settings.app_id, event.sessionKey)
+ let encryptData = JSON.parse(event.encryptData)
+ console.log('encryptData:', encryptData)
+
+ var data = null
+ try {
+ var data = pc.decryptData(encryptData.encryptedData, encryptData.iv)
+ } catch(e) {
+ console.error(e)
+ }
+ if(!data) {
+ return {
+ status :false,
+ message: 'fail_parse_encryptdata'
+ }
+ }
+ console.log('data:', data)
+ // var data = pc.decryptData(encryptedData, iv)
+ const result = await getUser(openid)
+ if (!result) {
+ return {
+ status: false,
+ message: 'user_not_found'
+ }
+ }
+
+ const updateResult = await updateUserMobilePhone(openid, data.mobile_phone)
+ if (!updateResult) {
+ return {
+ status: false,
+ message: 'fail_update_user'
+ }
+ }
+
+ return {
+ status: true,
+ message: 'ok',
+ data: {
+ nextpage: '/pages/home/home',
+ openid: wxContext.OPENID
+ }
+ }
+}
+
+
+
+const registByCloudID = async (event, wxContext) => {
+ console.log('registByCloudID:')
+ console.log(event)
+ console.log(wxContext)
+
+
+ const openid = wxContext.OPENID
+ var mobile_phone = null
+ if (event.weRunData && event.weRunData.data && event.weRunData.data.purePhoneNumber) {
+ mobile_phone = event.weRunData.data.purePhoneNumber
+ } else {
+ return {
+ status: false,
+ message: 'fail_to_get_mobile_phone',
+ data: event
+ }
+ }
+
+ const updateResult = await updateUserMobilePhone(openid, mobile_phone)
+ if (!updateResult) {
+ return {
+ status: false,
+ message: 'fail_update_user',
+ data: event
+ }
+ }
+
+ return {
+ status: true,
+ message: 'ok',
+ data: {
+ nextpage: '/pages/home/home',
+ openid: wxContext.OPENID,
+ data: event
+ }
+ }
+}
+
+
+
+
+module.exports = {
+ regist: regist,
+ registByCloudID: registByCloudID
+}
diff --git a/cloudfunctions/main/settings.example.js b/cloudfunctions/main/settings.example.js
new file mode 100644
index 0000000..58c52d2
--- /dev/null
+++ b/cloudfunctions/main/settings.example.js
@@ -0,0 +1,19 @@
+const settings = {
+ cloudenv: '',
+ app_id: '',
+ app_secret: '',
+ wechat_access_token_record_id: '',
+ depositMsgId: '',
+ payMsgId: '',
+ wechat: {
+ appid: "",
+ mch_id: "",
+ ip: "",
+ notify_url: "",
+ key: "",
+ url: ""
+ }
+}
+
+
+module.exports = settings
\ No newline at end of file
diff --git a/cloudfunctions/main/user.js b/cloudfunctions/main/user.js
new file mode 100644
index 0000000..792333f
--- /dev/null
+++ b/cloudfunctions/main/user.js
@@ -0,0 +1,109 @@
+const cloud = require('wx-server-sdk')
+const db = require('./db')
+
+const updateBirthday = async (event, wxContext, user) => {
+ let result = null
+ try {
+ result = await db.collection('user').doc(user._id).update({
+ data: {
+ birthday: event.birthday
+ }
+ })
+ console.log('result:', result)
+ } catch (e) {
+ console.error(e)
+ }
+ if (!result) {
+ return {
+ status: false,
+ message: 'update_birthday_error'
+ }
+ }
+ return {
+ status: true,
+ message: 'ok'
+ }
+}
+
+const updateGender = async (event, wxContext, user) => {
+ let result = null
+ try {
+ result = await db.collection('user').doc(user._id).update({
+ data: {
+ gender: event.gender
+ }
+ })
+ console.log('result:', result)
+ } catch (e) {
+ console.error(e)
+ }
+ if (!result) {
+ return {
+ status: false,
+ message: 'update_gender_error'
+ }
+ }
+ return {
+ status: true,
+ message: 'ok'
+ }
+}
+
+const updateUserName = async (event, wxContext, user) => {
+ let result = null
+ try {
+ result = await db.collection('user').doc(user._id).update({
+ data: {
+ realName: event.realName,
+ nickName: event.nickName
+ }
+ })
+ console.log('result:', result)
+ } catch (e) {
+ console.error(e)
+ }
+ if (!result) {
+ return {
+ status: false,
+ message: 'update_name_error'
+ }
+ }
+ return {
+ status: true,
+ message: 'ok'
+ }
+}
+
+
+
+
+const updateAddress = async (event, wxContext, user) => {
+ let result = null
+ try {
+ result = await db.collection('user').doc(user._id).update({
+ data: {
+ address: event.address
+ }
+ })
+ console.log('result:', result)
+ } catch (e) {
+ console.error(e)
+ }
+ if (!result) {
+ return {
+ status: false,
+ message: 'update_address_error'
+ }
+ }
+ return {
+ status: true,
+ message: 'ok'
+ }
+}
+
+module.exports = {
+ updateBirthday: updateBirthday,
+ updateGender: updateGender,
+ updateUserName: updateUserName,
+ updateAddress, updateAddress
+}
diff --git a/cloudfunctions/main/utils/WXBizDataCrypt.js b/cloudfunctions/main/utils/WXBizDataCrypt.js
new file mode 100755
index 0000000..b6afef7
--- /dev/null
+++ b/cloudfunctions/main/utils/WXBizDataCrypt.js
@@ -0,0 +1,39 @@
+var crypto = require('crypto')
+
+function WXBizDataCrypt(appId, sessionKey) {
+ this.appId = appId
+ this.sessionKey = sessionKey
+}
+
+WXBizDataCrypt.prototype.decryptData = function (encryptedData, iv) {
+ // base64 decode
+ console.log('firstarg:', encryptedData)
+ console.log('iv:', iv)
+ console.log(this.appId)
+ console.log(this.sessionKey)
+ var sessionKey = new Buffer(this.sessionKey, 'base64')
+ encryptedData = new Buffer(encryptedData, 'base64')
+ iv = new Buffer(iv, 'base64')
+
+ try {
+ // 解密
+ var decipher = crypto.createDecipheriv('aes-128-cbc', sessionKey, iv)
+ // 设置自动 padding 为 true,删除填充补位
+ decipher.setAutoPadding(true)
+ var decoded = decipher.update(encryptedData, 'binary', 'utf8')
+ decoded += decipher.final('utf8')
+
+ decoded = JSON.parse(decoded)
+
+ } catch (err) {
+ throw new Error('Illegal Buffer')
+ }
+
+ if (decoded.watermark.appid !== this.appId) {
+ throw new Error('Illegal Buffer')
+ }
+
+ return decoded
+}
+
+module.exports = WXBizDataCrypt
diff --git a/cloudfunctions/main/utils/demo.js b/cloudfunctions/main/utils/demo.js
new file mode 100755
index 0000000..43be945
--- /dev/null
+++ b/cloudfunctions/main/utils/demo.js
@@ -0,0 +1,2 @@
+var WXBizDataCrypt = require('./WXBizDataCrypt')
+var appId = ''
diff --git a/cloudfunctions/main/utils/shortid.js b/cloudfunctions/main/utils/shortid.js
new file mode 100644
index 0000000..fd4a29b
--- /dev/null
+++ b/cloudfunctions/main/utils/shortid.js
@@ -0,0 +1,32 @@
+
+
+Date.prototype.Format = function (fmt) { //author: meizz
+ var o = {
+ "M+": this.getMonth() + 1, //月份
+ "d+": this.getDate(), //日
+ "h+": this.getHours(), //小时
+ "m+": this.getMinutes(), //分
+ "s+": this.getSeconds(), //秒
+ "q+": Math.floor((this.getMonth() + 3) / 3), //季度
+ "S": this.getMilliseconds() //毫秒
+ };
+ if (/(y+)/.test(fmt))
+ fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
+ for (var k in o)
+ if (new RegExp("(" + k + ")").test(fmt))
+ fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
+ return fmt;
+}
+
+function shortid(length=5) {
+ let maxNum = Math.pow(10, length) - 1
+ let minNum = Math.pow(10, length - 1)
+
+ let s = (new Date()).Format("yyyyMMddhhmmss")
+ console.log(s)
+ let salt = parseInt(Math.random() * (maxNum - minNum + 1) + minNum, 10);
+ console.log(salt)
+ return `${s}${salt}`
+}
+
+module.exports = shortid
diff --git a/cloudfunctions/main/utils/tpl_notify.js b/cloudfunctions/main/utils/tpl_notify.js
new file mode 100644
index 0000000..3cb2f8a
--- /dev/null
+++ b/cloudfunctions/main/utils/tpl_notify.js
@@ -0,0 +1,48 @@
+const axios = require('axios');
+const db = require('../db');
+const sendTemplateMsg = async (msgid, msgData, openid, formid, page) => {
+
+ let tokenResult = null
+ try {
+ tokenResult = await db.collection('wechat_token').doc(settings.wechat_access_token_record_id).get()
+ if(!tokenResult || tokenResult.errMsg != 'document.get.ok' ) {
+ return
+ }
+ } catch(e) {
+ return {
+ status: false,
+ data: 'fail_to_get_token'
+ }
+ }
+ let result = null
+ console.log('tokenResult:', tokenResult)
+ try {
+ result = await axios.post('https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send?access_token=' + tokenResult.data.token,
+ {
+ touser: openid,
+ template_id: msgid,
+ page: page,
+ form_id: formid,
+ data: msgData
+ })
+ } catch(e) {
+ console.error(e)
+ }
+
+ if(!result || !result.data) {
+ return {
+ status: false,
+ data: result
+ }
+ } else {
+ return {
+ status: true,
+ data: result
+ }
+ }
+
+}
+
+module.exports = {
+ sendTemplateMsg: sendTemplateMsg
+}
diff --git a/cloudfunctions/main/uuid.js b/cloudfunctions/main/uuid.js
new file mode 100644
index 0000000..497a48e
--- /dev/null
+++ b/cloudfunctions/main/uuid.js
@@ -0,0 +1,81 @@
+function UUID() {
+ this.id = this.createUUID();
+}
+
+
+
+// When asked what this Object is, lie and return it's value
+UUID.prototype.valueOf = function () { return this.id; };
+UUID.prototype.toString = function () { return this.id; };
+
+
+
+//
+// INSTANCE SPECIFIC METHODS
+//
+UUID.prototype.createUUID = function () {
+ //
+ // Loose interpretation of the specification DCE 1.1: Remote Procedure Call
+ // since JavaScript doesn't allow access to internal systems, the last 48 bits
+ // of the node section is made up using a series of random numbers (6 octets long).
+ //
+ var dg = new Date(1582, 10, 15, 0, 0, 0, 0);
+ var dc = new Date();
+ var t = dc.getTime() - dg.getTime();
+ var tl = UUID.getIntegerBits(t, 0, 31);
+ var tm = UUID.getIntegerBits(t, 32, 47);
+ var thv = UUID.getIntegerBits(t, 48, 59) + '1'; // version 1, security version is 2
+ var csar = UUID.getIntegerBits(UUID.rand(4095), 0, 7);
+ var csl = UUID.getIntegerBits(UUID.rand(4095), 0, 7);
+
+ // since detection of anything about the machine/browser is far to buggy,
+ // include some more random numbers here
+ // if NIC or an IP can be obtained reliably, that should be put in
+ // here instead.
+ var n = UUID.getIntegerBits(UUID.rand(8191), 0, 7) +
+ UUID.getIntegerBits(UUID.rand(8191), 8, 15) +
+ UUID.getIntegerBits(UUID.rand(8191), 0, 7) +
+ UUID.getIntegerBits(UUID.rand(8191), 8, 15) +
+ UUID.getIntegerBits(UUID.rand(8191), 0, 15); // this last number is two octets long
+ return tl + tm + thv + csar + csl + n;
+};
+
+
+
+//Pull out only certain bits from a very large integer, used to get the time
+//code information for the first part of a UUID. Will return zero's if there
+//aren't enough bits to shift where it needs to.
+UUID.getIntegerBits = function (val, start, end) {
+ var base16 = UUID.returnBase(val, 16);
+ var quadArray = new Array();
+ var quadString = '';
+ var i = 0;
+ for (i = 0; i < base16.length; i++) {
+ quadArray.push(base16.substring(i, i + 1));
+ }
+ for (i = Math.floor(start / 4); i <= Math.floor(end / 4); i++) {
+ if (!quadArray[i] || quadArray[i] == '') quadString += '0';
+ else quadString += quadArray[i];
+ }
+ return quadString;
+};
+
+
+
+//Replaced from the original function to leverage the built in methods in
+//JavaScript. Thanks to Robert Kieffer for pointing this one out
+UUID.returnBase = function (number, base) {
+ return (number).toString(base).toUpperCase();
+};
+
+
+
+//pick a random number within a range of numbers
+//int b rand(int a); where 0 <= b <= a
+UUID.rand = function (max) {
+ return Math.floor(Math.random() * (max + 1));
+};
+
+module.exports = {
+ UUID: UUID
+}
diff --git a/cloudfunctions/main/wechat_triggers.js b/cloudfunctions/main/wechat_triggers.js
new file mode 100644
index 0000000..7ca2ae2
--- /dev/null
+++ b/cloudfunctions/main/wechat_triggers.js
@@ -0,0 +1,223 @@
+const cloud = require('wx-server-sdk')
+const db = require('./db')
+const axios = require('axios');
+const settings = require('./settings')
+const tpl_notify = require('./utils/tpl_notify')
+const moment = require('moment')
+const APPID = settings.app_id;
+const APPSECRET = settings.app_secret;
+const COLLNAME = 'wechat_token';
+const FIELDNAME = settings.wechat_access_token_record_id
+
+
+const update_access_token = async (event, context) => {
+ let res = null
+ let resUpdate = null
+ try {
+ res = await axios.get(
+ "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + APPID + "&secret=" + APPSECRET
+ )
+ console.log('get_token_result:', res)
+ if (!res.data || !res.data.access_token) {
+ console.log('wechat:', res)
+ return
+ }
+ let resUpdate = await db.collection(COLLNAME).doc(FIELDNAME).update({
+ data: {
+ token: res.data.access_token,
+ update_at: new Date()
+ }
+ })
+ console.log('resUpdate:', resUpdate)
+ if (!resUpdate || resUpdate.errMsg !== 'document.update:ok') {
+
+ return
+ }
+ } catch (e) {
+ console.error(e)
+ }
+}
+
+
+function getDepositMsgData(order) {
+ let msgData = {
+ "keyword1": {
+ "value": order.orderNo
+ },
+ "keyword2": {
+ "value": "充值"
+ },
+ "keyword3": {
+ "value": order.amount
+ },
+ "keyword4": {
+ "value": order.orderInfo.displayTotal
+ },
+ "keyword5": {
+ "value": order.balance
+ },
+ "keyword6": {
+ "value": moment(order.create_at).format('YYYY/MM/DD HH:mm')
+ }
+ };
+ if (order.mobile_phone && order.userName) {
+ msgData["keyword7"] = {
+ "value": `用户姓名: ${order.userName}, 电话: ${order.mobile_phone}`
+ }
+ }
+ return msgData
+}
+
+function getPayMsgData(order) {
+ let goodsName = []
+ for (let item of order.orderInfo.entities) {
+ goodsName.push(`${item.name}x${item.count}`)
+ }
+
+ let address = ''
+ if (order.addressInfo) {
+ address = `收货人:${order.addressInfo.userName}, 电话:${order.addressInfo.telNumber}, 地址:${order.addressInfo.provinceName} ${order.addressInfo.cityName} ${order.addressInfo.countyName} ${order.addressInfo.detailInfo}`
+ }
+
+
+ let msgData = {
+ "keyword1": {
+ "value": order.orderNo
+ },
+ "keyword2": {
+ "value": order.amount
+ },
+ "keyword3": {
+ "value": goodsName.join(',')
+ },
+ "keyword4": {
+ "value": '余额支付'
+ },
+ "keyword9": {
+ "value": moment(order.create_at).format('YYYY/MM/DD HH:mm')
+ },
+ };
+
+ if (address) {
+ msgData["keywords8"] = {
+ "value": address
+ }
+ }
+
+ if (order.userName) {
+ msgData["keyword5"] = {
+ "value": order.userName
+ }
+ }
+ if (order.mobile_phone) {
+ msgData["keyword6"] = {
+ "value": order.mobile_phone
+ }
+ }
+ return msgData
+}
+
+const send_notification = async (event, context) => {
+ let result = null
+ try {
+ result = await db.collection('admin').where({ is_enable: true }).get()
+ console.log('result: ', result)
+ if (!result || result.errMsg !== 'collection.get:ok') {
+ console.log(result)
+ }
+ } catch (e) {
+ console.error(e)
+ }
+
+ let admins = []
+ for (let item of result.data) {
+ admins.push({
+ name: item.name,
+ openid: item.user_id
+ })
+ }
+ console.log('admins:', admins)
+ let orderResult = null
+ try {
+ orderResult = await db.collection('order').where({
+ is_enable: true, is_admin_notified: false
+ }).get()
+ console.log('orderResult:', orderResult)
+ if (!orderResult || orderResult.errMsg !== 'collection.get:ok') {
+ console.log(orderResult)
+ }
+ } catch (e) {
+ console.error(e)
+ }
+
+ let orders = []
+ for (let item of orderResult.data) {
+ orders.push(item)
+ }
+ console.log('orders:', orders)
+ let sendResult = null
+ for (let admin of admins) {
+ for (let order of orders) {
+ var msgid;
+ var msgData = null;
+ if (order.type == 'despit') {
+ msgid = settings.depositMsgId
+ msgData = getDepositMsgData(order)
+ } else if (order.type == 'pay') {
+ msgid = settings.payMsgId
+ msgData = getPayMsgData(order)
+ }
+ if (msgid && msgData) {
+ try {
+ var tokenResult = await db.collection('admin_push_token').where({ user_id: admin.user_id }).orderBy('create_at', 'asc').limit(1).get();
+ console.log('tokenResult:', tokenResult)
+ if (tokenResult && tokenResult.errCode == 'collection.get.ok' && tokenResult.data.length !== 0) {
+ sendResult = await sendTemplateMsg(tokenResult[0], msgid, msgData, admin.user_id, tokenResult.data[0].token, `pages/user_orders/user_orders?user_id=${order.openid}`)
+ console.log('sendResult:', sendResult)
+ }
+
+ } catch (e) {
+ console.error(e)
+ }
+
+ }
+
+ }
+ }
+
+ console.log('start update orders')
+ let updateResult = null
+ let orderIds = []
+ for (let item of orders) {
+ orderIds.push(item._id)
+ }
+ console.log('orderIds:', orderIds)
+ if (orderIds.length !== 0) {
+ try {
+ updateResult = await db.collection('order').where({ _id: db.command.in(orderIds) }).update({
+ data: {
+ is_admin_notified: true
+ }
+ })
+ db.collection('todos').where({
+ done: false
+ }).update({
+ data: {
+ progress: _.inc(10)
+ },
+ })
+ console.log('updateResult:', updateResult)
+ if (!updateResult || updateResult.errMsg !== 'collection.update:ok') {
+ console.log(updateResult)
+ }
+ } catch (e) {
+ console.error(e)
+ }
+ }
+
+}
+
+module.exports = {
+ update_access_token: update_access_token,
+ send_notification: send_notification
+}
diff --git a/miniprogram/app.js b/miniprogram/app.js
new file mode 100644
index 0000000..ecdbf36
--- /dev/null
+++ b/miniprogram/app.js
@@ -0,0 +1,62 @@
+import moment from './utils/moment.min.js'
+import settings from './settings/index'
+moment.locale('zh-cn');
+
+
+App({
+ onLaunch: function (e) {
+ console.log('onLaunch:', e)
+ this.globalData.systemInfo = wx.getSystemInfoSync()
+ if (!wx.cloud) {
+ console.error('请使用 2.2.3 或以上的基础库以使用云能力')
+ } else {
+ wx.cloud.init({
+ env: settings.cloudenv,
+ traceUser: true,
+ })
+ }
+
+
+ if(e.query.invite_by) {
+ wx.setStorageSync('invite_by', invite_by)
+ }
+
+ if (e.query.invite_from) {
+ wx.setStorageSync('invite_from', invite_from)
+ }
+
+ const sessionid = wx.getStorageSync('sessionid')
+ if (sessionid) {
+ console.log('sessionid:', sessionid)
+ this.goToURL(e.query.nextpage || settings.HomePage)
+ } else {
+ if(e.query.nextpage) {
+ wx.setStorageSync('nextpage_registed', e.query.nextpage)
+ }
+ }
+ },
+ isTab: function (url) {
+ let flag = false;
+ for (let item of settings.TAB_URLS) {
+ if (url.includes(item)) {
+ return true
+ }
+ }
+ return flag
+ },
+ goToURL: function (url) {
+ if (this.isTab(url)) {
+ wx.switchTab({
+ url: url
+ })
+ } else {
+ wx.redirectTo({
+ url: url
+ })
+ }
+ },
+ globalData: {
+ userInfo: null,
+ systemInfo: null
+ }
+})
diff --git a/miniprogram/app.json b/miniprogram/app.json
new file mode 100644
index 0000000..e866341
--- /dev/null
+++ b/miniprogram/app.json
@@ -0,0 +1,59 @@
+{
+ "pages": [
+ "pages/index/index",
+ "pages/home/home",
+ "pages/goods/goods",
+ "pages/me/me",
+ "pages/regist/regist",
+ "pages/orders/orders",
+ "pages/profile/profile",
+ "pages/buycart/buycart",
+ "pages/name_form/name_form",
+ "pages/order_details/order_details",
+ "pages/users/users",
+ "pages/user_orders/user_orders",
+ "pages/update_address/update_address",
+ "pages/update_delivery/update_delivery",
+ "pages/update_order/update_order",
+ "pages/update_remarks/update_remarks",
+ "pages/update_total/update_total",
+ "pages/cancel_order/cancel_order",
+ "pages/all_orders/all_orders",
+ "pages/admin_message/admin_message"
+ ],
+ "window": {
+ "backgroundColor": "#e67774",
+ "backgroundTextStyle": "light",
+ "navigationBarBackgroundColor": "#e67774",
+ "navigationBarTitleText": "Jing Studio",
+ "navigationBarTextStyle": "white"
+ },
+ "tabBar": {
+ "selectedColor": "#333",
+ "color": "#999",
+ "backgroundColor": "#fff",
+ "borderStyle": "black",
+ "position": "bottom",
+ "list": [
+ {
+ "pagePath": "pages/home/home",
+ "text": "首页",
+ "iconPath": "./assets/images/tabs/home.png",
+ "selectedIconPath": "./assets/images/tabs/home-selected.png"
+ },
+ {
+ "pagePath": "pages/goods/goods",
+ "text": "商城",
+ "iconPath": "./assets/images/tabs/cake.png",
+ "selectedIconPath": "./assets/images/tabs/cake-selected.png"
+ },
+ {
+ "pagePath": "pages/me/me",
+ "text": "我的",
+ "iconPath": "./assets/images/tabs/me.png",
+ "selectedIconPath": "./assets/images/tabs/me-selected.png"
+ }
+ ]
+ },
+ "sitemapLocation": "sitemap.json"
+}
\ No newline at end of file
diff --git a/miniprogram/app.wxss b/miniprogram/app.wxss
new file mode 100644
index 0000000..3181a88
--- /dev/null
+++ b/miniprogram/app.wxss
@@ -0,0 +1,158 @@
+
+
+/*
+.container {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ box-sizing: border-box;
+}
+
+button {
+ background: initial;
+}
+
+button:focus{
+ outline: 0;
+}
+
+button::after{
+ border: none;
+}
+
+
+page {
+ background: #f6f6f6;
+ display: flex;
+ flex-direction: column;
+ justify-content: flex-start;
+}
+
+.userinfo, .uploader, .tunnel {
+ margin-top: 40rpx;
+ height: 140rpx;
+ width: 100%;
+ background: #fff;
+ border: 1px solid rgba(0, 0, 0, 0.1);
+ border-left: none;
+ border-right: none;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ transition: all 300ms ease;
+}
+
+.userinfo-avatar {
+ width: 100rpx;
+ height: 100rpx;
+ margin: 20rpx;
+ border-radius: 50%;
+ background-size: cover;
+ background-color: white;
+}
+
+.userinfo-avatar:after {
+ border: none;
+}
+
+.userinfo-nickname {
+ font-size: 32rpx;
+ color: #007aff;
+ background-color: white;
+ background-size: cover;
+}
+
+.userinfo-nickname::after {
+ border: none;
+}
+
+.uploader, .tunnel {
+ height: auto;
+ padding: 0 0 0 40rpx;
+ flex-direction: column;
+ align-items: flex-start;
+ box-sizing: border-box;
+}
+
+.uploader-text, .tunnel-text {
+ width: 100%;
+ line-height: 52px;
+ font-size: 34rpx;
+ color: #007aff;
+}
+
+.uploader-container {
+ width: 100%;
+ height: 400rpx;
+ padding: 20rpx 20rpx 20rpx 0;
+ display: flex;
+ align-content: center;
+ justify-content: center;
+ box-sizing: border-box;
+ border-top: 1px solid rgba(0, 0, 0, 0.1);
+}
+
+.uploader-image {
+ width: 100%;
+ height: 360rpx;
+}
+
+.tunnel {
+ padding: 0 0 0 40rpx;
+}
+
+.tunnel-text {
+ position: relative;
+ color: #222;
+ display: flex;
+ flex-direction: row;
+ align-content: center;
+ justify-content: space-between;
+ box-sizing: border-box;
+ border-top: 1px solid rgba(0, 0, 0, 0.1);
+}
+
+.tunnel-text:first-child {
+ border-top: none;
+}
+
+.tunnel-switch {
+ position: absolute;
+ right: 20rpx;
+ top: -2rpx;
+}
+
+.disable {
+ color: #888;
+}
+
+.service {
+ position: fixed;
+ right: 40rpx;
+ bottom: 40rpx;
+ width: 140rpx;
+ height: 140rpx;
+ border-radius: 50%;
+ background: linear-gradient(#007aff, #0063ce);
+ box-shadow: 0 5px 10px rgba(0, 0, 0, 0.3);
+ display: flex;
+ align-content: center;
+ justify-content: center;
+ transition: all 300ms ease;
+}
+
+.service-button {
+ position: absolute;
+ top: 40rpx;
+}
+
+.service:active {
+ box-shadow: none;
+}
+
+.request-text {
+ padding: 20rpx 0;
+ font-size: 24rpx;
+ line-height: 36rpx;
+ word-break: break-all;
+} */
diff --git a/miniprogram/assets/icons/demo.css b/miniprogram/assets/icons/demo.css
new file mode 100644
index 0000000..a67054a
--- /dev/null
+++ b/miniprogram/assets/icons/demo.css
@@ -0,0 +1,539 @@
+/* Logo 字体 */
+@font-face {
+ font-family: "iconfont logo";
+ src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834');
+ src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834#iefix') format('embedded-opentype'),
+ url('https://at.alicdn.com/t/font_985780_km7mi63cihi.woff?t=1545807318834') format('woff'),
+ url('https://at.alicdn.com/t/font_985780_km7mi63cihi.ttf?t=1545807318834') format('truetype'),
+ url('https://at.alicdn.com/t/font_985780_km7mi63cihi.svg?t=1545807318834#iconfont') format('svg');
+}
+
+.logo {
+ font-family: "iconfont logo";
+ font-size: 160px;
+ font-style: normal;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+/* tabs */
+.nav-tabs {
+ position: relative;
+}
+
+.nav-tabs .nav-more {
+ position: absolute;
+ right: 0;
+ bottom: 0;
+ height: 42px;
+ line-height: 42px;
+ color: #666;
+}
+
+#tabs {
+ border-bottom: 1px solid #eee;
+}
+
+#tabs li {
+ cursor: pointer;
+ width: 100px;
+ height: 40px;
+ line-height: 40px;
+ text-align: center;
+ font-size: 16px;
+ border-bottom: 2px solid transparent;
+ position: relative;
+ z-index: 1;
+ margin-bottom: -1px;
+ color: #666;
+}
+
+
+#tabs .active {
+ border-bottom-color: #f00;
+ color: #222;
+}
+
+.tab-container .content {
+ display: none;
+}
+
+/* 页面布局 */
+.main {
+ padding: 30px 100px;
+ width: 960px;
+ margin: 0 auto;
+}
+
+.main .logo {
+ color: #333;
+ text-align: left;
+ margin-bottom: 30px;
+ line-height: 1;
+ height: 110px;
+ margin-top: -50px;
+ overflow: hidden;
+ *zoom: 1;
+}
+
+.main .logo a {
+ font-size: 160px;
+ color: #333;
+}
+
+.helps {
+ margin-top: 40px;
+}
+
+.helps pre {
+ padding: 20px;
+ margin: 10px 0;
+ border: solid 1px #e7e1cd;
+ background-color: #fffdef;
+ overflow: auto;
+}
+
+.icon_lists {
+ width: 100% !important;
+ overflow: hidden;
+ *zoom: 1;
+}
+
+.icon_lists li {
+ width: 100px;
+ margin-bottom: 10px;
+ margin-right: 20px;
+ text-align: center;
+ list-style: none !important;
+ cursor: default;
+}
+
+.icon_lists li .code-name {
+ line-height: 1.2;
+}
+
+.icon_lists .icon {
+ display: block;
+ height: 100px;
+ line-height: 100px;
+ font-size: 42px;
+ margin: 10px auto;
+ color: #333;
+ -webkit-transition: font-size 0.25s linear, width 0.25s linear;
+ -moz-transition: font-size 0.25s linear, width 0.25s linear;
+ transition: font-size 0.25s linear, width 0.25s linear;
+}
+
+.icon_lists .icon:hover {
+ font-size: 100px;
+}
+
+.icon_lists .svg-icon {
+ /* 通过设置 font-size 来改变图标大小 */
+ width: 1em;
+ /* 图标和文字相邻时,垂直对齐 */
+ vertical-align: -0.15em;
+ /* 通过设置 color 来改变 SVG 的颜色/fill */
+ fill: currentColor;
+ /* path 和 stroke 溢出 viewBox 部分在 IE 下会显示
+ normalize.css 中也包含这行 */
+ overflow: hidden;
+}
+
+.icon_lists li .name,
+.icon_lists li .code-name {
+ color: #666;
+}
+
+/* markdown 样式 */
+.markdown {
+ color: #666;
+ font-size: 14px;
+ line-height: 1.8;
+}
+
+.highlight {
+ line-height: 1.5;
+}
+
+.markdown img {
+ vertical-align: middle;
+ max-width: 100%;
+}
+
+.markdown h1 {
+ color: #404040;
+ font-weight: 500;
+ line-height: 40px;
+ margin-bottom: 24px;
+}
+
+.markdown h2,
+.markdown h3,
+.markdown h4,
+.markdown h5,
+.markdown h6 {
+ color: #404040;
+ margin: 1.6em 0 0.6em 0;
+ font-weight: 500;
+ clear: both;
+}
+
+.markdown h1 {
+ font-size: 28px;
+}
+
+.markdown h2 {
+ font-size: 22px;
+}
+
+.markdown h3 {
+ font-size: 16px;
+}
+
+.markdown h4 {
+ font-size: 14px;
+}
+
+.markdown h5 {
+ font-size: 12px;
+}
+
+.markdown h6 {
+ font-size: 12px;
+}
+
+.markdown hr {
+ height: 1px;
+ border: 0;
+ background: #e9e9e9;
+ margin: 16px 0;
+ clear: both;
+}
+
+.markdown p {
+ margin: 1em 0;
+}
+
+.markdown>p,
+.markdown>blockquote,
+.markdown>.highlight,
+.markdown>ol,
+.markdown>ul {
+ width: 80%;
+}
+
+.markdown ul>li {
+ list-style: circle;
+}
+
+.markdown>ul li,
+.markdown blockquote ul>li {
+ margin-left: 20px;
+ padding-left: 4px;
+}
+
+.markdown>ul li p,
+.markdown>ol li p {
+ margin: 0.6em 0;
+}
+
+.markdown ol>li {
+ list-style: decimal;
+}
+
+.markdown>ol li,
+.markdown blockquote ol>li {
+ margin-left: 20px;
+ padding-left: 4px;
+}
+
+.markdown code {
+ margin: 0 3px;
+ padding: 0 5px;
+ background: #eee;
+ border-radius: 3px;
+}
+
+.markdown strong,
+.markdown b {
+ font-weight: 600;
+}
+
+.markdown>table {
+ border-collapse: collapse;
+ border-spacing: 0px;
+ empty-cells: show;
+ border: 1px solid #e9e9e9;
+ width: 95%;
+ margin-bottom: 24px;
+}
+
+.markdown>table th {
+ white-space: nowrap;
+ color: #333;
+ font-weight: 600;
+}
+
+.markdown>table th,
+.markdown>table td {
+ border: 1px solid #e9e9e9;
+ padding: 8px 16px;
+ text-align: left;
+}
+
+.markdown>table th {
+ background: #F7F7F7;
+}
+
+.markdown blockquote {
+ font-size: 90%;
+ color: #999;
+ border-left: 4px solid #e9e9e9;
+ padding-left: 0.8em;
+ margin: 1em 0;
+}
+
+.markdown blockquote p {
+ margin: 0;
+}
+
+.markdown .anchor {
+ opacity: 0;
+ transition: opacity 0.3s ease;
+ margin-left: 8px;
+}
+
+.markdown .waiting {
+ color: #ccc;
+}
+
+.markdown h1:hover .anchor,
+.markdown h2:hover .anchor,
+.markdown h3:hover .anchor,
+.markdown h4:hover .anchor,
+.markdown h5:hover .anchor,
+.markdown h6:hover .anchor {
+ opacity: 1;
+ display: inline-block;
+}
+
+.markdown>br,
+.markdown>p>br {
+ clear: both;
+}
+
+
+.hljs {
+ display: block;
+ background: white;
+ padding: 0.5em;
+ color: #333333;
+ overflow-x: auto;
+}
+
+.hljs-comment,
+.hljs-meta {
+ color: #969896;
+}
+
+.hljs-string,
+.hljs-variable,
+.hljs-template-variable,
+.hljs-strong,
+.hljs-emphasis,
+.hljs-quote {
+ color: #df5000;
+}
+
+.hljs-keyword,
+.hljs-selector-tag,
+.hljs-type {
+ color: #a71d5d;
+}
+
+.hljs-literal,
+.hljs-symbol,
+.hljs-bullet,
+.hljs-attribute {
+ color: #0086b3;
+}
+
+.hljs-section,
+.hljs-name {
+ color: #63a35c;
+}
+
+.hljs-tag {
+ color: #333333;
+}
+
+.hljs-title,
+.hljs-attr,
+.hljs-selector-id,
+.hljs-selector-class,
+.hljs-selector-attr,
+.hljs-selector-pseudo {
+ color: #795da3;
+}
+
+.hljs-addition {
+ color: #55a532;
+ background-color: #eaffea;
+}
+
+.hljs-deletion {
+ color: #bd2c00;
+ background-color: #ffecec;
+}
+
+.hljs-link {
+ text-decoration: underline;
+}
+
+/* 代码高亮 */
+/* PrismJS 1.15.0
+https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript */
+/**
+ * prism.js default theme for JavaScript, CSS and HTML
+ * Based on dabblet (http://dabblet.com)
+ * @author Lea Verou
+ */
+code[class*="language-"],
+pre[class*="language-"] {
+ color: black;
+ background: none;
+ text-shadow: 0 1px white;
+ font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
+ text-align: left;
+ white-space: pre;
+ word-spacing: normal;
+ word-break: normal;
+ word-wrap: normal;
+ line-height: 1.5;
+
+ -moz-tab-size: 4;
+ -o-tab-size: 4;
+ tab-size: 4;
+
+ -webkit-hyphens: none;
+ -moz-hyphens: none;
+ -ms-hyphens: none;
+ hyphens: none;
+}
+
+pre[class*="language-"]::-moz-selection,
+pre[class*="language-"] ::-moz-selection,
+code[class*="language-"]::-moz-selection,
+code[class*="language-"] ::-moz-selection {
+ text-shadow: none;
+ background: #b3d4fc;
+}
+
+pre[class*="language-"]::selection,
+pre[class*="language-"] ::selection,
+code[class*="language-"]::selection,
+code[class*="language-"] ::selection {
+ text-shadow: none;
+ background: #b3d4fc;
+}
+
+@media print {
+
+ code[class*="language-"],
+ pre[class*="language-"] {
+ text-shadow: none;
+ }
+}
+
+/* Code blocks */
+pre[class*="language-"] {
+ padding: 1em;
+ margin: .5em 0;
+ overflow: auto;
+}
+
+:not(pre)>code[class*="language-"],
+pre[class*="language-"] {
+ background: #f5f2f0;
+}
+
+/* Inline code */
+:not(pre)>code[class*="language-"] {
+ padding: .1em;
+ border-radius: .3em;
+ white-space: normal;
+}
+
+.token.comment,
+.token.prolog,
+.token.doctype,
+.token.cdata {
+ color: slategray;
+}
+
+.token.punctuation {
+ color: #999;
+}
+
+.namespace {
+ opacity: .7;
+}
+
+.token.property,
+.token.tag,
+.token.boolean,
+.token.number,
+.token.constant,
+.token.symbol,
+.token.deleted {
+ color: #905;
+}
+
+.token.selector,
+.token.attr-name,
+.token.string,
+.token.char,
+.token.builtin,
+.token.inserted {
+ color: #690;
+}
+
+.token.operator,
+.token.entity,
+.token.url,
+.language-css .token.string,
+.style .token.string {
+ color: #9a6e3a;
+ background: hsla(0, 0%, 100%, .5);
+}
+
+.token.atrule,
+.token.attr-value,
+.token.keyword {
+ color: #07a;
+}
+
+.token.function,
+.token.class-name {
+ color: #DD4A68;
+}
+
+.token.regex,
+.token.important,
+.token.variable {
+ color: #e90;
+}
+
+.token.important,
+.token.bold {
+ font-weight: bold;
+}
+
+.token.italic {
+ font-style: italic;
+}
+
+.token.entity {
+ cursor: help;
+}
diff --git a/miniprogram/assets/icons/demo_index.html b/miniprogram/assets/icons/demo_index.html
new file mode 100644
index 0000000..56350fb
--- /dev/null
+++ b/miniprogram/assets/icons/demo_index.html
@@ -0,0 +1,883 @@
+
+
+
+
+ IconFont Demo
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ - Unicode
+ - Font class
+ - Symbol
+
+
+
查看项目
+
+
+
+
+
+
+ -
+
+
购物车满
+ 
+
+
+ -
+
+
购物车空
+ 
+
+
+ -
+
+
账户充值
+ 
+
+
+ -
+
+
我的
+ 
+
+
+ -
+
+
蛋糕
+ 
+
+
+ -
+
+
首页
+ 
+
+
+ -
+
+
首页1
+ 
+
+
+ -
+
+
分类1
+ 
+
+
+ -
+
+
购物车1
+ 
+
+
+ -
+
+
我的1
+ 
+
+
+ -
+
+
返回
+ 
+
+
+ -
+
+
返回首页
+ 
+
+
+ -
+
+
更多
+ 
+
+
+ -
+
+
查看更多
+ 
+
+
+ -
+
+
菜单
+ 
+
+
+ -
+
+
搜索
+ 
+
+
+ -
+
+
关键字
+ 
+
+
+ -
+
+
关闭
+ 
+
+
+ -
+
+
选项
+ 
+
+
+ -
+
+
点赞
+ 
+
+
+ -
+
+
喜欢
+ 
+
+
+ -
+
+
分享
+ 
+
+
+ -
+
+
扫一扫
+ 
+
+
+ -
+
+
客服
+ 
+
+
+ -
+
+
评论
+ 
+
+
+ -
+
+
删除
+ 
+
+
+ -
+
+
提示
+ 
+
+
+ -
+
+
进行中
+ 
+
+
+ -
+
+
成功
+ 
+
+
+ -
+
+
失败
+ 
+
+
+ -
+
+
活动
+ 
+
+
+
+
+
Unicode 引用
+
+
+
Unicode 是字体在网页端最原始的应用方式,特点是:
+
+ - 兼容性最好,支持 IE6+,及所有现代浏览器。
+ - 支持按字体的方式去动态调整图标大小,颜色等等。
+ - 但是因为是字体,所以不支持多色。只能使用平台里单色的图标,就算项目里有多色图标也会自动去色。
+
+
+ 注意:新版 iconfont 支持多色图标,这些多色图标在 Unicode 模式下将不能使用,如果有需求建议使用symbol 的引用方式
+
+
Unicode 使用步骤如下:
+
第一步:拷贝项目下面生成的 @font-face
+
@font-face {
+ font-family: 'iconfont';
+ src: url('iconfont.eot');
+ src: url('iconfont.eot?#iefix') format('embedded-opentype'),
+ url('iconfont.woff2') format('woff2'),
+ url('iconfont.woff') format('woff'),
+ url('iconfont.ttf') format('truetype'),
+ url('iconfont.svg#iconfont') format('svg');
+}
+
+
第二步:定义使用 iconfont 的样式
+
.iconfont {
+ font-family: "iconfont" !important;
+ font-size: 16px;
+ font-style: normal;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+
第三步:挑选相应图标并获取字体编码,应用于页面
+
+<span class="iconfont">3</span>
+
+
+ "iconfont" 是你项目下的 font-family。可以通过编辑项目查看,默认是 "iconfont"。
+
+
+
+
+
+
+
font-class 引用
+
+
+
font-class 是 Unicode 使用方式的一种变种,主要是解决 Unicode 书写不直观,语意不明确的问题。
+
与 Unicode 使用方式相比,具有如下特点:
+
+ - 兼容性良好,支持 IE8+,及所有现代浏览器。
+ - 相比于 Unicode 语意明确,书写更直观。可以很容易分辨这个 icon 是什么。
+ - 因为使用 class 来定义图标,所以当要替换图标时,只需要修改 class 里面的 Unicode 引用。
+ - 不过因为本质上还是使用的字体,所以多色图标还是不支持的。
+
+
使用步骤如下:
+
第一步:引入项目下面生成的 fontclass 代码:
+
<link rel="stylesheet" href="./iconfont.css">
+
+
第二步:挑选相应图标并获取类名,应用于页面:
+
<span class="iconfont icon-xxx"></span>
+
+
+ "
+ iconfont" 是你项目下的 font-family。可以通过编辑项目查看,默认是 "iconfont"。
+
+
+
+
+
+
+
Symbol 引用
+
+
+
这是一种全新的使用方式,应该说这才是未来的主流,也是平台目前推荐的用法。相关介绍可以参考这篇文章
+ 这种用法其实是做了一个 SVG 的集合,与另外两种相比具有如下特点:
+
+ - 支持多色图标了,不再受单色限制。
+ - 通过一些技巧,支持像字体那样,通过
font-size
, color
来调整样式。
+ - 兼容性较差,支持 IE9+,及现代浏览器。
+ - 浏览器渲染 SVG 的性能一般,还不如 png。
+
+
使用步骤如下:
+
第一步:引入项目下面生成的 symbol 代码:
+
<script src="./iconfont.js"></script>
+
+
第二步:加入通用 CSS 代码(引入一次就行):
+
<style>
+.icon {
+ width: 1em;
+ height: 1em;
+ vertical-align: -0.15em;
+ fill: currentColor;
+ overflow: hidden;
+}
+</style>
+
+
第三步:挑选相应图标并获取类名,应用于页面:
+
<svg class="icon" aria-hidden="true">
+ <use xlink:href="#icon-xxx"></use>
+</svg>
+
+
+
+
+
+
+
+
+
diff --git a/miniprogram/assets/icons/iconfont.eot b/miniprogram/assets/icons/iconfont.eot
new file mode 100644
index 0000000..07c11ce
Binary files /dev/null and b/miniprogram/assets/icons/iconfont.eot differ
diff --git a/miniprogram/assets/icons/iconfont.js b/miniprogram/assets/icons/iconfont.js
new file mode 100644
index 0000000..89ebdec
--- /dev/null
+++ b/miniprogram/assets/icons/iconfont.js
@@ -0,0 +1 @@
+!function(a){var c,t='',l=(c=document.getElementsByTagName("script"))[c.length-1].getAttribute("data-injectcss");if(l&&!a.__iconfont__svg__cssinject__){a.__iconfont__svg__cssinject__=!0;try{document.write("")}catch(c){console&&console.log(c)}}!function(c){if(document.addEventListener)if(~["complete","loaded","interactive"].indexOf(document.readyState))setTimeout(c,0);else{var l=function(){document.removeEventListener("DOMContentLoaded",l,!1),c()};document.addEventListener("DOMContentLoaded",l,!1)}else document.attachEvent&&(h=c,i=a.document,o=!1,(s=function(){try{i.documentElement.doScroll("left")}catch(c){return void setTimeout(s,50)}t()})(),i.onreadystatechange=function(){"complete"==i.readyState&&(i.onreadystatechange=null,t())});function t(){o||(o=!0,h())}var h,i,o,s}(function(){var c,l;(c=document.createElement("div")).innerHTML=t,t=null,(l=c.getElementsByTagName("svg")[0])&&(l.setAttribute("aria-hidden","true"),l.style.position="absolute",l.style.width=0,l.style.height=0,l.style.overflow="hidden",function(c,l){l.firstChild?function(c,l){l.parentNode.insertBefore(c,l)}(c,l.firstChild):l.appendChild(c)}(l,document.body))})}(window);
\ No newline at end of file
diff --git a/miniprogram/assets/icons/iconfont.svg b/miniprogram/assets/icons/iconfont.svg
new file mode 100644
index 0000000..a338060
--- /dev/null
+++ b/miniprogram/assets/icons/iconfont.svg
@@ -0,0 +1,119 @@
+
+
+
+
diff --git a/miniprogram/assets/icons/iconfont.ttf b/miniprogram/assets/icons/iconfont.ttf
new file mode 100644
index 0000000..b835bd4
Binary files /dev/null and b/miniprogram/assets/icons/iconfont.ttf differ
diff --git a/miniprogram/assets/icons/iconfont.woff b/miniprogram/assets/icons/iconfont.woff
new file mode 100644
index 0000000..ef419ef
Binary files /dev/null and b/miniprogram/assets/icons/iconfont.woff differ
diff --git a/miniprogram/assets/icons/iconfont.woff2 b/miniprogram/assets/icons/iconfont.woff2
new file mode 100644
index 0000000..19b2e57
Binary files /dev/null and b/miniprogram/assets/icons/iconfont.woff2 differ
diff --git a/miniprogram/assets/icons/iconfont.wxss b/miniprogram/assets/icons/iconfont.wxss
new file mode 100644
index 0000000..1bc860f
--- /dev/null
+++ b/miniprogram/assets/icons/iconfont.wxss
@@ -0,0 +1,141 @@
+@font-face {font-family: "iconfont";
+ src: url('iconfont.eot?t=1564286613049'); /* IE9 */
+ src: url('iconfont.eot?t=1564286613049#iefix') format('embedded-opentype'), /* IE6-IE8 */
+ url('data:application/x-font-woff2;charset=utf-8;base64,d09GMgABAAAAABPoAAsAAAAAJywAABOYAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHEIGVgCGVAq6VK4nATYCJAOBAAtCAAQgBYRtB4J6G/MfRaSTpJUFsv/rBE6ujnVHCEU4arsFlvYY8SjTj2xpdfnOvbsitmXpV+MtFmAV6iRV8OCgUTRQZZTiiwqOGUrJwz/7ufttjg/RcfoyGU+iUbUE8QQ1kEiU9LCtOUweCykgqsndnCRrNphTk5JDKcnIUOK0I0BDYZwOgOWvffczBDYOGMY3QHDk1wF/fluaD/wXQMDwtM1/F+QRgoEbByJmgDajZSY6MZoZrBIjsWrRunL6w5jr1kUxF6mLX6X+uSg3dcZJStP/7R6W4tj1acddsSXbASmmUg8QYBT/+TnTFkao+SDDuJFFK/5LUnj5/+C3o/QwB9t6HQM7So8oHYJjUAQS5YSc0NN22s35QbqlV+lnrzWmDhn6sN/MB6vAFc44RcVojPrcnZwEqGndcH5xaUuFwNQEg1xfnB2oOLxEQM2EEa0ERebwHRSM9DX0BgBv/O0n/2DgCkjJDDultdULx6b/A/+1R76abIcJuElPw644kAFtIAfJlzDuE4S/2ObUEg39jX80+fTERUBhtax1NiBqtD9NgIsdrbttdeNmgUQs1e2l9ZWIj1Hp/j8ezWCy2IjD5fEFQlIklkhlcoVSpdZodSApoQM3AMkDerRAgKcgASGSgkBESiDsVW5WAJEchEGkDGKeSAXEApEqiEUiNRCFInUQRSINEMVcB1gJuE6wUnBdYGXgusHKwfWAVYDrBasEV4BVgesDM4FrgtWA6werAzcAVg9uEKwB3BBYI7hhsCZwI2DN4EbBWsCNgbWCGwdrAzcB1o7htAAm30VMAx6oLtCYwqI+uDS9+2akHtetEm4y7DyGPSUJKdCqFLGfrYPgVTSIoJLngbmWJuNx8XJb2mPj+1SYxOCjtoqUbn8kLfhFZuvbNIRvGJA2hE/ppyCqGWqu/Guv+xg6JdmXWK3CZ1iqcR4ZpIslRIeB11cY+YR21TlGjtpX1GvuceWEd33Fn2uzTMulkoxw9AaKiV00QGwUU133OCdRCan5dBoqHsbBXdhSQ4d25ZaI7D1vSbHtTa01mtu0Wdx0wPeFYlEMApnSJQggWCp+hiyNExnMyWMEDBDAOzgmQalEVSGs5hPxqBU1+Th0oHSqdCQ0oQUeV5MwN/z2a5+Uz9pH8kHUmeO0572R3i/wNJ36xK8hl1pujLb9Cu4eVYK3glY8P+IfACTbEMvnOZi6q91X7ql3SqBViHfJ5QQbErJgUto4o4R2l9xR7yn3ZRCD+OrDIdcfD3u3AsG1R0OvPBg8KoJKIR7N5VpjRCNi0AEQtDzNAdJz35NXOFPxFoc4hy2qCaFpooiqM4DoqsnBzG0c1W6WOoK0xdRbECq3cZe9P3ljs2GYHosPbY1lvq+raSoW7qYZRF+fSCqn62AHUaRswfJJeXeTI7EHqjoxDAuaaxX5jyCpNnE0T3FF1ytK+VtuXs3aN1TOkVrAV+RzN52cVvBua+DYKHRfB1a7anNnsULU+HEhcunuSxx9HtSHxxiapXQiWDcLfrmAePTDYATT95pQ9k4JQNc+VYXRGk9rWXVAcqnqNws3/JpQsShGg0AOK3RtxOLCYk6LyyE94fuTkQXDimnmGUFXOSnfoOsgpLPoGZXCyuNecuG6drVRdB6CA8j3hTRsGPou2AeUvABSKvXovp6PEq8gBAz7Ir4W0PmM1gXBtKdF8aS/FDWCxmJrP2XUqrQnAh0KQDleCLErzZKZtVOsmAQhMsD2QSJDa0E/rA07VpxS876Vyz0vBHBrsrYzllq+It9TpB6jS0/8itzVTHGGfjI9DcMZL97Ffx9DxO/NmmXPce+1oUEgBkXxyuClJdQnP6ObJCBu/O2gvlKppDjijct5O5EtOrfazPBrLM0hTOcqg9gHOugqJJ0Cz4dSLUYOY6jw5VYcG2yjkQIAF3pZGRh2Ol/LNLkVuqvwa1abiqexMQNMp75DsllFUD8EBG2j/0nB/3LxX9H/xwA7wS3At0QCsvH4qOGkklLEvFUhNjQgiGhHz5YaDDxTEaUrlhmlfTCRPNotrFTGsXxk4icEPZtP8zJKIA53oAxGw7JVyKUYgUuZpCDUitPsyCB5lMLOyIqSejvk5okSMlSqxeR6Tph8KDgIIDT5E++HsFffXjpVIhB2idErWpN3FqzzuVfWnr4fb4tqFuwwOXTtXhWUT/RNu02cOT8Y+oKAVB20EYPF/hntprmBtrjh0eKElofixwVOI2tMqZPkNT5e6OX1WhRMyvCPgzpKJVXorYZYobeO74Ng3+FtpOY5o+dYupBK6TJKF9v+tOKY+8GBurvmcHkBg2LLdclqxVgz4+VYMUVKasr7TQ6FoOoel4vMomqDYassfBkg5TRu6SrOgmHnUH1awStfuod+y4Eej0NYPbYxBejxjk5YI2uXtLX/uTAdgDiNjZqBLQ9CizNdpiFrb1JAvOAMVXGbmlQTqTYAOms4Hc4lAI76gwvmaGlNe1+u2FBMCE98HmaxmNKffAFfL1YaMn1/GKxyTddoCgP+0isIfi7uCC+XYMqIFS31QMJITKtwg/bl+o4ZLfhT3KuhlcznI2nBUuUlDNYojf4lHPMJnSpOwZrBDiAGMHLjSmoYGqosXXOloSbo3G5ZOrcm9k0EaS4ccD0+TlVfGMgOteA32WAkY/Zt1TxbjLleVp3P8tobU+VHsqTa4U75o2frAOiH/JQL/DwvqILH3w1FVz5UCGZkyRDNbIdopOwsJ5kwXLgZWSwzzB6r4KSYVv24Q2mvwIrj2p/Q826mREqaG0QF1ZfSd1z9WNkimvqpqqVUsT2l1WVrHpruamGYbjPAkDqeJopg6VwwNz2znGBbK1OZ+iv+Z6qquW/qz/hfqT53IdPHVbVv/EG4N6Xy683mOb++OFJVFuv4dkBPtndlKXOp8nLffl9CKjk8p8s4fzpib/JrGe1Ty3i+ao50zUvtChsaDSYDiJlv6bXtTRK6tyu/g/e3jXcOspQk6pnlQs/vdQfvvBr/9ogcEjP6pIo3k55B9HO3mnVghtUhz+7EbfNqxA1pmjiln2fdds+MJHlLuglyOGEDgABRnEO/fkXtPpcAl2VO4vm6Pbj9dfBr3VDw2vr6oh9+SOYn4y56zK8NHtK9BvW1wUplK65asECFR/B3aPhKfHTnqXgRO4Q8gV+Ja3g7vgAbnkflblEWtwXiMyHtggVa14AWLjh7pndrNtdPKWNFsaKhKOjaayELF2qnVRPVx+xJUVHVK1ZeHPvhFROqr8J4WsG0X2mTjqHXl/g1l/rl6P0vQggg6CL/De1f/YblY9hCelF4kYQaMYqxseUb9P/CtXZOSU/o5DHEY3xtHTUaJY2dWvNlcqVqEdUqKE+Ttypo1WOusjIH+HAoLLf+Huv/bSDyd2RFVxrHDp+BhJVjwBbQ8MM0Dwd7vyi2Besi/CAfl8xZFYdQb1F6WVOMx/Qp+17KLcsz5AHCduFj4XbCwGXEwzcIB2ze2AwINxyvzhvC9vti9lvGBvpb4Qv7KfoGxhTLd32e1HTT8hZFSj1jebotiHIaLSHE+wqRErTch1mPet6yCXOaiP/VvVCP0UjEnyTUixDCrPt6lVav79JmddrNMpDQ0L7crTu3WQ/sQERiMslk51J1gZOGz8TTOKH8XEJc0mh06i3Lm+sOuKZhXCzNNcQ2jTuTm2Ybqqn0ejwXYDTrQGHht9QvK7cb2KOWBckreYriAN7Di/FafJnBYDnKTr/w7DOpiXyC3ER60UkuMMV+pvp3nejyp36OJ2rybojPZ/mzBHYg8NCe33uPKawjFFZHfu/b7ZNJaISzysszoRGRnTec1RjgnWl1AHUiLFALz0oGbXYBAayHZDrdhLMTsYey9g+LmuJZw/jwME+ckb+W0kNwcpjQCZCs0Yn+8Pc+r5feY97k9ZDpAJzurz61Fbl1E9lqOwlzbUUc+beUgTnxdQrH+Ox/HOJ9oKyKzEmRjoWyEqy8YN9H6sQQl1NlSE8PXGorEh3LEMcQVfsmRIEJZMYJowaQMfN9I+AwxbjoFcesxFXBI4xjYeYRswgXg5Pxq5kinoj51r9w4Mxa3hjY1vdiTMiJblv3a6qApwJj2OxIG5kTlGo0pkGBGX6nerxabs8OBl1xcTMdP116zi8IPFm1x+aeuXAPr0ClXpNJyGyQFEiSJMl8M5gefLPdq141A0ozrk6FD+JLhUbyNJlCDoOdrQ8v5RhrrhqOZe2w25TO2qWtj4RqGG0ja8fC5f9jdasyPo5JxsmI1r1gfmyNzJkYI/pR5v81IAerSGwW3F8GygwPnvvXTvFuSobMNbYGzFfWYwYaiK/6UtI78dL01D6uitspl8nlHVwNcLB0FYh9F6c3BVMu9xoMmFXTKGP4BiV4eb8gY3kNKSmRcvtml7ypg2E4IDNKyEtEoBh6FXcIWSdXze1PTdkFd6am94H2qq6uDlzF7T95sv8lZ9GnOvMpKhCg1HwqEIxh9eF2BSUSUWpeIRJdyBccqjLQURy5kH/AEntLe/Exwi0P5F9AcIT23KAZofR8mhV9Euzbx2hLyhiyFO7aY5XCPT38vzuQGzcQu7clQLII7g5Mv5g9sLefq+P2Dw62N/vHgqPw5CR6DD3aeHQL5DiOJgatAxO3eFyXLB1+7OV28sSr5HK6rFbvZSh5SvMZT8/Yb32OvZLe9a/1XKW+TB/E+zD+JnE9OTHli3rKZzBdVe3UK182bVIXbmLYadj6xuGatAn+fUDHuaA5kG6eZi7ZpfC5ccRxwdndWnIk1jXFzrFM2CQZHtdfLPBkzaWnmrt/HEGMaMJ6as1fFmMQRtYs1eivwCNdf9rmx2qrY7mpGAc7SyGLqS9MDtgZzEpMvg3+zsrSszLhimZoAdNOFxL7b6Ti+PiA2Gs6WKwQEBNj4/ze/zkUqf5r3d40XiKAFlQ0D1S/LP3QyaE+eV0Owg0SxwI3Wa6fPHb2NYU43qw8gjOu/6jQH1CKj8dG+snN613lTvkS0Nh9qBwJzPJISVkpQIBktXsf5kHk558RuwcTIFsqfTB0R6/T6dfDjaYHvU4L+/OmsI8r3tMbGT3pNaGZrcoTNW9IR4rLoQxPhhIX0T3hkl3dRQTgM2MEMyZoNNZGughXMqav9/uC+zFaazQJxqVkTwyjabpyfkjO3tZ+bdycbyozEelLBmsFy60qAvLhBHi8oNsu1EF68f88vvLPiyiaL660WiY+cQuDxW7EUdK1kC2vwZfTRIpOTJYdLwf3an3r7jk673v0tIqP7aKPml91w+jpQycyD58knkGuRXmc8cJ28W+/YnSv2h6o8FrGr5ZDfz0d73/yH9ghjInuQ9bnYLFsunhfdQ1f727zh672O7u+T2unpCRYrF7kosMWFUO69VDi/KJE+hpLHljD/sh/Y6HE9VDqqrJUkhKuJ6gcZQaMVVdHHorT4euomoTGRoYVaGE1aeaQ19O0uisUyh9Bx2ELuPX7a2CEmdFMGlPIVFAcQ23/ocK/vNseig2EQ5ojgJ0uadx23CbsutQfuxVeOTIvrRCTL0qMAtXXkkSK/P2rptWYCWD2S67IhGxFdiqcCRLm/37BD0OvRAxO5Uj/tqRbljowWQwCD5Nnx8kh0rrUiE9or5Ph/qiCxKGLcTGdYwV/HBviyFcSVoT4kvSmZBJPvmr+GDN2WbZp9QkPzqEfu6uesSoyHE9EF04/yy4OmfhsS4glPK1l2Qsex7eTLISfzT5u8yW5R8tvVp2HerdU9HpaXeotn+fSVYpfyVXPeg9wsBPpsWehDO02D+tLvbPD5UAYyTMUpzJ8a+aBfhqH1p/27s9TxRQxObUCLOm0+oI4zkNlFlBe4LCIoK27OrRV3fdZlW3nwrM8t6qvd38HYLrDJyR7+uO04x9EBcD0OZcQBWCGSCUCAJg+4QgSzcNOuoZohFbDSNF0jM7GAID3IrD/LdKLhCLwFX4LvxPVHIFNYQNuIdn+A8aQeITdcwgJwCFqjcBuSEF4Kq2xKG4nref0NEVATL+5sgKTw5J1OczwKTL2b1jXpwnpJg71UuQCAJAB7BcPAfALi6PoyfLVdXUyFNwoeEKgy/pjyTRQp1yaBAE0+APACiNVnwOA32BJbDBW5ihraeVnX5S1JcCABHgCAsjA0YqW9RQIAANigQjIQCpQgQfQFI8BS7ASIABCKQAAd1CvCRCwAPsFGDDAeUREZW8jirKjAgHYgH/cRKpCiEAFtqQvJrGmf/O3iJDRqPaqvBYmdcpzY9BvtGWASJybnP4xJi+s9pvdvdcXMsY08kkne8iZFEUZ1aeWBw6DqClKhzpvHD2n43ZLh3w3Wsa7uUkiBPK7cUNpXZv1NMFo2dnc9ea/IasYgBgwzkuz/1CU+H1X9jZ2EtYvylLjLMvQyYl1kIlG1HPkSIyUT6KhQQ8IZRJn1kFatuFi+CdHWzItkqWb/KPGMUPvet94WeEqQ44CJSrUaKD5z8jdI3TQRQ/9wXA0nkxn88Vytd5sd/uDxZmUc9EOR+ClZdQL29ebA7buCDsSxn6tZbo+ncVgZTyzAKmSk3LF+jPqvvpGHtA38dXncCAYANgVv6QOaUOLbE2RlXbQJ6M49EqDT7R7laQkgs5tAe488M1XB731s8sHLy6frY0IwmkX7+7YZCrTvpoEcvUv46ceqdSTZzsULlvfwNqV55x1hl92nuuk3nY4K6LG1n6x8h6qBV+7ImbnubsDAAA=') format('woff2'),
+ url('iconfont.woff?t=1564286613049') format('woff'),
+ url('iconfont.ttf?t=1564286613049') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */
+ url('iconfont.svg?t=1564286613049#iconfont') format('svg'); /* iOS 4.1- */
+}
+
+.iconfont {
+ font-family: "iconfont" !important;
+ font-size: 16px;
+ font-style: normal;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+.icon-gouwucheman:before {
+ content: "\e600";
+}
+
+.icon-gouwuchekong:before {
+ content: "\e601";
+}
+
+.icon-zhanghuchongzhi-copy:before {
+ content: "\e621";
+}
+
+.icon-wode:before {
+ content: "\e665";
+}
+
+.icon-dangao:before {
+ content: "\e67e";
+}
+
+.icon-shouye:before {
+ content: "\e603";
+}
+
+.icon-shouye1:before {
+ content: "\e666";
+}
+
+.icon-fenlei:before {
+ content: "\e667";
+}
+
+.icon-gouwuche:before {
+ content: "\e669";
+}
+
+.icon-wode1:before {
+ content: "\e66b";
+}
+
+.icon-fanhui:before {
+ content: "\e676";
+}
+
+.icon-fanhuishouye:before {
+ content: "\e677";
+}
+
+.icon-gengduo:before {
+ content: "\e678";
+}
+
+.icon-chakangengduo:before {
+ content: "\e679";
+}
+
+.icon-caidan:before {
+ content: "\e67a";
+}
+
+.icon-sousuo:before {
+ content: "\e67b";
+}
+
+.icon-guanjianzi:before {
+ content: "\e67c";
+}
+
+.icon-guanbi:before {
+ content: "\e67d";
+}
+
+.icon-xuanxiang:before {
+ content: "\e67f";
+}
+
+.icon-dianzan:before {
+ content: "\e680";
+}
+
+.icon-xihuan:before {
+ content: "\e682";
+}
+
+.icon-fenxiang:before {
+ content: "\e684";
+}
+
+.icon-saoyisao:before {
+ content: "\e685";
+}
+
+.icon-kefu:before {
+ content: "\e686";
+}
+
+.icon-pinglun:before {
+ content: "\e687";
+}
+
+.icon-shanchu:before {
+ content: "\e688";
+}
+
+.icon-tishi:before {
+ content: "\e689";
+}
+
+.icon-jinhangzhong:before {
+ content: "\e68a";
+}
+
+.icon-chenggong:before {
+ content: "\e68b";
+}
+
+.icon-shibai:before {
+ content: "\e68c";
+}
+
+.icon-huodong:before {
+ content: "\e68d";
+}
+
diff --git a/miniprogram/assets/images/tabs/cake-selected.png b/miniprogram/assets/images/tabs/cake-selected.png
new file mode 100644
index 0000000..cd2957e
Binary files /dev/null and b/miniprogram/assets/images/tabs/cake-selected.png differ
diff --git a/miniprogram/assets/images/tabs/cake.png b/miniprogram/assets/images/tabs/cake.png
new file mode 100644
index 0000000..11794f2
Binary files /dev/null and b/miniprogram/assets/images/tabs/cake.png differ
diff --git a/miniprogram/assets/images/tabs/home-selected.png b/miniprogram/assets/images/tabs/home-selected.png
new file mode 100644
index 0000000..d7f4c12
Binary files /dev/null and b/miniprogram/assets/images/tabs/home-selected.png differ
diff --git a/miniprogram/assets/images/tabs/home.png b/miniprogram/assets/images/tabs/home.png
new file mode 100644
index 0000000..bda6cd9
Binary files /dev/null and b/miniprogram/assets/images/tabs/home.png differ
diff --git a/miniprogram/assets/images/tabs/me-selected.png b/miniprogram/assets/images/tabs/me-selected.png
new file mode 100644
index 0000000..f6f2ed2
Binary files /dev/null and b/miniprogram/assets/images/tabs/me-selected.png differ
diff --git a/miniprogram/assets/images/tabs/me.png b/miniprogram/assets/images/tabs/me.png
new file mode 100644
index 0000000..6b5f565
Binary files /dev/null and b/miniprogram/assets/images/tabs/me.png differ
diff --git a/miniprogram/assets/images/vip.png b/miniprogram/assets/images/vip.png
new file mode 100644
index 0000000..19ae56b
Binary files /dev/null and b/miniprogram/assets/images/vip.png differ
diff --git a/miniprogram/components/avatar/avatar.js b/miniprogram/components/avatar/avatar.js
new file mode 100644
index 0000000..5ac5548
--- /dev/null
+++ b/miniprogram/components/avatar/avatar.js
@@ -0,0 +1,36 @@
+// components/avatar/avatar.js
+Component({
+ /**
+ * 组件的属性列表
+ */
+ properties: {
+ size: {
+ type: Number,
+ value: 60
+ },
+ isCube: {
+ type: Boolean,
+ value: false
+ },
+ bordered: {
+ type: Boolean,
+ value: true
+ }
+ },
+
+ /**
+ * 组件的初始数据
+ */
+ data: {
+ avatarInfo: null
+ },
+
+ attached: function() {
+ let avatarInfo = wx.getStorageSync('avatarInfo')
+ this.setData({
+ avatarInfo: avatarInfo
+ })
+ },
+ methods: {
+ }
+})
diff --git a/miniprogram/components/avatar/avatar.json b/miniprogram/components/avatar/avatar.json
new file mode 100644
index 0000000..e8cfaaf
--- /dev/null
+++ b/miniprogram/components/avatar/avatar.json
@@ -0,0 +1,4 @@
+{
+ "component": true,
+ "usingComponents": {}
+}
\ No newline at end of file
diff --git a/miniprogram/components/avatar/avatar.wxml b/miniprogram/components/avatar/avatar.wxml
new file mode 100644
index 0000000..dfadc93
--- /dev/null
+++ b/miniprogram/components/avatar/avatar.wxml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/miniprogram/components/avatar/avatar.wxss b/miniprogram/components/avatar/avatar.wxss
new file mode 100644
index 0000000..5a9e13c
--- /dev/null
+++ b/miniprogram/components/avatar/avatar.wxss
@@ -0,0 +1,9 @@
+.avatar {
+ overflow: hidden;
+ box-sizing: border-box;
+ z-index: 2
+}
+
+.bordered {
+ border: 4px solid #eee;
+}
\ No newline at end of file
diff --git a/miniprogram/components/counter/counter.js b/miniprogram/components/counter/counter.js
new file mode 100644
index 0000000..48f4459
--- /dev/null
+++ b/miniprogram/components/counter/counter.js
@@ -0,0 +1,112 @@
+// utils/forms/counter/counter.js
+var tapInterval;
+
+Component({
+ /**
+ * 组件的属性列表
+ */
+ properties: {
+ counter: {
+ type: Number,
+ value: 0
+ },
+ maxCount: {
+ type: Number,
+ value: 0
+ },
+ price: {
+ type: String,
+ value: null
+ },
+ optId: {
+ type: String,
+ value: null
+ },
+ initvalue: {
+ type: String,
+ value: '0'
+ }
+ },
+
+ /**
+ * 组件的初始数据
+ */
+ data: {
+
+ },
+
+ ready() {
+ console.log('counterd:', this.data.initvalue)
+ this.setData({
+ counter: this.data.initvalue
+ })
+ },
+ methods: {
+ onTapSub: function(e) {
+ if((this.data.counter - 1) >= 0) {
+ this.setData({
+ counter: this.data.counter - 1
+ })
+ this.triggerEvent("action", {
+ actionType: 'counterUpdate',
+ counter: this.data.counter,
+ optId: this.data.optId,
+ price: this.data.price
+ });
+ }
+ },
+ onTapAdd: function(e) {
+ if((this.data.counter + 1) <= this.data.maxCount) {
+ this.setData({
+ counter: this.data.counter + 1
+ })
+ this.triggerEvent("action", {
+ actionType: 'counterUpdate',
+ counter: this.data.counter,
+ optId: this.data.optId,
+ price: this.data.price
+ });
+ }
+ },
+ onLongTapSub: function (e) {
+ tapInterval = setInterval(()=>{this.onTapSub()}, 100)
+ },
+ onLongTapAdd: function (e) {
+ tapInterval = setInterval(()=>{this.onTapAdd()}, 100)
+ },
+ onSubTapEnd: function() {
+ if(tapInterval){
+ clearInterval(tapInterval)
+ }
+ },
+ onAddTapEnd: function() {
+ if(tapInterval){
+ clearInterval(tapInterval)
+ }
+ },
+ onInputChange: function(e) {
+ if(!e.detail.value) {
+ this.triggerEvent("action", {
+ actionType: 'AF_FORM_COUNTER_UPDATE',
+ counter: '0',
+ optId: this.data.optId,
+ price: this.data.price
+ })
+ return '0'
+ } else {
+ let val = Math.abs(parseInt(e.detail.value))
+ if (val <= this.data.maxCount) {
+ this.triggerEvent("action", {
+ actionType: 'AF_FORM_COUNTER_UPDATE',
+ counter: val,
+ optId: this.data.optId,
+ price: this.data.price
+ })
+ return val.toString()
+ } else {
+ return this.data.maxCount.toString()
+ }
+ }
+ }
+ }
+})
diff --git a/miniprogram/components/counter/counter.json b/miniprogram/components/counter/counter.json
new file mode 100644
index 0000000..e8cfaaf
--- /dev/null
+++ b/miniprogram/components/counter/counter.json
@@ -0,0 +1,4 @@
+{
+ "component": true,
+ "usingComponents": {}
+}
\ No newline at end of file
diff --git a/miniprogram/components/counter/counter.wxml b/miniprogram/components/counter/counter.wxml
new file mode 100644
index 0000000..26cce6e
--- /dev/null
+++ b/miniprogram/components/counter/counter.wxml
@@ -0,0 +1,7 @@
+
+ -
+
+
+
+ +
+
diff --git a/miniprogram/components/counter/counter.wxss b/miniprogram/components/counter/counter.wxss
new file mode 100644
index 0000000..54aacdb
--- /dev/null
+++ b/miniprogram/components/counter/counter.wxss
@@ -0,0 +1,50 @@
+.counter-controls {
+ width:100%;
+ height: 30px;
+ border-radius: 5px;
+ border: 1px solid #ddd;
+ display: flex;
+ overflow: hidden;
+}
+
+.counter-sub, .counter-add {
+ height: 30px;
+ line-height: 30px;
+ width:30px;
+ box-sizing: border-box;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ background-color: #f5f5f5;
+ font-size: 120%;
+ font-weight: bold;
+ color: #333;
+ z-index: 1
+}
+.counter-input {
+ /* flex: 1; */
+ height: 30px;
+ width: calc(100% - 60px);
+ box-sizing: border-box;
+ font-size: 80%;
+ color: #333;
+}
+
+.counter-input input {
+ height: 30px;
+ z-index: 1;
+ text-align: center;
+}
+
+.counter-sub {
+ border-right: 1px solid #ddd;
+}
+
+.counter-add {
+ border-left: 1px solid #ddd;
+}
+
+
+.counter-sub.disabled, .counter-add.disabled {
+ color: #ccc;
+}
\ No newline at end of file
diff --git a/miniprogram/components/list/list.js b/miniprogram/components/list/list.js
new file mode 100644
index 0000000..bb7440c
--- /dev/null
+++ b/miniprogram/components/list/list.js
@@ -0,0 +1,47 @@
+// components/list/list.js
+
+// entity = {
+ // key: 1
+ // isLink: true
+ // title: '个人资料'
+ // value: '完成度100%',
+ // color: #333
+ // arrowColor: #999,
+ // openType
+ // isPicker
+ // useSlot
+// }
+
+Component({
+ /**
+ * 组件的属性列表
+ */
+ properties: {
+ entities: {
+ type: Array,
+ value: []
+ }
+ },
+
+ /**
+ * 组件的初始数据
+ */
+ data: {
+
+ },
+
+ /**
+ * 组件的方法列表
+ */
+ methods: {
+ onClickItem: function(e) {
+ let currentItem = this.data.entities[e.currentTarget.dataset.index]
+ if (currentItem.isLink && currentItem.url) {
+ wx.navigateTo({
+ url: currentItem.url,
+ })
+ }
+ this.triggerEvent('onTapListItem', {'index': e.currentTarget.dataset.index})
+ }
+ }
+})
diff --git a/miniprogram/components/list/list.json b/miniprogram/components/list/list.json
new file mode 100644
index 0000000..78013bd
--- /dev/null
+++ b/miniprogram/components/list/list.json
@@ -0,0 +1,5 @@
+{
+ "component": true,
+ "usingComponents": {
+ }
+}
\ No newline at end of file
diff --git a/miniprogram/components/list/list.wxml b/miniprogram/components/list/list.wxml
new file mode 100644
index 0000000..1f740a9
--- /dev/null
+++ b/miniprogram/components/list/list.wxml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+ {{item.title}}
+
+ {{item.value}}
+
+
+
+
+
+
\ No newline at end of file
diff --git a/miniprogram/components/list/list.wxss b/miniprogram/components/list/list.wxss
new file mode 100644
index 0000000..e52e5a9
--- /dev/null
+++ b/miniprogram/components/list/list.wxss
@@ -0,0 +1,85 @@
+@import '../../assets/icons/iconfont.wxss';
+
+.list {
+ background-color: #fff;
+}
+
+.item {
+ height: 60px;
+ line-height: 60px;
+ width: 100%;
+ box-sizing: border-box;
+ font-size: 14px;
+ padding-left: 20px;
+ padding-right: 20px;
+ color: #333;
+}
+
+.wrapper {
+ height: 100%;
+ width: 100%;
+ display: flex;
+ border-bottom: 1px solid #eee;
+}
+
+.item:last-child .wrapper {
+ border-bottom: 0;
+}
+
+.icon {
+ width: 30px;
+ /* background-color: #eee; */
+ /* border: 1px solid #333; */
+ text-align:center;
+ padding-top:3px;
+ box-sizing:border-box;
+}
+
+.title {
+ flex: 1;
+ /* background-color: #eee; */
+ /* border: 1px solid #333; */
+ box-sizing: border-box;
+}
+
+.value {
+ max-width: 100px;
+ /* background-color: #eee; */
+ /* border: 1px solid #333; */
+ box-sizing: border-box;
+ text-align: center;
+ line-height: 60px;
+}
+
+.arraw {
+ width: 20px;
+ /* background-color: #eee; */
+ /* border: 1px solid #333; */
+ box-sizing: border-box;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ padding-top:3px;
+}
+
+
+.ellipsis {
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+button::after {
+ border: none;
+}
+
+button {
+ background-color: #fff;
+ text-align: left;
+ padding-left: 0;
+ padding-right: 0;
+ border-radius:0;
+ font-size: 14px;
+ line-height: 60px;
+ margin-top: 1px;
+}
\ No newline at end of file
diff --git a/miniprogram/components/list_item/list_item.js b/miniprogram/components/list_item/list_item.js
new file mode 100644
index 0000000..ba3d0c8
--- /dev/null
+++ b/miniprogram/components/list_item/list_item.js
@@ -0,0 +1,76 @@
+Component({
+
+ properties: {
+ key: {
+ type: String,
+ value: null
+ },
+ icon: {
+ type: String,
+ value: null
+ },
+ isLink: {
+ type: Boolean,
+ value: false
+ },
+ title: {
+ type: String,
+ value: ''
+ },
+ value: {
+ type: String,
+ value: null
+ },
+ color: {
+ type: String,
+ value: '#666'
+ },
+ iconColor: {
+ type: String,
+ value: '#333'
+ },
+ titleColor: {
+ type: String,
+ value: '#999'
+ },
+ arrowColor: {
+ type: String,
+ value: '#999'
+ },
+ borderColor: {
+ type: String,
+ value: '#eee'
+ },
+ borderWidth: {
+ type: String,
+ value: '1'
+ },
+ url: {
+ type: String,
+ value: null
+ },
+ useSlot: {
+ type: Boolean,
+ value: false
+ },
+ openType: {
+ type: String,
+ value: null
+ }
+ },
+
+ data: {
+
+ },
+
+ methods: {
+ onClickItem: function (e) {
+ if(this.data.url && this.data.url.startsWith('/pages')) {
+ wx.navigateTo({
+ url: this.data.url,
+ })
+ }
+ this.triggerEvent('onTapItem', { 'key': this.data.key, 'value': this.data.value, 'url': this.data.url })
+ }
+ }
+})
diff --git a/miniprogram/components/list_item/list_item.json b/miniprogram/components/list_item/list_item.json
new file mode 100644
index 0000000..2176e13
--- /dev/null
+++ b/miniprogram/components/list_item/list_item.json
@@ -0,0 +1,6 @@
+{
+ "component": true,
+ "usingComponents": {
+
+ }
+}
\ No newline at end of file
diff --git a/miniprogram/components/list_item/list_item.wxml b/miniprogram/components/list_item/list_item.wxml
new file mode 100644
index 0000000..c4b2cb5
--- /dev/null
+++ b/miniprogram/components/list_item/list_item.wxml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+ {{title}}
+
+
+ {{value}}
+
+
+
+
+
\ No newline at end of file
diff --git a/miniprogram/components/list_item/list_item.wxss b/miniprogram/components/list_item/list_item.wxss
new file mode 100644
index 0000000..d85b869
--- /dev/null
+++ b/miniprogram/components/list_item/list_item.wxss
@@ -0,0 +1,2 @@
+@import '../list/list.wxss';
+@import '../../assets/icons/iconfont.wxss';
diff --git a/miniprogram/components/wux-weapp/animation-group/index.js b/miniprogram/components/wux-weapp/animation-group/index.js
new file mode 100644
index 0000000..2c08b5f
--- /dev/null
+++ b/miniprogram/components/wux-weapp/animation-group/index.js
@@ -0,0 +1 @@
+"use strict";var _baseComponent=_interopRequireDefault(require("../helpers/baseComponent")),_styleToCssString=_interopRequireDefault(require("../helpers/styleToCssString"));function _interopRequireDefault(t){return t&&t.__esModule?t:{default:t}}function _typeof(t){return(_typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}var ENTER="enter",ENTERING="entering",ENTERED="entered",EXIT="exit",EXITING="exiting",EXITED="exited",UNMOUNTED="unmounted",TRANSITION="transition",ANIMATION="animation",TIMEOUT=1e3/60,defaultClassNames={enter:"",enterActive:"",enterDone:"",exit:"",exitActive:"",exitDone:""};(0,_baseComponent.default)({properties:{in:{type:Boolean,value:!1,observer:function(t){this.data.isMounting&&this.updated(t)}},classNames:{type:null,value:defaultClassNames},duration:{type:null,value:null},type:{type:String,value:TRANSITION},appear:{type:Boolean,value:!1},enter:{type:Boolean,value:!0},exit:{type:Boolean,value:!0},mountOnEnter:{type:Boolean,value:!0},unmountOnExit:{type:Boolean,value:!0},wrapCls:{type:String,value:""},wrapStyle:{type:[String,Object],value:"",observer:function(t){this.setData({extStyle:(0,_styleToCssString.default)(t)})}},disableScroll:{type:Boolean,value:!1}},data:{animateCss:"",animateStatus:EXITED,isMounting:!1,extStyle:""},methods:{addEventListener:function(){var t=this.data.animateStatus,e=this.getTimeouts(),a=e.enter,n=e.exit;t===ENTERING&&!a&&this.data.enter&&this.performEntered(),t===EXITING&&!n&&this.data.exit&&this.performExited()},onTransitionEnd:function(){this.data.type===TRANSITION&&this.addEventListener()},onAnimationEnd:function(){this.data.type===ANIMATION&&this.addEventListener()},updateStatus:function(t,e){var a=1
+
+
diff --git a/miniprogram/components/wux-weapp/animation-group/index.wxss b/miniprogram/components/wux-weapp/animation-group/index.wxss
new file mode 100644
index 0000000..936cd3d
--- /dev/null
+++ b/miniprogram/components/wux-weapp/animation-group/index.wxss
@@ -0,0 +1 @@
+.wux-animate--fadeIn-enter{transition:opacity .3s;opacity:0}.wux-animate--fadeIn-enter-active,.wux-animate--fadeIn-enter-done{opacity:1}.wux-animate--fadeIn-exit{transition:opacity .3s;opacity:1}.wux-animate--fadeIn-exit-active,.wux-animate--fadeIn-exit-done{opacity:0}.wux-animate--fadeInDown-enter{transition:opacity .3s,transform .3s;opacity:0;transform:translate3d(0,-100%,0)}.wux-animate--fadeInDown-enter-active,.wux-animate--fadeInDown-enter-done{opacity:1;transform:none}.wux-animate--fadeInDown-exit{transition:opacity .3s,transform .3s;opacity:1;transform:none}.wux-animate--fadeInDown-exit-active,.wux-animate--fadeInDown-exit-done{opacity:0;transform:translate3d(0,-100%,0)}.wux-animate--fadeInLeft-enter{transition:opacity .3s,transform .3s;opacity:0;transform:translate3d(-100%,0,0)}.wux-animate--fadeInLeft-enter-active,.wux-animate--fadeInLeft-enter-done{opacity:1;transform:none}.wux-animate--fadeInLeft-exit{transition:opacity .3s,transform .3s;opacity:1;transform:none}.wux-animate--fadeInLeft-exit-active,.wux-animate--fadeInLeft-exit-done{opacity:0;transform:translate3d(-100%,0,0)}.wux-animate--fadeInRight-enter{transition:opacity .3s,transform .3s;opacity:0;transform:translate3d(100%,0,0)}.wux-animate--fadeInRight-enter-active,.wux-animate--fadeInRight-enter-done{opacity:1;transform:none}.wux-animate--fadeInRight-exit{transition:opacity .3s,transform .3s;opacity:1;transform:none}.wux-animate--fadeInRight-exit-active,.wux-animate--fadeInRight-exit-done{opacity:0;transform:translate3d(100%,0,0)}.wux-animate--fadeInUp-enter{transition:opacity .3s,transform .3s;opacity:0;transform:translate3d(0,100%,0)}.wux-animate--fadeInUp-enter-active,.wux-animate--fadeInUp-enter-done{opacity:1;transform:none}.wux-animate--fadeInUp-exit{transition:opacity .3s,transform .3s;opacity:1;transform:none}.wux-animate--fadeInUp-exit-active,.wux-animate--fadeInUp-exit-done{opacity:0;transform:translate3d(0,100%,0)}.wux-animate--slideInUp-enter{transition:transform .3s;transform:translate3d(0,100%,0);visibility:visible}.wux-animate--slideInUp-enter-active,.wux-animate--slideInUp-enter-done{transform:translateZ(0)}.wux-animate--slideInUp-exit{transition:transform .3s;transform:translateZ(0)}.wux-animate--slideInUp-exit-active,.wux-animate--slideInUp-exit-done{transform:translate3d(0,100%,0);visibility:visible}.wux-animate--slideInDown-enter{transition:transform .3s;transform:translate3d(0,-100%,0);visibility:visible}.wux-animate--slideInDown-enter-active,.wux-animate--slideInDown-enter-done{transform:translateZ(0)}.wux-animate--slideInDown-exit{transition:transform .3s;transform:translateZ(0)}.wux-animate--slideInDown-exit-active,.wux-animate--slideInDown-exit-done{transform:translate3d(0,-100%,0);visibility:visible}.wux-animate--slideInLeft-enter{transition:transform .3s;transform:translate3d(-100%,0,0);visibility:visible}.wux-animate--slideInLeft-enter-active,.wux-animate--slideInLeft-enter-done{transform:translateZ(0)}.wux-animate--slideInLeft-exit{transition:transform .3s;transform:translateZ(0)}.wux-animate--slideInLeft-exit-active,.wux-animate--slideInLeft-exit-done{transform:translate3d(-100%,0,0);visibility:visible}.wux-animate--slideInRight-enter{transition:transform .3s;transform:translate3d(100%,0,0);visibility:visible}.wux-animate--slideInRight-enter-active,.wux-animate--slideInRight-enter-done{transform:none}.wux-animate--slideInRight-exit{transition:transform .3s;transform:none}.wux-animate--slideInRight-exit-active,.wux-animate--slideInRight-exit-done{transform:translate3d(100%,0,0);visibility:visible}.wux-animate--zoom-enter{transition:all .3s cubic-bezier(.215,.61,.355,1);opacity:.01;transform:scale(.75)}.wux-animate--zoom-enter-active,.wux-animate--zoom-enter-done{opacity:1;transform:none}.wux-animate--zoom-exit{transition:all .25s linear;transform:none}.wux-animate--zoom-exit-active,.wux-animate--zoom-exit-done{opacity:.01;transform:scale(.75)}.wux-animate--punch-enter{transition:all .3s cubic-bezier(.215,.61,.355,1);opacity:.01;transform:scale(1.35)}.wux-animate--punch-enter-active,.wux-animate--punch-enter-done{opacity:1;transform:none}.wux-animate--punch-exit{transition:all .25s linear;transform:none}.wux-animate--punch-exit-active,.wux-animate--punch-exit-done{opacity:.01;transform:scale(1.35)}
\ No newline at end of file
diff --git a/miniprogram/components/wux-weapp/backdrop/index.js b/miniprogram/components/wux-weapp/backdrop/index.js
new file mode 100644
index 0000000..2f7b066
--- /dev/null
+++ b/miniprogram/components/wux-weapp/backdrop/index.js
@@ -0,0 +1 @@
+"use strict";var _baseComponent=_interopRequireDefault(require("../helpers/baseComponent"));function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}(0,_baseComponent.default)({properties:{prefixCls:{type:String,value:"wux-backdrop"},transparent:{type:Boolean,value:!1},zIndex:{type:Number,value:1e3},classNames:{type:null,value:"wux-animate--fadeIn"}},computed:{classes:["prefixCls, transparent",function(e,t){return{wrap:t?"".concat(e,"--transparent"):e}}]},methods:{retain:function(){"number"==typeof this.backdropHolds&&this.backdropHolds||(this.backdropHolds=0),this.backdropHolds=this.backdropHolds+1,1===this.backdropHolds&&this.setData({in:!0})},release:function(){1===this.backdropHolds&&this.setData({in:!1}),this.backdropHolds=Math.max(0,this.backdropHolds-1)},onClick:function(){this.triggerEvent("click")}}});
\ No newline at end of file
diff --git a/miniprogram/components/wux-weapp/backdrop/index.json b/miniprogram/components/wux-weapp/backdrop/index.json
new file mode 100644
index 0000000..9b9e7ab
--- /dev/null
+++ b/miniprogram/components/wux-weapp/backdrop/index.json
@@ -0,0 +1,6 @@
+{
+ "component": true,
+ "usingComponents": {
+ "wux-animation-group": "../animation-group/index"
+ }
+}
\ No newline at end of file
diff --git a/miniprogram/components/wux-weapp/backdrop/index.wxml b/miniprogram/components/wux-weapp/backdrop/index.wxml
new file mode 100644
index 0000000..d6ee398
--- /dev/null
+++ b/miniprogram/components/wux-weapp/backdrop/index.wxml
@@ -0,0 +1 @@
+
diff --git a/miniprogram/components/wux-weapp/backdrop/index.wxss b/miniprogram/components/wux-weapp/backdrop/index.wxss
new file mode 100644
index 0000000..63310d6
--- /dev/null
+++ b/miniprogram/components/wux-weapp/backdrop/index.wxss
@@ -0,0 +1 @@
+.wux-backdrop{background:rgba(0,0,0,.4)}.wux-backdrop,.wux-backdrop--transparent{position:fixed;z-index:1000;top:0;right:0;left:0;bottom:0}.wux-backdrop--transparent{background:0 0}
\ No newline at end of file
diff --git a/miniprogram/components/wux-weapp/calendar/index.js b/miniprogram/components/wux-weapp/calendar/index.js
new file mode 100644
index 0000000..33d6fdc
--- /dev/null
+++ b/miniprogram/components/wux-weapp/calendar/index.js
@@ -0,0 +1 @@
+"use strict";var _baseComponent=_interopRequireDefault(require("../helpers/baseComponent")),_classNames4=_interopRequireDefault(require("../helpers/classNames"));function _interopRequireDefault(t){return t&&t.__esModule?t:{default:t}}function _toConsumableArray(t){return _arrayWithoutHoles(t)||_iterableToArray(t)||_nonIterableSpread()}function _nonIterableSpread(){throw new TypeError("Invalid attempt to spread non-iterable instance")}function _iterableToArray(t){if(Symbol.iterator in Object(t)||"[object Arguments]"===Object.prototype.toString.call(t))return Array.from(t)}function _arrayWithoutHoles(t){if(Array.isArray(t)){for(var e=0,n=new Array(t.length);enew Date(h).getTime()||c&&dnew Date(s).getTime())return this.resetMonth();if(this.monthsTranslate=this.monthsTranslate-1,r===o){var c=100*-this.monthsTranslate,u=this.monthHTML(h,"next"),l=getTransform(c,this.isH),d=[this.data.months[1],this.data.months[2],u];this.$$setData({months:d,monthsTranslate:[a[1],a[2],l]}),"function"==typeof this.fns.onMonthAdd&&this.fns.onMonthAdd.call(this,d[d.length-1])}this.onMonthChangeStart("next");var f=getTransform(100*this.monthsTranslate,this.isH),m=this.data.animate?.3:0,g="transition-duration: ".concat(m,"s; ").concat(f);this.$$setData({wrapperTranslate:g}),setTimeout(function(){return t.onMonthChangeEnd("next")},m)},prevMonth:function(){var t=this,e=this.data,n=e.months,a=e.monthsTranslate,s=e.minDate,o=e.currentMonth,r=parseInt(n[0].month,10),i=parseInt(n[0].year,10),h=new Date(i,r+1,-1).getTime();if(s&&h
+
+
+
+
+
+
+
+
+ {{ currentMonthName }}
+
+
+
+
+
+
+
+
+ {{ currentYear }}
+
+
+
+
+
+
+
+
+
+
+ {{ item.dayName }}
+
+
+
+
+
+
+
+
+
+
+
+ {{ col.day }}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/miniprogram/components/wux-weapp/calendar/index.wxss b/miniprogram/components/wux-weapp/calendar/index.wxss
new file mode 100644
index 0000000..6e31940
--- /dev/null
+++ b/miniprogram/components/wux-weapp/calendar/index.wxss
@@ -0,0 +1 @@
+.wux-calendar{position:relative;background:#fff;height:600rpx;width:100%;overflow:hidden}.wux-calendar__content{position:relative;width:100%;height:100%;transition:transform .3s}.wux-calendar__bd{height:100%;position:relative;overflow:hidden}.wux-calendar__hd{position:relative;width:100%}.wux-calendar__hd:before{content:" ";position:absolute;left:0;top:0;right:0;height:2rpx;border-top:2rpx solid #d9d9d9;color:#d9d9d9;transform-origin:0 0;transform:scaleY(.5)}.wux-calendar__hd+.wux-calendar__bd{height:calc(97.8%)}.wux-calendar__toolbar{height:2.2rem;display:-ms-flexbox;display:flex;text-align:center}.wux-calendar__picker{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between;width:50%;max-width:400rpx;-ms-flex-negative:10;flex-shrink:10;display:block;line-height:2.2rem}.wux-calendar__link{float:left;width:25%;height:2.2rem;line-height:2rem;min-width:72rpx}.wux-calendar__icon{display:inline-block;vertical-align:middle;background-size:100% auto;background-position:center}.wux-calendar__icon--next,.wux-calendar__icon--prev{width:.75rem;height:.75rem}.wux-calendar__icon--next{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2015%2015'%3E%3Cg%3E%3Cpath%20fill%3D'%23007aff'%20d%3D'M1%2C1.6l11.8%2C5.8L1%2C13.4V1.6%20M0%2C0v15l15-7.6L0%2C0L0%2C0z'%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E")}.wux-calendar__icon--prev{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2015%2015'%3E%3Cg%3E%3Cpath%20fill%3D'%23007aff'%20d%3D'M14%2C1.6v11.8L2.2%2C7.6L14%2C1.6%20M15%2C0L0%2C7.6L15%2C15V0L15%2C0z'%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E")}.wux-calendar__value{-ms-flex-negative:1;flex-shrink:1;position:relative;overflow:hidden;text-overflow:ellipsis;float:left;width:50%;height:2.2rem}.wux-calendar__weekdays{height:36rpx;background:#f7f7f8;display:-ms-flexbox;display:flex;font-size:22rpx;box-sizing:border-box;position:relative}.wux-calendar__weekdays:after{content:" ";position:absolute;left:0;bottom:0;right:0;height:2rpx;border-bottom:2rpx solid #d9d9d9;color:#d9d9d9;transform-origin:0 100%;transform:scaleY(.5)}.wux-calendar__weekdays+.wux-calendar__months{height:calc(82%)}.wux-calendar__weekday{-ms-flex-negative:1;flex-shrink:1;width:14.28571429%;width:calc(14.28571429%);line-height:34rpx;text-align:center}.wux-calendar__months{width:100%;height:100%;overflow:hidden;position:relative}.wux-calendar__months-content{width:100%;height:100%;display:-ms-flexbox;display:flex;position:relative;-webkit-backface-visibility:hidden;transform:translate3d(0,0,0)}.wux-calendar__month{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;width:100%;height:100%;position:absolute;left:0;top:0}.wux-calendar__days{height:16.66666667%;height:calc(16.66666667%);display:-ms-flexbox;display:flex;-ms-flex-negative:1;flex-shrink:1;width:100%;position:relative}.wux-calendar__days:after{content:" ";position:absolute;left:0;bottom:0;right:0;height:2rpx;border-bottom:2rpx solid #d9d9d9;color:#d9d9d9;transform-origin:0 100%;transform:scaleY(.5)}.wux-calendar__days:last-child:after{display:none}.wux-calendar__day{-ms-flex-negative:1;flex-shrink:1;display:-ms-flexbox;display:flex;-ms-flex-pack:center;justify-content:center;-ms-flex-align:center;align-items:center;box-sizing:border-box;width:14.28571429%;width:calc(14.28571429%);text-align:center;color:#3d4145;font-size:30rpx;cursor:pointer}.wux-calendar__day--next,.wux-calendar__day--prev{color:#ccc}.wux-calendar__day--disabled{color:#d4d4d4;cursor:auto}.wux-calendar__day--today .wux-calendar__text{background:#e3e3e3}.wux-calendar__day--selected .wux-calendar__text{background:#0894ec;color:#fff}.wux-calendar__text{display:inline-block;border-radius:100%;width:60rpx;height:60rpx;line-height:60rpx}
\ No newline at end of file
diff --git a/miniprogram/components/wux-weapp/dialog/index.js b/miniprogram/components/wux-weapp/dialog/index.js
new file mode 100644
index 0000000..b4e1a5b
--- /dev/null
+++ b/miniprogram/components/wux-weapp/dialog/index.js
@@ -0,0 +1 @@
+"use strict";var _baseComponent=_interopRequireDefault(require("../helpers/baseComponent")),_classNames3=_interopRequireDefault(require("../helpers/classNames"));function _interopRequireDefault(t){return t&&t.__esModule?t:{default:t}}function _objectSpread(e){for(var t=1;t
+ {{ title }}
+
+ {{ content }}
+
+
+
+
+
+
+
+
+
+
diff --git a/miniprogram/components/wux-weapp/dialog/index.wxss b/miniprogram/components/wux-weapp/dialog/index.wxss
new file mode 100644
index 0000000..d7ff72a
--- /dev/null
+++ b/miniprogram/components/wux-weapp/dialog/index.wxss
@@ -0,0 +1 @@
+.wux-dialog__button{padding:0;margin:0;border-radius:0;color:inherit!important;background:0 0!important;font-size:inherit;line-height:inherit;text-align:inherit;text-decoration:inherit;overflow:inherit;display:block;-ms-flex:1;flex:1;color:#33cd5f;position:relative}.wux-dialog__button:after{position:static;top:auto;left:auto;width:auto;height:auto;border:none;border-radius:0;transform:none;transform-origin:0 0}.wux-dialog__button--default{color:#353535}.wux-dialog__button--primary{color:#33cd5f!important}.wux-dialog__button--bold{font-weight:500!important}.wux-dialog__button--hover{background-color:#ececec!important}.wux-dialog__button--disabled{opacity:.3}.wux-dialog__prompt{position:relative;margin-top:20rpx}.wux-dialog__prompt:after{content:" ";position:absolute;top:0;left:0;width:200%;height:200%;transform:scale(.5);transform-origin:0 0;pointer-events:none;box-sizing:border-box;border:0 solid #d5d5d6;border-top-width:2rpx;border-right-width:2rpx;border-bottom-width:2rpx;border-left-width:2rpx;border-radius:12rpx}.wux-dialog__input{padding:8rpx 12rpx;height:72rpx;line-height:1;width:100%;text-align:left;box-sizing:border-box}.wux-dialog__buttons{display:-ms-flexbox;display:flex;-ms-flex:1;flex:1}.wux-dialog__buttons--horizontal .wux-dialog__button:after{content:" ";position:absolute;left:0;top:0;width:2rpx;bottom:0;border-left:2rpx solid #d5d5d6;color:#d5d5d6;transform-origin:0 0;transform:scaleX(.5)}.wux-dialog__buttons--horizontal .wux-dialog__button:first-child:after{display:none}.wux-dialog__buttons--vertical{display:block;height:auto}.wux-dialog__buttons--vertical .wux-dialog__button:after{content:" ";position:absolute;left:0;top:0;right:0;height:2rpx;border-top:2rpx solid #d5d5d6;color:#d5d5d6;transform-origin:0 0;transform:scaleY(.5)}
\ No newline at end of file
diff --git a/miniprogram/components/wux-weapp/helpers/arrayTreeFilter.js b/miniprogram/components/wux-weapp/helpers/arrayTreeFilter.js
new file mode 100644
index 0000000..368a7c3
--- /dev/null
+++ b/miniprogram/components/wux-weapp/helpers/arrayTreeFilter.js
@@ -0,0 +1 @@
+"use strict";function arrayTreeFilter(e,r,t){(t=t||{}).childrenKeyName=t.childrenKeyName||"children";var a=e||[],l=[],i=0;do{var d=a.filter(function(e){return r(e,i)})[0];if(!d)break;l.push(d),a=d[t.childrenKeyName]||[],i+=1}while(0=").concat(libVersion," 后重试。")});var baseComponent=function(e){var r=0=Math.abs(s-o)?0 {
+ const componentCtx = ctx.selectComponent(selector)
+
+ if (!componentCtx) {
+ throw new Error('无法找到对应的组件,请按文档说明使用组件')
+ }
+
+ return componentCtx
+}
+
+const $wuxBackdrop = (selector = '#wux-backdrop', ctx) => getCtx(selector, ctx)
+const $wuxDialog = (selector = '#wux-dialog', ctx) => getCtx(selector, ctx)
+const $wuxCalendar = (selector = '#wux-calendar', ctx) => getCtx(selector, ctx)
+export {
+ $wuxBackdrop,
+ $wuxDialog,
+ $wuxCalendar
+}
\ No newline at end of file
diff --git a/miniprogram/components/wux-weapp/popup/index.js b/miniprogram/components/wux-weapp/popup/index.js
new file mode 100644
index 0000000..6edada9
--- /dev/null
+++ b/miniprogram/components/wux-weapp/popup/index.js
@@ -0,0 +1 @@
+"use strict";var _baseComponent=_interopRequireDefault(require("../helpers/baseComponent")),_classNames2=_interopRequireDefault(require("../helpers/classNames")),_styleToCssString=_interopRequireDefault(require("../helpers/styleToCssString")),_index=require("../index");function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}function _defineProperty(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}(0,_baseComponent.default)({useSafeArea:!0,externalClasses:["wux-content-class","wux-header-class","wux-body-class","wux-footer-class","wux-close-class"],properties:{prefixCls:{type:String,value:"wux-popup"},animationPrefixCls:{type:String,value:"wux-animate"},title:{type:String,value:""},content:{type:String,value:""},extra:{type:String,value:""},position:{type:String,value:"center",observer:"getTransitionName"},wrapStyle:{type:[String,Object],value:"",observer:function(e){this.setData({extStyle:(0,_styleToCssString.default)(e)})}},closable:{type:Boolean,value:!1},mask:{type:Boolean,value:!0},maskClosable:{type:Boolean,value:!0},visible:{type:Boolean,value:!1,observer:"setPopupVisible"},zIndex:{type:Number,value:1e3},hasHeader:{type:Boolean,value:!0},hasFooter:{type:Boolean,value:!0},mountOnEnter:{type:Boolean,value:!0},unmountOnExit:{type:Boolean,value:!0}},data:{transitionName:"",popupVisible:!1,extStyle:""},computed:{classes:["prefixCls, position, safeAreaConfig, isIPhoneX",function(e,t,a,i){var o;return{wrap:(0,_classNames2.default)("".concat(e,"-position"),(_defineProperty(o={},"".concat(e,"-position--").concat(t),t),_defineProperty(o,"".concat(e,"-position--is-iphonex"),a.bottom&&i),o)),content:"".concat(e,"__content"),hd:"".concat(e,"__hd"),title:"".concat(e,"__title"),bd:"".concat(e,"__bd"),ft:"".concat(e,"__ft"),extra:"".concat(e,"__extra"),close:"".concat(e,"__close"),x:"".concat(e,"__close-x")}}]},methods:{close:function(){this.triggerEvent("close")},onMaskClick:function(){this.data.maskClosable&&this.close()},onExited:function(){this.triggerEvent("closed")},getTransitionName:function(e){var t=0
+
+
+
+
+
+ {{ content }}
+
+
+
+
+
+
+
+
+
diff --git a/miniprogram/components/wux-weapp/popup/index.wxss b/miniprogram/components/wux-weapp/popup/index.wxss
new file mode 100644
index 0000000..835b55a
--- /dev/null
+++ b/miniprogram/components/wux-weapp/popup/index.wxss
@@ -0,0 +1 @@
+.wux-popup{position:fixed;z-index:1000;width:80%;max-width:600rpx}.wux-popup-position.wux-popup-position--center .wux-popup{top:50%;left:50%;transform:translate(-50%,-50%)}.wux-popup-position.wux-popup-position--center .wux-popup__content{border-radius:6rpx}.wux-popup-position.wux-popup-position--center .wux-popup__hd{padding:1.3em 1.6em .5em}.wux-popup-position.wux-popup-position--center .wux-popup__bd{padding:0 1.6em .8em}.wux-popup-position.wux-popup-position--center .wux-popup__ft:after{content:" ";position:absolute;left:0;top:0;right:0;height:2rpx;border-top:2rpx solid #d5d5d6;color:#d5d5d6;transform-origin:0 0;transform:scaleY(.5)}.wux-popup-position.wux-popup-position--top .wux-popup{position:fixed;left:0;top:0;width:100%;max-width:100%}.wux-popup-position.wux-popup-position--right .wux-popup{position:fixed;top:0;right:0;width:80%;max-width:100%;height:100%;max-height:100%}.wux-popup-position.wux-popup-position--bottom .wux-popup{position:fixed;left:0;bottom:0;width:100%;max-width:100%}.wux-popup-position.wux-popup-position--left .wux-popup{position:fixed;left:0;top:0;width:80%;max-width:100%;height:100%;max-height:100%}.wux-popup-position.wux-popup-position--is-iphonex .wux-popup__content{padding-bottom:68rpx}.wux-popup__content{position:relative;background-color:#fff;border:0;background-clip:padding-box;height:100%;text-align:center;overflow:hidden}.wux-popup__title{font-weight:400;font-size:36rpx}.wux-popup__bd{min-height:80rpx;font-size:30rpx;line-height:1.3;word-wrap:break-word;word-break:break-all;color:#999}.wux-popup__ft{position:relative;line-height:96rpx;font-size:36rpx;display:-ms-flexbox;display:flex}.wux-popup__close{border:0;padding:6rpx;background-color:transparent;outline:0;position:absolute;top:12rpx;right:12rpx;height:42rpx;width:42rpx}.wux-popup__close-x{display:inline-block;width:30rpx;height:30rpx;background-repeat:no-repeat;background-size:cover;background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='30' height='30' viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='%23888' fill-rule='evenodd'%3E%3Cpath d='M1.414 0l28.284 28.284-1.414 1.414L0 1.414z'/%3E%3Cpath d='M28.284 0L0 28.284l1.414 1.414L29.698 1.414z'/%3E%3C/g%3E%3C/svg%3E")}
\ No newline at end of file
diff --git a/miniprogram/images/code-cloud-callback-config.png b/miniprogram/images/code-cloud-callback-config.png
new file mode 100644
index 0000000..25b0bfc
Binary files /dev/null and b/miniprogram/images/code-cloud-callback-config.png differ
diff --git a/miniprogram/images/code-db-inc-dec.png b/miniprogram/images/code-db-inc-dec.png
new file mode 100644
index 0000000..d8770b1
Binary files /dev/null and b/miniprogram/images/code-db-inc-dec.png differ
diff --git a/miniprogram/images/code-db-onAdd.png b/miniprogram/images/code-db-onAdd.png
new file mode 100644
index 0000000..22c7afb
Binary files /dev/null and b/miniprogram/images/code-db-onAdd.png differ
diff --git a/miniprogram/images/code-db-onQuery.png b/miniprogram/images/code-db-onQuery.png
new file mode 100644
index 0000000..218550d
Binary files /dev/null and b/miniprogram/images/code-db-onQuery.png differ
diff --git a/miniprogram/images/code-db-onRemove.png b/miniprogram/images/code-db-onRemove.png
new file mode 100644
index 0000000..b4eff71
Binary files /dev/null and b/miniprogram/images/code-db-onRemove.png differ
diff --git a/miniprogram/images/code-func-sum.png b/miniprogram/images/code-func-sum.png
new file mode 100644
index 0000000..0414529
Binary files /dev/null and b/miniprogram/images/code-func-sum.png differ
diff --git a/miniprogram/images/console-entrance.png b/miniprogram/images/console-entrance.png
new file mode 100644
index 0000000..bbbb973
Binary files /dev/null and b/miniprogram/images/console-entrance.png differ
diff --git a/miniprogram/images/create-collection.png b/miniprogram/images/create-collection.png
new file mode 100644
index 0000000..e0fdb34
Binary files /dev/null and b/miniprogram/images/create-collection.png differ
diff --git a/miniprogram/pages/admin_message/admin_message.js b/miniprogram/pages/admin_message/admin_message.js
new file mode 100644
index 0000000..a729e95
--- /dev/null
+++ b/miniprogram/pages/admin_message/admin_message.js
@@ -0,0 +1,68 @@
+
+import regeneratorRuntime from '../../utils/regenerator-runtime/runtime'
+import BaseMixin from '../base/base'
+import mergePages from '../../utils/objectUtils'
+const moment = require('../../utils/moment.min.js')
+import { CallCloudFuncAPI } from '../../utils/async_cloudfunc.js'
+import { $wuxDialog } from '../../components/wux-weapp/index'
+
+const PageObject = mergePages({}, BaseMixin, {
+ data: {
+ total: 0
+ },
+ onInited(options) {
+ let push_token_total = wx.getStorageSync('push_token_total')
+ if(!push_token_total) {
+ this.setData({
+ total: 0
+ })
+ } else {
+ this.setData({
+ total: parseInt(push_token_total)
+ })
+ }
+ },
+ async submitForm(e) {
+ console.log(e)
+ this.showLoading()
+ let res = null
+ try {
+ res = await CallCloudFuncAPI(
+ "main",
+ {
+ apiName: "adminAPI.increasePushToken",
+ token: e.detail.formId
+ }
+ )
+ } catch (e) {
+ console.error(e)
+ this.hideLoading()
+ this.showToast({
+ title: e.message
+ })
+ setTimeout(() => {
+ wx.navigateBack()
+ }, this.data.settings.shortTipDuration)
+ return
+ }
+
+ this.hideLoading()
+ if (!res.result.status) {
+ this.showToast({
+ title: res.result.message
+ })
+ } else {
+ this.setData({
+ total: res.result.data.total
+ })
+ wx.setStorageSync('push_token_total', res.result.data.total)
+ this.showToast({
+ icon: 'success',
+ title: 'ok'
+ })
+ }
+
+ }
+})
+
+Page(PageObject)
\ No newline at end of file
diff --git a/miniprogram/pages/admin_message/admin_message.json b/miniprogram/pages/admin_message/admin_message.json
new file mode 100644
index 0000000..8835af0
--- /dev/null
+++ b/miniprogram/pages/admin_message/admin_message.json
@@ -0,0 +1,3 @@
+{
+ "usingComponents": {}
+}
\ No newline at end of file
diff --git a/miniprogram/pages/admin_message/admin_message.wxml b/miniprogram/pages/admin_message/admin_message.wxml
new file mode 100644
index 0000000..16a263d
--- /dev/null
+++ b/miniprogram/pages/admin_message/admin_message.wxml
@@ -0,0 +1,16 @@
+
+
+
+ 当前Token数量: {{total}}
+
+
+
+ 请在每天检查token的数量,只有在token数量不为0的情况下才能保证管理员能收到新订单的通知。
+ token不足时请点击下方按钮获取token。
+
+
+
+
+
\ No newline at end of file
diff --git a/miniprogram/pages/admin_message/admin_message.wxss b/miniprogram/pages/admin_message/admin_message.wxss
new file mode 100644
index 0000000..ef55271
--- /dev/null
+++ b/miniprogram/pages/admin_message/admin_message.wxss
@@ -0,0 +1,6 @@
+@import '../base/style.wxss';
+
+
+.help {
+ color: #999; font-size: 90%;text-align:center;
+}
\ No newline at end of file
diff --git a/miniprogram/pages/all_orders/all_orders.js b/miniprogram/pages/all_orders/all_orders.js
new file mode 100644
index 0000000..74334cc
--- /dev/null
+++ b/miniprogram/pages/all_orders/all_orders.js
@@ -0,0 +1,67 @@
+
+import regeneratorRuntime from '../../utils/regenerator-runtime/runtime'
+import BaseMixin from '../base/base'
+import PulldownMixin from '../base/pulldown_mixin'
+import OrdersMixin from '../base/orders_mixin'
+import mergePages from '../../utils/objectUtils'
+const moment = require('../../utils/moment.min.js')
+import { CallCloudFuncAPI } from '../../utils/async_cloudfunc.js'
+import { $wuxDialog } from '../../components/wux-weapp/index'
+import { $wuxCalendar } from '../../components/wux-weapp/index'
+import { StatusLabel, DeliveryStatusLabel } from '../../utils/constant'
+
+
+const PageObject = mergePages({}, BaseMixin, PulldownMixin, OrdersMixin, {
+
+ data: {
+ targetDate: [],
+ target_date: '',
+ reqData: {
+ page: 1,
+ pagesize: 10,
+ start_at: null,
+ end_at: null
+ },
+ entityIdField: '_id',
+ apiName: "adminAPI.getUserOrders",
+ isCloudFunc: true,
+ statuses: StatusLabel,
+ deliveryStatus: DeliveryStatusLabel,
+ itemFlags: {
+ pay: '-',
+ deposit: '+'
+ },
+ user_id: null,
+ orderid: null,
+ },
+ onInited(options) {
+ let start_at = moment().format('YYYY-MM-DD 00:00:00')
+ let end_at = moment().format('YYYY-MM-DD 23:59:59')
+ this.setData({
+ 'reqData.start_at': start_at,
+ 'reqData.end_at': end_at,
+ 'target_date': moment().format('YYYY-MM-DD')
+ })
+ wx.startPullDownRefresh()
+ },
+ showCalendar() {
+ $wuxCalendar().open({
+ value: this.data.targetDate,
+ onChange: (values, displayValues) => {
+ if (values && values.length === 0) {
+ return
+ }
+ console.log('onChange', values, displayValues)
+ this.setData({
+ targetDate: displayValues,
+ target_date: displayValues[0],
+ 'reqData.start_at': `${displayValues[0]} 00:00:00`,
+ 'reqData.end_at': `${displayValues[0]} 23:59:59`,
+ })
+ wx.startPullDownRefresh()
+ },
+ })
+ }
+})
+
+Page(PageObject)
\ No newline at end of file
diff --git a/miniprogram/pages/all_orders/all_orders.json b/miniprogram/pages/all_orders/all_orders.json
new file mode 100644
index 0000000..823f65f
--- /dev/null
+++ b/miniprogram/pages/all_orders/all_orders.json
@@ -0,0 +1,7 @@
+{
+ "enablePullDownRefresh": true,
+ "usingComponents": {
+ "wux-calendar": "../../components/wux-weapp/calendar/index",
+ "wux-dialog": "../../components/wux-weapp/dialog/index"
+ }
+}
\ No newline at end of file
diff --git a/miniprogram/pages/all_orders/all_orders.wxml b/miniprogram/pages/all_orders/all_orders.wxml
new file mode 100644
index 0000000..c34a743
--- /dev/null
+++ b/miniprogram/pages/all_orders/all_orders.wxml
@@ -0,0 +1,50 @@
+
+
+
+
+ {{target_date}}
+
+ 选择日期
+
+
+
+
+ 设置
+
+
+
+
+
+ {{item.title}}
+ {{item.orderNo}}
+ {{statuses[item.status].name}} {{deliveryStatus[item.delivery_status] ? deliveryStatus[item.delivery_status].name:''}}
+ {{item.create_at}}
+
+
+
+ {{entity.name}}
+ {{entity.price}} x {{entity.count}}
+
+
+
+
+ 收货地址:
+ {{item.addressInfo.provinceName}} {{item.addressInfo.cityName}} {{item.addressInfo.countyName}} {{item.addressInfo.detailInfo}}
+ 电话:{{item.addressInfo.telNumber}}
+ 邮编:{{item.addressInfo.postalCode}}
+
+
+
+ 快递公司:{{item.deliveryInfo.company_name||'本店御用快递小哥'}}
+ 订单编号:{{item.deliveryInfo.orderno}}
+ 送达时间:{{item.deliveryInfo.will_received_date}} {{item.deliveryInfo.will_received_time}}
+
+
+
+
+
+ {{itemFlags[item.type]}} {{ item.orderInfo.total}}
+ {{itemFlags[item.type]}} {{ item.orderInfo.display_total}} {{ item.orderInfo.display_total !== item.orderInfo.total ? item.orderInfo.total : ''}}
+
+
+
\ No newline at end of file
diff --git a/miniprogram/pages/all_orders/all_orders.wxss b/miniprogram/pages/all_orders/all_orders.wxss
new file mode 100644
index 0000000..c71e76a
--- /dev/null
+++ b/miniprogram/pages/all_orders/all_orders.wxss
@@ -0,0 +1,43 @@
+@import '../base/style.wxss';
+@import '../user_orders/user_orders.wxss';
+
+
+.datebar {
+ position: fixed;
+ left: 0;
+ top: 0;
+ width: 100%;
+ display: flex;
+ font-size: 12px;
+ padding-top: 10px;
+ box-sizing: border-box;
+ padding-bottom: 10px;
+ background-color: #f9f9f9;
+ border-bottom: 1px solid #ddd;
+}
+
+
+.datebar .date-label {
+ flex: 1;
+ padding-left: 10px;
+ height: 30px;
+ line-height:30px;
+}
+
+
+
+.datebar .date-btn-wrapper {
+ width: 160px;
+}
+
+.date-button {
+ width: 80px;
+ background-color: #E67774;
+ height: 30px;
+ color: #fff;
+ line-height: 30px;
+ border-radius: 10px;
+ text-align: center;
+ float: right;
+ margin-right: 10px;
+}
\ No newline at end of file
diff --git a/miniprogram/pages/base/base.js b/miniprogram/pages/base/base.js
new file mode 100644
index 0000000..e95499f
--- /dev/null
+++ b/miniprogram/pages/base/base.js
@@ -0,0 +1,144 @@
+import regeneratorRuntime from '../../utils/regenerator-runtime/runtime'
+import settings from '../../settings/index'
+import moment from '../../utils/moment.min.js'
+import message from './message'
+import { $wuxDialog } from '../../components/wux-weapp/index'
+const app = getApp()
+
+module.exports = {
+ data: {
+ pageName: null,
+ language: {},
+ locale: null,
+ systemInfo: null,
+ settings: settings
+ },
+ checkSession() {
+ let sessionid = wx.getStorageSync('sessionid')
+ if (!sessionid) {
+ let current_url = this.getCurrentPath()
+ if (!current_url.includes('home/home')) {
+ wx.reLaunch({
+ url: `${settings.HomePage}?nextpage=${encodeURIComponent(current_url)}`,
+ })
+ } else {
+ wx.reLaunch({
+ url: settings.HomePage,
+ })
+ }
+ }
+ },
+ showToast(options) {
+ console.log('options:', options)
+ let title = message[options.title]
+ console.log('message:', message)
+ console.log(title)
+ if(!title) {
+ title = '系统内部错误'
+ }
+ let myOptions = {
+ icon: 'none',
+ duration: settings.shortTipDuration,
+ ...options
+ }
+ myOptions.title = title
+ console.log(myOptions)
+ wx.showToast(myOptions)
+ },
+ hideToast() {
+ wx.hideToast()
+ },
+ showDialog(newConfig, isConfirm = false) {
+ let config = Object.assign({},
+ {
+ resetOnClose: true,
+ title: '',
+ content: ''
+ },
+ newConfig
+ )
+ if (isConfirm) {
+ $wuxDialog().confirm(config)
+ } else {
+ $wuxDialog().alert(config)
+ }
+ },
+ onReachBottom: function () {
+ wx.stopPullDownRefresh();
+ },
+
+ showLoading(message) {
+ wx.showLoading({
+ title: message || '加载中...',
+ })
+ },
+ hideLoading() {
+ wx.hideLoading()
+ },
+ onLoad: function (options) {
+ this.setData({
+ systemInfo: app.globalData.systemInfo
+ })
+ console.log('systemInfo:', this.data.systemInfo)
+ if (options.invite_code) {
+ wx.setStorage({
+ key: 'invite_code',
+ data: options.invite_code,
+ })
+ }
+
+ if (this.onInited) {
+ this.onInited(options)
+ }
+ },
+ getCurrentPath: function () {
+ let pages = getCurrentPages();
+ let currPage = null;
+ if (pages.length) {
+ currPage = pages[pages.length - 1];
+ }
+ if (currPage.options) {
+ let queryStr = this.joinUrlKey(currPage.options);
+ return `/${currPage.route}?${queryStr}`
+ } else {
+ return `/${currPage.route}`
+ }
+ },
+ joinUrlKey: function (keys) {
+ return Object.keys(keys).map(function (k) {
+ return encodeURIComponent(k) + "=" + encodeURIComponent(keys[k]);
+ }).join('&')
+ },
+ isTab: function (url) {
+ let flag = false;
+ for (let item of settings.TAB_URLS) {
+ if (url.includes(item)) {
+ return true
+ }
+ }
+ return flag
+ },
+ goToURL: function (url) {
+ if (this.isTab(url)) {
+ wx.switchTab({
+ url: url
+ })
+ } else {
+ wx.redirectTo({
+ url: url
+ })
+ }
+ },
+ formatEventDate(s1, e1) {
+ let startDate = moment(s1)
+ let endDate = moment(e1)
+ if (startDate.format('YYYY-MM-DD') == endDate.format('YYYY-MM-DD')) {
+ return `${startDate.format('YYYY-MM-DD HH:mm')}-${endDate.format('HH:mm')}`
+ } else {
+ return `${startDate.format('YYYY-MM-DD HH:mm')}-${endDate.format('YYYY-MM-DD HH:mm')}`
+ }
+ },
+ onShareAppMessage: function () {
+
+ }
+}
\ No newline at end of file
diff --git a/miniprogram/pages/base/buycart.js b/miniprogram/pages/base/buycart.js
new file mode 100644
index 0000000..89ca055
--- /dev/null
+++ b/miniprogram/pages/base/buycart.js
@@ -0,0 +1,121 @@
+import regeneratorRuntime from '../../utils/regenerator-runtime/runtime'
+import moment from '../../utils/moment.min.js'
+
+
+module.exports = {
+ onShow() {
+ this.loadBuycart()
+ },
+ loadBuycart() {
+ let buycart = wx.getStorageSync('buycart')
+ if (buycart) {
+ this.setData({
+ buycart: buycart
+ })
+ } else {
+ this.setData({
+ buycart: {
+ total: 0,
+ display_total: 0,
+ count: 0,
+ entities: []
+ }
+ })
+ }
+ },
+ addGoodsToCart(item) {
+ console.log('item:', item)
+ let flag = false
+ for (let entity of this.data.buycart.entities) {
+ if (entity.id == item._id) {
+ entity.count += 1
+ entity.total = entity.count * parseFloat(entity.price)
+ entity.display_total = entity.count * parseFloat(entity.display_price)
+ flag = true
+ }
+ }
+ console.log('flag:', flag)
+ if (flag === false) {
+ this.data.buycart.entities.push({
+ id: item._id,
+ name: item.name,
+ name_en: item.name_en,
+ count: 1,
+ price: item.price,
+ display_price: item.display_price,
+ cover: item.cover,
+ total: item.price,
+ display_total: item.display_price
+ })
+ }
+ this.setData({
+ 'buycart.entities': this.data.buycart.entities
+ })
+ let total = 0;
+ let count = 0;
+ let display_total = 0;
+ for (let entity of this.data.buycart.entities) {
+ total += parseFloat(entity.total)
+ display_total += parseFloat(entity.display_total)
+ count += entity.count
+ }
+ this.setData({
+ 'buycart.total': total,
+ 'buycart.display_total': display_total,
+ 'buycart.count': count
+ })
+ wx.setStorageSync('buycart', this.data.buycart)
+ },
+ updateGoodsCount(id, count) {
+ for (let item of this.data.buycart.entities) {
+ if (id === item.id) {
+ let itemTotal = parseFloat(item.total)
+ let itemDisplayTotal = parseFloat(item.display_total)
+ let itemCount = item.count
+ let countVal = count - itemCount
+ let totalVal = countVal * parseFloat(item.price)
+ let displayTotalVal = countVal * parseFloat(item.display_price)
+ let currentTotal = itemTotal + totalVal
+ let currentDisplayTotal = itemDisplayTotal + displayTotalVal
+ item.count = count
+ item.total = currentTotal
+ item.display_total = currentDisplayTotal
+ }
+ }
+ let totalAll = 0;
+ let displayTotalAll = 0;
+ let countAll = 0;
+ for (let item of this.data.buycart.entities) {
+ totalAll += parseFloat(item.total)
+ displayTotalAll += parseFloat(item.display_total)
+ countAll += item.count
+ }
+ this.data.buycart.total = totalAll
+ this.data.buycart.display_total = displayTotalAll
+ this.data.buycart.count = countAll
+
+ let entities = []
+ for (let item of this.data.buycart.entities) {
+ if (item.count !== 0) {
+ entities.push(item)
+ }
+ }
+ this.data.buycart.entities = entities
+
+ this.setData({
+ buycart: this.data.buycart
+ })
+ wx.setStorageSync('buycart', this.data.buycart)
+ },
+ _clearBuyCart() {
+ this.setData({
+ buycart: {
+ total: 0,
+ display_total: 0,
+ count: 0,
+ entities: []
+ }
+ })
+ wx.setStorageSync('buycart', this.data.buycart)
+ }
+}
\ No newline at end of file
diff --git a/miniprogram/pages/base/message.js b/miniprogram/pages/base/message.js
new file mode 100644
index 0000000..62a6ee9
--- /dev/null
+++ b/miniprogram/pages/base/message.js
@@ -0,0 +1,17 @@
+const message = {
+ ok: "成功",
+ address_not_found: "地址不存在",
+ update_address_error: "更新地址时发生错误",
+ setdefault_address_error: "设置默认地址时发生错误",
+ user_not_found: "用户不存在",
+ fail_create_user: "创建用户时发生错误",
+ get_orders_error: "获取订单时发生错误",
+ fail_update_user: "更新用户时发生错误",
+ update_birthday_error: "更新生日时发生错误",
+ update_gender_error: "更新性别时发生错误",
+ update_name_error: "更新名字时发生错误",
+ update_address_error: "更新地址是发生错误",
+ user_balance_error: "付款失败,余额不足"
+}
+
+export default message
\ No newline at end of file
diff --git a/miniprogram/pages/base/orders_mixin.js b/miniprogram/pages/base/orders_mixin.js
new file mode 100644
index 0000000..f04ab4a
--- /dev/null
+++ b/miniprogram/pages/base/orders_mixin.js
@@ -0,0 +1,140 @@
+
+import regeneratorRuntime from '../../utils/regenerator-runtime/runtime'
+import BaseMixin from '../base/base'
+import PulldownMixin from '../base/pulldown_mixin'
+import mergePages from '../../utils/objectUtils'
+const moment = require('../../utils/moment.min.js')
+import { CallCloudFuncAPI } from '../../utils/async_cloudfunc.js'
+import { $wuxDialog } from '../../components/wux-weapp/index'
+import { StatusLabel, DeliveryStatusLabel } from '../../utils/constant'
+
+
+export default {
+
+ data: {
+ reqData: {
+ page: 1,
+ pagesize: 10,
+ user_id: null
+ },
+ entityIdField: '_id',
+ apiName: "adminAPI.getUserOrders",
+ isCloudFunc: true,
+ statuses: StatusLabel,
+ deliveryStatus: DeliveryStatusLabel,
+ itemFlags: {
+ pay: '-',
+ deposit: '+'
+ },
+ user_id: null,
+ orderid: null,
+ admin: null
+ },
+ onShow() {
+ let admin = wx.getStorageSync('admin')
+ if(admin && admin.id) {
+ this.setData({
+ admin: admin
+ })
+ } else {
+ this.setData({
+ admin: null
+ })
+ }
+ },
+ onInited(options) {
+ if (!options.user_id) {
+ return
+ }
+ this.setData({
+ 'reqData.user_id': options.user_id
+ })
+ console.log('user_id:', this.data.user_id)
+ wx.startPullDownRefresh()
+ },
+ getEntitiesApiUrl() {
+ return "main"
+ },
+ formatEntities(data) {
+ console.log(data)
+ for (let entity of data.entities) {
+ entity.create_at = moment(entity.create_at).format('YYYY/MM/DD HH:mm')
+ if (entity.type == 'deposit') {
+ entity.title = '购买充值卡'
+ } else if (entity.type == 'pay') {
+ entity.title = this.getGoodsName(entity.orderInfo)
+ }
+ }
+ return data
+ },
+ getGoodsName(orderInfo) {
+ let goodsName = '';
+ orderInfo.entities.map((item, index) => {
+ if (index === 0) {
+ goodsName += item.name
+ } else if (index > 0 && index < 3) {
+ goodsName += '、' + item.name
+ } else if (index == 3) {
+ if (orderInfo.entities.length > 3) {
+ goodsName += '等'
+ }
+ }
+ })
+ return goodsName
+ },
+ onControlOrder(e) {
+ console.log(e)
+ this.setData({
+ orderid: e.currentTarget.dataset.orderid
+ })
+ let that = this;
+ wx.showActionSheet({
+ itemList: ['设置订单地址', '设置订单状态', '设置发货状态', '调整订单金额', '设置订单备注', '取消订单'],
+ success(res) {
+ console.log(res.tapIndex)
+ if (res.tapIndex === 0) {
+ wx.navigateTo({
+ url: `/pages/update_address/update_address?orderid=${that.data.orderid}`,
+ })
+ }
+
+ if (res.tapIndex === 1) {
+ wx.navigateTo({
+ url: `/pages/update_order/update_order?orderid=${that.data.orderid}`,
+ })
+ }
+
+ if (res.tapIndex === 2) {
+ wx.navigateTo({
+ url: `/pages/update_delivery/update_delivery?orderid=${that.data.orderid}`,
+ })
+ }
+
+ if (res.tapIndex === 3) {
+ wx.navigateTo({
+ url: `/pages/update_total/update_total?orderid=${that.data.orderid}`,
+ })
+ }
+
+ if (res.tapIndex === 4) {
+ wx.navigateTo({
+ url: `/pages/update_remarks/update_remarks?orderid=${that.data.orderid}`,
+ })
+ }
+
+ if (res.tapIndex === 5) {
+ wx.navigateTo({
+ url: `/pages/cancel_order/cancel_order?orderid=${that.data.orderid}`,
+ })
+ }
+
+
+
+ },
+ fail(res) {
+ console.log(res.errMsg)
+ }
+ })
+ }
+
+}
\ No newline at end of file
diff --git a/miniprogram/pages/base/pulldown_mixin.js b/miniprogram/pages/base/pulldown_mixin.js
new file mode 100644
index 0000000..ceff946
--- /dev/null
+++ b/miniprogram/pages/base/pulldown_mixin.js
@@ -0,0 +1,164 @@
+import regeneratorRuntime from '../../utils/regenerator-runtime/runtime'
+import { ApiRequest } from '../../utils/async_api'
+import { CallCloudFuncAPI } from '../../utils/async_cloudfunc'
+export default {
+ data: {
+ entities: [],
+ entityIdField: 'id',
+ lastId: null,
+ reqData: {
+ page: 1,
+ pagesize: 10
+ }
+ },
+ getEntities: async function () {
+ this.showLoading()
+ try {
+ await this._getEntitiesAPI()
+ } catch (e) {
+ console.error(e)
+ }
+ this.hideLoading()
+ },
+ updateOldEntities: function (newItem) {
+ for (let i = 0; i < this.data.entities.length; i++) {
+ if (this.data.entities[i][this.data.entityIdField] == newItem[this.data.entityIdField]) {
+ this.data.entities[i] = newItem
+ }
+ }
+ },
+ refreshNewEntities: async function () {
+ this.showLoading()
+ try {
+ let newReqData = { ...this.data.reqData }
+ newReqData.page = 1
+ let result = await this.callEntitiesAPI(newReqData)
+ if (!this.data.isCloudFunc && !result.code) {
+ this.showToast({title: result.message})
+ return
+ } else if (this.data.isCloudFunc && result.result.status === false) {
+ this.showToast({title: result.result.message})
+ return
+ }
+
+ if (this.data.isCloudFunc) {
+ result = result.result
+ }
+
+ let entities = []
+ let newEntities = []
+ let oldEntities = this._getEntitiyIds()
+
+ if (result.data && result.data.entities) {
+ if (this.formatEntities) {
+ let formatedData = await this.formatEntities(result.data)
+ entities = formatedData.entities
+ } else {
+ entities = result.data.entities
+ }
+ }
+
+ for (let item of result.data.entities) {
+ if (!oldEntities.includes(item[this.data.entityIdField])) {
+ newEntities.push(item)
+ } else {
+ this.updateOldEntities(item)
+ }
+ }
+
+ if (newEntities.length != 0) {
+ this.setData({
+ entities: [...newEntities, ...this.data.entities]
+ })
+ } else {
+ this.setData({
+ entities: this.data.entities
+ })
+ }
+
+ if (this.data.lastId === null) {
+ this.setData({
+ lastId: this.data.entities[this.data.entities.length - 1][this.data.entityIdField],
+ 'reqData.page': this.data.reqData.page + 1
+ })
+ }
+ } catch (e) {
+ console.error(e)
+ }
+ this.hideLoading()
+ },
+ getEntitiesApiUrl: function () {
+ return null
+ },
+
+ callEntitiesAPI: async function (reqData) {
+ if(!this.data.isCloudFunc) {
+ return await ApiRequest(this.getEntitiesApiUrl(), reqData)
+ } else {
+ return await CallCloudFuncAPI(this.getEntitiesApiUrl(), {
+ apiName: this.data.apiName,
+ ...reqData
+ })
+ }
+ },
+ _getEntitiesAPI: async function () {
+ let result;
+ let reqData = this.data.reqData
+ result = await this.callEntitiesAPI(reqData)
+ if (!this.data.isCloudFunc && !result.code) {
+ this.showToast({title: result.message})
+ return
+ } else if(this.data.isCloudFunc && result.result.status === false) {
+ this.showToast({
+ message: result.result.message
+ })
+ return
+ }
+
+ if(this.data.isCloudFunc) {
+ result = result.result
+ }
+
+ let entities = []
+ if (result.data && result.data.entities) {
+ if (this.formatEntities) {
+ let formatedData = await this.formatEntities(result.data)
+ entities = formatedData.entities
+ } else {
+ entities = result.data.entities
+ }
+ }
+
+ if (entities.length === 0) {
+ this.showToast({
+ message: '没有更多数据了'
+ })
+ return
+ }
+
+ let all_entities = []
+ let lastId = entities[entities.length - 1][this.data.entityIdField]
+ if (this.data.lastId != lastId) {
+ all_entities = [...this.data.entities, ...entities]
+ this.setData({
+ entities: all_entities,
+ lastId: lastId,
+ 'reqData.page': this.data.reqData.page + 1
+ })
+ }
+ },
+ _getEntitiyIds: function () {
+ let entityIds = []
+ for (let entity of this.data.entities) {
+ entityIds.push(entity[this.data.entityIdField])
+ }
+ return entityIds
+ },
+ onReachBottom: async function () {
+ await this.getEntities()
+ },
+ onPullDownRefresh: async function () {
+ await this.refreshNewEntities()
+ wx.stopPullDownRefresh()
+ },
+}
\ No newline at end of file
diff --git a/miniprogram/pages/base/style.wxss b/miniprogram/pages/base/style.wxss
new file mode 100644
index 0000000..214a584
--- /dev/null
+++ b/miniprogram/pages/base/style.wxss
@@ -0,0 +1,157 @@
+@font-face {
+ font-family: 'iconfont';
+ src: url('../../assets/icons/iconfont.eot');
+ src: url('../../assets/icons/iconfont.eot?#iefix') format('embedded-opentype'),
+ url('../../assets/icons/iconfont.woff2') format('woff2'),
+ url('../../assets/icons/iconfont.woff') format('woff'),
+ url('../../assets/icons/iconfont.ttf') format('truetype'),
+ url('../../assets/icons/iconfont.svg#iconfont') format('svg');
+}
+@import '../../assets/icons/iconfont.wxss';
+
+/* page {
+ background-color: #e67774;
+} */
+
+.round-button {
+ padding-left: 30rpx;
+ padding-right: 30rpx;
+ height: 90rpx;
+ background-color: #d9262f;
+ border-radius: 45rpx;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ flex-direction: row;
+ box-sizing: border-box;
+ border-color: transparent transparent #80161b transparent;
+ box-shadow: rgba(0, 0, 0, 0.2) 5rpx 5rpx 10rpx 5rpx;
+ color: #fff;
+}
+
+.round-button text {
+ color: #fff;
+}
+
+.round-button.floated {
+ position: fixed;
+ bottom: 80rpx;
+ right: 40rpx;
+}
+
+.ellipsis {
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+.panel-form {
+ width: 100%;
+ background-color: #f5f5f5;
+ border-top-left-radius: 20px;
+ border-top-right-radius: 20px;
+ padding-top: 10px;
+}
+
+/* form */
+
+.section {
+ font-size: 90%;
+ padding: 12px;
+ width: 100%;
+ box-sizing: border-box;
+}
+
+.section__field {
+ border: 1px solid #ddd;
+ width: 100%;
+ min-height: 34px;
+ line-height: 24px;
+ padding: 5px;
+ box-sizing: border-box;
+ background-color: #fff;
+ font-size: 14px;
+ color: #333;
+ border-radius: 4px;
+}
+
+.section__checkbox {
+ background-color: #f5f5f5;
+}
+
+.section__auto_height {
+ min-height: 102px;
+}
+
+.section__auto_height textarea {
+ min-height: 90px;
+ width: 100%;
+}
+
+.section__note {
+ font-size: 80%;
+ color: #999;
+ margin-top: 3px;
+}
+
+/* panel */
+
+.panel-button {
+ position: relative;
+ width: 100%;
+ right: 0;
+ bottom: 0;
+ margin-bottom: 30px;
+}
+
+/* triangle */
+
+.triangle-bottomright {
+ width: 0;
+ height: 0;
+ border-bottom: 50px solid #fde2e2;
+ border-left: 50px solid transparent;
+ position: absolute;
+ bottom: 0;
+ right: 0;
+}
+
+.italic-text {
+ position: absolute;
+ bottom: 10px;
+ right: 0;
+ color: #f56c6c;
+ font-size: 70%;
+ width: 40px;
+ text-align: center;
+ transform: rotate(-45deg);
+}
+
+/* emptybox */
+
+.empty-box {
+ width: 100px;
+ height: 100px;
+ top: 100px;
+ position: absolute;
+ left: 50%;
+ margin-left: -50px;
+}
+
+.empty-icon {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
+
+.empty-icon image {
+ width: 48px;
+ height: 48px;
+}
+
+.empty-txt {
+ text-align: center;
+ color: #999;
+ font-size: 90%;
+ margin-top: 20px;
+}
diff --git a/miniprogram/pages/buycart/buycart.js b/miniprogram/pages/buycart/buycart.js
new file mode 100644
index 0000000..b6502fc
--- /dev/null
+++ b/miniprogram/pages/buycart/buycart.js
@@ -0,0 +1,222 @@
+import regeneratorRuntime from '../../utils/regenerator-runtime/runtime'
+import mergePages from '../../utils/objectUtils'
+import BaseMixin from '../base/base'
+import BuycartMixin from '../base/buycart'
+import { $wuxDialog } from '../../components/wux-weapp/index'
+import { getWxAddress } from '../../utils/async_tools/async_address'
+import { CallCloudFuncAPI } from '../../utils/async_cloudfunc'
+
+const PageObject = mergePages({}, BaseMixin, BuycartMixin, {
+
+ /**
+ * 页面的初始数据
+ */
+ data: {
+ buycart: null,
+ isAgree: false,
+ userInfo: null,
+ address: null
+ },
+ onInited(options) {
+ this.getProfile()
+ },
+ onShow() {
+ this.loadBuycart()
+ this.loadAgreeStatus()
+ this.loadDeliveryStatus()
+ },
+ loadDeliveryStatus() {
+ let isDelivery = wx.getStorageSync('isDelivery')
+ if(isDelivery === true) {
+ this.setData({
+ 'buycart.isDelivery': true
+ })
+ } else {
+ this.setData({
+ 'buycart.isDelivery': false
+ })
+ wx.setStorageSync('isDelivery', false)
+ }
+ },
+ loadAgreeStatus() {
+ let isAgree = wx.getStorageSync('isAgree')
+ if (isAgree === true) {
+ this.setData({
+ isAgree: true
+ })
+ } else {
+ this.setData({
+ isAgree: false
+ })
+ wx.setStorageSync('isAgree', false)
+ }
+ },
+ counterUpdate(e) {
+ console.log(e)
+ if (e.detail.actionType == 'counterUpdate') {
+ this.updateGoodsCount(e.detail.optId, e.detail.counter)
+ }
+ },
+ ontapAgree() {
+ this.setData({
+ isAgree: !this.data.isAgree
+ })
+ wx.setStorageSync('isAgree', this.data.isAgree)
+ },
+ goCake() {
+ wx.navigateBack()
+ },
+ ontapClearBuycart() {
+ $wuxDialog().confirm({
+ resetOnClose: true,
+ title: '',
+ content: '请确定是否清空购物车',
+ onConfirm: (e, response) => {
+ this._clearBuyCart()
+ }
+ })
+ },
+ ontapSubmit() {
+ if (!this.data.isAgree) {
+ $wuxDialog().alert({
+ resetOnClose: true,
+ content: '请点击同意用户协议后再提交订单',
+ })
+ } else {
+ if (this.data.isDelivery && !this.data.address) {
+ this.showToast({
+ title: '请选择收货地址'
+ })
+ return
+ }
+
+
+ if(!this.data.buycart.entities || this.data.buycart.entities.length === 0) {
+ $wuxDialog().confirm({
+ resetOnClose: true,
+ title: `您还没有选择商品`,
+ content: '返回商城',
+ onConfirm: (e, response) => {
+ wx.navigateBack()
+ }
+ })
+ return
+ }
+
+ $wuxDialog().confirm({
+ resetOnClose: true,
+ title: `订单总金额${this.data.buycart.total}元`,
+ content: '确定是否提交订单',
+ onConfirm: (e, response) => {
+ this.submitOrder()
+ }
+ })
+ }
+ },
+ async submitOrder() {
+ console.log('submitOrder')
+ this.showLoading()
+ let res = null
+ try {
+ res = await CallCloudFuncAPI('main', {
+ apiName: 'payAPI.orderPay',
+ orderInfo: this.data.buycart
+ })
+ } catch (e) {
+ console.error(e)
+ this.hideLoading()
+ this.showToast({
+ title: e.message
+ })
+ return
+ }
+
+ this.hideLoading()
+ if (!res.result.status) {
+ this.showToast({
+ title: res.result.message,
+ })
+ return
+ }
+
+ this._clearBuyCart()
+ this.submitPaySuccess()
+ },
+ submitPaySuccess() {
+ $wuxDialog().alert({
+ resetOnClose: true,
+ content: '支付成功',
+ onConfirm: (e, response) => {
+ wx.navigateTo({
+ url: '/pages/orders/orders',
+ })
+ }
+ })
+ },
+ async ontapAddress() {
+ let [err, result] = await getWxAddress()
+ console.log(err)
+ console.log(result)
+ if (err !== null) {
+ return
+ }
+ this.updateAddress(result)
+
+ },
+ async updateAddress(address) {
+ let result = null
+ try {
+ result = CallCloudFuncAPI("main",
+ {
+ apiName: "userAPI.updateAddress",
+ address: address
+ })
+ } catch (e) {
+ console.error(e)
+ }
+ if (result === null) {
+ return
+ }
+ wx.setStorageSync('address', address)
+ this.setData({
+ address: address
+ })
+ },
+ async getProfile() {
+ let that = this
+ let res = null
+ try {
+ res = await CallCloudFuncAPI(
+ "main",
+ {
+ apiName: "getProfile"
+ }
+ )
+ } catch (e) {
+ console.error(e)
+ }
+
+
+ if (res) {
+ this.setData({
+ userInfo: res.result.data.user,
+ address: res.result.data.user.address
+ })
+ wx.setStorageSync('address', res.result.data.user.address)
+ }
+ },
+ onSelectNotDelivery() {
+ this.setData({
+ 'buycart.isDelivery': false
+ })
+ wx.setStorageSync('isDelivery', false)
+ },
+ onSelectDelivery() {
+ this.setData({
+ 'buycart.isDelivery': true,
+ })
+ wx.setStorageSync('isDelivery', true)
+ }
+})
+
+Page(PageObject)
\ No newline at end of file
diff --git a/miniprogram/pages/buycart/buycart.json b/miniprogram/pages/buycart/buycart.json
new file mode 100644
index 0000000..6779fe6
--- /dev/null
+++ b/miniprogram/pages/buycart/buycart.json
@@ -0,0 +1,6 @@
+{
+ "usingComponents": {
+ "counter": "../../components/counter/counter",
+ "wux-dialog": "../../components/wux-weapp/dialog/index"
+ }
+}
\ No newline at end of file
diff --git a/miniprogram/pages/buycart/buycart.wxml b/miniprogram/pages/buycart/buycart.wxml
new file mode 100644
index 0000000..b7d3d1b
--- /dev/null
+++ b/miniprogram/pages/buycart/buycart.wxml
@@ -0,0 +1,107 @@
+
+
+
+
+
+
+
+
+ {{address.detailInfo}}
+
+ {{address.userName}}
+ {{address.telNumber}}
+
+
+
+ 请选择您的收货地址
+
+
+
+
+
+
+
+
+ 新龙路1333弄108号211室
+
+ 上海市
+ 闵行区七宝镇
+
+
+
+
+
+
+ 到店自提
+ 周边外送
+
+
+
+
+
+
+ 我的订单
+ 清空购物车
+
+
+
+
+
+
+
+
+
+
+ {{item.name}}
+ ¥ {{item.price}}
+
+
+
+
+
+
+
+ ¥ {{item.total}}
+
+
+
+
+
+
+
+
+
+
+ 提交
+
+
+ 继续购物
+
+
\ No newline at end of file
diff --git a/miniprogram/pages/buycart/buycart.wxss b/miniprogram/pages/buycart/buycart.wxss
new file mode 100644
index 0000000..4fa9b8b
--- /dev/null
+++ b/miniprogram/pages/buycart/buycart.wxss
@@ -0,0 +1,271 @@
+@import '../base/style.wxss';
+
+.container {
+ /* background-color: #e67774; */
+ position: relative;
+ padding-bottom: 100px
+}
+
+.body {
+ padding: 5px;
+ box-shadow: 1px 1px 10px rgba(0, 0, 0, 0.2);
+}
+
+.header {
+ padding: 20px;
+ background-color: #e67774;
+ color: #fff;
+}
+
+.buycart-title text {
+ display: inline-block;
+ font-size: 140%;
+}
+
+.buycart-meta {
+ font-size: 90%;
+ color: #ccc;
+}
+
+.item {
+ display: flex;
+ height: 90px;
+ padding: 10px;
+ box-sizing: border-box;
+ border-top: 1px solid #f5f5f5;
+}
+
+.item:last-child {
+ border-bottom: 1px solid #f5f5f5;
+}
+
+.goods-cover {
+ width: 90px;
+ height: 100%;
+}
+
+.goods-info {
+ flex: 1;
+ height: 100%;
+}
+
+.goods-cover image {
+ width: 60px;
+ height: 60px;
+ border-radius: 30px;
+ box-shadow: 1px 1px 10px rgba(0, 0, 0, 0.2);
+}
+
+.title {
+ display: flex;
+ font-weight: bold;
+}
+
+.title .price {
+ width: 80px;
+ justify-content: center;
+ align-items: center;
+ text-align: right;
+ color: #333;
+ font-size: 90%;
+}
+
+.title .name {
+ flex: 1;
+ color: #333;
+}
+
+.info {
+ display: flex;
+ padding-top: 10px;
+}
+
+.info .count {
+ flex: 1;
+}
+
+.info .total {
+ width: 80px;
+}
+
+.count-wrapper {
+ width: 120px;
+}
+
+.foot-wrapper {
+ display: flex;
+ padding-right: 10px;
+}
+
+.goods-agree {
+ width: 80px;
+ justify-content: center;
+ align-items: center;
+ display: flex;
+}
+
+.goods-agree-info {
+ flex: 1;
+ padding-top: 10px;
+ padding-bottom: 10px;
+}
+
+.agree-button {
+ width: 40px;
+ height: 40px;
+ border: 2px solid #ddd;
+ border-radius: 20px;
+ position: relative;
+ box-sizing: border-box;
+}
+
+.agree-button-inner {
+ height: 30px;
+ width: 30px;
+ border-radius: 15px;
+ background-color: #fff;
+ position: absolute;
+ top: 3px;
+ left: 3px;
+ border: 2px solid #ddd;
+ box-sizing: border-box;
+}
+
+.agree-button-inner.agreed {
+ background-color: #333;
+}
+
+.goods-note {
+ font-size: 80%;
+ color: #666;
+}
+
+.goods-total {
+ display: flex;
+ padding-bottom: 5px;
+}
+
+.total-label {
+ font-size: 80%;
+}
+
+.total-line {
+ flex: 1;
+ border-bottom: 1px dotted #ddd;
+}
+
+.total-amount {
+ font-size: 80%;
+}
+
+.submit-button {
+ height: 50px;
+ width: 120px;
+ line-height: 50px;
+ border-radius: 25px;
+ color: #fff;
+ font-weight: bold;
+ text-align: center;
+ background-color: #ddd;
+ position: fixed;
+ right: 20px;
+ bottom: 30px;
+ box-shadow: 1px 1px 10px rgba(0, 0, 0, 0.2);
+}
+
+.submit-button.agreed {
+ background-color: #fa8282;
+}
+
+.return-buy {
+ height: 30px;
+ width: 120px;
+ line-height: 30px;
+ border-radius: 15px;
+ color: #333;
+ font-weight: bold;
+ text-align: center;
+ background-color: #f5f5f5;
+ position: fixed;
+ right: 150px;
+ bottom: 40px;
+ box-shadow: 1px 1px 10px rgba(0, 0, 0, 0.2);
+}
+
+.body-header {
+ padding-bottom: 5px;
+}
+
+.body-header-wrapper {
+ height: 30px;
+ line-height: 30px;
+ display: flex;
+ padding-left: 10px;
+ padding-right: 10px;
+ box-sizing: border-box;
+ font-size: 80%;
+ color: #666;
+}
+
+.body-header-wrapper label {
+ width: 80px;
+}
+
+.body-header-wrapper .clear {
+ flex: 1;
+ text-align: right;
+}
+
+.address {
+ position: relative;
+ padding: 10px;
+ box-sizing: border-box;
+}
+
+.address-wrapper {
+ margin-right: 60px;
+}
+
+.address .icon-gengduo {
+ position: absolute;
+ top: 30px;
+ right: 20px;
+}
+
+.address .address-detail {
+ color: #333;
+ font-size: 110%;
+}
+
+.address .address-name {
+ color: #666;
+ font-size: 90%;
+ margin-top: 5px;
+}
+
+
+.delivery-method {
+ padding-left: 10px;
+ padding-bottom: 10px;
+ padding-right: 10px;
+ text-align: right;
+}
+
+.delivery-method .method-name {
+ display: inline-block;
+ font-size: 80%;
+ padding-left: 8px;
+ padding-right: 8px;
+ background-color: #ddd;
+ margin-right: 5px;
+ color: #fff;
+ border-radius: 15px;
+ height: 30px;
+ line-height: 30px;
+ box-sizing: border-box;
+}
+
+.delivery-method .method-name.selected {
+ color: #fff;
+ background-color: #e67774;
+}
diff --git a/miniprogram/pages/cancel_order/cancel_order.js b/miniprogram/pages/cancel_order/cancel_order.js
new file mode 100644
index 0000000..fe4a2b8
--- /dev/null
+++ b/miniprogram/pages/cancel_order/cancel_order.js
@@ -0,0 +1,106 @@
+
+import regeneratorRuntime from '../../utils/regenerator-runtime/runtime'
+import BaseMixin from '../base/base'
+import mergePages from '../../utils/objectUtils'
+const moment = require('../../utils/moment.min.js')
+import { CallCloudFuncAPI } from '../../utils/async_cloudfunc.js'
+import { $wuxDialog } from '../../components/wux-weapp/index'
+
+const PageObject = mergePages({}, BaseMixin, {
+ data: {
+ refund_amount: 0
+ },
+ onInited(options) {
+
+ this.setData({
+ orderid: options.orderid
+ })
+ this.getOrderDetail()
+ },
+ async getOrderDetail() {
+ this.showLoading()
+ let res = null
+ try {
+ res = await CallCloudFuncAPI(
+ "main",
+ {
+ apiName: "adminAPI.getUserOrders",
+ orderid: this.data.orderid
+ }
+ )
+ } catch (e) {
+ console.error(e)
+ this.hideLoading()
+ setTimeout(() => {
+ wx.navigateBack()
+ }, this.data.settings.shortTipDuration)
+ return
+ }
+
+
+ this.hideLoading()
+ if (!res.result.status) {
+ this.showToast({
+ title: res.result.message
+ })
+ setTimeout(() => {
+ wx.navigateBack()
+ }, this.data.settings.shortTipDuration)
+ return
+ }
+ },
+
+
+ async submitForm() {
+ this.showLoading()
+ let res = null
+ try {
+ res = await CallCloudFuncAPI(
+ "main",
+ {
+ apiName: "adminAPI.cancelOrder",
+ refund_amount: this.data.refund_amount,
+ orderId: this.data.orderid
+ }
+ )
+ } catch (e) {
+ console.error(e)
+ this.hideLoading()
+ this.showToast({
+ title: e.message
+ })
+ setTimeout(() => {
+ wx.navigateBack()
+ }, this.data.settings.shortTipDuration)
+ return
+ }
+
+ this.hideLoading()
+ if (!res.result.status) {
+ this.showToast({
+ title: res.result.message
+ })
+ } else {
+ this.showToast({
+ icon: 'success',
+ title: 'ok'
+ })
+ }
+
+ setTimeout(() => {
+ wx.navigateBack()
+ }, this.data.settings.shortTipDuration)
+ },
+ bindInputChange(e) {
+ try {
+ this.setData({
+ refund_amount: parseInt(e.detail.value)
+ })
+ } catch (e) {
+ console.error(e)
+ }
+
+ }
+})
+
+Page(PageObject)
\ No newline at end of file
diff --git a/miniprogram/pages/cancel_order/cancel_order.json b/miniprogram/pages/cancel_order/cancel_order.json
new file mode 100644
index 0000000..d66e201
--- /dev/null
+++ b/miniprogram/pages/cancel_order/cancel_order.json
@@ -0,0 +1,5 @@
+{
+ "usingComponents": {
+ "wux-dialog": "../../components/wux-weapp/dialog/index"
+ }
+}
\ No newline at end of file
diff --git a/miniprogram/pages/cancel_order/cancel_order.wxml b/miniprogram/pages/cancel_order/cancel_order.wxml
new file mode 100644
index 0000000..e3e9fc2
--- /dev/null
+++ b/miniprogram/pages/cancel_order/cancel_order.wxml
@@ -0,0 +1,11 @@
+
+
+ * 退款金额
+
+
+
+
+
+ 取消订单
+
+
\ No newline at end of file
diff --git a/miniprogram/pages/cancel_order/cancel_order.wxss b/miniprogram/pages/cancel_order/cancel_order.wxss
new file mode 100644
index 0000000..d18ce62
--- /dev/null
+++ b/miniprogram/pages/cancel_order/cancel_order.wxss
@@ -0,0 +1 @@
+@import '../base/style.wxss';
\ No newline at end of file
diff --git a/miniprogram/pages/goods/goods.js b/miniprogram/pages/goods/goods.js
new file mode 100644
index 0000000..9da3df4
--- /dev/null
+++ b/miniprogram/pages/goods/goods.js
@@ -0,0 +1,71 @@
+
+import regeneratorRuntime from '../../utils/regenerator-runtime/runtime'
+import mergePages from '../../utils/objectUtils'
+import BaseMixin from '../base/base'
+import BuycartMixin from '../base/buycart'
+import { CallCloudFuncAPI } from '../../utils/async_cloudfunc'
+
+const PageObject = mergePages({}, BaseMixin, BuycartMixin, {
+
+ data: {
+ entities: [],
+ colors: {
+ one: '#ffc0d0',
+ two: '#ffe0e0',
+ three: '#ffedff'
+ },
+ buycart: null
+ },
+
+ onInited: function (options) {
+ wx.startPullDownRefresh()
+ },
+ onPullDownRefresh: async function () {
+ await this.getGoods()
+ wx.stopPullDownRefresh()
+ },
+ async getGoods () {
+ this.showLoading()
+ let result = null
+ try {
+ result = await CallCloudFuncAPI('main', {
+ apiName: 'goodsAPI.getGoods'
+ })
+ } catch(e) {
+ console.error(e)
+ this.showToast({
+ title: e.message
+ })
+ this.hideLoading()
+ return
+ }
+
+ if (result.result.status !== true) {
+ this.showToast({
+ title: result.result.message
+ })
+ this.hideLoading()
+ return
+ }
+
+ this.setData({
+ entities: result.result.data.entities
+ })
+ this.hideLoading()
+ },
+ ontapCard(e) {
+ console.log('ontapCard')
+ },
+ onCatchTap(e) {
+ let index = e.currentTarget.dataset.index
+ this.addGoodsToCart(this.data.entities[index])
+ },
+ ontapBuycart() {
+ wx.navigateTo({
+ url: '/pages/buycart/buycart'
+ })
+ }
+})
+
+
+Page(PageObject)
\ No newline at end of file
diff --git a/miniprogram/pages/goods/goods.json b/miniprogram/pages/goods/goods.json
new file mode 100644
index 0000000..4047677
--- /dev/null
+++ b/miniprogram/pages/goods/goods.json
@@ -0,0 +1,6 @@
+{
+ "enablePullDownRefresh": true,
+ "usingComponents": {
+ "wux-dialog": "../../components/wux-weapp/dialog/index"
+ }
+}
\ No newline at end of file
diff --git a/miniprogram/pages/goods/goods.wxml b/miniprogram/pages/goods/goods.wxml
new file mode 100644
index 0000000..9825c14
--- /dev/null
+++ b/miniprogram/pages/goods/goods.wxml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+ {{item.name}}
+
+ ¥{{item.display_price}}
+ 购买
+
+
+
+
+
+
+ ¥{{buycart.display_total}}
+ {{buycart.count}}件商品
+
+
+
+
+
+
\ No newline at end of file
diff --git a/miniprogram/pages/goods/goods.wxss b/miniprogram/pages/goods/goods.wxss
new file mode 100644
index 0000000..6395960
--- /dev/null
+++ b/miniprogram/pages/goods/goods.wxss
@@ -0,0 +1,117 @@
+@import '../base/style.wxss';
+
+.container {
+ /* background-color: #e67774; */
+ position: relative;
+}
+
+.goods-wrapper {
+ box-sizing: border-box;
+ padding: 12px;
+}
+
+.goods .goods-item {
+ background-color: #f9f9f9;
+ box-sizing: border-box;
+ font-size: 12px;
+ border-radius: 20px;
+ text-align: center;
+ box-shadow: 1px 1px 10px rgba(0, 0, 0, 0.2);
+ overflow: hidden;
+ position: relative;
+ height: 220px;
+}
+
+.goods-item .goods-image image {
+ width: 100%;
+ height: 220px;
+}
+
+.goods-item .goods-meta {
+ position: absolute;
+ left: 0;
+ bottom: 0;
+ width: 100%;
+ height: 50px;
+ background-color: rgba(255, 255, 255, 0.7);
+ line-height: 50px;
+ display: flex;
+}
+
+.goods-label {
+ font-size: 160%;
+ color: #333;
+ /* font-weight: bold; */
+ flex: 1;
+ text-align: left;
+ padding-left: 20px;
+}
+
+.goods-button {
+ height: 30px;
+ line-height: 30px;
+ border-radius: 15px;
+ background-color: #fa8282;
+ margin-top: 10px;
+ margin-right: 5px;
+}
+
+.goods-button .goods-price {
+ padding-left: 10px;
+ padding-right: 5px;
+ font-size: 120%;
+}
+
+.goods-button .goods-buycart {
+ padding-right: 10px;
+}
+
+.header {
+ padding: 10px;
+ /* border-bottom: 1px solid #f9f9f9; */
+}
+
+.buycart {
+ position: fixed;
+ bottom: 20px;
+ left: 20px;
+ width: 60px;
+ height: 60px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ color: #fa8282;
+ border-radius: 30px;
+ box-sizing: border-box;
+ background-color: #fae3d9;
+ border: 3px solid #fff;
+ z-index: 20;
+}
+
+.buycart text {
+ font-size: 30px;
+}
+
+.display-total {
+ position: fixed;
+ bottom: 20px;
+ left: 50px;
+ height: 60px;
+ width: 120px;
+ border-top-right-radius: 30px;
+ border-bottom-right-radius: 30px;
+ padding-left: 15px;
+ box-sizing: border-box;
+ z-index: 10;
+ background-color: #f9f9f9;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ box-shadow: 1px 1px 10px rgba(0, 0, 0, 0.2);
+}
+
+.display-total text {
+ display: block;
+ font-size: 13px;
+}
diff --git a/miniprogram/pages/home/home.js b/miniprogram/pages/home/home.js
new file mode 100644
index 0000000..1a69707
--- /dev/null
+++ b/miniprogram/pages/home/home.js
@@ -0,0 +1,173 @@
+
+import regeneratorRuntime from '../../utils/regenerator-runtime/runtime'
+import mergePages from '../../utils/objectUtils'
+import BaseMixin from '../base/base'
+import { $wuxDialog } from '../../components/wux-weapp/index'
+import { CallCloudFuncAPI } from '../../utils/async_cloudfunc.js'
+import { asyncPayment } from '../../utils/async_tools/async_payment.js'
+
+
+const PageObject = mergePages({}, BaseMixin, {
+
+ data: {
+ entities: [],
+ images: [],
+ targetImage: null,
+ cardId: null,
+ colors: {
+ one: '#ffc0d0',
+ two: '#ffe0e0',
+ three: '#ffedff'
+ }
+ },
+
+ onInited: function (options) {
+ wx.startPullDownRefresh()
+ },
+ onPullDownRefresh: async function () {
+ await this.getCards()
+ wx.stopPullDownRefresh()
+ },
+ async getCards() {
+ this.showLoading()
+ let res = null
+ try {
+ res = await CallCloudFuncAPI('main', {
+ apiName: 'getCards'
+ })
+ } catch (e) {
+ console.error(e)
+ this.showToast({
+ title: e.message
+ })
+ this.hideLoading()
+ wx.stopPullDownRefresh()
+ return
+ }
+ this.hideLoading()
+ console.log(res)
+ if (!res.result.status) {
+ this.showToast({
+ title: res.result.message
+ })
+ } else {
+ this.setData({
+ entities: res.result.data.entities,
+ images: res.result.data.images,
+
+ })
+ if(this.data.images && this.data.images.length !== 0 ) {
+ this.setData({
+ targetImage: this.data.images[0].url
+ })
+ console.log(this.data.targetImage)
+ }
+ }
+ wx.stopPullDownRefresh()
+ },
+ ontapCard(e) {
+ let that = this
+ let card = e.currentTarget.dataset.card
+ $wuxDialog().confirm({
+ resetOnClose: true,
+ title: `您正在购买充值卡,支付${card.value}元实际得到${card.real_value}元`,
+ content: '确定是否提交订单',
+ onConfirm: (e, response) => {
+ that.setData({
+ cardId: card._id
+ })
+ if (that.data.cardId) {
+ that.submitDepositOrder()
+ }
+ }
+ })
+ },
+ submitDepositOrder() {
+ let that = this
+ console.log('card:', that.data.cardId)
+ wx.cloud.callFunction({
+ name: 'main',
+ data: {
+ apiName: 'depositAPI.deposit',
+ cardId: that.data.cardId
+ },
+ success: res => {
+ console.log(res)
+ if (!res.result.status) {
+ this.showToast({
+ title: res.result.message
+ })
+ return
+ } else {
+ this.startPayment(res.result.data.orderNo, res.result.data.payData)
+ }
+
+ },
+ fail: err => {
+ console.error('[云函数] [login] 调用失败', err)
+ }
+ })
+ },
+ async startPayment(orderNo, payargs) {
+ let result = null
+ try {
+ result = await asyncPayment(payargs)
+ } catch(e) {
+ console.error(e)
+ if (e && e.errMsg == 'requestPayment:fail cancel') {
+ return
+ } else {
+ this.showToast({
+ title: e
+ })
+ }
+ }
+ console.log(result)
+ if (result && result.errMsg && result.errMsg == 'requestPayment:ok') {
+ // TODO: 查询支付结果
+ this.depositSuccess(orderNo)
+ }
+
+
+ },
+ async depositSuccess(orderNo) {
+ this.showLoading()
+ let result = null
+ try {
+ result = await CallCloudFuncAPI('main', {
+ apiName: 'depositAPI.depositSuccess',
+ orderNo: orderNo
+ })
+ } catch (e) {
+ console.error(e)
+ this.showToast({
+ title: e.message
+ })
+ this.hideLoading()
+ return
+ }
+
+
+ this.hideLoading()
+ if (result.result.status !== true) {
+ this.showToast({
+ title: result.result.message
+ })
+ return
+ }
+
+ $wuxDialog().alert({
+ resetOnClose: true,
+ content: '充值成功',
+ onConfirm: (e, response) => {
+ wx.navigateTo({
+ url: '/pages/orders/orders',
+ })
+ }
+ })
+
+ },
+})
+
+
+Page(PageObject)
\ No newline at end of file
diff --git a/miniprogram/pages/home/home.json b/miniprogram/pages/home/home.json
new file mode 100644
index 0000000..4047677
--- /dev/null
+++ b/miniprogram/pages/home/home.json
@@ -0,0 +1,6 @@
+{
+ "enablePullDownRefresh": true,
+ "usingComponents": {
+ "wux-dialog": "../../components/wux-weapp/dialog/index"
+ }
+}
\ No newline at end of file
diff --git a/miniprogram/pages/home/home.wxml b/miniprogram/pages/home/home.wxml
new file mode 100644
index 0000000..d0c3f36
--- /dev/null
+++ b/miniprogram/pages/home/home.wxml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+ {{item.name}}
+ 买{{item.value}}元得{{item.real_value}}元
+
+
+
+
+
\ No newline at end of file
diff --git a/miniprogram/pages/home/home.wxss b/miniprogram/pages/home/home.wxss
new file mode 100644
index 0000000..71305aa
--- /dev/null
+++ b/miniprogram/pages/home/home.wxss
@@ -0,0 +1,83 @@
+@import '../base/style.wxss';
+
+.cards {
+ padding: 20px;
+ box-sizing: border-box;
+}
+.card-note {
+ font-size: 120%;
+ color: #333;
+}
+
+.card-label {
+ font-size: 120%;
+ color: #fff;
+ font-weight: bold;
+}
+
+.header {
+ padding: 10px;
+ border-bottom: 1px solid #f9f9f9;
+}
+
+.grid {
+ width: 100%;
+ display: grid;
+ grid-gap: 20px 20px;
+ grid-template-rows: repeat(6, 1fr);
+ grid-template-columns: repeat(6, 1fr);
+ grid-template-areas: "a a a a b b" "a a a a c c" "f f f f c c" "d d e e c c" "g g g g g g" "g g g g g g";
+}
+
+.grid .item, .card-free {
+ min-height: 60px;
+ border-radius: 20px;
+ box-shadow: 1px 1px 10px rgba(0, 0, 0, 0.1);
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ text-align: center;
+}
+
+.grid .item-a {
+ grid-area: a;
+ background: skyblue;
+ flex-direction: column;
+}
+
+.grid .item-b {
+ grid-area: b;
+ background: mediumaquamarine;
+}
+
+.grid .item-c {
+ grid-area: c;
+ background: wheat;
+}
+
+.grid .item-d {
+ grid-area: d;
+ background: lightcoral;
+}
+
+.grid .item-e {
+ grid-area: e;
+ background: plum;
+}
+
+.grid .item-f {
+ grid-area: f;
+ background: pink;
+}
+
+.grid .item-g {
+ grid-area: g;
+ background-color: lavender;
+}
+
+
+.grid .item-a .card-note {
+ color: #fff;
+ font-size: 100%;
+}
+
diff --git a/miniprogram/pages/index/index.js b/miniprogram/pages/index/index.js
new file mode 100644
index 0000000..7165230
--- /dev/null
+++ b/miniprogram/pages/index/index.js
@@ -0,0 +1,132 @@
+import mergePages from '../../utils/objectUtils'
+import BaseMixin from '../base/base'
+const app = getApp()
+
+
+const PageObject = mergePages({}, BaseMixin, {
+ data: {
+ avatarUrl: './user-unlogin.png',
+ userInfo: {},
+ logged: false,
+ takeSession: false,
+ requestResult: '',
+ nextpage: null
+ },
+
+ onInited: function(options) {
+ // 获取用户信息
+ this.showLoading()
+ wx.getSetting({
+ success: res => {
+ if (res.authSetting['scope.userInfo']) {
+ // 已经授权,可以直接调用 getUserInfo 获取头像昵称,不会弹框
+ wx.getUserInfo({
+ success: res => {
+ this.setData({
+ avatarUrl: res.userInfo.avatarUrl,
+ userInfo: res.userInfo
+ })
+ }
+ })
+ }
+ },
+ complete: () => {
+ this.hideLoading()
+ }
+ })
+ },
+
+ onGetUserInfo: function(e) {
+ console.log(e)
+ let that = this
+ this.showLoading()
+ wx.cloud.callFunction({
+ name: 'main',
+ data: {
+ apiName: 'loginAPI.login',
+ userinfo: e.detail.userInfo
+ },
+ success: res => {
+ console.log('onlogin')
+ console.log(res)
+ if (res.result.status) {
+ app.globalData.openid = res.result.data.openid
+ if (res.result.data.registed) {
+ wx.setStorageSync('sessionid', res.result.data.openid)
+ }
+
+ if (res.result.status) {
+ that.goToURL(res.result.data.nextpage)
+ }
+ } else if (res.result.status === false && res.result.message == 'user_not_found') {
+ wx.navigateTo({
+ url: '/pages/regist/regist'
+ })
+ }
+
+ },
+ fail: err => {
+ console.error('[云函数] [login] 调用失败', err)
+ },
+ complete: () => {
+ console.log(this)
+ this.hideLoading()
+ }
+ })
+ },
+
+
+ // 上传图片
+ doUpload: function() {
+ // 选择图片
+ wx.chooseImage({
+ count: 1,
+ sizeType: ['compressed'],
+ sourceType: ['album', 'camera'],
+ success: function(res) {
+
+ wx.showLoading({
+ title: '上传中',
+ })
+
+ const filePath = res.tempFilePaths[0]
+
+ // 上传图片
+ const cloudPath = 'my-image' + filePath.match(/\.[^.]+?$/)[0]
+ wx.cloud.uploadFile({
+ cloudPath,
+ filePath,
+ success: res => {
+ console.log('[上传文件] 成功:', res)
+
+ app.globalData.fileID = res.fileID
+ app.globalData.cloudPath = cloudPath
+ app.globalData.imagePath = filePath
+
+ wx.navigateTo({
+ url: '../storageConsole/storageConsole'
+ })
+ },
+ fail: e => {
+ console.error('[上传文件] 失败:', e)
+ wx.showToast({
+ icon: 'none',
+ title: '上传失败',
+ })
+ },
+ complete: () => {
+ wx.hideLoading()
+ }
+ })
+
+ },
+ fail: e => {
+ console.error(e)
+ }
+ })
+ },
+
+})
+
+
+Page(PageObject)
\ No newline at end of file
diff --git a/miniprogram/pages/index/index.json b/miniprogram/pages/index/index.json
new file mode 100644
index 0000000..d66e201
--- /dev/null
+++ b/miniprogram/pages/index/index.json
@@ -0,0 +1,5 @@
+{
+ "usingComponents": {
+ "wux-dialog": "../../components/wux-weapp/dialog/index"
+ }
+}
\ No newline at end of file
diff --git a/miniprogram/pages/index/index.wxml b/miniprogram/pages/index/index.wxml
new file mode 100644
index 0000000..cc2829c
--- /dev/null
+++ b/miniprogram/pages/index/index.wxml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/miniprogram/pages/index/index.wxss b/miniprogram/pages/index/index.wxss
new file mode 100644
index 0000000..5476991
--- /dev/null
+++ b/miniprogram/pages/index/index.wxss
@@ -0,0 +1,148 @@
+
+
+page {
+ display: flex;
+ flex-direction: column;
+ justify-content: flex-start;
+ background-color: #e67774;
+}
+
+.userinfo, .uploader, .tunnel {
+ margin-top: 40rpx;
+ height: 140rpx;
+ width: 100%;
+ background: #fff;
+ border: 1px solid rgba(0, 0, 0, 0.1);
+ border-left: none;
+ border-right: none;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ transition: all 300ms ease;
+}
+
+.userinfo-avatar {
+ width: 140rpx;
+ height: 140rpx;
+ border-radius: 50%;
+ background-size: cover;
+ background-color: white;
+ margin-top: 100px;
+ border: 3px solid #fff;
+ box-sizing: border-box;
+}
+
+.userinfo-avatar:after {
+ border: none;
+}
+
+.userinfo-nickname {
+ font-size: 32rpx;
+ color: white;
+ background-color: #7dd3da;
+ background-size: cover;
+ height: 40px;
+ line-height: 40px;
+ width: 120px;
+ border-radius: 20px;
+ position: absolute;
+ bottom: 100px;
+ left: 50%;
+ margin-left: -60px;
+ box-shadow: 1px 1px 10px rgba(0, 0, 0, 0.3);
+}
+
+.userinfo-nickname::after {
+ border: none;
+}
+
+.uploader, .tunnel {
+ height: auto;
+ padding: 0 0 0 40rpx;
+ flex-direction: column;
+ align-items: flex-start;
+ box-sizing: border-box;
+}
+
+.uploader-text, .tunnel-text {
+ width: 100%;
+ line-height: 52px;
+ font-size: 34rpx;
+ color: #7dd3da;
+}
+
+.uploader-container {
+ width: 100%;
+ height: 400rpx;
+ padding: 20rpx 20rpx 20rpx 0;
+ display: flex;
+ align-content: center;
+ justify-content: center;
+ box-sizing: border-box;
+ border-top: 1px solid rgba(0, 0, 0, 0.1);
+}
+
+.uploader-image {
+ width: 100%;
+ height: 360rpx;
+}
+
+.tunnel {
+ padding: 0 0 0 40rpx;
+}
+
+.tunnel-text {
+ position: relative;
+ color: #222;
+ display: flex;
+ flex-direction: row;
+ align-content: center;
+ justify-content: space-between;
+ box-sizing: border-box;
+ border-top: 1px solid rgba(0, 0, 0, 0.1);
+}
+
+.tunnel-text:first-child {
+ border-top: none;
+}
+
+.tunnel-switch {
+ position: absolute;
+ right: 20rpx;
+ top: -2rpx;
+}
+
+.disable {
+ color: #888;
+}
+
+.service {
+ position: fixed;
+ right: 40rpx;
+ bottom: 40rpx;
+ width: 140rpx;
+ height: 140rpx;
+ border-radius: 50%;
+ background: linear-gradient(#007aff, #0063ce);
+ box-shadow: 0 5px 10px rgba(0, 0, 0, 0.3);
+ display: flex;
+ align-content: center;
+ justify-content: center;
+ transition: all 300ms ease;
+}
+
+.service-button {
+ position: absolute;
+ top: 40rpx;
+}
+
+.service:active {
+ box-shadow: none;
+}
+
+.request-text {
+ padding: 20rpx 0;
+ font-size: 24rpx;
+ line-height: 36rpx;
+ word-break: break-all;
+}
diff --git a/miniprogram/pages/index/user-unlogin.png b/miniprogram/pages/index/user-unlogin.png
new file mode 100644
index 0000000..95b27e4
Binary files /dev/null and b/miniprogram/pages/index/user-unlogin.png differ
diff --git a/miniprogram/pages/me/me.js b/miniprogram/pages/me/me.js
new file mode 100644
index 0000000..9dcd73a
--- /dev/null
+++ b/miniprogram/pages/me/me.js
@@ -0,0 +1,228 @@
+
+import regeneratorRuntime from '../../utils/regenerator-runtime/runtime'
+import BaseMixin from '../base/base'
+import mergePages from '../../utils/objectUtils'
+const moment = require('../../utils/moment.min.js')
+import { CallCloudFuncAPI } from '../../utils/async_cloudfunc.js'
+import { $wuxDialog } from '../../components/wux-weapp/index'
+
+
+const PageObject = mergePages({}, BaseMixin, {
+ data: {
+ sessionid: '',
+ action: '',
+ imagePath: null,
+ userInfo: null,
+ admin: null,
+ myList: [
+ {
+ key: 'userinfo',
+ isLink: true,
+ title: '个人资料',
+ value: '',
+ color: '#666',
+ iconColor: '#F56C6C',
+ titleColor: '#999',
+ // icon: 'ios-contact',
+ url: "/pages/profile/profile"
+ },
+ {
+ key: 'balance',
+ isLink: true,
+ title: '查询余额',
+ value: '',
+ color: '#666',
+ iconColor: '#F56C6C',
+ titleColor: '#999',
+ // icon: 'ios-contact'
+ },
+ {
+ key: 'orders',
+ isLink: true,
+ title: '我的订单',
+ value: '',
+ color: '#666',
+ iconColor: '#F56C6C',
+ titleColor: '#999',
+ // icon: 'ios-list-box',
+ url: "/pages/orders/orders"
+ },
+ {
+ key: 'logout',
+ isLink: true,
+ title: '退出登录',
+ value: '',
+ color: '#666',
+ iconColor: '#F56C6C',
+ titleColor: '#999',
+ // icon: 'ios-log-out'
+ }
+ ],
+ staffList: [
+ {
+ key: 'users',
+ isLink: true,
+ title: '客户',
+ value: '',
+ color: '#07C160',
+ iconColor: '#07C160',
+ titleColor: '#07C160',
+ // icon: 'ios-log-out'
+ url: "/pages/users/users"
+ },
+ {
+ key: 'all_orders',
+ isLink: true,
+ title: '订单',
+ value: '',
+ color: '#07C160',
+ iconColor: '#07C160',
+ titleColor: '#07C160',
+ // icon: 'ios-log-out'
+ url: "/pages/all_orders/all_orders"
+ },
+ {
+ key: 'admin_message',
+ isLink: true,
+ title: '消息推送',
+ value: '',
+ color: '#07C160',
+ iconColor: '#07C160',
+ titleColor: '#07C160',
+ // icon: 'ios-log-out'
+ url: "/pages/admin_message/admin_message"
+ }
+ ]
+ },
+ onPullDownRefresh: function () {
+ this.getProfile()
+ },
+ getHeaderCanvas: function () {
+ var ctx = wx.createCanvasContext('canvas')
+ // Draw quadratic curve
+ ctx.beginPath()
+ ctx.moveTo(0, 60)
+ ctx.bezierCurveTo(20, 100, 200, 80, this.data.systemInfo.windowWidth, -30)
+ ctx.lineTo(this.data.systemInfo.windowWidth, 0)
+ ctx.lineTo(0, 0)
+ ctx.lineTo(0, 60)
+ ctx.setFillStyle('#fde2e2')
+ ctx.fill()
+
+ ctx.beginPath()
+ ctx.moveTo(0, 45)
+ ctx.bezierCurveTo(20, 100, 200, 90, this.data.systemInfo.windowWidth, -50)
+ ctx.lineTo(this.data.systemInfo.windowWidth, 0)
+ ctx.lineTo(0, 0)
+ ctx.lineTo(0, 45)
+ ctx.setFillStyle('#f56c6c')
+ ctx.fill()
+
+ ctx.beginPath()
+ ctx.moveTo(0, 30)
+ ctx.bezierCurveTo(20, 60, 160, 130, this.data.systemInfo.windowWidth, -60)
+ ctx.lineTo(this.data.systemInfo.windowWidth, 0)
+ ctx.lineTo(0, 0)
+ ctx.lineTo(0, 30)
+ ctx.setFillStyle(this.data.settings.Theme.redColor)
+ ctx.fill()
+
+ ctx.draw(false, () => {
+ this.canvasToTempImage();
+ })
+ },
+
+ canvasToTempImage: function () {
+ wx.canvasToTempFilePath({
+ canvasId: "canvas",
+ success: (res) => {
+ let tempFilePath = res.tempFilePath;
+ this.setData({
+ imagePath: tempFilePath,
+ });
+ }
+ }, this);
+ },
+ onInited: function (options) {
+ this.getHeaderCanvas()
+ wx.startPullDownRefresh()
+ },
+ onTapListItem: async function (e) {
+ console.log('onTapListItem:', e)
+ let index = e.detail.index;
+ let item = this.data.myList[index]
+ if (item.key == 'logout') {
+ this.showDialog({
+ title: '',
+ content: '确定是否退出登录',
+ onConfirm: (e) => {
+ this.logout()
+ },
+ onCancel(e) {
+
+ },
+ }, true)
+ } else if (item.key == 'balance') {
+ await this.getProfile()
+ let balance = this.data.userInfo.balance ? this.data.userInfo.balance : 0
+ $wuxDialog().alert({
+ title: '您当前的余额为',
+ content: `${balance}元`
+ })
+ }
+
+ },
+ onTapStaffListItem: async function (e) {
+ console.log('onTapListItem:', e)
+ let index = e.detail.index;
+ let item = this.data.staffList[index]
+ },
+ onGotUserInfo: function (res) {
+ wx.login({
+ success: res => {
+ // 发送 res.code 到后台换取 openId, sessionKey, unionId
+ console.log(res)
+ this.getRegistKey(res.code)
+ },
+ fail: () => {
+ }
+ })
+
+ },
+ logout: function (res) {
+ wx.clearStorageSync()
+ },
+ async getProfile() {
+ this.showLoading()
+ let that = this
+ let res = null
+ try {
+ res = await CallCloudFuncAPI(
+ "main",
+ {
+ apiName: "getProfile"
+ }
+ )
+ } catch (e) {
+ this.hideLoading()
+ console.error(e)
+ return
+ }
+
+
+ if (res) {
+ this.setData({
+ userInfo: res.result.data.user
+ })
+
+ if(res.result.data.admin && res.result.data.admin.id) {
+ this.setData({admin: res.result.data.admin})
+ wx.setStorageSync('admin', res.result.data.admin)
+ }
+ }
+ this.hideLoading()
+ wx.stopPullDownRefresh()
+ }
+})
+
+Page(PageObject)
\ No newline at end of file
diff --git a/miniprogram/pages/me/me.json b/miniprogram/pages/me/me.json
new file mode 100644
index 0000000..f947073
--- /dev/null
+++ b/miniprogram/pages/me/me.json
@@ -0,0 +1,8 @@
+{
+ "enablePullDownRefresh": true,
+ "usingComponents": {
+ "myList": "../../components/list/list",
+ "avatar": "../../components/avatar/avatar",
+ "wux-dialog": "../../components/wux-weapp/dialog/index"
+ }
+}
\ No newline at end of file
diff --git a/miniprogram/pages/me/me.wxml b/miniprogram/pages/me/me.wxml
new file mode 100644
index 0000000..88864d1
--- /dev/null
+++ b/miniprogram/pages/me/me.wxml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/miniprogram/pages/me/me.wxss b/miniprogram/pages/me/me.wxss
new file mode 100644
index 0000000..a5263aa
--- /dev/null
+++ b/miniprogram/pages/me/me.wxss
@@ -0,0 +1,118 @@
+@import '../base/style.wxss';
+
+page {
+ background-color: #fff;
+}
+
+.container {
+ background-color: #fff;
+}
+
+.header {
+ padding: 40rpx;
+ /* background-color: #d9262f; */
+ position: relative;
+ height: 120rpx;
+ box-sizing: border-box;
+ /* border: solid 5px #000; */
+ /* border-color: transparent transparent #000 transparent;
+ border-radius: 0 0 1000rpx 90%/120rpx; */
+ width: 100%;
+ background-color: #E67774
+}
+
+.lucky-index-img {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 150px;
+ z-index: 1;
+}
+
+.lucky-index-round {
+ position: fixed;
+ top: 9999rpx;
+ left: 0;
+ /* position: absolute;
+ left: 0;
+ top: 0;
+ width: 100%; */
+}
+
+.avatarWrap {
+ position: absolute;
+ left: 30px;
+ z-index: 2;
+}
+
+.userinfo {
+ position: absolute;
+ font-size: 13px;
+ color: #880e4f;
+ background-color: #fef1e6;
+ text-align: center;
+ max-width: 100px;
+ height: 30px;
+ line-height: 30px;
+ border-radius: 4px;
+ box-shadow: rgba(0, 0, 0, 0.2) 2rpx 2rpx 4rpx 2rpx;
+ right: 30px;
+ top: 35px;
+ padding-left: 10px;
+ padding-right: 10px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ z-index: 2;
+}
+
+.username {
+ position: absolute;
+ font-size: 15px;
+ color: #333;
+ font-weight: bold;
+ top: 30px;
+ left: 100px;
+ max-width: 180px;
+ z-index: 2;
+}
+
+.nickname open-data {
+ font-size: 36rpx;
+ color: #333;
+ font-weight: bold;
+}
+.nickname {
+ color: #fff;
+}
+.nickname {
+ display: flex;
+ justify-content: flex-start;
+ align-items: center;
+}
+
+.nickname wux-icon {
+ margin-left: 24rpx;
+}
+
+.body {
+ margin-top: 100rpx;
+}
+
+.round-button {
+ position: relative !important;
+ width: 100%;
+ right: 0;
+ bottom: 0;
+}
+
+.menuTitle {
+ margin-top: 30px;
+ text-align: center;
+ border-bottom: 1px solid #eee;
+ padding-bottom: 15px;
+ margin-left: 20px;
+ margin-right: 20px;
+ color: #666;
+}
diff --git a/miniprogram/pages/name_form/name_form.js b/miniprogram/pages/name_form/name_form.js
new file mode 100644
index 0000000..36b6c40
--- /dev/null
+++ b/miniprogram/pages/name_form/name_form.js
@@ -0,0 +1,104 @@
+
+import regeneratorRuntime from '../../utils/regenerator-runtime/runtime'
+import BaseMixin from '../base/base'
+import mergePages from '../../utils/objectUtils'
+const moment = require('../../utils/moment.min.js')
+import { CallCloudFuncAPI } from '../../utils/async_cloudfunc.js'
+import { $wuxDialog } from '../../components/wux-weapp/index'
+
+
+const PageObject = mergePages({}, BaseMixin, {
+ data: {
+ userInfo: null
+ },
+ onInited(options) {
+ this.getProfile()
+ },
+ async getProfile() {
+ this.showLoading()
+ let res = null
+ try {
+ res = await CallCloudFuncAPI(
+ "main",
+ {
+ apiName: "getProfile"
+ }
+ )
+ } catch (e) {
+ console.error(e)
+ this.hideLoading()
+ setTimeout(() => {
+ wx.navigateBack()
+ }, this.data.settings.shortTipDuration)
+ return
+ }
+
+
+ this.hideLoading()
+ if (!res.result.status) {
+ this.showToast({
+ title: res.result.message
+ })
+ setTimeout(() => {
+ wx.navigateBack()
+ }, this.data.settings.shortTipDuration)
+ return
+ }
+
+ this.setData({
+ userInfo: res.result.data.user
+ })
+ },
+ async submitForm() {
+ this.showLoading()
+ let res = null
+ try {
+ res = await CallCloudFuncAPI(
+ "main",
+ {
+ apiName: "userAPI.updateUserName",
+ nickName: this.data.userInfo.nickName,
+ realName: this.data.userInfo.realName
+ }
+ )
+ } catch (e) {
+ console.error(e)
+ this.hideLoading()
+ this.showToast({
+ title: e.message
+ })
+ setTimeout(() => {
+ wx.navigateBack()
+ }, this.data.settings.shortTipDuration)
+ return
+ }
+
+ this.hideLoading()
+ if (!res.result.status) {
+ this.showToast({
+ title: res.result.message
+ })
+ } else {
+ this.showToast({
+ icon: 'success',
+ title: 'ok'
+ })
+ }
+
+ setTimeout(() => {
+ wx.navigateBack()
+ }, this.data.settings.shortTipDuration)
+ },
+ bindInputRealName(e) {
+ this.setData({
+ 'userInfo.realName': e.detail.value
+ })
+ },
+ bindInputNickName(e) {
+ this.setData({
+ 'userInfo.nickName': e.detail.value
+ })
+ }
+})
+
+Page(PageObject)
\ No newline at end of file
diff --git a/miniprogram/pages/name_form/name_form.json b/miniprogram/pages/name_form/name_form.json
new file mode 100644
index 0000000..d66e201
--- /dev/null
+++ b/miniprogram/pages/name_form/name_form.json
@@ -0,0 +1,5 @@
+{
+ "usingComponents": {
+ "wux-dialog": "../../components/wux-weapp/dialog/index"
+ }
+}
\ No newline at end of file
diff --git a/miniprogram/pages/name_form/name_form.wxml b/miniprogram/pages/name_form/name_form.wxml
new file mode 100644
index 0000000..e492fa3
--- /dev/null
+++ b/miniprogram/pages/name_form/name_form.wxml
@@ -0,0 +1,17 @@
+
+
+ * 姓名
+
+
+
+
+
+ * 昵称
+
+
+
+
+
+ 提交
+
+
\ No newline at end of file
diff --git a/miniprogram/pages/name_form/name_form.wxss b/miniprogram/pages/name_form/name_form.wxss
new file mode 100644
index 0000000..d18ce62
--- /dev/null
+++ b/miniprogram/pages/name_form/name_form.wxss
@@ -0,0 +1 @@
+@import '../base/style.wxss';
\ No newline at end of file
diff --git a/miniprogram/pages/order_details/order_details.js b/miniprogram/pages/order_details/order_details.js
new file mode 100644
index 0000000..98bfcf6
--- /dev/null
+++ b/miniprogram/pages/order_details/order_details.js
@@ -0,0 +1,87 @@
+
+import regeneratorRuntime from '../../utils/regenerator-runtime/runtime'
+import BaseMixin from '../base/base'
+import PulldownMixin from '../base/pulldown_mixin'
+import mergePages from '../../utils/objectUtils'
+const moment = require('../../utils/moment.min.js')
+import { CallCloudFuncAPI } from '../../utils/async_cloudfunc.js'
+import { $wuxDialog } from '../../components/wux-weapp/index'
+import { StatusLabel } from '../../utils/constant'
+
+
+const PageObject = mergePages({}, BaseMixin, PulldownMixin, {
+
+ data: {
+ reqData: {
+ page: 1,
+ pagesize: 10
+ },
+ entityIdField: '_id',
+ apiName: "orderAPI.getOrders",
+ isCloudFunc: true,
+ statuses: StatusLabel,
+ itemFlags: {
+ pay: '-',
+ deposit: '+'
+ }
+ },
+ onInited() {
+ wx.startPullDownRefresh()
+ },
+ getEntitiesApiUrl() {
+ return "main"
+ },
+ async getOrders() {
+ let res = null
+ try {
+ res = await CallCloudFuncAPI(
+ "main",
+ {
+ apiName: "orderAPI.getOrders"
+ }
+ )
+ } catch (e) {
+ console.error(e)
+ wx.stopPullDownRefresh()
+ return
+ }
+
+ if (res) {
+ console.log(res)
+ this.setData({
+ entities: res.result.data.entities
+ })
+ }
+ wx.stopPullDownRefresh()
+ },
+ formatEntities(data) {
+ console.log(data)
+ for (let entity of data.entities) {
+ entity.create_at = moment(entity.create_at).format('YYYY/MM/DD HH:mm')
+ if (entity.type == 'deposit') {
+ entity.title = '购买充值卡'
+ } else if (entity.type == 'pay') {
+ entity.title = this.getGoodsName(entity.orderInfo)
+ }
+ }
+ return data
+ },
+ getGoodsName(orderInfo) {
+ let goodsName = '';
+ orderInfo.entities.map((item, index) => {
+ if (index === 0) {
+ goodsName += item.name
+ } else if (index > 0 && index < 3) {
+ goodsName += '、' + item.name
+ } else if (index == 3) {
+ if (orderInfo.entities.length > 3) {
+ goodsName += '等'
+ }
+ }
+ })
+ return goodsName
+ }
+
+})
+
+Page(PageObject)
\ No newline at end of file
diff --git a/miniprogram/pages/order_details/order_details.json b/miniprogram/pages/order_details/order_details.json
new file mode 100644
index 0000000..69b19d4
--- /dev/null
+++ b/miniprogram/pages/order_details/order_details.json
@@ -0,0 +1,4 @@
+{
+ "enablePullDownRefresh": true,
+ "usingComponents": {}
+}
\ No newline at end of file
diff --git a/miniprogram/pages/order_details/order_details.wxml b/miniprogram/pages/order_details/order_details.wxml
new file mode 100644
index 0000000..c46862e
--- /dev/null
+++ b/miniprogram/pages/order_details/order_details.wxml
@@ -0,0 +1,2 @@
+
+miniprogram/pages/order_details/order_details.wxml
diff --git a/miniprogram/pages/order_details/order_details.wxss b/miniprogram/pages/order_details/order_details.wxss
new file mode 100644
index 0000000..8be7ae4
--- /dev/null
+++ b/miniprogram/pages/order_details/order_details.wxss
@@ -0,0 +1 @@
+/* miniprogram/pages/order_details/order_details.wxss */
\ No newline at end of file
diff --git a/miniprogram/pages/orders/orders.js b/miniprogram/pages/orders/orders.js
new file mode 100644
index 0000000..fe22ab9
--- /dev/null
+++ b/miniprogram/pages/orders/orders.js
@@ -0,0 +1,55 @@
+
+import regeneratorRuntime from '../../utils/regenerator-runtime/runtime'
+import BaseMixin from '../base/base'
+import PulldownMixin from '../base/pulldown_mixin'
+import OrdersMixin from '../base/orders_mixin'
+import mergePages from '../../utils/objectUtils'
+import { CallCloudFuncAPI } from '../../utils/async_cloudfunc.js'
+
+const PageObject = mergePages({}, BaseMixin, PulldownMixin, OrdersMixin, {
+
+ data: {
+ reqData: {
+ page: 1,
+ pagesize: 10
+ },
+ entityIdField: '_id',
+ apiName: "orderAPI.getOrders",
+ isCloudFunc: true,
+ itemFlags: {
+ pay: '-',
+ deposit: '+'
+ }
+ },
+ onInited() {
+ wx.startPullDownRefresh()
+ },
+ getEntitiesApiUrl() {
+ return "main"
+ },
+ async getOrders() {
+ let res = null
+ try {
+ res = await CallCloudFuncAPI(
+ "main",
+ {
+ apiName: "orderAPI.getOrders"
+ }
+ )
+ } catch (e) {
+ console.error(e)
+ wx.stopPullDownRefresh()
+ return
+ }
+
+ if (res) {
+ console.log(res)
+ this.setData({
+ entities: res.result.data.entities
+ })
+ }
+ wx.stopPullDownRefresh()
+ }
+})
+
+Page(PageObject)
\ No newline at end of file
diff --git a/miniprogram/pages/orders/orders.json b/miniprogram/pages/orders/orders.json
new file mode 100644
index 0000000..69b19d4
--- /dev/null
+++ b/miniprogram/pages/orders/orders.json
@@ -0,0 +1,4 @@
+{
+ "enablePullDownRefresh": true,
+ "usingComponents": {}
+}
\ No newline at end of file
diff --git a/miniprogram/pages/orders/orders.wxml b/miniprogram/pages/orders/orders.wxml
new file mode 100644
index 0000000..e7eeb08
--- /dev/null
+++ b/miniprogram/pages/orders/orders.wxml
@@ -0,0 +1,40 @@
+
+
+
+ 设置
+
+
+
+
+
+ {{item.title}}
+ {{item.orderNo}}
+ {{statuses[item.status].name}} {{deliveryStatus[item.delivery_status] ? deliveryStatus[item.delivery_status].name:''}} {{item.is_cancel?'已取消':''}}
+ {{item.create_at}}
+
+
+
+ {{entity.name}}
+ {{entity.price}} x {{entity.count}}
+
+
+
+
+ 收货地址:
+ {{item.addressInfo.provinceName}} {{item.addressInfo.cityName}} {{item.addressInfo.countyName}} {{item.addressInfo.detailInfo}}
+ 电话:{{item.addressInfo.telNumber}}
+ 邮编:{{item.addressInfo.postalCode}}
+
+
+ 快递公司:{{item.deliveryInfo.company_name||'本店御用快递小哥'}}
+ 订单编号:{{item.deliveryInfo.orderno}}
+ 送达时间:{{item.deliveryInfo.will_received_date}} {{item.deliveryInfo.will_received_time}}
+
+
+
+
+
+ {{itemFlags[item.type]}} {{item.orderInfo.total}}
+
+
+
\ No newline at end of file
diff --git a/miniprogram/pages/orders/orders.wxss b/miniprogram/pages/orders/orders.wxss
new file mode 100644
index 0000000..8479f8a
--- /dev/null
+++ b/miniprogram/pages/orders/orders.wxss
@@ -0,0 +1,2 @@
+@import '../base/style.wxss';
+@import '../user_orders/user_orders.wxss';
diff --git a/miniprogram/pages/profile/profile.js b/miniprogram/pages/profile/profile.js
new file mode 100644
index 0000000..61ef798
--- /dev/null
+++ b/miniprogram/pages/profile/profile.js
@@ -0,0 +1,149 @@
+
+import regeneratorRuntime from '../../utils/regenerator-runtime/runtime'
+import BaseMixin from '../base/base'
+import mergePages from '../../utils/objectUtils'
+const moment = require('../../utils/moment.min.js')
+import { CallCloudFuncAPI } from '../../utils/async_cloudfunc.js'
+import { $wuxDialog } from '../../components/wux-weapp/index'
+
+const genderTypes = [
+ {
+ label: '男',
+ value: '0'
+ },
+ {
+ label: '女',
+ value: '1'
+ },
+]
+
+
+const PageObject = mergePages({}, BaseMixin, {
+ data: {
+ userInfo: null,
+ genderTypes: genderTypes,
+ genderName: '',
+ birthEndDay: null
+ },
+ onInited(options) {
+ this.setData({
+ birthEndDay: moment().format('YYYY-MM-DD')
+ })
+ wx.startPullDownRefresh()
+ },
+ async getProfile() {
+ this.showLoading()
+ let res = null
+ try {
+ res = await CallCloudFuncAPI(
+ "main",
+ {
+ apiName: "getProfile"
+ }
+ )
+ } catch (e) {
+ console.error(e)
+ this.hideLoading()
+ this.showToast({
+ title: e.message
+ })
+ setTimeout(() => {
+ wx.navigateBack()
+ }, this.data.settings.shortTipDuration)
+
+ }
+
+ if (!res.result.status) {
+ this.showToast({
+ title: res.result.message
+ })
+ this.hideLoading()
+ wx.stopPullDownRefresh()
+ return
+ }
+
+ this.setData({
+ userInfo: res.result.data.user,
+ genderName: genderTypes[parseInt(res.result.data.user.gender)].label
+ })
+
+ wx.hideLoading()
+ wx.stopPullDownRefresh()
+ },
+ async bindGenderChange(e) {
+ this.showLoading()
+ this.setData({
+ 'userInfo.gender': this.data.genderTypes[e.detail.value].value,
+ genderName: this.data.genderTypes[e.detail.value].label
+ })
+ let res = null
+ try {
+ res = await CallCloudFuncAPI(
+ "main",
+ {
+ apiName: "userAPI.updateGender",
+ gender: this.data.userInfo.gender
+ }
+ )
+ } catch (e) {
+ this.hideLoading()
+ this.showToast({
+ title: e.message
+ })
+ console.error(e)
+ return
+ }
+
+ if (res.result.status) {
+ console.log(res)
+ this.hideLoading()
+ this.showToast({
+ icon: 'success',
+ title: 'ok'
+ })
+ setTimeout(() => {
+ wx.navigateBack()
+ }, this.data.settings.shortTipDuration)
+
+ }
+ },
+ async bindDateChange(e) {
+ console.log(e)
+ this.showLoading()
+ let res = null
+ try {
+ res = await CallCloudFuncAPI(
+ "main",
+ {
+ apiName: "userAPI.updateBirthday",
+ birthday: e.detail.value
+ }
+ )
+ } catch (e) {
+ this.hideLoading()
+ this.showToast({
+ title: e.message
+ })
+ console.error(e)
+ return
+ }
+
+ if (res.result.status) {
+ console.log(res)
+ this.hideLoading()
+ this.showToast({
+ icon: 'success',
+ title: 'ok'
+ })
+ setTimeout(() => {
+ wx.navigateBack()
+ }, this.data.settings.shortTipDuration)
+
+ }
+ },
+ onPullDownRefresh: function () {
+ this.getProfile()
+ },
+})
+
+Page(PageObject)
\ No newline at end of file
diff --git a/miniprogram/pages/profile/profile.json b/miniprogram/pages/profile/profile.json
new file mode 100644
index 0000000..e6dd469
--- /dev/null
+++ b/miniprogram/pages/profile/profile.json
@@ -0,0 +1,7 @@
+{
+ "enablePullDownRefresh": true,
+ "usingComponents": {
+ "wux-dialog": "../../components/wux-weapp/dialog/index",
+ "list-item": "../../components/list_item/list_item"
+ }
+}
\ No newline at end of file
diff --git a/miniprogram/pages/profile/profile.wxml b/miniprogram/pages/profile/profile.wxml
new file mode 100644
index 0000000..b5f7b88
--- /dev/null
+++ b/miniprogram/pages/profile/profile.wxml
@@ -0,0 +1,14 @@
+
+
+
+ 个人资料
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/miniprogram/pages/profile/profile.wxss b/miniprogram/pages/profile/profile.wxss
new file mode 100644
index 0000000..184b3f5
--- /dev/null
+++ b/miniprogram/pages/profile/profile.wxss
@@ -0,0 +1,9 @@
+@import '../base/style.wxss';
+
+.list-title {
+ padding-left: 20px;
+ padding-top: 40px;
+ padding-bottom: 10px;
+ font-size: 16px;
+ color: #333;
+}
\ No newline at end of file
diff --git a/miniprogram/pages/regist/regist.js b/miniprogram/pages/regist/regist.js
new file mode 100644
index 0000000..d4959f9
--- /dev/null
+++ b/miniprogram/pages/regist/regist.js
@@ -0,0 +1,141 @@
+
+import regeneratorRuntime from '../../utils/regenerator-runtime/runtime'
+import mergePages from '../../utils/objectUtils'
+import { asyncLogin } from '../../utils/async_tools/async_login'
+import { asyncChecksession } from '../../utils/async_tools/async_checksession'
+import { callAsync } from '../../utils/async_tools/async_tools'
+import { CallCloudFuncAPI } from '../../utils/async_cloudfunc'
+import { wxRequest } from '../../utils/async_http'
+import BaseMixin from '../base/base'
+import { $wuxDialog } from '../../components/wux-weapp/index'
+
+const PageObject = mergePages({}, BaseMixin, {
+
+ data: {
+ nextpage: null,
+ sessionKey: null
+ },
+
+ onInited: async function (options) {
+ const nextpage = wx.getStorageSync('nextpage_registed')
+ if (nextpage) {
+ this.setData({
+ nextpage: nextpage
+ })
+ }
+ // await this.wxLogin()
+ },
+ async cloudRegist(data, sessionKey) {
+ let res = null
+ try {
+ res = await CallCloudFuncAPI(
+ "main",
+ {
+ apiName: "registAPI.regist",
+ encryptData: data,
+ sessionKey: sessionKey
+ }
+ )
+ } catch (e) {
+
+ console.error(e)
+ this.showToast({
+ title: e.message
+ })
+
+ return
+ }
+
+ wx.setStorageSync('sessionid', res.result.data.openid)
+ if (res.result.status) {
+ if (this.data.nextpage) {
+ wx.removeStorageSync('nextpage_registed')
+ }
+ wx.switchTab({
+ url: this.data.nextpage || res.result.data.nextpage,
+ })
+ }
+ },
+ async registByCloudID(cloudId) {
+ let res = null
+ try {
+ res = await CallCloudFuncAPI(
+ "main",
+ {
+ apiName: "registAPI.registByCloudID",
+ weRunData: cloudId,
+ }
+ )
+ } catch (e) {
+
+ console.error('registByCloudID error: ', e)
+ this.showToast({
+ title: 'system_error'
+ })
+
+ return
+ }
+
+ wx.setStorageSync('sessionid', res.result.data.openid)
+ if (res.result.status) {
+ if (this.data.nextpage) {
+ wx.removeStorageSync('nextpage_registed')
+ }
+ wx.switchTab({
+ url: this.data.nextpage || res.result.data.nextpage,
+ })
+ }
+ },
+ async wxLogin() {
+ let result = await callAsync(asyncLogin)
+ console.log('asyncLogin-status:', result[0])
+ console.log('asyncLogin-result:', result[1])
+ if (result[0]) {
+ this.showToast({
+ title: result.message
+ })
+ setTimeout(() => {
+ wx.navigateBack()
+ }, this.data.settings.shortTipDuration)
+ return
+ }
+ let url = `https://api.weixin.qq.com/sns/jscode2session?appid=${this.data.settings.app_id}&secret=${this.data.settings.app_secret}&js_code=${result[1].code}&grant_type=authorization_code`
+ console.log('url:', url)
+ result = await wxRequest(url, { method: 'GET' })
+ console.log('jscode2session-result:', result)
+ if (result.errMsg != 'request:ok') {
+ this.showToast({
+ title: result.errMsg
+ })
+ setTimeout(() => {
+ wx.navigateBack()
+ }, this.data.settings.shortTipDuration)
+ return
+ }
+ this.setData({
+ sessionKey: result.data.session_key
+ })
+ },
+ onGetPhoneNumber: async function (e) {
+ // if(!this.data.sessionKey) {
+ // this.showToast({
+ // title: '未能获取到sessionKey'
+ // })
+ // return
+ // }
+ console.log('onGetPhoneNumber:', e)
+ // await this.cloudRegist(JSON.stringify({
+ // iv: e.detail.iv,
+ // encryptedData: e.detail.encryptedData
+ // }), this.data.sessionKey)
+ this.showLoading()
+ try {
+ await this.registByCloudID(wx.cloud.CloudID(e.detail.cloudID))
+ } catch(e) {
+ logger.error(e)
+ }
+ this.hideLoading()
+ }
+})
+
+Page(PageObject)
\ No newline at end of file
diff --git a/miniprogram/pages/regist/regist.json b/miniprogram/pages/regist/regist.json
new file mode 100644
index 0000000..d66e201
--- /dev/null
+++ b/miniprogram/pages/regist/regist.json
@@ -0,0 +1,5 @@
+{
+ "usingComponents": {
+ "wux-dialog": "../../components/wux-weapp/dialog/index"
+ }
+}
\ No newline at end of file
diff --git a/miniprogram/pages/regist/regist.wxml b/miniprogram/pages/regist/regist.wxml
new file mode 100644
index 0000000..2e22715
--- /dev/null
+++ b/miniprogram/pages/regist/regist.wxml
@@ -0,0 +1,7 @@
+
+
+
+ 为了更好的为您服务,我们需要获取您的手机号
+
+
+
\ No newline at end of file
diff --git a/miniprogram/pages/regist/regist.wxss b/miniprogram/pages/regist/regist.wxss
new file mode 100644
index 0000000..3301eba
--- /dev/null
+++ b/miniprogram/pages/regist/regist.wxss
@@ -0,0 +1,37 @@
+page {
+ display: flex;
+ flex-direction: column;
+ justify-content: flex-start;
+ background-color: #e67774;
+}
+
+
+.userinfo-nickname {
+ font-size: 32rpx;
+ color: white;
+ background-color: #7dd3da;
+ background-size: cover;
+ height: 40px;
+ line-height: 40px;
+ width: 120px;
+ border-radius: 20px;
+ position: absolute;
+ bottom: 100px;
+ left: 50%;
+ margin-left: -60px;
+ box-shadow: 1px 1px 10px rgba(0, 0, 0, 0.3);
+}
+
+.userinfo-nickname::after {
+ border: none;
+}
+
+.note {
+ padding: 40px;
+ margin: 40px;
+ background-color: #fb5655;
+ text-align: center;
+ color: #fff;
+ font-size: 120%;
+ border-radius: 20px;
+}
\ No newline at end of file
diff --git a/miniprogram/pages/update_address/update_address.js b/miniprogram/pages/update_address/update_address.js
new file mode 100644
index 0000000..368f46c
--- /dev/null
+++ b/miniprogram/pages/update_address/update_address.js
@@ -0,0 +1,155 @@
+
+import regeneratorRuntime from '../../utils/regenerator-runtime/runtime'
+import BaseMixin from '../base/base'
+import mergePages from '../../utils/objectUtils'
+const moment = require('../../utils/moment.min.js')
+import { CallCloudFuncAPI } from '../../utils/async_cloudfunc.js'
+import { $wuxDialog } from '../../components/wux-weapp/index'
+
+
+const PageObject = mergePages({}, BaseMixin, {
+ data: {
+ addressInfo: {
+ userName: '',
+ telNumber: '',
+ provinceName: '',
+ cityName: '',
+ countyName: '',
+ postalCode: '',
+ detailInfo: ''
+ }
+ },
+ onInited(options) {
+
+ this.setData({
+ orderid: options.orderid
+ })
+ this.getOrderDetail()
+ },
+ async getOrderDetail() {
+ this.showLoading()
+ let res = null
+ try {
+ res = await CallCloudFuncAPI(
+ "main",
+ {
+ apiName: "adminAPI.getUserOrders",
+ orderid: this.data.orderid
+ }
+ )
+ } catch (e) {
+ console.error(e)
+ this.hideLoading()
+ setTimeout(() => {
+ wx.navigateBack()
+ }, this.data.settings.shortTipDuration)
+ return
+ }
+
+
+ this.hideLoading()
+ if (!res.result.status) {
+ this.showToast({
+ title: res.result.message
+ })
+ setTimeout(() => {
+ wx.navigateBack()
+ }, this.data.settings.shortTipDuration)
+ return
+ }
+
+ if(res.result.data.entities && res.result.data.entities[0].addressInfo) {
+ this.setData({
+ addressInfo: res.result.data.entities[0].addressInfo
+ })
+ }
+ },
+ async submitForm() {
+ this.showLoading()
+ let res = null
+ try {
+ res = await CallCloudFuncAPI(
+ "main",
+ {
+ apiName: "adminAPI.updateOrderAddress",
+ addressInfo: this.data.addressInfo,
+ orderId: this.data.orderid
+ }
+ )
+ } catch (e) {
+ console.error(e)
+ this.hideLoading()
+ this.showToast({
+ title: e.message
+ })
+ setTimeout(() => {
+ wx.navigateBack()
+ }, this.data.settings.shortTipDuration)
+ return
+ }
+
+ this.hideLoading()
+ if (!res.result.status) {
+ this.showToast({
+ title: res.result.message
+ })
+ } else {
+ this.showToast({
+ icon: 'success',
+ title: 'ok'
+ })
+ }
+
+ setTimeout(() => {
+ wx.navigateBack()
+ }, this.data.settings.shortTipDuration)
+ },
+ bindInputChange(e) {
+ console.log(e)
+ if (e.currentTarget.dataset.field == 'userName') {
+ this.setData({
+ 'addressInfo.userName': e.detail.value
+ })
+ }
+
+ if (e.currentTarget.dataset.field == 'telNumber') {
+ this.setData({
+ 'addressInfo.telNumber': e.detail.value
+ })
+ }
+
+ if (e.currentTarget.dataset.field == 'provinceName') {
+
+ this.setData({
+ 'addressInfo.provinceName': e.detail.value
+ })
+ }
+
+ if (e.currentTarget.dataset.field == 'cityName') {
+ this.setData({
+ 'addressInfo.cityName': e.detail.value
+ })
+ }
+
+ if (e.currentTarget.dataset.field == 'countyName') {
+ this.setData({
+ 'addressInfo.countyName': e.detail.value
+ })
+ }
+
+ if (e.currentTarget.dataset.field == 'postalCode') {
+
+ this.setData({
+ 'addressInfo.postalCode': e.detail.value
+ })
+ }
+
+ if (e.currentTarget.dataset.field == 'detailInfo') {
+ this.setData({
+ 'addressInfo.detailInfo': e.detail.value
+ })
+ }
+ }
+})
+
+Page(PageObject)
\ No newline at end of file
diff --git a/miniprogram/pages/update_address/update_address.json b/miniprogram/pages/update_address/update_address.json
new file mode 100644
index 0000000..8835af0
--- /dev/null
+++ b/miniprogram/pages/update_address/update_address.json
@@ -0,0 +1,3 @@
+{
+ "usingComponents": {}
+}
\ No newline at end of file
diff --git a/miniprogram/pages/update_address/update_address.wxml b/miniprogram/pages/update_address/update_address.wxml
new file mode 100644
index 0000000..17596c4
--- /dev/null
+++ b/miniprogram/pages/update_address/update_address.wxml
@@ -0,0 +1,47 @@
+
+
+ * 收货人姓名
+
+
+
+
+
+ * 联系电话
+
+
+
+
+
+ * 所在省份或直辖市
+
+
+
+
+
+ * 所在城市或辖区
+
+
+
+
+
+ 所在区
+
+
+
+
+
+ 邮编
+
+
+
+
+
+ * 详细地址
+
+
+
+
+
+ 保存
+
+
\ No newline at end of file
diff --git a/miniprogram/pages/update_address/update_address.wxss b/miniprogram/pages/update_address/update_address.wxss
new file mode 100644
index 0000000..d18ce62
--- /dev/null
+++ b/miniprogram/pages/update_address/update_address.wxss
@@ -0,0 +1 @@
+@import '../base/style.wxss';
\ No newline at end of file
diff --git a/miniprogram/pages/update_delivery/update_delivery.js b/miniprogram/pages/update_delivery/update_delivery.js
new file mode 100644
index 0000000..3520e15
--- /dev/null
+++ b/miniprogram/pages/update_delivery/update_delivery.js
@@ -0,0 +1,190 @@
+
+import regeneratorRuntime from '../../utils/regenerator-runtime/runtime'
+import BaseMixin from '../base/base'
+import mergePages from '../../utils/objectUtils'
+const moment = require('../../utils/moment.min.js')
+import { CallCloudFuncAPI } from '../../utils/async_cloudfunc.js'
+import { $wuxDialog } from '../../components/wux-weapp/index'
+import { $wuxCalendar } from '../../components/wux-weapp/index'
+
+const DeliveryStatus = {
+ '0': 'preparing',
+ '1': 'shipping',
+ '2': 'delivering',
+ '3': 'received'
+}
+
+const companies = [
+ { name: '顺丰' },
+ { name: '韵达' },
+ { name: '中通' },
+ { name: '圆通' },
+ { name: '申通' },
+ { name: '自营' }
+]
+
+const PageObject = mergePages({}, BaseMixin, {
+ data: {
+ status: null,
+ companies: companies,
+ targetDate: [],
+ deliveryInfo: {
+ company_name: '',
+ orderno: '',
+ will_received_date: '',
+ will_received_time: '',
+ create_at: '',
+ fee: 0
+ }
+ },
+ onInited(options) {
+ this.setData({
+ orderid: options.orderid
+ })
+ this.getOrderDetail()
+ },
+
+ openCalendar() {
+ $wuxCalendar().open({
+ value: this.data.targetDate,
+ onChange: (values, displayValues) => {
+ console.log('onChange', values, displayValues)
+ this.setData({
+ targetDate: displayValues,
+ 'deliveryInfo.will_received_date': displayValues[0]
+ })
+ },
+ })
+ },
+ bindTimeChange(e) {
+ this.setData({
+ 'deliveryInfo.will_received_time': e.detail.value
+ })
+ },
+ bindOrdernoChange(e) {
+ this.setData({
+ 'deliveryInfo.orderno': e.detail.value
+ })
+ },
+ bindDeliveryCompanyInputChange(e) {
+ this.setData({
+ 'deliveryInfo.company_name': e.detail.value
+ })
+ },
+ bindOrdeFeeChange(e) {
+ try {
+ parseInt(e.detail.value)
+ } catch(error) {
+ console.error(error)
+ return
+ }
+ this.setData({
+ 'deliveryInfo.fee': parseInt(e.detail.value)
+ })
+ },
+ async getOrderDetail() {
+ this.showLoading()
+ let res = null
+ try {
+ res = await CallCloudFuncAPI(
+ "main",
+ {
+ apiName: "adminAPI.getUserOrders",
+ orderid: this.data.orderid
+ }
+ )
+ } catch (e) {
+ console.error(e)
+ this.hideLoading()
+ setTimeout(() => {
+ wx.navigateBack()
+ }, this.data.settings.shortTipDuration)
+ return
+ }
+
+
+ this.hideLoading()
+ if (!res.result.status) {
+ this.showToast({
+ title: res.result.message
+ })
+ setTimeout(() => {
+ wx.navigateBack()
+ }, this.data.settings.shortTipDuration)
+ return
+ }
+
+ this.setData({
+ status: res.result.data.delivery_status
+ })
+ },
+
+ setOrderStatus() {
+ let that = this;
+ wx.showActionSheet({
+ itemList: ['备货中', '已发货', '正在送货', '已签收'],
+ success(res) {
+ console.log(res.tapIndex)
+ that.setData({
+ status: DeliveryStatus[res.tapIndex.toString()]
+ })
+ that.submitForm()
+ },
+ fail(res) {
+ console.log(res.errMsg)
+
+ }
+ })
+ },
+
+ async submitForm() {
+ console.log('status:', this.data.status)
+ this.showLoading()
+ let res = null
+ try {
+ res = await CallCloudFuncAPI(
+ "main",
+ {
+ apiName: "adminAPI.updateDeliveryStatus",
+ status: this.data.status,
+ orderId: this.data.orderid,
+ deliveryInfo: this.data.deliveryInfo
+ }
+ )
+ } catch (e) {
+ console.error(e)
+ this.hideLoading()
+ this.showToast({
+ title: e.message
+ })
+ setTimeout(() => {
+ wx.navigateBack()
+ }, this.data.settings.shortTipDuration)
+ return
+ }
+
+ this.hideLoading()
+ if (!res.result.status) {
+ this.showToast({
+ title: res.result.message
+ })
+ } else {
+ this.showToast({
+ icon: 'success',
+ title: 'ok'
+ })
+ }
+
+ setTimeout(() => {
+ wx.navigateBack()
+ }, this.data.settings.shortTipDuration)
+ },
+ bindDeliveryCompanyChange(e) {
+ console.log(e)
+ this.setData({
+ 'deliveryInfo.company_name': companies[parseInt(e.detail.value)].name
+ })
+ }
+})
+
+Page(PageObject)
\ No newline at end of file
diff --git a/miniprogram/pages/update_delivery/update_delivery.json b/miniprogram/pages/update_delivery/update_delivery.json
new file mode 100644
index 0000000..f70ed2d
--- /dev/null
+++ b/miniprogram/pages/update_delivery/update_delivery.json
@@ -0,0 +1,5 @@
+{
+ "usingComponents": {
+ "wux-calendar": "../../components/wux-weapp/calendar/index"
+ }
+}
\ No newline at end of file
diff --git a/miniprogram/pages/update_delivery/update_delivery.wxml b/miniprogram/pages/update_delivery/update_delivery.wxml
new file mode 100644
index 0000000..cee20c7
--- /dev/null
+++ b/miniprogram/pages/update_delivery/update_delivery.wxml
@@ -0,0 +1,50 @@
+
+
+
+
+ 快递公司
+
+
+
+
+
+
+
+
+
+ 订单号
+
+
+
+
+
+
+ 运费(元)
+
+
+
+
+
+
+
+ 预计送达日期
+
+
+
+
+
+
+
+ 预计送达时间
+
+
+
+
+
+
+
+
+
+ 设置发货状态
+
+
\ No newline at end of file
diff --git a/miniprogram/pages/update_delivery/update_delivery.wxss b/miniprogram/pages/update_delivery/update_delivery.wxss
new file mode 100644
index 0000000..d18ce62
--- /dev/null
+++ b/miniprogram/pages/update_delivery/update_delivery.wxss
@@ -0,0 +1 @@
+@import '../base/style.wxss';
\ No newline at end of file
diff --git a/miniprogram/pages/update_order/update_order.js b/miniprogram/pages/update_order/update_order.js
new file mode 100644
index 0000000..5d6be05
--- /dev/null
+++ b/miniprogram/pages/update_order/update_order.js
@@ -0,0 +1,133 @@
+
+import regeneratorRuntime from '../../utils/regenerator-runtime/runtime'
+import BaseMixin from '../base/base'
+import mergePages from '../../utils/objectUtils'
+const moment = require('../../utils/moment.min.js')
+import { CallCloudFuncAPI } from '../../utils/async_cloudfunc.js'
+import { $wuxDialog } from '../../components/wux-weapp/index'
+
+
+const OrderStatus = {
+ '0': 'submit',
+ '1': 'pay',
+ '2': 'received',
+ '3': 'refund',
+ '4': 'complete',
+
+}
+
+const PageObject = mergePages({}, BaseMixin, {
+ data: {
+ status: null
+ },
+ onInited(options) {
+
+ this.setData({
+ orderid: options.orderid
+ })
+ this.getOrderDetail()
+ },
+ async getOrderDetail() {
+ this.showLoading()
+ let res = null
+ try {
+ res = await CallCloudFuncAPI(
+ "main",
+ {
+ apiName: "adminAPI.getUserOrders",
+ orderid: this.data.orderid
+ }
+ )
+ } catch (e) {
+ console.error(e)
+ this.hideLoading()
+ setTimeout(() => {
+ wx.navigateBack()
+ }, this.data.settings.shortTipDuration)
+ return
+ }
+
+
+ this.hideLoading()
+ if (!res.result.status) {
+ this.showToast({
+ title: res.result.message
+ })
+ setTimeout(() => {
+ wx.navigateBack()
+ }, this.data.settings.shortTipDuration)
+ return
+ }
+
+ if (res.result.data.entities && res.result.data.entities[0].addressInfo) {
+ this.setData({
+ addressInfo: res.result.data.entities[0].addressInfo
+ })
+ }
+
+ this.setData({
+ status: res.result.data.status
+ })
+ },
+
+ setOrderStatus() {
+ let that = this;
+ wx.showActionSheet({
+ itemList: ['订单提交', '已支付', '已接单', '已退款', '已完成'],
+ success(res) {
+ console.log(res.tapIndex)
+ that.setData({
+ status: OrderStatus[res.tapIndex.toString()]
+ })
+ that.submitForm()
+ },
+ fail(res) {
+ console.log(res.errMsg)
+
+ }
+ })
+ },
+
+ async submitForm() {
+ this.showLoading()
+ let res = null
+ try {
+ res = await CallCloudFuncAPI(
+ "main",
+ {
+ apiName: "adminAPI.updateOrderStatus",
+ status: this.data.status,
+ orderId: this.data.orderid
+ }
+ )
+ } catch (e) {
+ console.error(e)
+ this.hideLoading()
+ this.showToast({
+ title: e.message
+ })
+ setTimeout(() => {
+ wx.navigateBack()
+ }, this.data.settings.shortTipDuration)
+ return
+ }
+
+ this.hideLoading()
+ if (!res.result.status) {
+ this.showToast({
+ title: res.result.message
+ })
+ } else {
+ this.showToast({
+ icon: 'success',
+ title: 'ok'
+ })
+ }
+
+ setTimeout(() => {
+ wx.navigateBack()
+ }, this.data.settings.shortTipDuration)
+ },
+})
+
+Page(PageObject)
\ No newline at end of file
diff --git a/miniprogram/pages/update_order/update_order.json b/miniprogram/pages/update_order/update_order.json
new file mode 100644
index 0000000..8835af0
--- /dev/null
+++ b/miniprogram/pages/update_order/update_order.json
@@ -0,0 +1,3 @@
+{
+ "usingComponents": {}
+}
\ No newline at end of file
diff --git a/miniprogram/pages/update_order/update_order.wxml b/miniprogram/pages/update_order/update_order.wxml
new file mode 100644
index 0000000..ea5b09d
--- /dev/null
+++ b/miniprogram/pages/update_order/update_order.wxml
@@ -0,0 +1,5 @@
+
+
+ 设置订单状态
+
+
\ No newline at end of file
diff --git a/miniprogram/pages/update_order/update_order.wxss b/miniprogram/pages/update_order/update_order.wxss
new file mode 100644
index 0000000..d18ce62
--- /dev/null
+++ b/miniprogram/pages/update_order/update_order.wxss
@@ -0,0 +1 @@
+@import '../base/style.wxss';
\ No newline at end of file
diff --git a/miniprogram/pages/update_remarks/update_remarks.js b/miniprogram/pages/update_remarks/update_remarks.js
new file mode 100644
index 0000000..b45216c
--- /dev/null
+++ b/miniprogram/pages/update_remarks/update_remarks.js
@@ -0,0 +1,117 @@
+
+import regeneratorRuntime from '../../utils/regenerator-runtime/runtime'
+import BaseMixin from '../base/base'
+import mergePages from '../../utils/objectUtils'
+const moment = require('../../utils/moment.min.js')
+import { CallCloudFuncAPI } from '../../utils/async_cloudfunc.js'
+import { $wuxDialog } from '../../components/wux-weapp/index'
+
+const PageObject = mergePages({}, BaseMixin, {
+ data: {
+ admin_remarks: '',
+ remarks: ''
+ },
+ onInited(options) {
+
+ this.setData({
+ orderid: options.orderid
+ })
+ this.getOrderDetail()
+ },
+ async getOrderDetail() {
+ this.showLoading()
+ let res = null
+ try {
+ res = await CallCloudFuncAPI(
+ "main",
+ {
+ apiName: "adminAPI.getUserOrders",
+ orderid: this.data.orderid
+ }
+ )
+ } catch (e) {
+ console.error(e)
+ this.hideLoading()
+ setTimeout(() => {
+ wx.navigateBack()
+ }, this.data.settings.shortTipDuration)
+ return
+ }
+
+
+ this.hideLoading()
+ if (!res.result.status) {
+ this.showToast({
+ title: res.result.message
+ })
+ setTimeout(() => {
+ wx.navigateBack()
+ }, this.data.settings.shortTipDuration)
+ return
+ }
+
+ if (res.result.data.entities && res.result.data.entities[0].orderInfo) {
+ console.log(res.result.data.entities[0])
+ this.setData({
+ remarks: res.result.data.entities[0].remarks || '',
+ admin_remarks: res.result.data.entities[0].admin_remarks || '',
+ })
+ }
+ },
+
+
+ async submitForm() {
+ this.showLoading()
+ let res = null
+ try {
+ res = await CallCloudFuncAPI(
+ "main",
+ {
+ apiName: "adminAPI.updateOrderRemarks",
+ remarks: this.data.remarks,
+ admin_remarks: this.data.admin_remarks,
+ orderId: this.data.orderid
+ }
+ )
+ } catch (e) {
+ console.error(e)
+ this.hideLoading()
+ this.showToast({
+ title: e.message
+ })
+ setTimeout(() => {
+ wx.navigateBack()
+ }, this.data.settings.shortTipDuration)
+ return
+ }
+
+ this.hideLoading()
+ if (!res.result.status) {
+ this.showToast({
+ title: res.result.message
+ })
+ } else {
+ this.showToast({
+ icon: 'success',
+ title: 'ok'
+ })
+ }
+
+ setTimeout(() => {
+ wx.navigateBack()
+ }, this.data.settings.shortTipDuration)
+ },
+ bindAdminRemarksChange(e) {
+ this.setData({
+ admin_remarks: e.detail.value
+ })
+
+ },
+ bindUserRemarksChange(e){
+ this.setData({
+ remarks: e.detail.value
+ })
+ }
+})
+
+Page(PageObject)
\ No newline at end of file
diff --git a/miniprogram/pages/update_remarks/update_remarks.json b/miniprogram/pages/update_remarks/update_remarks.json
new file mode 100644
index 0000000..8835af0
--- /dev/null
+++ b/miniprogram/pages/update_remarks/update_remarks.json
@@ -0,0 +1,3 @@
+{
+ "usingComponents": {}
+}
\ No newline at end of file
diff --git a/miniprogram/pages/update_remarks/update_remarks.wxml b/miniprogram/pages/update_remarks/update_remarks.wxml
new file mode 100644
index 0000000..be26f1c
--- /dev/null
+++ b/miniprogram/pages/update_remarks/update_remarks.wxml
@@ -0,0 +1,17 @@
+
+
+ * 管理员备注
+
+
+
+
+
+ * 用户备注
+
+
+
+
+
+ 保存
+
+
\ No newline at end of file
diff --git a/miniprogram/pages/update_remarks/update_remarks.wxss b/miniprogram/pages/update_remarks/update_remarks.wxss
new file mode 100644
index 0000000..d18ce62
--- /dev/null
+++ b/miniprogram/pages/update_remarks/update_remarks.wxss
@@ -0,0 +1 @@
+@import '../base/style.wxss';
\ No newline at end of file
diff --git a/miniprogram/pages/update_total/update_total.js b/miniprogram/pages/update_total/update_total.js
new file mode 100644
index 0000000..f86707a
--- /dev/null
+++ b/miniprogram/pages/update_total/update_total.js
@@ -0,0 +1,112 @@
+
+import regeneratorRuntime from '../../utils/regenerator-runtime/runtime'
+import BaseMixin from '../base/base'
+import mergePages from '../../utils/objectUtils'
+const moment = require('../../utils/moment.min.js')
+import { CallCloudFuncAPI } from '../../utils/async_cloudfunc.js'
+import { $wuxDialog } from '../../components/wux-weapp/index'
+
+const PageObject = mergePages({}, BaseMixin, {
+ data: {
+ total: 0
+ },
+ onInited(options) {
+
+ this.setData({
+ orderid: options.orderid
+ })
+ this.getOrderDetail()
+ },
+ async getOrderDetail() {
+ this.showLoading()
+ let res = null
+ try {
+ res = await CallCloudFuncAPI(
+ "main",
+ {
+ apiName: "adminAPI.getUserOrders",
+ orderid: this.data.orderid
+ }
+ )
+ } catch (e) {
+ console.error(e)
+ this.hideLoading()
+ setTimeout(() => {
+ wx.navigateBack()
+ }, this.data.settings.shortTipDuration)
+ return
+ }
+
+
+ this.hideLoading()
+ if (!res.result.status) {
+ this.showToast({
+ title: res.result.message
+ })
+ setTimeout(() => {
+ wx.navigateBack()
+ }, this.data.settings.shortTipDuration)
+ return
+ }
+
+ if (res.result.data.entities && res.result.data.entities[0].orderInfo) {
+ this.setData({
+ total: res.result.data.entities[0].orderInfo.total
+ })
+ }
+ },
+
+
+ async submitForm() {
+ this.showLoading()
+ let res = null
+ try {
+ res = await CallCloudFuncAPI(
+ "main",
+ {
+ apiName: "adminAPI.updateOrderTotal",
+ total: this.data.total,
+ orderId: this.data.orderid
+ }
+ )
+ } catch (e) {
+ console.error(e)
+ this.hideLoading()
+ this.showToast({
+ title: e.message
+ })
+ setTimeout(() => {
+ wx.navigateBack()
+ }, this.data.settings.shortTipDuration)
+ return
+ }
+
+ this.hideLoading()
+ if (!res.result.status) {
+ this.showToast({
+ title: res.result.message
+ })
+ } else {
+ this.showToast({
+ icon: 'success',
+ title: 'ok'
+ })
+ }
+
+ setTimeout(() => {
+ wx.navigateBack()
+ }, this.data.settings.shortTipDuration)
+ },
+ bindInputChange(e) {
+ try {
+ this.setData({
+ total: parseInt(e.detail.value)
+ })
+ } catch(e) {
+ console.error(e)
+ }
+
+ }
+})
+
+Page(PageObject)
\ No newline at end of file
diff --git a/miniprogram/pages/update_total/update_total.json b/miniprogram/pages/update_total/update_total.json
new file mode 100644
index 0000000..8835af0
--- /dev/null
+++ b/miniprogram/pages/update_total/update_total.json
@@ -0,0 +1,3 @@
+{
+ "usingComponents": {}
+}
\ No newline at end of file
diff --git a/miniprogram/pages/update_total/update_total.wxml b/miniprogram/pages/update_total/update_total.wxml
new file mode 100644
index 0000000..84a713d
--- /dev/null
+++ b/miniprogram/pages/update_total/update_total.wxml
@@ -0,0 +1,11 @@
+
+
+ * 调整后的订单总金额
+
+
+
+
+
+ 保存
+
+
\ No newline at end of file
diff --git a/miniprogram/pages/update_total/update_total.wxss b/miniprogram/pages/update_total/update_total.wxss
new file mode 100644
index 0000000..d18ce62
--- /dev/null
+++ b/miniprogram/pages/update_total/update_total.wxss
@@ -0,0 +1 @@
+@import '../base/style.wxss';
\ No newline at end of file
diff --git a/miniprogram/pages/user_orders/user_orders.js b/miniprogram/pages/user_orders/user_orders.js
new file mode 100644
index 0000000..ea2f260
--- /dev/null
+++ b/miniprogram/pages/user_orders/user_orders.js
@@ -0,0 +1,36 @@
+
+import regeneratorRuntime from '../../utils/regenerator-runtime/runtime'
+import BaseMixin from '../base/base'
+import PulldownMixin from '../base/pulldown_mixin'
+import OrdersMixin from '../base/orders_mixin'
+import mergePages from '../../utils/objectUtils'
+const moment = require('../../utils/moment.min.js')
+import { CallCloudFuncAPI } from '../../utils/async_cloudfunc.js'
+import { $wuxDialog } from '../../components/wux-weapp/index'
+import { StatusLabel, DeliveryStatusLabel } from '../../utils/constant'
+
+
+const PageObject = mergePages({}, BaseMixin, PulldownMixin, OrdersMixin, {
+
+ data: {
+ reqData: {
+ page: 1,
+ pagesize: 10,
+ user_id: null
+ },
+ entityIdField: '_id',
+ apiName: "adminAPI.getUserOrders",
+ isCloudFunc: true,
+ statuses: StatusLabel,
+ deliveryStatus: DeliveryStatusLabel,
+ itemFlags: {
+ pay: '-',
+ deposit: '+'
+ },
+ user_id: null,
+ orderid: null
+ }
+
+})
+
+Page(PageObject)
\ No newline at end of file
diff --git a/miniprogram/pages/user_orders/user_orders.json b/miniprogram/pages/user_orders/user_orders.json
new file mode 100644
index 0000000..69b19d4
--- /dev/null
+++ b/miniprogram/pages/user_orders/user_orders.json
@@ -0,0 +1,4 @@
+{
+ "enablePullDownRefresh": true,
+ "usingComponents": {}
+}
\ No newline at end of file
diff --git a/miniprogram/pages/user_orders/user_orders.wxml b/miniprogram/pages/user_orders/user_orders.wxml
new file mode 100644
index 0000000..5f7142e
--- /dev/null
+++ b/miniprogram/pages/user_orders/user_orders.wxml
@@ -0,0 +1,42 @@
+
+
+
+ 设置
+
+
+
+
+
+ {{item.title}}
+ {{item.orderNo}}
+ {{statuses[item.status].name}} {{deliveryStatus[item.delivery_status] ? deliveryStatus[item.delivery_status].name:''}}
+ {{item.create_at}}
+
+
+
+ {{entity.name}}
+ {{entity.price}} x {{entity.count}}
+
+
+
+
+ 收货地址:
+ {{item.addressInfo.provinceName}} {{item.addressInfo.cityName}} {{item.addressInfo.countyName}} {{item.addressInfo.detailInfo}}
+ 电话:{{item.addressInfo.telNumber}}
+ 邮编:{{item.addressInfo.postalCode}}
+
+
+
+ 快递公司:{{item.deliveryInfo.company_name||'本店御用快递小哥'}}
+ 订单编号:{{item.deliveryInfo.orderno}}
+ 送达时间:{{item.deliveryInfo.will_received_date}} {{item.deliveryInfo.will_received_time}}
+
+
+
+
+
+ {{itemFlags[item.type]}} {{ item.orderInfo.total}}
+ {{itemFlags[item.type]}} {{ item.orderInfo.display_total}} {{ item.orderInfo.display_total !== item.orderInfo.total ? item.orderInfo.total : ''}}
+
+
+
\ No newline at end of file
diff --git a/miniprogram/pages/user_orders/user_orders.wxss b/miniprogram/pages/user_orders/user_orders.wxss
new file mode 100644
index 0000000..dbd9b8a
--- /dev/null
+++ b/miniprogram/pages/user_orders/user_orders.wxss
@@ -0,0 +1,102 @@
+@import '../base/style.wxss';
+
+.order {
+ display: flex;
+ min-height: 120px;
+ padding: 10px;
+ box-sizing: border-box;
+ border-bottom: 1px solid #eee;
+ width: 100%;
+}
+
+.order:last-child {
+ border-bottom: 0;
+}
+
+.order .order-type {
+ flex-basis: 60px;
+ display: flex;
+ justify-content: center;
+ flex-shrink: 0;
+ flex-grow: 0;
+}
+
+.order .order-type text {
+ font-size: 30px;
+ color: #e67774;
+}
+
+.order .order-detail {
+ flex-basis: 100%;
+ min-width: 0;
+}
+
+.order .order-total {
+ flex-basis: 80px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ flex-shrink: 0;
+ flex-grow: 0;
+ font-size: 120%;
+}
+
+.order .order-total.pay {
+ color: green;
+}
+
+.order .order-total.deposit {
+ color: red;
+}
+
+.order .order-date {
+ font-size: 80%;
+ color: #999;
+ margin-top: 5px;
+}
+
+.order .order-cate {
+ font-size: 80%;
+ color: #666;
+ margin-top: 5px;
+}
+
+.order .entity {
+ display: flex;
+}
+
+.entity-name {
+ width: 50%;
+}
+
+.entity-price {
+ width: 50%;
+}
+
+.collapse-button {
+ font-size: 80%;
+ color: #333;
+}
+
+.order-entities {
+ color: #666;
+ margin-top: 10px;
+}
+
+
+.order-all-details, .order-delivery, .order-remarks, .order-admin_remarks, .delivery-info {
+ font-size: 80%;
+ color: #666;
+}
+
+.order-delivery, .order-remarks, .order-admin_remarks, .delivery-info {
+ margin-top: 20px;
+}
+
+
+.controls {
+ position: absolute;
+ right: 20px;
+ font-size: 80%;
+ color: #999;
+}
\ No newline at end of file
diff --git a/miniprogram/pages/users/users.js b/miniprogram/pages/users/users.js
new file mode 100644
index 0000000..e6f91ee
--- /dev/null
+++ b/miniprogram/pages/users/users.js
@@ -0,0 +1,87 @@
+
+import regeneratorRuntime from '../../utils/regenerator-runtime/runtime'
+import BaseMixin from '../base/base'
+import mergePages from '../../utils/objectUtils'
+const moment = require('../../utils/moment.min.js')
+import { CallCloudFuncAPI } from '../../utils/async_cloudfunc.js'
+import { $wuxDialog } from '../../components/wux-weapp/index'
+
+
+const PageObject = mergePages({}, BaseMixin, {
+ data: {
+ users: [],
+ search_text: '',
+ controlItems: [
+ {
+ id: 1,
+ name: '调整余额'
+ },
+ {
+ id: 2,
+ name: '设置状态'
+ }
+ ]
+ },
+ onInited(options) {
+ },
+ async getUsers() {
+ this.showLoading()
+ let res = null
+ try {
+ res = await CallCloudFuncAPI(
+ "main",
+ {
+ apiName: "adminAPI.getUsers",
+ search_text: this.data.search_text
+ }
+ )
+ } catch (e) {
+ console.error(e)
+ this.hideLoading()
+ setTimeout(() => {
+ wx.navigateBack()
+ }, this.data.settings.shortTipDuration)
+ return
+ }
+
+
+ this.hideLoading()
+ if (!res.result.status) {
+ this.showToast({
+ title: res.result.message
+ })
+ setTimeout(() => {
+ wx.navigateBack()
+ }, this.data.settings.shortTipDuration)
+ return
+ }
+ console.log(res.result.data.entities)
+ this.setData({
+ users: res.result.data.entities
+ })
+ },
+ bindInputSearchText(e) {
+ this.setData({
+ 'search_text': e.detail.value
+ })
+ },
+ goOrdes(e) {
+ console.log(e)
+ wx.navigateTo({
+ url: `/pages/user_orders/user_orders?user_id=${e.currentTarget.dataset.userid}`,
+ })
+ },
+ showUserControls() {
+ wx.showActionSheet({
+ itemList: ['A', 'B', 'C'],
+ success(res) {
+ console.log(res.tapIndex)
+ },
+ fail(res) {
+ console.log(res.errMsg)
+ }
+ })
+ }
+})
+
+Page(PageObject)
\ No newline at end of file
diff --git a/miniprogram/pages/users/users.json b/miniprogram/pages/users/users.json
new file mode 100644
index 0000000..8835af0
--- /dev/null
+++ b/miniprogram/pages/users/users.json
@@ -0,0 +1,3 @@
+{
+ "usingComponents": {}
+}
\ No newline at end of file
diff --git a/miniprogram/pages/users/users.wxml b/miniprogram/pages/users/users.wxml
new file mode 100644
index 0000000..ff9f65e
--- /dev/null
+++ b/miniprogram/pages/users/users.wxml
@@ -0,0 +1,23 @@
+
+
+ * 手机号或用户名
+
+
+
+
+
+ 提交
+
+
+
+
+
+
+
+ {{item.nickname}} {{item.realName}}
+ {{item.mobile_phone}}
+ {{item.balance}}
+
+
+
+
\ No newline at end of file
diff --git a/miniprogram/pages/users/users.wxss b/miniprogram/pages/users/users.wxss
new file mode 100644
index 0000000..391b494
--- /dev/null
+++ b/miniprogram/pages/users/users.wxss
@@ -0,0 +1,26 @@
+@import '../base/style.wxss';
+
+.item {
+ display: flex;
+ padding-bottom: 10px;
+ padding-top: 10px;
+ border-bottom: 1px solid #ddd;
+}
+
+.item .details {
+ padding-left: 20px;
+ flex: 1;
+ display: block;
+}
+
+.item .name {
+ color: #666;
+ display: block;
+}
+
+.item .balance {
+ font-size: 120%;
+ font-weight: bold;
+ color:tomato;
+ display: block;
+}
\ No newline at end of file
diff --git a/miniprogram/settings/index.js b/miniprogram/settings/index.js
new file mode 100644
index 0000000..f686ce9
--- /dev/null
+++ b/miniprogram/settings/index.js
@@ -0,0 +1 @@
+module.exports = require('./settings.pro');
diff --git a/miniprogram/sitemap.json b/miniprogram/sitemap.json
new file mode 100644
index 0000000..ca02add
--- /dev/null
+++ b/miniprogram/sitemap.json
@@ -0,0 +1,7 @@
+{
+ "desc": "关于本文件的更多信息,请参考文档 https://developers.weixin.qq.com/miniprogram/dev/framework/sitemap.html",
+ "rules": [{
+ "action": "allow",
+ "page": "*"
+ }]
+}
\ No newline at end of file
diff --git a/miniprogram/style/guide.wxss b/miniprogram/style/guide.wxss
new file mode 100644
index 0000000..5a77414
--- /dev/null
+++ b/miniprogram/style/guide.wxss
@@ -0,0 +1,144 @@
+page {
+ background: #f6f6f6;
+ display: flex;
+ flex-direction: column;
+ justify-content: flex-start;
+}
+
+.list {
+ margin-top: 40rpx;
+ height: auto;
+ width: 100%;
+ background: #fff;
+ padding: 0 40rpx;
+ border: 1px solid rgba(0, 0, 0, 0.1);
+ border-left: none;
+ border-right: none;
+ transition: all 300ms ease;
+ display: flex;
+ flex-direction: column;
+ align-items: stretch;
+ box-sizing: border-box;
+}
+
+.list-item {
+ width: 100%;
+ padding: 0;
+ line-height: 104rpx;
+ font-size: 34rpx;
+ color: #007aff;
+ border-top: 1px solid rgba(0, 0, 0, 0.1);
+ display: flex;
+ flex-direction: row;
+ align-content: center;
+ justify-content: space-between;
+ box-sizing: border-box;
+}
+
+.list-item:first-child {
+ border-top: none;
+}
+
+.list-item image {
+ max-width: 100%;
+ max-height: 20vh;
+ margin: 20rpx 0;
+}
+
+.request-text {
+ color: #222;
+ padding: 20rpx 0;
+ font-size: 24rpx;
+ line-height: 36rpx;
+ word-break: break-all;
+}
+
+.guide {
+ width: 100%;
+ padding: 40rpx;
+ box-sizing: border-box;
+ display: flex;
+ flex-direction: column;
+}
+
+.guide .headline {
+ font-size: 34rpx;
+ font-weight: bold;
+ color: #555;
+ line-height: 40rpx;
+}
+
+.guide .p {
+ margin-top: 20rpx;
+ font-size: 28rpx;
+ line-height: 36rpx;
+ color: #666;
+}
+
+.guide .code {
+ margin-top: 20rpx;
+ font-size: 28rpx;
+ line-height: 36rpx;
+ color: #666;
+ background: white;
+ white-space: pre;
+}
+
+.guide .code-dark {
+ margin-top: 20rpx;
+ background: rgba(0, 0, 0, 0.8);
+ padding: 20rpx;
+ font-size: 28rpx;
+ line-height: 36rpx;
+ border-radius: 6rpx;
+ color: #fff;
+ white-space: pre
+}
+
+.guide image {
+ max-width: 100%;
+}
+
+.guide .image1 {
+ margin-top: 20rpx;
+ max-width: 100%;
+ width: 356px;
+ height: 47px;
+}
+
+.guide .image2 {
+ margin-top: 20rpx;
+ width: 264px;
+ height: 100px;
+}
+
+.guide .flat-image {
+ height: 100px;
+}
+
+.guide .code-image {
+ max-width: 100%;
+}
+
+.guide .copyBtn {
+ width: 180rpx;
+ font-size: 20rpx;
+ margin-top: 16rpx;
+ margin-left: 0;
+}
+
+.guide .nav {
+ margin-top: 50rpx;
+ display: flex;
+ flex-direction: row;
+ align-content: space-between;
+}
+
+.guide .nav .prev {
+ margin-left: unset;
+}
+
+.guide .nav .next {
+ margin-right: unset;
+}
+
diff --git a/miniprogram/utils/HttpAPI.js b/miniprogram/utils/HttpAPI.js
new file mode 100644
index 0000000..eadebdf
--- /dev/null
+++ b/miniprogram/utils/HttpAPI.js
@@ -0,0 +1,89 @@
+import settings from '../settings/index'
+import { $wuxToast } from '../dist/index'
+const toastDuration = 3000
+
+export default function HttpAPI(options) {
+ console.log(options)
+ let addr = `${settings.server_addr}${settings.apis[options.addr].addr}`
+ console.log(addr)
+ let req = {
+ url: addr,
+ data: options.data,
+ method: options.method || 'POST',
+ dataType: options.dataType || 'json',
+ }
+
+ if (options.header) {
+ req.header = options.header
+ }
+
+ let sessionData = wx.getStorageSync('sessionData')
+ if (sessionData && sessionData.sessionid) {
+ if (req.header) {
+ req.header.sessionid = sessionData.sessionid
+ } else {
+ req.header = { 'sessionid': sessionData.sessionid }
+ }
+ }
+
+ req.success = (res) => {
+ if (res.statusCode == 200 && res.data.code > 0) {
+ console.log(res)
+ if (options.success) {
+ options.success(res)
+ } else {
+ $wuxToast().show({
+ type: 'success',
+ duration: toastDuration,
+ color: '#fff',
+ text: 'OK'
+ })
+ }
+ } else {
+ console.error(res)
+ if (options.fail) {
+ req.fail = (res) => {
+ options.fail(res)
+ }
+ } else {
+ if(res.statusCode == 403 || res.statusCode == 401) {
+ $wuxToast().show({
+ type: 'default',
+ duration: toastDuration,
+ color: '#fff',
+ icon: 'ios-information-circle-outline',
+ text: '用户未登录,即将为您跳转登陆页面'
+ })
+ wx.clearStorageSync('sessionData')
+ setTimeout(()=>{
+ wx.switchTab({
+ url: '/pages/profile/profile',
+ })
+ }, 3000)
+ } else {
+ $wuxToast().show({
+ type: 'default',
+ duration: toastDuration,
+ color: '#fff',
+ icon: 'ios-information-circle-outline',
+ text: `${res.data.message || '出现未知错误,请联系管理员'}`
+ })
+ }
+ }
+ }
+ }
+
+ req.complete = (res) => {
+ options.app.setData({
+ showSpinner: false
+ })
+ if(options.complete) {
+ options.complete(res)
+ }
+ }
+
+ options.app.setData({
+ showSpinner: true
+ })
+ wx.request(req)
+}
diff --git a/miniprogram/utils/async_api.js b/miniprogram/utils/async_api.js
new file mode 100644
index 0000000..83fc1e2
--- /dev/null
+++ b/miniprogram/utils/async_api.js
@@ -0,0 +1,25 @@
+import regeneratorRuntime from '../utils/regenerator-runtime/runtime.js'
+import {
+ wxRequest
+} from '../utils/async_http.js'
+// import { wxUpload } from '../utils/upload.js'
+import settings from '../settings/index'
+import moment from '../utils/moment.min.js'
+
+
+const ApiRequest = async function(apiName, data, withSession=true) {
+ console.log(`${apiName}-req: `, data)
+ let res;
+ let url;
+ if (apiName.includes('http')) {
+ url = apiName
+ } else {
+ url = `${settings.server_addr}${settings.apis[apiName].addr}`
+ }
+ res = await wxRequest(url, {data: data})
+ return res
+}
+
+export {
+ ApiRequest
+}
\ No newline at end of file
diff --git a/miniprogram/utils/async_cloudfunc.js b/miniprogram/utils/async_cloudfunc.js
new file mode 100644
index 0000000..a99f0ab
--- /dev/null
+++ b/miniprogram/utils/async_cloudfunc.js
@@ -0,0 +1,23 @@
+import regeneratorRuntime from './regenerator-runtime/runtime'
+import settings from '../settings/index'
+const toastDuration = 3000
+const CallCloudFuncAPI = async (name, data, config = {}) => {
+ let promiseResult = await new Promise((resolve, reject) => {
+ wx.cloud.callFunction({
+ name: name,
+ data: data,
+ config: config,
+ success: (res) => {
+ resolve(res)
+ },
+ fail: (err) => {
+ reject(err)
+ }
+ })
+ })
+ return promiseResult
+}
+
+export {
+ CallCloudFuncAPI
+}
\ No newline at end of file
diff --git a/miniprogram/utils/async_download.js b/miniprogram/utils/async_download.js
new file mode 100644
index 0000000..f7f86f9
--- /dev/null
+++ b/miniprogram/utils/async_download.js
@@ -0,0 +1,64 @@
+import regeneratorRuntime from './regenerator-runtime/runtime'
+import settings from '../settings/index'
+import { $wuxToast } from '../dist/index'
+const toastDuration = 3000
+const DownloadAPI = async (url, params = {}) => {
+ let data = params.data || {}
+ let method = params.method || 'POST'
+
+ if (params.hideLoading === false) {
+ wx.showLoading({
+ title: 'Loading',
+ })
+ }
+
+ let promiseResult = await new Promise((resolve, reject) => {
+ wx.downloadFile({
+ url: url,
+ success: (res) => {
+ if (res && res.statusCode == 200) {
+ console.log(res)
+ if (res.errMsg == 'downloadFile:ok') {
+ console.log('res.msg:', res.errMsg)
+ resolve(res)
+ } else {
+ $wuxToast().show({
+ type: 'default',
+ duration: toastDuration,
+ color: '#fff',
+ icon: 'ios-information-circle-outline',
+ text: `${res.data.message || '出现未知错误,请联系管理员'}`
+ })
+ reject(res.errMsg)
+ }
+ } else {
+ $wuxToast().show({
+ type: 'default',
+ duration: toastDuration,
+ color: '#fff',
+ icon: 'ios-information-circle-outline',
+ text: `${res.errMsg || '出现未知错误,请联系管理员'}`
+ })
+ reject(res)
+ }
+ },
+ fail: (err) => {
+ console.log('==== err ====')
+ $wuxToast().show({
+ type: 'default',
+ duration: toastDuration,
+ color: '#fff',
+ icon: 'ios-information-circle-outline',
+ text: `${err.errMsg || '出现未知错误,请联系管理员'}`
+ })
+
+ reject(err)
+ }
+ })
+ })
+ return promiseResult
+}
+
+export {
+ DownloadAPI
+}
\ No newline at end of file
diff --git a/miniprogram/utils/async_http.js b/miniprogram/utils/async_http.js
new file mode 100644
index 0000000..d9ff390
--- /dev/null
+++ b/miniprogram/utils/async_http.js
@@ -0,0 +1,37 @@
+import regeneratorRuntime from './regenerator-runtime/runtime'
+const toastDuration = 3000
+
+const wxRequest = async (url, params = {}, withSession=true) => {
+ let header = params.header || {
+ 'Content-Type': 'application/json',
+ 'dataType': 'json'
+ }
+ if(withSession) {
+ let sessionData = wx.getStorageSync('sessionData')
+ header.sessionid = sessionData.sessionid
+ }
+ let data = params.data || {}
+ let method = params.method || 'POST'
+
+ let promiseRes = await new Promise((resolve, reject) => {
+ wx.request({
+ url: url,
+ method: method,
+ data: data,
+ header: header,
+ success(res) {
+ console.log('wxrequest:', res)
+ resolve(res)
+ },
+ fail(err) {
+ reject(err)
+ }
+ })
+ })
+ return promiseRes
+}
+
+
+export {
+ wxRequest
+}
\ No newline at end of file
diff --git a/miniprogram/utils/async_tools/async_address.js b/miniprogram/utils/async_tools/async_address.js
new file mode 100644
index 0000000..4f2c4f0
--- /dev/null
+++ b/miniprogram/utils/async_tools/async_address.js
@@ -0,0 +1,38 @@
+import regeneratorRuntime from '../../utils/regenerator-runtime/runtime'
+import settings from '../../settings/index'
+import { wxSettings, openSettings } from './async_settings'
+import { callAsync } from './async_tools'
+
+const wxChooseAddress = async () => {
+ let promiseResult = await new Promise((resolve, reject) => {
+ wx.chooseAddress({
+ success(res) {
+ resolve(res)
+ },
+ fail(err) {
+ reject(err)
+ }
+ })
+ })
+ return promiseResult
+}
+
+
+const getWxAddress = async () => {
+
+ let [err, result] = await callAsync(wxSettings)
+ if(err) {
+ return [err, result]
+ }
+
+ if (result.authSetting['scope.address'] == false) {
+ return await callAsync(wxSettings())
+ }
+
+ return await callAsync(wxChooseAddress)
+
+}
+export {
+ wxChooseAddress,
+ getWxAddress
+}
diff --git a/miniprogram/utils/async_tools/async_checksession.js b/miniprogram/utils/async_tools/async_checksession.js
new file mode 100644
index 0000000..f66a741
--- /dev/null
+++ b/miniprogram/utils/async_tools/async_checksession.js
@@ -0,0 +1,21 @@
+import regeneratorRuntime from '../../utils/regenerator-runtime/runtime'
+import settings from '../../settings/index'
+
+const asyncChecksession = async () => {
+ let promiseResult = await new Promise((resolve, reject) => {
+ wx.checkSession({
+ success(res) {
+ resolve(res)
+ },
+ fail(err) {
+ console.error(err)
+ reject(err)
+ }
+ })
+ })
+ return promiseResult
+}
+
+export {
+ asyncChecksession
+}
\ No newline at end of file
diff --git a/miniprogram/utils/async_tools/async_login.js b/miniprogram/utils/async_tools/async_login.js
new file mode 100644
index 0000000..02eaaaa
--- /dev/null
+++ b/miniprogram/utils/async_tools/async_login.js
@@ -0,0 +1,22 @@
+import regeneratorRuntime from '../../utils/regenerator-runtime/runtime'
+import settings from '../../settings/index'
+
+const asyncLogin = async () => {
+ let promiseResult = await new Promise((resolve, reject) => {
+ wx.login({
+ success(res) {
+ resolve(res)
+ },
+ fail(err) {
+ console.error(err)
+ reject(err)
+ }
+ })
+ })
+ return promiseResult
+}
+
+
+export {
+ asyncLogin
+}
\ No newline at end of file
diff --git a/miniprogram/utils/async_tools/async_payment.js b/miniprogram/utils/async_tools/async_payment.js
new file mode 100644
index 0000000..42817d5
--- /dev/null
+++ b/miniprogram/utils/async_tools/async_payment.js
@@ -0,0 +1,26 @@
+import regeneratorRuntime from '../regenerator-runtime/runtime'
+
+const asyncPayment = async (params) => {
+ let paymentResult = await new Promise((resolve, reject) => {
+ wx.requestPayment({
+ timeStamp: params.timeStamp,
+ nonceStr: params.nonceStr,
+ package: params.package,
+ signType: params.signType,
+ paySign: params.paySign,
+ success: (res) => {
+ console.log(res)
+ resolve(res)
+ },
+ fail: (res) => {
+ console.error(res)
+ reject(res)
+ }
+ })
+ })
+ return paymentResult
+}
+
+export {
+ asyncPayment
+}
\ No newline at end of file
diff --git a/miniprogram/utils/async_tools/async_settings.js b/miniprogram/utils/async_tools/async_settings.js
new file mode 100644
index 0000000..6c4a754
--- /dev/null
+++ b/miniprogram/utils/async_tools/async_settings.js
@@ -0,0 +1,38 @@
+import regeneratorRuntime from '../../utils/regenerator-runtime/runtime'
+import settings from '../../settings/index'
+
+const wxSettings = async () => {
+ let promiseResult = await new Promise((resolve, reject) => {
+ wx.getSetting({
+ success(res) {
+ resolve(res)
+ },
+ fail(err) {
+ console.error(err)
+ reject(err)
+ }
+ })
+ })
+ return promiseResult
+}
+
+
+const openSettings = async() => {
+ let result = await new Promise((resovle, reject) => {
+ wx.openSetting({
+ success(res) {
+ resolve(res)
+ },
+ fail(err) {
+ console.error(err)
+ reject(err)
+ }
+ })
+ })
+ return result
+}
+
+export {
+ wxSettings,
+ openSettings
+}
\ No newline at end of file
diff --git a/miniprogram/utils/async_tools/async_tools.js b/miniprogram/utils/async_tools/async_tools.js
new file mode 100644
index 0000000..347c4c0
--- /dev/null
+++ b/miniprogram/utils/async_tools/async_tools.js
@@ -0,0 +1,14 @@
+import regeneratorRuntime from '../../utils/regenerator-runtime/runtime'
+const callAsync = async (func) => {
+ try {
+ let res = await func()
+ return [null, res]
+ } catch (e) {
+ console.error(e)
+ return [e, null]
+ }
+}
+
+export {
+ callAsync
+}
\ No newline at end of file
diff --git a/miniprogram/utils/async_upload.js b/miniprogram/utils/async_upload.js
new file mode 100644
index 0000000..70007cb
--- /dev/null
+++ b/miniprogram/utils/async_upload.js
@@ -0,0 +1,76 @@
+import regeneratorRuntime from './regenerator-runtime/runtime'
+import settings from '../settings/index'
+const ERR_DURATION = 3000
+const UploadAPI = async (apiName, params = {}, withSession = true) => {
+ let data = params.data || {}
+ let method = params.method || 'POST'
+
+ if (params.hideLoading === false) {
+ wx.showLoading({
+ title: 'Loading',
+ })
+ }
+ let header = {}
+ if (withSession) {
+ let sessionData = wx.getStorageSync('sessionData')
+ header.sessionid = sessionData.sessionid
+ }
+
+ let url;
+ if (apiName.includes('http')) {
+ url = apiName
+ } else {
+ url = `${settings.server_addr}${settings.apis[apiName].addr}`
+ }
+
+ let ReqData = {
+ url: url,
+ formData: data,
+ header: header,
+ name: params.fieldName || 'file',
+ filePath: params.filePath
+ }
+ if (params.header) {
+ ReqData.header = params.header
+ }
+ console.log('reqData:', ReqData)
+ let promiseResult = await new Promise((resolve, reject) => {
+ wx.uploadFile({
+ ...ReqData,
+ success: (res) => {
+ console.log('==== success ====')
+ console.log(url)
+ console.log(res)
+ if (res && res.data && res.statusCode == 200 ) {
+ console.log('res:', res)
+ let respData = JSON.parse(res.data)
+ resolve(respData)
+ } else {
+ wx.showToast({
+ title: 'System Error',
+ duration: ERR_DURATION
+ })
+ reject(res)
+ }
+ },
+ fail: (err) => {
+ console.log('==== err ====')
+ console.log(url)
+ console.log(err)
+ wx.showToast({
+ title: err.errMsg,
+ duration: ERR_DURATION
+ })
+ reject(err)
+ },
+ complete: (e) => {
+ wx.hideLoading()
+ }
+ })
+ })
+ return promiseResult
+}
+
+export {
+ UploadAPI
+}
\ No newline at end of file
diff --git a/miniprogram/utils/const.js b/miniprogram/utils/const.js
new file mode 100644
index 0000000..a7b530c
--- /dev/null
+++ b/miniprogram/utils/const.js
@@ -0,0 +1,5 @@
+const lightColor = '#F0f0f2'
+const lightColor2 = '#f4f4f2'
+const blueColor = '#7dd3da'
+const redColor = '#e67774'
+const greenColor = '#8dbb6a'
\ No newline at end of file
diff --git a/miniprogram/utils/constant.js b/miniprogram/utils/constant.js
new file mode 100644
index 0000000..763a51b
--- /dev/null
+++ b/miniprogram/utils/constant.js
@@ -0,0 +1,90 @@
+const idTypes = [{
+ label: '身份证',
+ value: '0'
+},
+{
+ label: '护照',
+ value: '1'
+},
+{
+ label: '港澳居民来往内地通行证',
+ value: '2'
+},
+{
+ label: '台湾居民来往大陆通行证',
+ value: '3'
+}]
+
+const genderTypes = [
+ {
+ label: '男',
+ value: 'M'
+ },
+ {
+ label: '女',
+ value: 'F'
+ },
+]
+
+const PayStatus = {
+ 'submit': 'submit',
+ 'recevied': 'received',
+ 'pay': 'pay',
+ 'refund': 'refund',
+ 'complete': 'complete'
+}
+const PayType = {
+ 'pay': 'pay',
+ 'deposit': 'deposit'
+}
+
+const StatusLabel = {
+ 'submit': {
+ 'name': '未支付',
+ 'name_en': 'Submit'
+ },
+ 'pay': {
+ 'name': '已付款',
+ 'name_en': 'Paid'
+ },
+ 'recevied': {
+ 'name': '已接单',
+ 'name_en': 'recevied'
+ },
+ 'refund': {
+ 'name': '已退款',
+ 'name_en': 'refund'
+ },
+ 'complete': {
+ 'name': '已完成',
+ 'name_en': 'Complete'
+ }
+}
+
+const DeliveryStatusLabel = {
+ 'preparing': {
+ 'name': '备货中',
+ 'name_en': 'Paid'
+ },
+ 'shipping': {
+ 'name': '已发货',
+ 'name_en': 'Shipping'
+ },
+ 'delivering': {
+ 'name': '正在送货',
+ 'name_en': 'Delivering'
+ },
+ 'received': {
+ 'name': '已签收',
+ 'name_en': 'Received'
+ }
+}
+
+module.exports = {
+ idTypes,
+ genderTypes,
+ PayStatus,
+ PayType,
+ StatusLabel,
+ DeliveryStatusLabel
+}
\ No newline at end of file
diff --git a/miniprogram/utils/country.js b/miniprogram/utils/country.js
new file mode 100644
index 0000000..50b828e
--- /dev/null
+++ b/miniprogram/utils/country.js
@@ -0,0 +1,1504 @@
+const countries = [
+ {
+ "en": "AFGHANISTAN",
+ "abbr": "AF",
+ "cn": "阿富汗",
+ "id": 4
+ },
+ {
+ "en": "ÅLAND ISLANDS",
+ "abbr": "AX",
+ "cn": "奥兰群岛(芬兰属)",
+ "id": 248
+ },
+ {
+ "en": "ALBANIA",
+ "abbr": "AL",
+ "cn": "阿尔巴尼亚",
+ "id": 8
+ },
+ {
+ "en": "ALGERIA",
+ "abbr": "DZ",
+ "cn": "阿尔及利亚",
+ "id": 12
+ },
+ {
+ "en": "AMERICAN SAMOA",
+ "abbr": "AS",
+ "cn": "美属萨摩亚",
+ "id": 16
+ },
+ {
+ "en": "ANDORRA",
+ "abbr": "AD",
+ "cn": "安道尔",
+ "id": 20
+ },
+ {
+ "en": "ANGOLA",
+ "abbr": "AO",
+ "cn": "安哥拉",
+ "id": 24
+ },
+ {
+ "en": "ANGUILLA",
+ "abbr": "AI",
+ "cn": "安圭拉岛",
+ "id": 660
+ },
+ {
+ "en": "ANTARCTICA",
+ "abbr": "AQ",
+ "cn": "南极洲",
+ "id": 10
+ },
+ {
+ "en": "ANTIGUA AND BARBUDA",
+ "abbr": "AG",
+ "cn": "安提瓜和巴布达",
+ "id": 28
+ },
+ {
+ "en": "ARGENTINA",
+ "abbr": "AR",
+ "cn": "阿根廷",
+ "id": 32
+ },
+ {
+ "en": "ARMENIA",
+ "abbr": "AM",
+ "cn": "亚美尼亚",
+ "id": 51
+ },
+ {
+ "en": "ARUBA",
+ "abbr": "AW",
+ "cn": "阿鲁巴",
+ "id": 533
+ },
+ {
+ "en": "AUSTRALIA",
+ "abbr": "AU",
+ "cn": "澳大利亚",
+ "id": 36
+ },
+ {
+ "en": "AUSTRIA",
+ "abbr": "AT",
+ "cn": "奥地利",
+ "id": 40
+ },
+ {
+ "en": "AZERBAIJAN",
+ "abbr": "AZ",
+ "cn": "阿塞拜疆",
+ "id": 31
+ },
+ {
+ "en": "BAHAMAS",
+ "abbr": "BS",
+ "cn": "巴哈马",
+ "id": 44
+ },
+ {
+ "en": "BAHRAIN",
+ "abbr": "BH",
+ "cn": "巴林",
+ "id": 48
+ },
+ {
+ "en": "BANGLADESH",
+ "abbr": "BD",
+ "cn": "孟加拉国",
+ "id": 50
+ },
+ {
+ "en": "BARBADOS",
+ "abbr": "BB",
+ "cn": "巴巴多斯",
+ "id": 52
+ },
+ {
+ "en": "BELARUS",
+ "abbr": "BY",
+ "cn": "白俄罗斯",
+ "id": 112
+ },
+ {
+ "en": "BELGIUM",
+ "abbr": "BE",
+ "cn": "比利时",
+ "id": 56
+ },
+ {
+ "en": "BELIZE",
+ "abbr": "BZ",
+ "cn": "伯利兹",
+ "id": 84
+ },
+ {
+ "en": "BENIN",
+ "abbr": "BJ",
+ "cn": "贝宁",
+ "id": 204
+ },
+ {
+ "en": "BERMUDA",
+ "abbr": "BM",
+ "cn": "百慕大群岛",
+ "id": 60
+ },
+ {
+ "en": "BHUTAN",
+ "abbr": "BT",
+ "cn": "不丹",
+ "id": 64
+ },
+ {
+ "en": "BOLIVIA, PLURINATIONAL STATE OF",
+ "abbr": "BO",
+ "cn": "玻利维亚",
+ "id": 68
+ },
+ {
+ "en": "BOSNIA AND HERZEGOVINA",
+ "abbr": "BA",
+ "cn": "波斯尼亚和黑塞哥维那",
+ "id": 70
+ },
+ {
+ "en": "BOTSWANA",
+ "abbr": "BW",
+ "cn": "博茨瓦纳",
+ "id": 72
+ },
+ {
+ "en": "BOUVET ISLAND",
+ "abbr": "BV",
+ "cn": "布韦岛",
+ "id": 74
+ },
+ {
+ "en": "BRAZIL",
+ "abbr": "BR",
+ "cn": "巴西",
+ "id": 76
+ },
+ {
+ "en": "BRITISH INDIAN OCEAN TERRITORY",
+ "abbr": "IO",
+ "cn": "英属印度洋领地",
+ "id": 86
+ },
+ {
+ "en": "BRUNEI DARUSSALAM",
+ "abbr": "BN",
+ "cn": "文莱",
+ "id": 96
+ },
+ {
+ "en": "BULGARIA",
+ "abbr": "BG",
+ "cn": "保加利亚",
+ "id": 100
+ },
+ {
+ "en": "BURKINA FASO",
+ "abbr": "BF",
+ "cn": "布基纳法索",
+ "id": 854
+ },
+ {
+ "en": "BURUNDI",
+ "abbr": "BI",
+ "cn": "布隆迪",
+ "id": 108
+ },
+ {
+ "en": "CAMBODIA",
+ "abbr": "KH",
+ "cn": "柬埔寨",
+ "id": 116
+ },
+ {
+ "en": "CAMEROON",
+ "abbr": "CM",
+ "cn": "喀麦隆",
+ "id": 120
+ },
+ {
+ "en": "CANADA",
+ "abbr": "CA",
+ "cn": "加拿大",
+ "id": 124
+ },
+ {
+ "en": "CAPE VERDE",
+ "abbr": "CV",
+ "cn": "佛得角",
+ "id": 132
+ },
+ {
+ "en": "CAYMAN ISLANDS",
+ "abbr": "KY",
+ "cn": "开曼群岛",
+ "id": 136
+ },
+ {
+ "en": "CENTRAL AFRICAN REPUBLIC",
+ "abbr": "CF",
+ "cn": "中非共和国",
+ "id": 140
+ },
+ {
+ "en": "CHAD",
+ "abbr": "TD",
+ "cn": "乍得",
+ "id": 148
+ },
+ {
+ "en": "CHILE",
+ "abbr": "CL",
+ "cn": "智利",
+ "id": 152
+ },
+ {
+ "en": "CHINA",
+ "abbr": "CN",
+ "cn": "中国",
+ "id": 156
+ },
+ {
+ "en": "CHRISTMAS ISLAND",
+ "abbr": "CX",
+ "cn": "圣诞岛",
+ "id": 162
+ },
+ {
+ "en": "COCOS (KEELING) ISLANDS",
+ "abbr": "CC",
+ "cn": "科科斯群岛(基灵群岛)",
+ "id": 166
+ },
+ {
+ "en": "COLOMBIA",
+ "abbr": "CO",
+ "cn": "哥伦比亚",
+ "id": 170
+ },
+ {
+ "en": "COMOROS",
+ "abbr": "KM",
+ "cn": "科摩罗",
+ "id": 174
+ },
+ {
+ "en": "CONGO",
+ "abbr": "CG",
+ "cn": "刚果",
+ "id": 178
+ },
+ {
+ "en": "CONGO, THE DEMOCRATIC REPUBLIC OF THE",
+ "abbr": "CD",
+ "cn": "刚果民主共和国",
+ "id": 180
+ },
+ {
+ "en": "COOK ISLANDS",
+ "abbr": "CK",
+ "cn": "库克群岛",
+ "id": 184
+ },
+ {
+ "en": "COSTA RICA",
+ "abbr": "CR",
+ "cn": "哥斯达黎加",
+ "id": 188
+ },
+ {
+ "en": "CÔTE D'IVOIRE",
+ "abbr": "CI",
+ "cn": "科特迪瓦",
+ "id": 384
+ },
+ {
+ "en": "CROATIA",
+ "abbr": "HR",
+ "cn": "克罗地亚",
+ "id": 191
+ },
+ {
+ "en": "CUBA",
+ "abbr": "CU",
+ "cn": "古巴",
+ "id": 192
+ },
+ {
+ "en": "CYPRUS",
+ "abbr": "CY",
+ "cn": "塞浦路斯",
+ "id": 196
+ },
+ {
+ "en": "CZECH REPUBLIC",
+ "abbr": "CZ",
+ "cn": "捷克共和国",
+ "id": 203
+ },
+ {
+ "en": "DENMARK",
+ "abbr": "DK",
+ "cn": "丹麦",
+ "id": 208
+ },
+ {
+ "en": "DJIBOUTI",
+ "abbr": "DJ",
+ "cn": "吉布提",
+ "id": 262
+ },
+ {
+ "en": "DOMINICA",
+ "abbr": "DM",
+ "cn": "多米尼加",
+ "id": 212
+ },
+ {
+ "en": "DOMINICAN REPUBLIC",
+ "abbr": "DO",
+ "cn": "多米尼加共和国",
+ "id": 214
+ },
+ {
+ "en": "ECUADOR",
+ "abbr": "EC",
+ "cn": "厄瓜多尔",
+ "id": 218
+ },
+ {
+ "en": "EGYPT",
+ "abbr": "EG",
+ "cn": "埃及",
+ "id": 818
+ },
+ {
+ "en": "EL SALVADOR",
+ "abbr": "SV",
+ "cn": "萨尔瓦多",
+ "id": 222
+ },
+ {
+ "en": "EQUATORIAL GUINEA",
+ "abbr": "GQ",
+ "cn": "赤道几内亚",
+ "id": 226
+ },
+ {
+ "en": "ERITREA",
+ "abbr": "ER",
+ "cn": "厄立特里亚",
+ "id": 232
+ },
+ {
+ "en": "ESTONIA",
+ "abbr": "EE",
+ "cn": "爱沙尼亚",
+ "id": 233
+ },
+ {
+ "en": "ETHIOPIA",
+ "abbr": "ET",
+ "cn": "埃塞俄比亚",
+ "id": 231
+ },
+ {
+ "en": "FALKLAND ISLANDS (MALVINAS)",
+ "abbr": "FK",
+ "cn": "福克兰群岛(马尔维纳斯群岛)",
+ "id": 238
+ },
+ {
+ "en": "FAROE ISLANDS",
+ "abbr": "FO",
+ "cn": "法罗群岛",
+ "id": 234
+ },
+ {
+ "en": "FIJI",
+ "abbr": "FJ",
+ "cn": "斐济群岛",
+ "id": 242
+ },
+ {
+ "en": "FINLAND",
+ "abbr": "FI",
+ "cn": "芬兰",
+ "id": 246
+ },
+ {
+ "en": "FRANCE",
+ "abbr": "FR",
+ "cn": "法国",
+ "id": 250
+ },
+ {
+ "en": "FRENCH GUIANA",
+ "abbr": "GF",
+ "cn": "法属圭亚那",
+ "id": 254
+ },
+ {
+ "en": "FRENCH POLYNESIA",
+ "abbr": "PF",
+ "cn": "法属波利尼西亚",
+ "id": 258
+ },
+ {
+ "en": "FRENCH SOUTHERN TERRITORIES",
+ "abbr": "TF",
+ "cn": "法属南极地区",
+ "id": 260
+ },
+ {
+ "en": "GABON",
+ "abbr": "GA",
+ "cn": "加蓬",
+ "id": 266
+ },
+ {
+ "en": "GAMBIA",
+ "abbr": "GM",
+ "cn": "冈比亚",
+ "id": 270
+ },
+ {
+ "en": "GEORGIA",
+ "abbr": "GE",
+ "cn": "乔治亚",
+ "id": 268
+ },
+ {
+ "en": "GERMANY",
+ "abbr": "DE",
+ "cn": "德国",
+ "id": 276
+ },
+ {
+ "en": "GHANA",
+ "abbr": "GH",
+ "cn": "加纳",
+ "id": 288
+ },
+ {
+ "en": "GIBRALTAR",
+ "abbr": "GI",
+ "cn": "直布罗陀",
+ "id": 292
+ },
+ {
+ "en": "GREECE",
+ "abbr": "GR",
+ "cn": "希腊",
+ "id": 300
+ },
+ {
+ "en": "GREENLAND",
+ "abbr": "GL",
+ "cn": "格陵兰",
+ "id": 304
+ },
+ {
+ "en": "GRENADA",
+ "abbr": "GD",
+ "cn": "格林纳达",
+ "id": 308
+ },
+ {
+ "en": "GUADELOUPE",
+ "abbr": "GP",
+ "cn": "瓜德罗普岛",
+ "id": 312
+ },
+ {
+ "en": "GUAM",
+ "abbr": "GU",
+ "cn": "关岛",
+ "id": 316
+ },
+ {
+ "en": "GUATEMALA",
+ "abbr": "GT",
+ "cn": "危地马拉",
+ "id": 320
+ },
+ {
+ "en": "GUERNSEY",
+ "abbr": "GG",
+ "cn": "格恩西",
+ "id": 831
+ },
+ {
+ "en": "GUINEA",
+ "abbr": "GN",
+ "cn": "几内亚",
+ "id": 324
+ },
+ {
+ "en": "GUINEA-BISSAU",
+ "abbr": "GW",
+ "cn": "几内亚比绍",
+ "id": 624
+ },
+ {
+ "en": "GUYANA",
+ "abbr": "GY",
+ "cn": "圭亚那",
+ "id": 328
+ },
+ {
+ "en": "HAITI",
+ "abbr": "HT",
+ "cn": "海地",
+ "id": 332
+ },
+ {
+ "en": "HEARD ISLAND AND MCDONALD ISLANDS",
+ "abbr": "HM",
+ "cn": "赫德和麦克唐纳群岛",
+ "id": 334
+ },
+ {
+ "en": "HOLY SEE (VATICAN CITY STATE)",
+ "abbr": "VA",
+ "cn": "梵蒂冈城",
+ "id": 336
+ },
+ {
+ "en": "HONDURAS",
+ "abbr": "HN",
+ "cn": "洪都拉斯",
+ "id": 340
+ },
+ {
+ "en": "HONG KONG",
+ "abbr": "HK",
+ "cn": "中国香港",
+ "id": 344
+ },
+ {
+ "en": "HUNGARY",
+ "abbr": "HU",
+ "cn": "匈牙利",
+ "id": 348
+ },
+ {
+ "en": "ICELAND",
+ "abbr": "IS",
+ "cn": "冰岛",
+ "id": 352
+ },
+ {
+ "en": "INDIA",
+ "abbr": "IN",
+ "cn": "印度",
+ "id": 356
+ },
+ {
+ "en": "INDONESIA",
+ "abbr": "ID",
+ "cn": "印度尼西亚",
+ "id": 360
+ },
+ {
+ "en": "IRAN, ISLAMIC REPUBLIC OF",
+ "abbr": "IR",
+ "cn": "伊朗",
+ "id": 364
+ },
+ {
+ "en": "IRAQ",
+ "abbr": "IQ",
+ "cn": "伊拉克",
+ "id": 368
+ },
+ {
+ "en": "IRELAND",
+ "abbr": "IE",
+ "cn": "爱尔兰",
+ "id": 372
+ },
+ {
+ "en": "ISLE OF MAN",
+ "abbr": "IM",
+ "cn": "马恩岛",
+ "id": 833
+ },
+ {
+ "en": "ISRAEL",
+ "abbr": "IL",
+ "cn": "以色列",
+ "id": 376
+ },
+ {
+ "en": "ITALY",
+ "abbr": "IT",
+ "cn": "意大利",
+ "id": 380
+ },
+ {
+ "en": "JAMAICA",
+ "abbr": "JM",
+ "cn": "牙买加",
+ "id": 388
+ },
+ {
+ "en": "JAPAN",
+ "abbr": "JP",
+ "cn": "日本",
+ "id": 392
+ },
+ {
+ "en": "JERSEY",
+ "abbr": "JE",
+ "cn": "泽西",
+ "id": 832
+ },
+ {
+ "en": "JORDAN",
+ "abbr": "JO",
+ "cn": "约旦",
+ "id": 400
+ },
+ {
+ "en": "KAZAKHSTAN",
+ "abbr": "KZ",
+ "cn": "哈萨克斯坦",
+ "id": 398
+ },
+ {
+ "en": "KENYA",
+ "abbr": "KE",
+ "cn": "肯尼亚",
+ "id": 404
+ },
+ {
+ "en": "KIRIBATI",
+ "abbr": "KI",
+ "cn": "基里巴斯",
+ "id": 296
+ },
+ {
+ "en": "KOREA, DEMOCRATIC PEOPLE'S REPUBLIC OF",
+ "abbr": "KP",
+ "cn": "朝鲜",
+ "id": 408
+ },
+ {
+ "en": "KOREA, REPUBLIC OF",
+ "abbr": "KR",
+ "cn": "韩国",
+ "id": 410
+ },
+ {
+ "en": "KUWAIT",
+ "abbr": "KW",
+ "cn": "科威特",
+ "id": 414
+ },
+ {
+ "en": "KYRGYZSTAN",
+ "abbr": "KG",
+ "cn": "吉尔吉斯斯坦",
+ "id": 417
+ },
+ {
+ "en": "LAO PEOPLE'S DEMOCRATIC REPUBLIC",
+ "abbr": "LA",
+ "cn": "老挝",
+ "id": 418
+ },
+ {
+ "en": "LATVIA",
+ "abbr": "LV",
+ "cn": "拉脱维亚",
+ "id": 428
+ },
+ {
+ "en": "LEBANON",
+ "abbr": "LB",
+ "cn": "黎巴嫩",
+ "id": 422
+ },
+ {
+ "en": "LESOTHO",
+ "abbr": "LS",
+ "cn": "莱索托",
+ "id": 426
+ },
+ {
+ "en": "LIBERIA",
+ "abbr": "LR",
+ "cn": "利比里亚",
+ "id": 430
+ },
+ {
+ "en": "LIBYAN ARAB JAMAHIRIYA",
+ "abbr": "LY",
+ "cn": "利比亚",
+ "id": 434
+ },
+ {
+ "en": "LIECHTENSTEIN",
+ "abbr": "LI",
+ "cn": "列支敦士登",
+ "id": 438
+ },
+ {
+ "en": "LITHUANIA",
+ "abbr": "LT",
+ "cn": "立陶宛",
+ "id": 440
+ },
+ {
+ "en": "LUXEMBOURG",
+ "abbr": "LU",
+ "cn": "卢森堡",
+ "id": 442
+ },
+ {
+ "en": "MACAO",
+ "abbr": "MO",
+ "cn": "中国澳门",
+ "id": 446
+ },
+ {
+ "en": "MACEDONIA, THE FORMER YUGOSLAV REPUBLIC OF",
+ "abbr": "MK",
+ "cn": "马其顿,前南斯拉夫共和国",
+ "id": 807
+ },
+ {
+ "en": "MADAGASCAR",
+ "abbr": "MG",
+ "cn": "马达加斯加",
+ "id": 450
+ },
+ {
+ "en": "MALAWI",
+ "abbr": "MW",
+ "cn": "马拉维",
+ "id": 454
+ },
+ {
+ "en": "MALAYSIA",
+ "abbr": "MY",
+ "cn": "马来西亚",
+ "id": 458
+ },
+ {
+ "en": "MALDIVES",
+ "abbr": "MV",
+ "cn": "马尔代夫",
+ "id": 462
+ },
+ {
+ "en": "MALI",
+ "abbr": "ML",
+ "cn": "马里",
+ "id": 466
+ },
+ {
+ "en": "MALTA",
+ "abbr": "MT",
+ "cn": "马耳他",
+ "id": 470
+ },
+ {
+ "en": "MARSHALL ISLANDS",
+ "abbr": "MH",
+ "cn": "马绍尔群岛",
+ "id": 584
+ },
+ {
+ "en": "MARTINIQUE",
+ "abbr": "MQ",
+ "cn": "马提尼克岛",
+ "id": 474
+ },
+ {
+ "en": "MAURITANIA",
+ "abbr": "MR",
+ "cn": "毛里塔尼亚",
+ "id": 478
+ },
+ {
+ "en": "MAURITIUS",
+ "abbr": "MU",
+ "cn": "毛里求斯",
+ "id": 480
+ },
+ {
+ "en": "MAYOTTE",
+ "abbr": "YT",
+ "cn": "马约特岛",
+ "id": 175
+ },
+ {
+ "en": "MEXICO",
+ "abbr": "MX",
+ "cn": "墨西哥",
+ "id": 484
+ },
+ {
+ "en": "MICRONESIA, FEDERATED STATES OF",
+ "abbr": "FM",
+ "cn": "密克罗尼西亚",
+ "id": 583
+ },
+ {
+ "en": "MOLDOVA, REPUBLIC OF",
+ "abbr": "MD",
+ "cn": "摩尔多瓦",
+ "id": 498
+ },
+ {
+ "en": "MONACO",
+ "abbr": "MC",
+ "cn": "摩纳哥",
+ "id": 492
+ },
+ {
+ "en": "MONGOLIA",
+ "abbr": "MN",
+ "cn": "蒙古",
+ "id": 496
+ },
+ {
+ "en": "MONTENEGRO",
+ "abbr": "ME",
+ "cn": "门的内哥罗(黑山)",
+ "id": 499
+ },
+ {
+ "en": "MONTSERRAT",
+ "abbr": "MS",
+ "cn": "蒙特塞拉特",
+ "id": 500
+ },
+ {
+ "en": "MOROCCO",
+ "abbr": "MA",
+ "cn": "摩洛哥",
+ "id": 504
+ },
+ {
+ "en": "MOZAMBIQUE",
+ "abbr": "MZ",
+ "cn": "莫桑比克",
+ "id": 508
+ },
+ {
+ "en": "MYANMAR",
+ "abbr": "MM",
+ "cn": "缅甸",
+ "id": 104
+ },
+ {
+ "en": "NAMIBIA",
+ "abbr": "NA",
+ "cn": "纳米比亚",
+ "id": 516
+ },
+ {
+ "en": "NAURU",
+ "abbr": "NR",
+ "cn": "瑙鲁",
+ "id": 520
+ },
+ {
+ "en": "NEPAL",
+ "abbr": "NP",
+ "cn": "尼泊尔",
+ "id": 524
+ },
+ {
+ "en": "NETHERLANDS",
+ "abbr": "NL",
+ "cn": "荷兰",
+ "id": 528
+ },
+ {
+ "en": "NETHERLANDS ANTILLES",
+ "abbr": "AN",
+ "cn": "荷属安的列斯群岛",
+ "id": 530
+ },
+ {
+ "en": "NEW CALEDONIA",
+ "abbr": "NC",
+ "cn": "新喀里多尼亚",
+ "id": 540
+ },
+ {
+ "en": "NEW ZEALAND",
+ "abbr": "NZ",
+ "cn": "新西兰",
+ "id": 554
+ },
+ {
+ "en": "NICARAGUA",
+ "abbr": "NI",
+ "cn": "尼加拉瓜",
+ "id": 558
+ },
+ {
+ "en": "NIGER",
+ "abbr": "NE",
+ "cn": "尼日尔",
+ "id": 562
+ },
+ {
+ "en": "NIGERIA",
+ "abbr": "NG",
+ "cn": "尼日利亚",
+ "id": 566
+ },
+ {
+ "en": "NIUE",
+ "abbr": "NU",
+ "cn": "纽埃",
+ "id": 570
+ },
+ {
+ "en": "NORFOLK ISLAND",
+ "abbr": "NF",
+ "cn": "诺福克岛",
+ "id": 574
+ },
+ {
+ "en": "NORTHERN MARIANA ISLANDS",
+ "abbr": "MP",
+ "cn": "北马里亚纳群岛",
+ "id": 580
+ },
+ {
+ "en": "NORWAY",
+ "abbr": "NO",
+ "cn": "挪威",
+ "id": 578
+ },
+ {
+ "en": "OMAN",
+ "abbr": "OM",
+ "cn": "阿曼",
+ "id": 512
+ },
+ {
+ "en": "PAKISTAN",
+ "abbr": "PK",
+ "cn": "巴基斯坦",
+ "id": 586
+ },
+ {
+ "en": "PALAU",
+ "abbr": "PW",
+ "cn": "帕劳群岛",
+ "id": 585
+ },
+ {
+ "en": "PALESTINIAN TERRITORY, OCCUPIED",
+ "abbr": "PS",
+ "cn": "巴勒斯坦当局",
+ "id": 275
+ },
+ {
+ "en": "PANAMA",
+ "abbr": "PA",
+ "cn": "巴拿马",
+ "id": 591
+ },
+ {
+ "en": "PAPUA NEW GUINEA",
+ "abbr": "PG",
+ "cn": "巴布亚新几内亚",
+ "id": 598
+ },
+ {
+ "en": "PARAGUAY",
+ "abbr": "PY",
+ "cn": "巴拉圭",
+ "id": 600
+ },
+ {
+ "en": "PERU",
+ "abbr": "PE",
+ "cn": "秘鲁",
+ "id": 604
+ },
+ {
+ "en": "PHILIPPINES",
+ "abbr": "PH",
+ "cn": "菲律宾",
+ "id": 608
+ },
+ {
+ "en": "PITCAIRN",
+ "abbr": "PN",
+ "cn": "皮特克恩群岛",
+ "id": 612
+ },
+ {
+ "en": "POLAND",
+ "abbr": "PL",
+ "cn": "波兰",
+ "id": 616
+ },
+ {
+ "en": "PORTUGAL",
+ "abbr": "PT",
+ "cn": "葡萄牙",
+ "id": 620
+ },
+ {
+ "en": "PUERTO RICO",
+ "abbr": "PR",
+ "cn": "波多黎各",
+ "id": 630
+ },
+ {
+ "en": "QATAR",
+ "abbr": "QA",
+ "cn": "卡塔尔",
+ "id": 634
+ },
+ {
+ "en": "REUNION",
+ "abbr": "RE",
+ "cn": "留尼汪岛",
+ "id": 638
+ },
+ {
+ "en": "ROMANIA",
+ "abbr": "RO",
+ "cn": "罗马尼亚",
+ "id": 642
+ },
+ {
+ "en": "RUSSIAN FEDERATION",
+ "abbr": "RU",
+ "cn": "俄罗斯",
+ "id": 643
+ },
+ {
+ "en": "RWANDA",
+ "abbr": "RW",
+ "cn": "卢旺达",
+ "id": 646
+ },
+ {
+ "en": "SAINT BARTHÉLEMY",
+ "abbr": "BL",
+ "cn": "圣巴泰勒米",
+ "id": 652
+ },
+ {
+ "en": "SAINT HELENA",
+ "abbr": "SH",
+ "cn": "圣赫勒拿岛",
+ "id": 654
+ },
+ {
+ "en": "SAINT KITTS AND NEVIS",
+ "abbr": "KN",
+ "cn": "圣基茨和尼维斯",
+ "id": 659
+ },
+ {
+ "en": "SAINT LUCIA",
+ "abbr": "LC",
+ "cn": "圣卢西亚",
+ "id": 662
+ },
+ {
+ "en": "SAINT MARTIN",
+ "abbr": "MF",
+ "cn": "圣马丁",
+ "id": 663
+ },
+ {
+ "en": "SAINT PIERRE AND MIQUELON",
+ "abbr": "PM",
+ "cn": "圣皮埃尔岛和密克隆岛",
+ "id": 666
+ },
+ {
+ "en": "SAINT VINCENT AND THE GRENADINES",
+ "abbr": "VC",
+ "cn": "圣文森特和格林纳丁斯",
+ "id": 670
+ },
+ {
+ "en": "SAMOA",
+ "abbr": "WS",
+ "cn": "萨摩亚",
+ "id": 882
+ },
+ {
+ "en": "SAN MARINO",
+ "abbr": "SM",
+ "cn": "圣马力诺",
+ "id": 674
+ },
+ {
+ "en": "SAO TOME AND PRINCIPE",
+ "abbr": "ST",
+ "cn": "圣多美和普林西比",
+ "id": 678
+ },
+ {
+ "en": "SAUDI ARABIA",
+ "abbr": "SA",
+ "cn": "沙特阿拉伯",
+ "id": 682
+ },
+ {
+ "en": "SENEGAL",
+ "abbr": "SN",
+ "cn": "塞内加尔",
+ "id": 686
+ },
+ {
+ "en": "SERBIA",
+ "abbr": "RS",
+ "cn": "塞尔维亚",
+ "id": 688
+ },
+ {
+ "en": "SEYCHELLES",
+ "abbr": "SC",
+ "cn": "塞舌尔",
+ "id": 690
+ },
+ {
+ "en": "SIERRA LEONE",
+ "abbr": "SL",
+ "cn": "塞拉利昂",
+ "id": 694
+ },
+ {
+ "en": "SINGAPORE",
+ "abbr": "SG",
+ "cn": "新加坡",
+ "id": 702
+ },
+ {
+ "en": "SLOVAKIA",
+ "abbr": "SK",
+ "cn": "斯洛伐克",
+ "id": 703
+ },
+ {
+ "en": "SLOVENIA",
+ "abbr": "SI",
+ "cn": "斯洛文尼亚",
+ "id": 705
+ },
+ {
+ "en": "SOLOMON ISLANDS",
+ "abbr": "SB",
+ "cn": "所罗门群岛",
+ "id": 90
+ },
+ {
+ "en": "SOMALIA",
+ "abbr": "SO",
+ "cn": "索马里",
+ "id": 706
+ },
+ {
+ "en": "SOUTH AFRICA",
+ "abbr": "ZA",
+ "cn": "南非",
+ "id": 710
+ },
+ {
+ "en": "SOUTH GEORGIA AND THE SOUTH SANDWICH ISLANDS",
+ "abbr": "GS",
+ "cn": "南乔治亚和南桑德威奇群岛",
+ "id": 239
+ },
+ {
+ "en": "SPAIN",
+ "abbr": "ES",
+ "cn": "西班牙",
+ "id": 724
+ },
+ {
+ "en": "SRI LANKA",
+ "abbr": "LK",
+ "cn": "斯里兰卡",
+ "id": 144
+ },
+ {
+ "en": "SUDAN",
+ "abbr": "SD",
+ "cn": "苏丹",
+ "id": 736
+ },
+ {
+ "en": "SURINAME",
+ "abbr": "SR",
+ "cn": "苏里南",
+ "id": 740
+ },
+ {
+ "en": "SVALBARD AND JAN MAYEN",
+ "abbr": "SJ",
+ "cn": "斯瓦尔巴群岛和扬马延",
+ "id": 744
+ },
+ {
+ "en": "SWAZILAND",
+ "abbr": "SZ",
+ "cn": "斯威士兰",
+ "id": 748
+ },
+ {
+ "en": "SWEDEN",
+ "abbr": "SE",
+ "cn": "瑞典",
+ "id": 752
+ },
+ {
+ "en": "SWITZERLAND",
+ "abbr": "CH",
+ "cn": "瑞士",
+ "id": 756
+ },
+ {
+ "en": "SYRIAN ARAB REPUBLIC",
+ "abbr": "SY",
+ "cn": "叙利亚",
+ "id": 760
+ },
+ {
+ "en": "TAIWAN, PROVINCE OF CHINA",
+ "abbr": "TW",
+ "cn": "中国台湾省",
+ "id": 158
+ },
+ {
+ "en": "TAJIKISTAN",
+ "abbr": "TJ",
+ "cn": "塔吉克斯坦",
+ "id": 762
+ },
+ {
+ "en": "TANZANIA, UNITED REPUBLIC OF",
+ "abbr": "TZ",
+ "cn": "坦桑尼亚",
+ "id": 834
+ },
+ {
+ "en": "THAILAND",
+ "abbr": "TH",
+ "cn": "泰国",
+ "id": 764
+ },
+ {
+ "en": "TIMOR-LESTE",
+ "abbr": "TL",
+ "cn": "东帝汶",
+ "id": 626
+ },
+ {
+ "en": "TOGO",
+ "abbr": "TG",
+ "cn": "多哥",
+ "id": 768
+ },
+ {
+ "en": "TOKELAU",
+ "abbr": "TK",
+ "cn": "托克劳",
+ "id": 772
+ },
+ {
+ "en": "TONGA",
+ "abbr": "TO",
+ "cn": "汤加",
+ "id": 776
+ },
+ {
+ "en": "TRINIDAD AND TOBAGO",
+ "abbr": "TT",
+ "cn": "特立尼达和多巴哥",
+ "id": 780
+ },
+ {
+ "en": "TUNISIA",
+ "abbr": "TN",
+ "cn": "突尼斯",
+ "id": 788
+ },
+ {
+ "en": "TURKEY",
+ "abbr": "TR",
+ "cn": "土耳其",
+ "id": 792
+ },
+ {
+ "en": "TURKMENISTAN",
+ "abbr": "TM",
+ "cn": "土库曼斯坦",
+ "id": 795
+ },
+ {
+ "en": "TURKS AND CAICOS ISLANDS",
+ "abbr": "TC",
+ "cn": "特克斯群岛和凯科斯群岛",
+ "id": 796
+ },
+ {
+ "en": "TUVALU",
+ "abbr": "TV",
+ "cn": "图瓦卢",
+ "id": 798
+ },
+ {
+ "en": "UGANDA",
+ "abbr": "UG",
+ "cn": "乌干达",
+ "id": 800
+ },
+ {
+ "en": "UKRAINE",
+ "abbr": "UA",
+ "cn": "乌克兰",
+ "id": 804
+ },
+ {
+ "en": "UNITED ARAB EMIRATES",
+ "abbr": "AE",
+ "cn": "阿拉伯联合酋长国",
+ "id": 784
+ },
+ {
+ "en": "UNITED KINGDOM",
+ "abbr": "GB",
+ "cn": "英国",
+ "id": 826
+ },
+ {
+ "en": "UNITED STATES",
+ "abbr": "US",
+ "cn": "美国",
+ "id": 840
+ },
+ {
+ "en": "UNITED STATES MINOR OUTLYING ISLANDS",
+ "abbr": "UM",
+ "cn": "美属小奥特兰群岛",
+ "id": 581
+ },
+ {
+ "en": "URUGUAY",
+ "abbr": "UY",
+ "cn": "乌拉圭",
+ "id": 858
+ },
+ {
+ "en": "UZBEKISTAN",
+ "abbr": "UZ",
+ "cn": "乌兹别克斯坦",
+ "id": 860
+ },
+ {
+ "en": "VANUATU",
+ "abbr": "VU",
+ "cn": "瓦努阿图",
+ "id": 548
+ },
+ {
+ "en": "VENEZUELA, BOLIVARIAN REPUBLIC OF",
+ "abbr": "VE",
+ "cn": "委内瑞拉",
+ "id": 862
+ },
+ {
+ "en": "VIET NAM",
+ "abbr": "VN",
+ "cn": "越南",
+ "id": 704
+ },
+ {
+ "en": "VIRGIN ISLANDS, BRITISH",
+ "abbr": "VG",
+ "cn": "维尔京群岛(英属)",
+ "id": 92
+ },
+ {
+ "en": "VIRGIN ISLANDS, U.S.",
+ "abbr": "VI",
+ "cn": "维尔京群岛",
+ "id": 850
+ },
+ {
+ "en": "WALLIS AND FUTUNA",
+ "abbr": "WF",
+ "cn": "瓦利斯群岛和富图纳群岛",
+ "id": 876
+ },
+ {
+ "en": "WESTERN SAHARA",
+ "abbr": "EH",
+ "cn": "西撒哈拉",
+ "id": 732
+ },
+ {
+ "en": "YEMEN",
+ "abbr": "YE",
+ "cn": "也门",
+ "id": 887
+ },
+ {
+ "en": "ZAMBIA",
+ "abbr": "ZM",
+ "cn": "赞比亚",
+ "id": 894
+ },
+ {
+ "en": "ZIMBABWE",
+ "abbr": "ZW",
+ "cn": "津巴布韦",
+ "id": 716,
+ },
+ {
+ "en": "SCOTLAND",
+ "abbr": "SCOTLAND",
+ "cn": "苏格兰",
+ "id": 9001,
+ }
+]
+
+
+const chinaAreas = [{
+ "en": "HONG KONG",
+ "abbr": "HK",
+ "cn": "中国香港",
+ "id": 344
+},
+{
+ "en": "MACAO",
+ "abbr": "MO",
+ "cn": "中国澳门",
+ "id": 446
+}]
+
+
+module.exports = {
+ chinaAreas: chinaAreas,
+ countries: countries
+}
diff --git a/miniprogram/utils/icons.js b/miniprogram/utils/icons.js
new file mode 100644
index 0000000..bc5b1ea
--- /dev/null
+++ b/miniprogram/utils/icons.js
@@ -0,0 +1,13 @@
+
+
+const camera = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/PjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+PHN2ZyB0PSIxNTQwOTY2NzY5NDQyIiBjbGFzcz0iaWNvbiIgc3R5bGU9IiIgdmlld0JveD0iMCAwIDEzNjUgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9IjE5MTgiIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iMjY2LjYwMTU2MjUiIGhlaWdodD0iMjAwIj48ZGVmcz48c3R5bGUgdHlwZT0idGV4dC9jc3MiPjwvc3R5bGU+PC9kZWZzPjxwYXRoIGQ9Ik0xNjcuNTg0MzM0IDE3MS4xNjYxNjVjMC0xOS41Mjc4MzYgMC0zNy4yODA0MTMgMC01NS43NDMwOTQgNDAuNDc1ODc3IDAgNzkuODg2NiAwIDEyMC4zNjI0NzcgMCAwIDE4LjEwNzYyOSAwIDM1Ljg2MDIwNyAwIDU0LjMyMjg4OCAyNS41NjM3MTIgMi40ODUzNjEgNDcuMjIxODU3IDQuOTcwNzIyIDY2Ljc0OTY5Mi0xOS4xNzI3ODQgMzMuMzc0ODQ2LTQwLjQ3NTg3NyA3MC42NTUyNTktNzcuNzU2MjkxIDEwNy4yMjU1Ny0xMTUuMzkxNzU1QzQ4NS43MTA1MjcgMTAuNjgyODYyIDUxMy43NTk2LTAuNjc4Nzg4IDU0OS4yNjQ3NTUgMC4wMzEzMTZjOTIuNjY4NDU2IDIuMTMwMzA5IDE4NS42OTE5NjMgMS43NzUyNTggMjc4LjcxNTQ3MSAwIDMwLjg4OTQ4NS0wLjM1NTA1MiA1Ni4wOTgxNDYgOC41MjEyMzcgNzYuNjkxMTM2IDI5LjQ2OTI3OSA0MS4xODU5OCA0Mi4yNTExMzUgODEuMzA2ODA2IDg1LjU2NzQyNSAxMjEuNDI3NjMyIDEyOS4yMzg3NjYgOC41MjEyMzcgOS4yMzEzNCAxNi42ODc0MjMgMTIuNDI2ODA0IDI5LjExNDIyOCAxMi40MjY4MDQgNjYuNzQ5NjkyLTAuNzEwMTAzIDEzMy44NTQ0MzYtMC4zNTUwNTIgMjAwLjYwNDEyOS0wLjM1NTA1MiA2My4xOTkxNzcgMCAxMDguMjkwNzI0IDQ1LjA5MTU0NyAxMDguNjQ1Nzc2IDEwOC4yOTA3MjQgMCAyMDguNzcwMzE0LTAuMzU1MDUyIDQxNy41NDA2MjkgMC4zNTUwNTIgNjI2LjMxMDk0MyAwIDU2LjA5ODE0Ni00My42NzEzNDEgMTE4LjIzMjE2OC0xMTcuMTY3MDEzIDExNy44NzcxMTYtMzczLjE1OTE4NC0xLjQyMDIwNi03NDYuNjczNDItMS40MjAyMDYtMTExOS44MzI2MDQgMC02Ni4zOTQ2NDEgMC4zNTUwNTItMTI4LjUyODY2My01OS4yOTM2MS0xMjcuNDYzNTA4LTEyNy44MTg1NiAyLjQ4NTM2MS0yMDIuNzM0NDM4IDIuMTMwMzA5LTQwNS44MjM5MjcgMC4zNTUwNTItNjA4LjU1ODM2NS0wLjcxMDEwMy02Ny44MTQ4NDcgNTYuODA4MjQ5LTExNS43NDY4MDcgMTE1LjM5MTc1NS0xMTYuMTAxODU4QzEzMi4wNzkxNzggMTcxLjE2NjE2NSAxNDguNzY2NjAyIDE3MS4xNjYxNjUgMTY3LjU4NDMzNCAxNzEuMTY2MTY1ek0zNzkuOTA1MTY0IDU3OS4xMjA0MDJjMCAxNjcuMjI5MjgyIDEzNC4yMDk0ODggMzAyLjUwMzkyNSAzMDEuMDgzNzE5IDMwMi44NTg5NzYgMTY4LjI5NDQzNyAwLjM1NTA1MiAzMDMuOTI0MTMxLTEzMy44NTQ0MzYgMzA0LjI3OTE4My0zMDEuNDM4NzcgMC4zNTUwNTItMTY4LjI5NDQzNy0xMzQuMjA5NDg4LTMwMy41NjkwNzktMzAyLjE0ODg3My0zMDMuOTI0MTMxQzUxNS4xNzk4MDYgMjc2LjYxNjQ3NyAzNzkuOTA1MTY0IDQxMS4xODEwMTYgMzc5LjkwNTE2NCA1NzkuMTIwNDAyek0xMDIzLjk2ODY4NCAzNDQuMDc2MjcyYzIwLjU5Mjk5IDAgMzkuNzY1Nzc0IDAgNTguMjI4NDU1IDAgMC0yMC4yMzc5MzkgMC0zOS40MTA3MjMgMC01OC4yMjg0NTUtMjAuMjM3OTM5IDAtMzguNzAwNjE5IDAtNTguMjI4NDU1IDBDMTAyMy45Njg2ODQgMzA1LjM3NTY1MyAxMDIzLjk2ODY4NCAzMjMuODM4MzM0IDEwMjMuOTY4Njg0IDM0NC4wNzYyNzJ6IiBwLWlkPSIxOTE5IiBmaWxsPSIjZmZmZmZmIj48L3BhdGg+PHBhdGggZD0iTTY4Mi4wNTQwMzcgMzMyLjAwNDUxOWMxMzUuOTg0NzQ2IDIuNDg1MzYxIDI0Ni43NjA4MzEgMTA0Ljc0MDIwOSAyNDcuNDcwOTM0IDI0Ni40MDU3NzkgMS4wNjUxNTUgMTM4LjExNTA1NS0xMDYuNTE1NDY2IDI0Ni43NjA4MzEtMjQ3LjExNTg4MiAyNDguMTgxMDM3LTEzNS4yNzQ2NDIgMS40MjAyMDYtMjQ2Ljc2MDgzMS0xMTEuNDg2MTg4LTI0Ny40NzA5MzQtMjQ3LjExNTg4MkM0MzQuNTgzMTAzIDQ0NC45MTA5MTQgNTQ1LjcxNDI0IDMzMy40MjQ3MjYgNjgyLjA1NDAzNyAzMzIuMDA0NTE5ek02ODIuNDA5MDg5IDY5My4wOTE5NTFjNjEuMDY4ODY3IDAgMTEzLjI2MTQ0Ni01MS40ODI0NzUgMTEzLjk3MTU0OS0xMTIuNTUxMzQzIDAuNzEwMTAzLTYxLjc3ODk3MS01MS40ODI0NzUtMTE0LjY4MTY1Mi0xMTMuNjE2NDk4LTExNC42ODE2NTItNjEuMDY4ODY3IDAtMTEyLjkwNjM5NCA1MS4xMjc0MjQtMTEzLjk3MTU0OSAxMTIuNTUxMzQzQzU2OC4wODI0ODggNjM5LjgzNDIxOCA2MjAuMjc1MDY2IDY5My4wOTE5NTEgNjgyLjQwOTA4OSA2OTMuMDkxOTUxeiIgcC1pZD0iMTkyMCIgZmlsbD0iI2ZmZmZmZiI+PC9wYXRoPjwvc3ZnPg=='
+
+
+const namecard = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/PjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+PHN2ZyB0PSIxNTQwOTY3ODA5MjAyIiBjbGFzcz0iaWNvbiIgc3R5bGU9IiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9IjI1MjgiIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iMjAwIiBoZWlnaHQ9IjIwMCI+PGRlZnM+PHN0eWxlIHR5cGU9InRleHQvY3NzIj48L3N0eWxlPjwvZGVmcz48cGF0aCBkPSJNNzU2Ljc1MTM2IDM0OC44MzA3MiA3MDIuMzYxNiAzNDguODMwNzJjLTE1LjAzMjMyIDAtMjcuMTk3NDQgMTIuMTkwNzItMjcuMTk3NDQgMjcuMTk3NDRsMCA1NC4zODk3NmMwIDE1LjAzMjMyIDEyLjE2NTEyIDI3LjE5NzQ0IDI3LjE5NzQ0IDI3LjE5NzQ0bDU0LjM4OTc2IDBjMTUuMDMyMzIgMCAyNy4xOTIzMi0xMi4xNjUxMiAyNy4xOTIzMi0yNy4xOTc0NEw3ODMuOTQzNjggMzc2LjAyODE2Qzc4My45Mzg1NiAzNjEuMDIxNDQgNzcxLjc3ODU2IDM0OC44MzA3MiA3NTYuNzUxMzYgMzQ4LjgzMDcyeiIgcC1pZD0iMjUyOSIgZmlsbD0iI2ZmZmZmZiI+PC9wYXRoPjxwYXRoIGQ9Ik04MzguMzI4MzIgMTkwLjc5MTY4IDE4NS42NzE2OCAxOTAuNzkxNjhjLTYwLjA3Mjk2IDAtMTA4Ljc3OTUyIDQ4LjcwNjU2LTEwOC43Nzk1MiAxMDguNzc5NTJsMCA0MzUuMTAyNzJjMCA2MC4wNzI5NiA0OC43MDY1NiAxMDguNzc5NTIgMTA4Ljc3OTUyIDEwOC43Nzk1Mmw2NTIuNjYxNzYgMGM2MC4wNjc4NCAwIDEwOC43NzQ0LTQ4LjcwNjU2IDEwOC43NzQ0LTEwOC43Nzk1Mkw5NDcuMTA3ODQgMjk5LjU2NjA4Qzk0Ny4xMDI3MiAyMzkuNDkzMTIgODk4LjQwMTI4IDE5MC43OTE2OCA4MzguMzI4MzIgMTkwLjc5MTY4ek01MzkuMTk3NDQgNzI5LjU0ODggMjEyLjg2NCA3MjkuNTQ4OGMtMTUuMDMyMzIgMC0yNy4xOTc0NC0xMi4xNi0yNy4xOTc0NC0yNy4xOTIzMnMxMi4xNi0yNy4xOTc0NCAyNy4xOTc0NC0yNy4xOTc0NGwzMjYuMzI4MzIgMGMxNS4wMjcyIDAgMjcuMTk3NDQgMTIuMTY1MTIgMjcuMTk3NDQgMjcuMTk3NDRTNTU0LjIyNDY0IDcyOS41NDg4IDUzOS4xOTc0NCA3MjkuNTQ4OHpNNTM5LjE5NzQ0IDYyMC43Nzk1MiAyMTIuODY0IDYyMC43Nzk1MmMtMTUuMDMyMzIgMC0yNy4xOTc0NC0xMi4xNzAyNC0yNy4xOTc0NC0yNy4yMDI1NiAwLTE1LjAwMTYgMTIuMTYtMjcuMTkyMzIgMjcuMTk3NDQtMjcuMTkyMzJsMzI2LjMyODMyIDBjMTUuMDI3MiAwIDI3LjE5NzQ0IDEyLjE5MDcyIDI3LjE5NzQ0IDI3LjE5MjMyQzU2Ni4zODk3NiA2MDguNjA5MjggNTU0LjIyNDY0IDYyMC43Nzk1MiA1MzkuMTk3NDQgNjIwLjc3OTUyek04MzguMzI4MzIgNDU3LjYxMDI0YzAgMzAuMDM5MDQtMjQuMzUwNzIgNTQuMzg5NzYtNTQuMzg5NzYgNTQuMzg5NzZsLTEwOC43NzQ0IDBjLTMwLjAzMzkyIDAtNTQuMzg5NzYtMjQuMzUwNzItNTQuMzg5NzYtNTQuMzg5NzZMNjIwLjc3NDQgMzQ4LjgzNTg0YzAtMzAuMDMzOTIgMjQuMzU1ODQtNTQuMzg5NzYgNTQuMzg5NzYtNTQuMzg5NzZsMTA4Ljc3NDQgMGMzMC4wMzkwNCAwIDU0LjM4OTc2IDI0LjM1MDcyIDU0LjM4OTc2IDU0LjM4OTc2TDgzOC4zMjgzMiA0NTcuNjEwMjR6IiBwLWlkPSIyNTMwIiBmaWxsPSIjZmZmZmZmIj48L3BhdGg+PC9zdmc+'
+
+
+
+module.exports = {
+ camera: camera,
+ namecard: namecard
+}
diff --git a/miniprogram/utils/locale/zh-cn.js b/miniprogram/utils/locale/zh-cn.js
new file mode 100644
index 0000000..678bb1c
--- /dev/null
+++ b/miniprogram/utils/locale/zh-cn.js
@@ -0,0 +1,110 @@
+//! moment.js locale configuration
+
+; (function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined'
+ && typeof require === 'function' ? factory(require('../moment.min')) :
+ typeof define === 'function' && define.amd ? define(['../moment.min'], factory) :
+ factory(global.moment)
+}(this, (function (moment) {
+ 'use strict';
+
+
+ var zhCn = moment.defineLocale('zh-cn', {
+ months: '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_'),
+ monthsShort: '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),
+ weekdays: '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'),
+ weekdaysShort: '周日_周一_周二_周三_周四_周五_周六'.split('_'),
+ weekdaysMin: '日_一_二_三_四_五_六'.split('_'),
+ longDateFormat: {
+ LT: 'HH:mm',
+ LTS: 'HH:mm:ss',
+ L: 'YYYY/MM/DD',
+ LL: 'YYYY年M月D日',
+ LLL: 'YYYY年M月D日Ah点mm分',
+ LLLL: 'YYYY年M月D日ddddAh点mm分',
+ l: 'YYYY/M/D',
+ ll: 'YYYY年M月D日',
+ lll: 'YYYY年M月D日 HH:mm',
+ llll: 'YYYY年M月D日dddd HH:mm'
+ },
+ meridiemParse: /凌晨|早上|上午|中午|下午|晚上/,
+ meridiemHour: function (hour, meridiem) {
+ if (hour === 12) {
+ hour = 0;
+ }
+ if (meridiem === '凌晨' || meridiem === '早上' ||
+ meridiem === '上午') {
+ return hour;
+ } else if (meridiem === '下午' || meridiem === '晚上') {
+ return hour + 12;
+ } else {
+ // '中午'
+ return hour >= 11 ? hour : hour + 12;
+ }
+ },
+ meridiem: function (hour, minute, isLower) {
+ var hm = hour * 100 + minute;
+ if (hm < 600) {
+ return '凌晨';
+ } else if (hm < 900) {
+ return '早上';
+ } else if (hm < 1130) {
+ return '上午';
+ } else if (hm < 1230) {
+ return '中午';
+ } else if (hm < 1800) {
+ return '下午';
+ } else {
+ return '晚上';
+ }
+ },
+ calendar: {
+ sameDay: '[今天]LT',
+ nextDay: '[明天]LT',
+ nextWeek: '[下]ddddLT',
+ lastDay: '[昨天]LT',
+ lastWeek: '[上]ddddLT',
+ sameElse: 'L'
+ },
+ dayOfMonthOrdinalParse: /\d{1,2}(日|月|周)/,
+ ordinal: function (number, period) {
+ switch (period) {
+ case 'd':
+ case 'D':
+ case 'DDD':
+ return number + '日';
+ case 'M':
+ return number + '月';
+ case 'w':
+ case 'W':
+ return number + '周';
+ default:
+ return number;
+ }
+ },
+ relativeTime: {
+ future: '%s内',
+ past: '%s前',
+ s: '几秒',
+ ss: '%d 秒',
+ m: '1 分钟',
+ mm: '%d 分钟',
+ h: '1 小时',
+ hh: '%d 小时',
+ d: '1 天',
+ dd: '%d 天',
+ M: '1 个月',
+ MM: '%d 个月',
+ y: '1 年',
+ yy: '%d 年'
+ },
+ week: {
+ // GB/T 7408-1994《数据元和交换格式·信息交换·日期和时间表示法》与ISO 8601:1988等效
+ dow: 1, // Monday is the first day of the week.
+ doy: 4 // The week that contains Jan 4th is the first week of the year.
+ }
+ });
+
+ return zhCn;
+
+})));
diff --git a/miniprogram/utils/moment.min.js b/miniprogram/utils/moment.min.js
new file mode 100644
index 0000000..5df70b3
--- /dev/null
+++ b/miniprogram/utils/moment.min.js
@@ -0,0 +1 @@
+!function (e, t) { "object" == typeof exports && "undefined" != typeof module ? module.exports = t() : "function" == typeof define && define.amd ? define(t) : e.moment = t() }(this, function () { "use strict"; var e, i; function c() { return e.apply(null, arguments) } function o(e) { return e instanceof Array || "[object Array]" === Object.prototype.toString.call(e) } function u(e) { return null != e && "[object Object]" === Object.prototype.toString.call(e) } function l(e) { return void 0 === e } function h(e) { return "number" == typeof e || "[object Number]" === Object.prototype.toString.call(e) } function d(e) { return e instanceof Date || "[object Date]" === Object.prototype.toString.call(e) } function f(e, t) { var n, s = []; for (n = 0; n < e.length; ++n)s.push(t(e[n], n)); return s } function m(e, t) { return Object.prototype.hasOwnProperty.call(e, t) } function _(e, t) { for (var n in t) m(t, n) && (e[n] = t[n]); return m(t, "toString") && (e.toString = t.toString), m(t, "valueOf") && (e.valueOf = t.valueOf), e } function y(e, t, n, s) { return Tt(e, t, n, s, !0).utc() } function g(e) { return null == e._pf && (e._pf = { empty: !1, unusedTokens: [], unusedInput: [], overflow: -2, charsLeftOver: 0, nullInput: !1, invalidMonth: null, invalidFormat: !1, userInvalidated: !1, iso: !1, parsedDateParts: [], meridiem: null, rfc2822: !1, weekdayMismatch: !1 }), e._pf } function v(e) { if (null == e._isValid) { var t = g(e), n = i.call(t.parsedDateParts, function (e) { return null != e }), s = !isNaN(e._d.getTime()) && t.overflow < 0 && !t.empty && !t.invalidMonth && !t.invalidWeekday && !t.weekdayMismatch && !t.nullInput && !t.invalidFormat && !t.userInvalidated && (!t.meridiem || t.meridiem && n); if (e._strict && (s = s && 0 === t.charsLeftOver && 0 === t.unusedTokens.length && void 0 === t.bigHour), null != Object.isFrozen && Object.isFrozen(e)) return s; e._isValid = s } return e._isValid } function p(e) { var t = y(NaN); return null != e ? _(g(t), e) : g(t).userInvalidated = !0, t } i = Array.prototype.some ? Array.prototype.some : function (e) { for (var t = Object(this), n = t.length >>> 0, s = 0; s < n; s++)if (s in t && e.call(this, t[s], s, t)) return !0; return !1 }; var r = c.momentProperties = []; function w(e, t) { var n, s, i; if (l(t._isAMomentObject) || (e._isAMomentObject = t._isAMomentObject), l(t._i) || (e._i = t._i), l(t._f) || (e._f = t._f), l(t._l) || (e._l = t._l), l(t._strict) || (e._strict = t._strict), l(t._tzm) || (e._tzm = t._tzm), l(t._isUTC) || (e._isUTC = t._isUTC), l(t._offset) || (e._offset = t._offset), l(t._pf) || (e._pf = g(t)), l(t._locale) || (e._locale = t._locale), 0 < r.length) for (n = 0; n < r.length; n++)l(i = t[s = r[n]]) || (e[s] = i); return e } var t = !1; function M(e) { w(this, e), this._d = new Date(null != e._d ? e._d.getTime() : NaN), this.isValid() || (this._d = new Date(NaN)), !1 === t && (t = !0, c.updateOffset(this), t = !1) } function k(e) { return e instanceof M || null != e && null != e._isAMomentObject } function S(e) { return e < 0 ? Math.ceil(e) || 0 : Math.floor(e) } function D(e) { var t = +e, n = 0; return 0 !== t && isFinite(t) && (n = S(t)), n } function a(e, t, n) { var s, i = Math.min(e.length, t.length), r = Math.abs(e.length - t.length), a = 0; for (s = 0; s < i; s++)(n && e[s] !== t[s] || !n && D(e[s]) !== D(t[s])) && a++; return a + r } function Y(e) { !1 === c.suppressDeprecationWarnings && "undefined" != typeof console && console.warn && console.warn("Deprecation warning: " + e) } function n(i, r) { var a = !0; return _(function () { if (null != c.deprecationHandler && c.deprecationHandler(null, i), a) { for (var e, t = [], n = 0; n < arguments.length; n++) { if (e = "", "object" == typeof arguments[n]) { for (var s in e += "\n[" + n + "] ", arguments[0]) e += s + ": " + arguments[0][s] + ", "; e = e.slice(0, -2) } else e = arguments[n]; t.push(e) } Y(i + "\nArguments: " + Array.prototype.slice.call(t).join("") + "\n" + (new Error).stack), a = !1 } return r.apply(this, arguments) }, r) } var s, O = {}; function T(e, t) { null != c.deprecationHandler && c.deprecationHandler(e, t), O[e] || (Y(t), O[e] = !0) } function b(e) { return e instanceof Function || "[object Function]" === Object.prototype.toString.call(e) } function x(e, t) { var n, s = _({}, e); for (n in t) m(t, n) && (u(e[n]) && u(t[n]) ? (s[n] = {}, _(s[n], e[n]), _(s[n], t[n])) : null != t[n] ? s[n] = t[n] : delete s[n]); for (n in e) m(e, n) && !m(t, n) && u(e[n]) && (s[n] = _({}, s[n])); return s } function P(e) { null != e && this.set(e) } c.suppressDeprecationWarnings = !1, c.deprecationHandler = null, s = Object.keys ? Object.keys : function (e) { var t, n = []; for (t in e) m(e, t) && n.push(t); return n }; var W = {}; function C(e, t) { var n = e.toLowerCase(); W[n] = W[n + "s"] = W[t] = e } function H(e) { return "string" == typeof e ? W[e] || W[e.toLowerCase()] : void 0 } function R(e) { var t, n, s = {}; for (n in e) m(e, n) && (t = H(n)) && (s[t] = e[n]); return s } var U = {}; function F(e, t) { U[e] = t } function L(e, t, n) { var s = "" + Math.abs(e), i = t - s.length; return (0 <= e ? n ? "+" : "" : "-") + Math.pow(10, Math.max(0, i)).toString().substr(1) + s } var N = /(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g, G = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g, V = {}, E = {}; function I(e, t, n, s) { var i = s; "string" == typeof s && (i = function () { return this[s]() }), e && (E[e] = i), t && (E[t[0]] = function () { return L(i.apply(this, arguments), t[1], t[2]) }), n && (E[n] = function () { return this.localeData().ordinal(i.apply(this, arguments), e) }) } function A(e, t) { return e.isValid() ? (t = j(t, e.localeData()), V[t] = V[t] || function (s) { var e, i, t, r = s.match(N); for (e = 0, i = r.length; e < i; e++)E[r[e]] ? r[e] = E[r[e]] : r[e] = (t = r[e]).match(/\[[\s\S]/) ? t.replace(/^\[|\]$/g, "") : t.replace(/\\/g, ""); return function (e) { var t, n = ""; for (t = 0; t < i; t++)n += b(r[t]) ? r[t].call(e, s) : r[t]; return n } }(t), V[t](e)) : e.localeData().invalidDate() } function j(e, t) { var n = 5; function s(e) { return t.longDateFormat(e) || e } for (G.lastIndex = 0; 0 <= n && G.test(e);)e = e.replace(G, s), G.lastIndex = 0, n -= 1; return e } var Z = /\d/, z = /\d\d/, $ = /\d{3}/, q = /\d{4}/, J = /[+-]?\d{6}/, B = /\d\d?/, Q = /\d\d\d\d?/, X = /\d\d\d\d\d\d?/, K = /\d{1,3}/, ee = /\d{1,4}/, te = /[+-]?\d{1,6}/, ne = /\d+/, se = /[+-]?\d+/, ie = /Z|[+-]\d\d:?\d\d/gi, re = /Z|[+-]\d\d(?::?\d\d)?/gi, ae = /[0-9]{0,256}['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFF07\uFF10-\uFFEF]{1,256}|[\u0600-\u06FF\/]{1,256}(\s*?[\u0600-\u06FF]{1,256}){1,2}/i, oe = {}; function ue(e, n, s) { oe[e] = b(n) ? n : function (e, t) { return e && s ? s : n } } function le(e, t) { return m(oe, e) ? oe[e](t._strict, t._locale) : new RegExp(he(e.replace("\\", "").replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, function (e, t, n, s, i) { return t || n || s || i }))) } function he(e) { return e.replace(/[-\/\\^$*+?.()|[\]{}]/g, "\\$&") } var de = {}; function ce(e, n) { var t, s = n; for ("string" == typeof e && (e = [e]), h(n) && (s = function (e, t) { t[n] = D(e) }), t = 0; t < e.length; t++)de[e[t]] = s } function fe(e, i) { ce(e, function (e, t, n, s) { n._w = n._w || {}, i(e, n._w, n, s) }) } var me = 0, _e = 1, ye = 2, ge = 3, ve = 4, pe = 5, we = 6, Me = 7, ke = 8; function Se(e) { return De(e) ? 366 : 365 } function De(e) { return e % 4 == 0 && e % 100 != 0 || e % 400 == 0 } I("Y", 0, 0, function () { var e = this.year(); return e <= 9999 ? "" + e : "+" + e }), I(0, ["YY", 2], 0, function () { return this.year() % 100 }), I(0, ["YYYY", 4], 0, "year"), I(0, ["YYYYY", 5], 0, "year"), I(0, ["YYYYYY", 6, !0], 0, "year"), C("year", "y"), F("year", 1), ue("Y", se), ue("YY", B, z), ue("YYYY", ee, q), ue("YYYYY", te, J), ue("YYYYYY", te, J), ce(["YYYYY", "YYYYYY"], me), ce("YYYY", function (e, t) { t[me] = 2 === e.length ? c.parseTwoDigitYear(e) : D(e) }), ce("YY", function (e, t) { t[me] = c.parseTwoDigitYear(e) }), ce("Y", function (e, t) { t[me] = parseInt(e, 10) }), c.parseTwoDigitYear = function (e) { return D(e) + (68 < D(e) ? 1900 : 2e3) }; var Ye, Oe = Te("FullYear", !0); function Te(t, n) { return function (e) { return null != e ? (xe(this, t, e), c.updateOffset(this, n), this) : be(this, t) } } function be(e, t) { return e.isValid() ? e._d["get" + (e._isUTC ? "UTC" : "") + t]() : NaN } function xe(e, t, n) { e.isValid() && !isNaN(n) && ("FullYear" === t && De(e.year()) && 1 === e.month() && 29 === e.date() ? e._d["set" + (e._isUTC ? "UTC" : "") + t](n, e.month(), Pe(n, e.month())) : e._d["set" + (e._isUTC ? "UTC" : "") + t](n)) } function Pe(e, t) { if (isNaN(e) || isNaN(t)) return NaN; var n, s = (t % (n = 12) + n) % n; return e += (t - s) / 12, 1 === s ? De(e) ? 29 : 28 : 31 - s % 7 % 2 } Ye = Array.prototype.indexOf ? Array.prototype.indexOf : function (e) { var t; for (t = 0; t < this.length; ++t)if (this[t] === e) return t; return -1 }, I("M", ["MM", 2], "Mo", function () { return this.month() + 1 }), I("MMM", 0, 0, function (e) { return this.localeData().monthsShort(this, e) }), I("MMMM", 0, 0, function (e) { return this.localeData().months(this, e) }), C("month", "M"), F("month", 8), ue("M", B), ue("MM", B, z), ue("MMM", function (e, t) { return t.monthsShortRegex(e) }), ue("MMMM", function (e, t) { return t.monthsRegex(e) }), ce(["M", "MM"], function (e, t) { t[_e] = D(e) - 1 }), ce(["MMM", "MMMM"], function (e, t, n, s) { var i = n._locale.monthsParse(e, s, n._strict); null != i ? t[_e] = i : g(n).invalidMonth = e }); var We = /D[oD]?(\[[^\[\]]*\]|\s)+MMMM?/, Ce = "January_February_March_April_May_June_July_August_September_October_November_December".split("_"); var He = "Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"); function Re(e, t) { var n; if (!e.isValid()) return e; if ("string" == typeof t) if (/^\d+$/.test(t)) t = D(t); else if (!h(t = e.localeData().monthsParse(t))) return e; return n = Math.min(e.date(), Pe(e.year(), t)), e._d["set" + (e._isUTC ? "UTC" : "") + "Month"](t, n), e } function Ue(e) { return null != e ? (Re(this, e), c.updateOffset(this, !0), this) : be(this, "Month") } var Fe = ae; var Le = ae; function Ne() { function e(e, t) { return t.length - e.length } var t, n, s = [], i = [], r = []; for (t = 0; t < 12; t++)n = y([2e3, t]), s.push(this.monthsShort(n, "")), i.push(this.months(n, "")), r.push(this.months(n, "")), r.push(this.monthsShort(n, "")); for (s.sort(e), i.sort(e), r.sort(e), t = 0; t < 12; t++)s[t] = he(s[t]), i[t] = he(i[t]); for (t = 0; t < 24; t++)r[t] = he(r[t]); this._monthsRegex = new RegExp("^(" + r.join("|") + ")", "i"), this._monthsShortRegex = this._monthsRegex, this._monthsStrictRegex = new RegExp("^(" + i.join("|") + ")", "i"), this._monthsShortStrictRegex = new RegExp("^(" + s.join("|") + ")", "i") } function Ge(e) { var t; if (e < 100 && 0 <= e) { var n = Array.prototype.slice.call(arguments); n[0] = e + 400, t = new Date(Date.UTC.apply(null, n)), isFinite(t.getUTCFullYear()) && t.setUTCFullYear(e) } else t = new Date(Date.UTC.apply(null, arguments)); return t } function Ve(e, t, n) { var s = 7 + t - n; return -((7 + Ge(e, 0, s).getUTCDay() - t) % 7) + s - 1 } function Ee(e, t, n, s, i) { var r, a, o = 1 + 7 * (t - 1) + (7 + n - s) % 7 + Ve(e, s, i); return a = o <= 0 ? Se(r = e - 1) + o : o > Se(e) ? (r = e + 1, o - Se(e)) : (r = e, o), { year: r, dayOfYear: a } } function Ie(e, t, n) { var s, i, r = Ve(e.year(), t, n), a = Math.floor((e.dayOfYear() - r - 1) / 7) + 1; return a < 1 ? s = a + Ae(i = e.year() - 1, t, n) : a > Ae(e.year(), t, n) ? (s = a - Ae(e.year(), t, n), i = e.year() + 1) : (i = e.year(), s = a), { week: s, year: i } } function Ae(e, t, n) { var s = Ve(e, t, n), i = Ve(e + 1, t, n); return (Se(e) - s + i) / 7 } I("w", ["ww", 2], "wo", "week"), I("W", ["WW", 2], "Wo", "isoWeek"), C("week", "w"), C("isoWeek", "W"), F("week", 5), F("isoWeek", 5), ue("w", B), ue("ww", B, z), ue("W", B), ue("WW", B, z), fe(["w", "ww", "W", "WW"], function (e, t, n, s) { t[s.substr(0, 1)] = D(e) }); function je(e, t) { return e.slice(t, 7).concat(e.slice(0, t)) } I("d", 0, "do", "day"), I("dd", 0, 0, function (e) { return this.localeData().weekdaysMin(this, e) }), I("ddd", 0, 0, function (e) { return this.localeData().weekdaysShort(this, e) }), I("dddd", 0, 0, function (e) { return this.localeData().weekdays(this, e) }), I("e", 0, 0, "weekday"), I("E", 0, 0, "isoWeekday"), C("day", "d"), C("weekday", "e"), C("isoWeekday", "E"), F("day", 11), F("weekday", 11), F("isoWeekday", 11), ue("d", B), ue("e", B), ue("E", B), ue("dd", function (e, t) { return t.weekdaysMinRegex(e) }), ue("ddd", function (e, t) { return t.weekdaysShortRegex(e) }), ue("dddd", function (e, t) { return t.weekdaysRegex(e) }), fe(["dd", "ddd", "dddd"], function (e, t, n, s) { var i = n._locale.weekdaysParse(e, s, n._strict); null != i ? t.d = i : g(n).invalidWeekday = e }), fe(["d", "e", "E"], function (e, t, n, s) { t[s] = D(e) }); var Ze = "Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"); var ze = "Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"); var $e = "Su_Mo_Tu_We_Th_Fr_Sa".split("_"); var qe = ae; var Je = ae; var Be = ae; function Qe() { function e(e, t) { return t.length - e.length } var t, n, s, i, r, a = [], o = [], u = [], l = []; for (t = 0; t < 7; t++)n = y([2e3, 1]).day(t), s = this.weekdaysMin(n, ""), i = this.weekdaysShort(n, ""), r = this.weekdays(n, ""), a.push(s), o.push(i), u.push(r), l.push(s), l.push(i), l.push(r); for (a.sort(e), o.sort(e), u.sort(e), l.sort(e), t = 0; t < 7; t++)o[t] = he(o[t]), u[t] = he(u[t]), l[t] = he(l[t]); this._weekdaysRegex = new RegExp("^(" + l.join("|") + ")", "i"), this._weekdaysShortRegex = this._weekdaysRegex, this._weekdaysMinRegex = this._weekdaysRegex, this._weekdaysStrictRegex = new RegExp("^(" + u.join("|") + ")", "i"), this._weekdaysShortStrictRegex = new RegExp("^(" + o.join("|") + ")", "i"), this._weekdaysMinStrictRegex = new RegExp("^(" + a.join("|") + ")", "i") } function Xe() { return this.hours() % 12 || 12 } function Ke(e, t) { I(e, 0, 0, function () { return this.localeData().meridiem(this.hours(), this.minutes(), t) }) } function et(e, t) { return t._meridiemParse } I("H", ["HH", 2], 0, "hour"), I("h", ["hh", 2], 0, Xe), I("k", ["kk", 2], 0, function () { return this.hours() || 24 }), I("hmm", 0, 0, function () { return "" + Xe.apply(this) + L(this.minutes(), 2) }), I("hmmss", 0, 0, function () { return "" + Xe.apply(this) + L(this.minutes(), 2) + L(this.seconds(), 2) }), I("Hmm", 0, 0, function () { return "" + this.hours() + L(this.minutes(), 2) }), I("Hmmss", 0, 0, function () { return "" + this.hours() + L(this.minutes(), 2) + L(this.seconds(), 2) }), Ke("a", !0), Ke("A", !1), C("hour", "h"), F("hour", 13), ue("a", et), ue("A", et), ue("H", B), ue("h", B), ue("k", B), ue("HH", B, z), ue("hh", B, z), ue("kk", B, z), ue("hmm", Q), ue("hmmss", X), ue("Hmm", Q), ue("Hmmss", X), ce(["H", "HH"], ge), ce(["k", "kk"], function (e, t, n) { var s = D(e); t[ge] = 24 === s ? 0 : s }), ce(["a", "A"], function (e, t, n) { n._isPm = n._locale.isPM(e), n._meridiem = e }), ce(["h", "hh"], function (e, t, n) { t[ge] = D(e), g(n).bigHour = !0 }), ce("hmm", function (e, t, n) { var s = e.length - 2; t[ge] = D(e.substr(0, s)), t[ve] = D(e.substr(s)), g(n).bigHour = !0 }), ce("hmmss", function (e, t, n) { var s = e.length - 4, i = e.length - 2; t[ge] = D(e.substr(0, s)), t[ve] = D(e.substr(s, 2)), t[pe] = D(e.substr(i)), g(n).bigHour = !0 }), ce("Hmm", function (e, t, n) { var s = e.length - 2; t[ge] = D(e.substr(0, s)), t[ve] = D(e.substr(s)) }), ce("Hmmss", function (e, t, n) { var s = e.length - 4, i = e.length - 2; t[ge] = D(e.substr(0, s)), t[ve] = D(e.substr(s, 2)), t[pe] = D(e.substr(i)) }); var tt, nt = Te("Hours", !0), st = { calendar: { sameDay: "[Today at] LT", nextDay: "[Tomorrow at] LT", nextWeek: "dddd [at] LT", lastDay: "[Yesterday at] LT", lastWeek: "[Last] dddd [at] LT", sameElse: "L" }, longDateFormat: { LTS: "h:mm:ss A", LT: "h:mm A", L: "MM/DD/YYYY", LL: "MMMM D, YYYY", LLL: "MMMM D, YYYY h:mm A", LLLL: "dddd, MMMM D, YYYY h:mm A" }, invalidDate: "Invalid date", ordinal: "%d", dayOfMonthOrdinalParse: /\d{1,2}/, relativeTime: { future: "in %s", past: "%s ago", s: "a few seconds", ss: "%d seconds", m: "a minute", mm: "%d minutes", h: "an hour", hh: "%d hours", d: "a day", dd: "%d days", M: "a month", MM: "%d months", y: "a year", yy: "%d years" }, months: Ce, monthsShort: He, week: { dow: 0, doy: 6 }, weekdays: Ze, weekdaysMin: $e, weekdaysShort: ze, meridiemParse: /[ap]\.?m?\.?/i }, it = {}, rt = {}; function at(e) { return e ? e.toLowerCase().replace("_", "-") : e } function ot(e) { var t = null; if (!it[e] && "undefined" != typeof module && module && module.exports) try { t = tt._abbr, require("./locale/" + e), ut(t) } catch (e) { } return it[e] } function ut(e, t) { var n; return e && ((n = l(t) ? ht(e) : lt(e, t)) ? tt = n : "undefined" != typeof console && console.warn && console.warn("Locale " + e + " not found. Did you forget to load it?")), tt._abbr } function lt(e, t) { if (null === t) return delete it[e], null; var n, s = st; if (t.abbr = e, null != it[e]) T("defineLocaleOverride", "use moment.updateLocale(localeName, config) to change an existing locale. moment.defineLocale(localeName, config) should only be used for creating a new locale See http://momentjs.com/guides/#/warnings/define-locale/ for more info."), s = it[e]._config; else if (null != t.parentLocale) if (null != it[t.parentLocale]) s = it[t.parentLocale]._config; else { if (null == (n = ot(t.parentLocale))) return rt[t.parentLocale] || (rt[t.parentLocale] = []), rt[t.parentLocale].push({ name: e, config: t }), null; s = n._config } return it[e] = new P(x(s, t)), rt[e] && rt[e].forEach(function (e) { lt(e.name, e.config) }), ut(e), it[e] } function ht(e) { var t; if (e && e._locale && e._locale._abbr && (e = e._locale._abbr), !e) return tt; if (!o(e)) { if (t = ot(e)) return t; e = [e] } return function (e) { for (var t, n, s, i, r = 0; r < e.length;) { for (t = (i = at(e[r]).split("-")).length, n = (n = at(e[r + 1])) ? n.split("-") : null; 0 < t;) { if (s = ot(i.slice(0, t).join("-"))) return s; if (n && n.length >= t && a(i, n, !0) >= t - 1) break; t-- } r++ } return tt }(e) } function dt(e) { var t, n = e._a; return n && -2 === g(e).overflow && (t = n[_e] < 0 || 11 < n[_e] ? _e : n[ye] < 1 || n[ye] > Pe(n[me], n[_e]) ? ye : n[ge] < 0 || 24 < n[ge] || 24 === n[ge] && (0 !== n[ve] || 0 !== n[pe] || 0 !== n[we]) ? ge : n[ve] < 0 || 59 < n[ve] ? ve : n[pe] < 0 || 59 < n[pe] ? pe : n[we] < 0 || 999 < n[we] ? we : -1, g(e)._overflowDayOfYear && (t < me || ye < t) && (t = ye), g(e)._overflowWeeks && -1 === t && (t = Me), g(e)._overflowWeekday && -1 === t && (t = ke), g(e).overflow = t), e } function ct(e, t, n) { return null != e ? e : null != t ? t : n } function ft(e) { var t, n, s, i, r, a = []; if (!e._d) { var o, u; for (o = e, u = new Date(c.now()), s = o._useUTC ? [u.getUTCFullYear(), u.getUTCMonth(), u.getUTCDate()] : [u.getFullYear(), u.getMonth(), u.getDate()], e._w && null == e._a[ye] && null == e._a[_e] && function (e) { var t, n, s, i, r, a, o, u; if (null != (t = e._w).GG || null != t.W || null != t.E) r = 1, a = 4, n = ct(t.GG, e._a[me], Ie(bt(), 1, 4).year), s = ct(t.W, 1), ((i = ct(t.E, 1)) < 1 || 7 < i) && (u = !0); else { r = e._locale._week.dow, a = e._locale._week.doy; var l = Ie(bt(), r, a); n = ct(t.gg, e._a[me], l.year), s = ct(t.w, l.week), null != t.d ? ((i = t.d) < 0 || 6 < i) && (u = !0) : null != t.e ? (i = t.e + r, (t.e < 0 || 6 < t.e) && (u = !0)) : i = r } s < 1 || s > Ae(n, r, a) ? g(e)._overflowWeeks = !0 : null != u ? g(e)._overflowWeekday = !0 : (o = Ee(n, s, i, r, a), e._a[me] = o.year, e._dayOfYear = o.dayOfYear) }(e), null != e._dayOfYear && (r = ct(e._a[me], s[me]), (e._dayOfYear > Se(r) || 0 === e._dayOfYear) && (g(e)._overflowDayOfYear = !0), n = Ge(r, 0, e._dayOfYear), e._a[_e] = n.getUTCMonth(), e._a[ye] = n.getUTCDate()), t = 0; t < 3 && null == e._a[t]; ++t)e._a[t] = a[t] = s[t]; for (; t < 7; t++)e._a[t] = a[t] = null == e._a[t] ? 2 === t ? 1 : 0 : e._a[t]; 24 === e._a[ge] && 0 === e._a[ve] && 0 === e._a[pe] && 0 === e._a[we] && (e._nextDay = !0, e._a[ge] = 0), e._d = (e._useUTC ? Ge : function (e, t, n, s, i, r, a) { var o; return e < 100 && 0 <= e ? (o = new Date(e + 400, t, n, s, i, r, a), isFinite(o.getFullYear()) && o.setFullYear(e)) : o = new Date(e, t, n, s, i, r, a), o }).apply(null, a), i = e._useUTC ? e._d.getUTCDay() : e._d.getDay(), null != e._tzm && e._d.setUTCMinutes(e._d.getUTCMinutes() - e._tzm), e._nextDay && (e._a[ge] = 24), e._w && void 0 !== e._w.d && e._w.d !== i && (g(e).weekdayMismatch = !0) } } var mt = /^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/, _t = /^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/, yt = /Z|[+-]\d\d(?::?\d\d)?/, gt = [["YYYYYY-MM-DD", /[+-]\d{6}-\d\d-\d\d/], ["YYYY-MM-DD", /\d{4}-\d\d-\d\d/], ["GGGG-[W]WW-E", /\d{4}-W\d\d-\d/], ["GGGG-[W]WW", /\d{4}-W\d\d/, !1], ["YYYY-DDD", /\d{4}-\d{3}/], ["YYYY-MM", /\d{4}-\d\d/, !1], ["YYYYYYMMDD", /[+-]\d{10}/], ["YYYYMMDD", /\d{8}/], ["GGGG[W]WWE", /\d{4}W\d{3}/], ["GGGG[W]WW", /\d{4}W\d{2}/, !1], ["YYYYDDD", /\d{7}/]], vt = [["HH:mm:ss.SSSS", /\d\d:\d\d:\d\d\.\d+/], ["HH:mm:ss,SSSS", /\d\d:\d\d:\d\d,\d+/], ["HH:mm:ss", /\d\d:\d\d:\d\d/], ["HH:mm", /\d\d:\d\d/], ["HHmmss.SSSS", /\d\d\d\d\d\d\.\d+/], ["HHmmss,SSSS", /\d\d\d\d\d\d,\d+/], ["HHmmss", /\d\d\d\d\d\d/], ["HHmm", /\d\d\d\d/], ["HH", /\d\d/]], pt = /^\/?Date\((\-?\d+)/i; function wt(e) { var t, n, s, i, r, a, o = e._i, u = mt.exec(o) || _t.exec(o); if (u) { for (g(e).iso = !0, t = 0, n = gt.length; t < n; t++)if (gt[t][1].exec(u[1])) { i = gt[t][0], s = !1 !== gt[t][2]; break } if (null == i) return void (e._isValid = !1); if (u[3]) { for (t = 0, n = vt.length; t < n; t++)if (vt[t][1].exec(u[3])) { r = (u[2] || " ") + vt[t][0]; break } if (null == r) return void (e._isValid = !1) } if (!s && null != r) return void (e._isValid = !1); if (u[4]) { if (!yt.exec(u[4])) return void (e._isValid = !1); a = "Z" } e._f = i + (r || "") + (a || ""), Yt(e) } else e._isValid = !1 } var Mt = /^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\s)?(\d{1,2})\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(\d{2,4})\s(\d\d):(\d\d)(?::(\d\d))?\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|([+-]\d{4}))$/; function kt(e, t, n, s, i, r) { var a = [function (e) { var t = parseInt(e, 10); { if (t <= 49) return 2e3 + t; if (t <= 999) return 1900 + t } return t }(e), He.indexOf(t), parseInt(n, 10), parseInt(s, 10), parseInt(i, 10)]; return r && a.push(parseInt(r, 10)), a } var St = { UT: 0, GMT: 0, EDT: -240, EST: -300, CDT: -300, CST: -360, MDT: -360, MST: -420, PDT: -420, PST: -480 }; function Dt(e) { var t, n, s, i = Mt.exec(e._i.replace(/\([^)]*\)|[\n\t]/g, " ").replace(/(\s\s+)/g, " ").replace(/^\s\s*/, "").replace(/\s\s*$/, "")); if (i) { var r = kt(i[4], i[3], i[2], i[5], i[6], i[7]); if (t = i[1], n = r, s = e, t && ze.indexOf(t) !== new Date(n[0], n[1], n[2]).getDay() && (g(s).weekdayMismatch = !0, !(s._isValid = !1))) return; e._a = r, e._tzm = function (e, t, n) { if (e) return St[e]; if (t) return 0; var s = parseInt(n, 10), i = s % 100; return (s - i) / 100 * 60 + i }(i[8], i[9], i[10]), e._d = Ge.apply(null, e._a), e._d.setUTCMinutes(e._d.getUTCMinutes() - e._tzm), g(e).rfc2822 = !0 } else e._isValid = !1 } function Yt(e) { if (e._f !== c.ISO_8601) if (e._f !== c.RFC_2822) { e._a = [], g(e).empty = !0; var t, n, s, i, r, a, o, u, l = "" + e._i, h = l.length, d = 0; for (s = j(e._f, e._locale).match(N) || [], t = 0; t < s.length; t++)i = s[t], (n = (l.match(le(i, e)) || [])[0]) && (0 < (r = l.substr(0, l.indexOf(n))).length && g(e).unusedInput.push(r), l = l.slice(l.indexOf(n) + n.length), d += n.length), E[i] ? (n ? g(e).empty = !1 : g(e).unusedTokens.push(i), a = i, u = e, null != (o = n) && m(de, a) && de[a](o, u._a, u, a)) : e._strict && !n && g(e).unusedTokens.push(i); g(e).charsLeftOver = h - d, 0 < l.length && g(e).unusedInput.push(l), e._a[ge] <= 12 && !0 === g(e).bigHour && 0 < e._a[ge] && (g(e).bigHour = void 0), g(e).parsedDateParts = e._a.slice(0), g(e).meridiem = e._meridiem, e._a[ge] = function (e, t, n) { var s; if (null == n) return t; return null != e.meridiemHour ? e.meridiemHour(t, n) : (null != e.isPM && ((s = e.isPM(n)) && t < 12 && (t += 12), s || 12 !== t || (t = 0)), t) }(e._locale, e._a[ge], e._meridiem), ft(e), dt(e) } else Dt(e); else wt(e) } function Ot(e) { var t, n, s, i, r = e._i, a = e._f; return e._locale = e._locale || ht(e._l), null === r || void 0 === a && "" === r ? p({ nullInput: !0 }) : ("string" == typeof r && (e._i = r = e._locale.preparse(r)), k(r) ? new M(dt(r)) : (d(r) ? e._d = r : o(a) ? function (e) { var t, n, s, i, r; if (0 === e._f.length) return g(e).invalidFormat = !0, e._d = new Date(NaN); for (i = 0; i < e._f.length; i++)r = 0, t = w({}, e), null != e._useUTC && (t._useUTC = e._useUTC), t._f = e._f[i], Yt(t), v(t) && (r += g(t).charsLeftOver, r += 10 * g(t).unusedTokens.length, g(t).score = r, (null == s || r < s) && (s = r, n = t)); _(e, n || t) }(e) : a ? Yt(e) : l(n = (t = e)._i) ? t._d = new Date(c.now()) : d(n) ? t._d = new Date(n.valueOf()) : "string" == typeof n ? (s = t, null === (i = pt.exec(s._i)) ? (wt(s), !1 === s._isValid && (delete s._isValid, Dt(s), !1 === s._isValid && (delete s._isValid, c.createFromInputFallback(s)))) : s._d = new Date(+i[1])) : o(n) ? (t._a = f(n.slice(0), function (e) { return parseInt(e, 10) }), ft(t)) : u(n) ? function (e) { if (!e._d) { var t = R(e._i); e._a = f([t.year, t.month, t.day || t.date, t.hour, t.minute, t.second, t.millisecond], function (e) { return e && parseInt(e, 10) }), ft(e) } }(t) : h(n) ? t._d = new Date(n) : c.createFromInputFallback(t), v(e) || (e._d = null), e)) } function Tt(e, t, n, s, i) { var r, a = {}; return !0 !== n && !1 !== n || (s = n, n = void 0), (u(e) && function (e) { if (Object.getOwnPropertyNames) return 0 === Object.getOwnPropertyNames(e).length; var t; for (t in e) if (e.hasOwnProperty(t)) return !1; return !0 }(e) || o(e) && 0 === e.length) && (e = void 0), a._isAMomentObject = !0, a._useUTC = a._isUTC = i, a._l = n, a._i = e, a._f = t, a._strict = s, (r = new M(dt(Ot(a))))._nextDay && (r.add(1, "d"), r._nextDay = void 0), r } function bt(e, t, n, s) { return Tt(e, t, n, s, !1) } c.createFromInputFallback = n("value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are discouraged and will be removed in an upcoming major release. Please refer to http://momentjs.com/guides/#/warnings/js-date/ for more info.", function (e) { e._d = new Date(e._i + (e._useUTC ? " UTC" : "")) }), c.ISO_8601 = function () { }, c.RFC_2822 = function () { }; var xt = n("moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/", function () { var e = bt.apply(null, arguments); return this.isValid() && e.isValid() ? e < this ? this : e : p() }), Pt = n("moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/", function () { var e = bt.apply(null, arguments); return this.isValid() && e.isValid() ? this < e ? this : e : p() }); function Wt(e, t) { var n, s; if (1 === t.length && o(t[0]) && (t = t[0]), !t.length) return bt(); for (n = t[0], s = 1; s < t.length; ++s)t[s].isValid() && !t[s][e](n) || (n = t[s]); return n } var Ct = ["year", "quarter", "month", "week", "day", "hour", "minute", "second", "millisecond"]; function Ht(e) { var t = R(e), n = t.year || 0, s = t.quarter || 0, i = t.month || 0, r = t.week || t.isoWeek || 0, a = t.day || 0, o = t.hour || 0, u = t.minute || 0, l = t.second || 0, h = t.millisecond || 0; this._isValid = function (e) { for (var t in e) if (-1 === Ye.call(Ct, t) || null != e[t] && isNaN(e[t])) return !1; for (var n = !1, s = 0; s < Ct.length; ++s)if (e[Ct[s]]) { if (n) return !1; parseFloat(e[Ct[s]]) !== D(e[Ct[s]]) && (n = !0) } return !0 }(t), this._milliseconds = +h + 1e3 * l + 6e4 * u + 1e3 * o * 60 * 60, this._days = +a + 7 * r, this._months = +i + 3 * s + 12 * n, this._data = {}, this._locale = ht(), this._bubble() } function Rt(e) { return e instanceof Ht } function Ut(e) { return e < 0 ? -1 * Math.round(-1 * e) : Math.round(e) } function Ft(e, n) { I(e, 0, 0, function () { var e = this.utcOffset(), t = "+"; return e < 0 && (e = -e, t = "-"), t + L(~~(e / 60), 2) + n + L(~~e % 60, 2) }) } Ft("Z", ":"), Ft("ZZ", ""), ue("Z", re), ue("ZZ", re), ce(["Z", "ZZ"], function (e, t, n) { n._useUTC = !0, n._tzm = Nt(re, e) }); var Lt = /([\+\-]|\d\d)/gi; function Nt(e, t) { var n = (t || "").match(e); if (null === n) return null; var s = ((n[n.length - 1] || []) + "").match(Lt) || ["-", 0, 0], i = 60 * s[1] + D(s[2]); return 0 === i ? 0 : "+" === s[0] ? i : -i } function Gt(e, t) { var n, s; return t._isUTC ? (n = t.clone(), s = (k(e) || d(e) ? e.valueOf() : bt(e).valueOf()) - n.valueOf(), n._d.setTime(n._d.valueOf() + s), c.updateOffset(n, !1), n) : bt(e).local() } function Vt(e) { return 15 * -Math.round(e._d.getTimezoneOffset() / 15) } function Et() { return !!this.isValid() && (this._isUTC && 0 === this._offset) } c.updateOffset = function () { }; var It = /^(\-|\+)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)(\.\d*)?)?$/, At = /^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/; function jt(e, t) { var n, s, i, r = e, a = null; return Rt(e) ? r = { ms: e._milliseconds, d: e._days, M: e._months } : h(e) ? (r = {}, t ? r[t] = e : r.milliseconds = e) : (a = It.exec(e)) ? (n = "-" === a[1] ? -1 : 1, r = { y: 0, d: D(a[ye]) * n, h: D(a[ge]) * n, m: D(a[ve]) * n, s: D(a[pe]) * n, ms: D(Ut(1e3 * a[we])) * n }) : (a = At.exec(e)) ? (n = "-" === a[1] ? -1 : 1, r = { y: Zt(a[2], n), M: Zt(a[3], n), w: Zt(a[4], n), d: Zt(a[5], n), h: Zt(a[6], n), m: Zt(a[7], n), s: Zt(a[8], n) }) : null == r ? r = {} : "object" == typeof r && ("from" in r || "to" in r) && (i = function (e, t) { var n; if (!e.isValid() || !t.isValid()) return { milliseconds: 0, months: 0 }; t = Gt(t, e), e.isBefore(t) ? n = zt(e, t) : ((n = zt(t, e)).milliseconds = -n.milliseconds, n.months = -n.months); return n }(bt(r.from), bt(r.to)), (r = {}).ms = i.milliseconds, r.M = i.months), s = new Ht(r), Rt(e) && m(e, "_locale") && (s._locale = e._locale), s } function Zt(e, t) { var n = e && parseFloat(e.replace(",", ".")); return (isNaN(n) ? 0 : n) * t } function zt(e, t) { var n = {}; return n.months = t.month() - e.month() + 12 * (t.year() - e.year()), e.clone().add(n.months, "M").isAfter(t) && --n.months, n.milliseconds = +t - +e.clone().add(n.months, "M"), n } function $t(s, i) { return function (e, t) { var n; return null === t || isNaN(+t) || (T(i, "moment()." + i + "(period, number) is deprecated. Please use moment()." + i + "(number, period). See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info."), n = e, e = t, t = n), qt(this, jt(e = "string" == typeof e ? +e : e, t), s), this } } function qt(e, t, n, s) { var i = t._milliseconds, r = Ut(t._days), a = Ut(t._months); e.isValid() && (s = null == s || s, a && Re(e, be(e, "Month") + a * n), r && xe(e, "Date", be(e, "Date") + r * n), i && e._d.setTime(e._d.valueOf() + i * n), s && c.updateOffset(e, r || a)) } jt.fn = Ht.prototype, jt.invalid = function () { return jt(NaN) }; var Jt = $t(1, "add"), Bt = $t(-1, "subtract"); function Qt(e, t) { var n = 12 * (t.year() - e.year()) + (t.month() - e.month()), s = e.clone().add(n, "months"); return -(n + (t - s < 0 ? (t - s) / (s - e.clone().add(n - 1, "months")) : (t - s) / (e.clone().add(n + 1, "months") - s))) || 0 } function Xt(e) { var t; return void 0 === e ? this._locale._abbr : (null != (t = ht(e)) && (this._locale = t), this) } c.defaultFormat = "YYYY-MM-DDTHH:mm:ssZ", c.defaultFormatUtc = "YYYY-MM-DDTHH:mm:ss[Z]"; var Kt = n("moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.", function (e) { return void 0 === e ? this.localeData() : this.locale(e) }); function en() { return this._locale } var tn = 126227808e5; function nn(e, t) { return (e % t + t) % t } function sn(e, t, n) { return e < 100 && 0 <= e ? new Date(e + 400, t, n) - tn : new Date(e, t, n).valueOf() } function rn(e, t, n) { return e < 100 && 0 <= e ? Date.UTC(e + 400, t, n) - tn : Date.UTC(e, t, n) } function an(e, t) { I(0, [e, e.length], 0, t) } function on(e, t, n, s, i) { var r; return null == e ? Ie(this, s, i).year : ((r = Ae(e, s, i)) < t && (t = r), function (e, t, n, s, i) { var r = Ee(e, t, n, s, i), a = Ge(r.year, 0, r.dayOfYear); return this.year(a.getUTCFullYear()), this.month(a.getUTCMonth()), this.date(a.getUTCDate()), this }.call(this, e, t, n, s, i)) } I(0, ["gg", 2], 0, function () { return this.weekYear() % 100 }), I(0, ["GG", 2], 0, function () { return this.isoWeekYear() % 100 }), an("gggg", "weekYear"), an("ggggg", "weekYear"), an("GGGG", "isoWeekYear"), an("GGGGG", "isoWeekYear"), C("weekYear", "gg"), C("isoWeekYear", "GG"), F("weekYear", 1), F("isoWeekYear", 1), ue("G", se), ue("g", se), ue("GG", B, z), ue("gg", B, z), ue("GGGG", ee, q), ue("gggg", ee, q), ue("GGGGG", te, J), ue("ggggg", te, J), fe(["gggg", "ggggg", "GGGG", "GGGGG"], function (e, t, n, s) { t[s.substr(0, 2)] = D(e) }), fe(["gg", "GG"], function (e, t, n, s) { t[s] = c.parseTwoDigitYear(e) }), I("Q", 0, "Qo", "quarter"), C("quarter", "Q"), F("quarter", 7), ue("Q", Z), ce("Q", function (e, t) { t[_e] = 3 * (D(e) - 1) }), I("D", ["DD", 2], "Do", "date"), C("date", "D"), F("date", 9), ue("D", B), ue("DD", B, z), ue("Do", function (e, t) { return e ? t._dayOfMonthOrdinalParse || t._ordinalParse : t._dayOfMonthOrdinalParseLenient }), ce(["D", "DD"], ye), ce("Do", function (e, t) { t[ye] = D(e.match(B)[0]) }); var un = Te("Date", !0); I("DDD", ["DDDD", 3], "DDDo", "dayOfYear"), C("dayOfYear", "DDD"), F("dayOfYear", 4), ue("DDD", K), ue("DDDD", $), ce(["DDD", "DDDD"], function (e, t, n) { n._dayOfYear = D(e) }), I("m", ["mm", 2], 0, "minute"), C("minute", "m"), F("minute", 14), ue("m", B), ue("mm", B, z), ce(["m", "mm"], ve); var ln = Te("Minutes", !1); I("s", ["ss", 2], 0, "second"), C("second", "s"), F("second", 15), ue("s", B), ue("ss", B, z), ce(["s", "ss"], pe); var hn, dn = Te("Seconds", !1); for (I("S", 0, 0, function () { return ~~(this.millisecond() / 100) }), I(0, ["SS", 2], 0, function () { return ~~(this.millisecond() / 10) }), I(0, ["SSS", 3], 0, "millisecond"), I(0, ["SSSS", 4], 0, function () { return 10 * this.millisecond() }), I(0, ["SSSSS", 5], 0, function () { return 100 * this.millisecond() }), I(0, ["SSSSSS", 6], 0, function () { return 1e3 * this.millisecond() }), I(0, ["SSSSSSS", 7], 0, function () { return 1e4 * this.millisecond() }), I(0, ["SSSSSSSS", 8], 0, function () { return 1e5 * this.millisecond() }), I(0, ["SSSSSSSSS", 9], 0, function () { return 1e6 * this.millisecond() }), C("millisecond", "ms"), F("millisecond", 16), ue("S", K, Z), ue("SS", K, z), ue("SSS", K, $), hn = "SSSS"; hn.length <= 9; hn += "S")ue(hn, ne); function cn(e, t) { t[we] = D(1e3 * ("0." + e)) } for (hn = "S"; hn.length <= 9; hn += "S")ce(hn, cn); var fn = Te("Milliseconds", !1); I("z", 0, 0, "zoneAbbr"), I("zz", 0, 0, "zoneName"); var mn = M.prototype; function _n(e) { return e } mn.add = Jt, mn.calendar = function (e, t) { var n = e || bt(), s = Gt(n, this).startOf("day"), i = c.calendarFormat(this, s) || "sameElse", r = t && (b(t[i]) ? t[i].call(this, n) : t[i]); return this.format(r || this.localeData().calendar(i, this, bt(n))) }, mn.clone = function () { return new M(this) }, mn.diff = function (e, t, n) { var s, i, r; if (!this.isValid()) return NaN; if (!(s = Gt(e, this)).isValid()) return NaN; switch (i = 6e4 * (s.utcOffset() - this.utcOffset()), t = H(t)) { case "year": r = Qt(this, s) / 12; break; case "month": r = Qt(this, s); break; case "quarter": r = Qt(this, s) / 3; break; case "second": r = (this - s) / 1e3; break; case "minute": r = (this - s) / 6e4; break; case "hour": r = (this - s) / 36e5; break; case "day": r = (this - s - i) / 864e5; break; case "week": r = (this - s - i) / 6048e5; break; default: r = this - s }return n ? r : S(r) }, mn.endOf = function (e) { var t; if (void 0 === (e = H(e)) || "millisecond" === e || !this.isValid()) return this; var n = this._isUTC ? rn : sn; switch (e) { case "year": t = n(this.year() + 1, 0, 1) - 1; break; case "quarter": t = n(this.year(), this.month() - this.month() % 3 + 3, 1) - 1; break; case "month": t = n(this.year(), this.month() + 1, 1) - 1; break; case "week": t = n(this.year(), this.month(), this.date() - this.weekday() + 7) - 1; break; case "isoWeek": t = n(this.year(), this.month(), this.date() - (this.isoWeekday() - 1) + 7) - 1; break; case "day": case "date": t = n(this.year(), this.month(), this.date() + 1) - 1; break; case "hour": t = this._d.valueOf(), t += 36e5 - nn(t + (this._isUTC ? 0 : 6e4 * this.utcOffset()), 36e5) - 1; break; case "minute": t = this._d.valueOf(), t += 6e4 - nn(t, 6e4) - 1; break; case "second": t = this._d.valueOf(), t += 1e3 - nn(t, 1e3) - 1; break }return this._d.setTime(t), c.updateOffset(this, !0), this }, mn.format = function (e) { e || (e = this.isUtc() ? c.defaultFormatUtc : c.defaultFormat); var t = A(this, e); return this.localeData().postformat(t) }, mn.from = function (e, t) { return this.isValid() && (k(e) && e.isValid() || bt(e).isValid()) ? jt({ to: this, from: e }).locale(this.locale()).humanize(!t) : this.localeData().invalidDate() }, mn.fromNow = function (e) { return this.from(bt(), e) }, mn.to = function (e, t) { return this.isValid() && (k(e) && e.isValid() || bt(e).isValid()) ? jt({ from: this, to: e }).locale(this.locale()).humanize(!t) : this.localeData().invalidDate() }, mn.toNow = function (e) { return this.to(bt(), e) }, mn.get = function (e) { return b(this[e = H(e)]) ? this[e]() : this }, mn.invalidAt = function () { return g(this).overflow }, mn.isAfter = function (e, t) { var n = k(e) ? e : bt(e); return !(!this.isValid() || !n.isValid()) && ("millisecond" === (t = H(t) || "millisecond") ? this.valueOf() > n.valueOf() : n.valueOf() < this.clone().startOf(t).valueOf()) }, mn.isBefore = function (e, t) { var n = k(e) ? e : bt(e); return !(!this.isValid() || !n.isValid()) && ("millisecond" === (t = H(t) || "millisecond") ? this.valueOf() < n.valueOf() : this.clone().endOf(t).valueOf() < n.valueOf()) }, mn.isBetween = function (e, t, n, s) { var i = k(e) ? e : bt(e), r = k(t) ? t : bt(t); return !!(this.isValid() && i.isValid() && r.isValid()) && ("(" === (s = s || "()")[0] ? this.isAfter(i, n) : !this.isBefore(i, n)) && (")" === s[1] ? this.isBefore(r, n) : !this.isAfter(r, n)) }, mn.isSame = function (e, t) { var n, s = k(e) ? e : bt(e); return !(!this.isValid() || !s.isValid()) && ("millisecond" === (t = H(t) || "millisecond") ? this.valueOf() === s.valueOf() : (n = s.valueOf(), this.clone().startOf(t).valueOf() <= n && n <= this.clone().endOf(t).valueOf())) }, mn.isSameOrAfter = function (e, t) { return this.isSame(e, t) || this.isAfter(e, t) }, mn.isSameOrBefore = function (e, t) { return this.isSame(e, t) || this.isBefore(e, t) }, mn.isValid = function () { return v(this) }, mn.lang = Kt, mn.locale = Xt, mn.localeData = en, mn.max = Pt, mn.min = xt, mn.parsingFlags = function () { return _({}, g(this)) }, mn.set = function (e, t) { if ("object" == typeof e) for (var n = function (e) { var t = []; for (var n in e) t.push({ unit: n, priority: U[n] }); return t.sort(function (e, t) { return e.priority - t.priority }), t }(e = R(e)), s = 0; s < n.length; s++)this[n[s].unit](e[n[s].unit]); else if (b(this[e = H(e)])) return this[e](t); return this }, mn.startOf = function (e) { var t; if (void 0 === (e = H(e)) || "millisecond" === e || !this.isValid()) return this; var n = this._isUTC ? rn : sn; switch (e) { case "year": t = n(this.year(), 0, 1); break; case "quarter": t = n(this.year(), this.month() - this.month() % 3, 1); break; case "month": t = n(this.year(), this.month(), 1); break; case "week": t = n(this.year(), this.month(), this.date() - this.weekday()); break; case "isoWeek": t = n(this.year(), this.month(), this.date() - (this.isoWeekday() - 1)); break; case "day": case "date": t = n(this.year(), this.month(), this.date()); break; case "hour": t = this._d.valueOf(), t -= nn(t + (this._isUTC ? 0 : 6e4 * this.utcOffset()), 36e5); break; case "minute": t = this._d.valueOf(), t -= nn(t, 6e4); break; case "second": t = this._d.valueOf(), t -= nn(t, 1e3); break }return this._d.setTime(t), c.updateOffset(this, !0), this }, mn.subtract = Bt, mn.toArray = function () { var e = this; return [e.year(), e.month(), e.date(), e.hour(), e.minute(), e.second(), e.millisecond()] }, mn.toObject = function () { var e = this; return { years: e.year(), months: e.month(), date: e.date(), hours: e.hours(), minutes: e.minutes(), seconds: e.seconds(), milliseconds: e.milliseconds() } }, mn.toDate = function () { return new Date(this.valueOf()) }, mn.toISOString = function (e) { if (!this.isValid()) return null; var t = !0 !== e, n = t ? this.clone().utc() : this; return n.year() < 0 || 9999 < n.year() ? A(n, t ? "YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]" : "YYYYYY-MM-DD[T]HH:mm:ss.SSSZ") : b(Date.prototype.toISOString) ? t ? this.toDate().toISOString() : new Date(this.valueOf() + 60 * this.utcOffset() * 1e3).toISOString().replace("Z", A(n, "Z")) : A(n, t ? "YYYY-MM-DD[T]HH:mm:ss.SSS[Z]" : "YYYY-MM-DD[T]HH:mm:ss.SSSZ") }, mn.inspect = function () { if (!this.isValid()) return "moment.invalid(/* " + this._i + " */)"; var e = "moment", t = ""; this.isLocal() || (e = 0 === this.utcOffset() ? "moment.utc" : "moment.parseZone", t = "Z"); var n = "[" + e + '("]', s = 0 <= this.year() && this.year() <= 9999 ? "YYYY" : "YYYYYY", i = t + '[")]'; return this.format(n + s + "-MM-DD[T]HH:mm:ss.SSS" + i) }, mn.toJSON = function () { return this.isValid() ? this.toISOString() : null }, mn.toString = function () { return this.clone().locale("en").format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ") }, mn.unix = function () { return Math.floor(this.valueOf() / 1e3) }, mn.valueOf = function () { return this._d.valueOf() - 6e4 * (this._offset || 0) }, mn.creationData = function () { return { input: this._i, format: this._f, locale: this._locale, isUTC: this._isUTC, strict: this._strict } }, mn.year = Oe, mn.isLeapYear = function () { return De(this.year()) }, mn.weekYear = function (e) { return on.call(this, e, this.week(), this.weekday(), this.localeData()._week.dow, this.localeData()._week.doy) }, mn.isoWeekYear = function (e) { return on.call(this, e, this.isoWeek(), this.isoWeekday(), 1, 4) }, mn.quarter = mn.quarters = function (e) { return null == e ? Math.ceil((this.month() + 1) / 3) : this.month(3 * (e - 1) + this.month() % 3) }, mn.month = Ue, mn.daysInMonth = function () { return Pe(this.year(), this.month()) }, mn.week = mn.weeks = function (e) { var t = this.localeData().week(this); return null == e ? t : this.add(7 * (e - t), "d") }, mn.isoWeek = mn.isoWeeks = function (e) { var t = Ie(this, 1, 4).week; return null == e ? t : this.add(7 * (e - t), "d") }, mn.weeksInYear = function () { var e = this.localeData()._week; return Ae(this.year(), e.dow, e.doy) }, mn.isoWeeksInYear = function () { return Ae(this.year(), 1, 4) }, mn.date = un, mn.day = mn.days = function (e) { if (!this.isValid()) return null != e ? this : NaN; var t, n, s = this._isUTC ? this._d.getUTCDay() : this._d.getDay(); return null != e ? (t = e, n = this.localeData(), e = "string" != typeof t ? t : isNaN(t) ? "number" == typeof (t = n.weekdaysParse(t)) ? t : null : parseInt(t, 10), this.add(e - s, "d")) : s }, mn.weekday = function (e) { if (!this.isValid()) return null != e ? this : NaN; var t = (this.day() + 7 - this.localeData()._week.dow) % 7; return null == e ? t : this.add(e - t, "d") }, mn.isoWeekday = function (e) { if (!this.isValid()) return null != e ? this : NaN; if (null == e) return this.day() || 7; var t, n, s = (t = e, n = this.localeData(), "string" == typeof t ? n.weekdaysParse(t) % 7 || 7 : isNaN(t) ? null : t); return this.day(this.day() % 7 ? s : s - 7) }, mn.dayOfYear = function (e) { var t = Math.round((this.clone().startOf("day") - this.clone().startOf("year")) / 864e5) + 1; return null == e ? t : this.add(e - t, "d") }, mn.hour = mn.hours = nt, mn.minute = mn.minutes = ln, mn.second = mn.seconds = dn, mn.millisecond = mn.milliseconds = fn, mn.utcOffset = function (e, t, n) { var s, i = this._offset || 0; if (!this.isValid()) return null != e ? this : NaN; if (null == e) return this._isUTC ? i : Vt(this); if ("string" == typeof e) { if (null === (e = Nt(re, e))) return this } else Math.abs(e) < 16 && !n && (e *= 60); return !this._isUTC && t && (s = Vt(this)), this._offset = e, this._isUTC = !0, null != s && this.add(s, "m"), i !== e && (!t || this._changeInProgress ? qt(this, jt(e - i, "m"), 1, !1) : this._changeInProgress || (this._changeInProgress = !0, c.updateOffset(this, !0), this._changeInProgress = null)), this }, mn.utc = function (e) { return this.utcOffset(0, e) }, mn.local = function (e) { return this._isUTC && (this.utcOffset(0, e), this._isUTC = !1, e && this.subtract(Vt(this), "m")), this }, mn.parseZone = function () { if (null != this._tzm) this.utcOffset(this._tzm, !1, !0); else if ("string" == typeof this._i) { var e = Nt(ie, this._i); null != e ? this.utcOffset(e) : this.utcOffset(0, !0) } return this }, mn.hasAlignedHourOffset = function (e) { return !!this.isValid() && (e = e ? bt(e).utcOffset() : 0, (this.utcOffset() - e) % 60 == 0) }, mn.isDST = function () { return this.utcOffset() > this.clone().month(0).utcOffset() || this.utcOffset() > this.clone().month(5).utcOffset() }, mn.isLocal = function () { return !!this.isValid() && !this._isUTC }, mn.isUtcOffset = function () { return !!this.isValid() && this._isUTC }, mn.isUtc = Et, mn.isUTC = Et, mn.zoneAbbr = function () { return this._isUTC ? "UTC" : "" }, mn.zoneName = function () { return this._isUTC ? "Coordinated Universal Time" : "" }, mn.dates = n("dates accessor is deprecated. Use date instead.", un), mn.months = n("months accessor is deprecated. Use month instead", Ue), mn.years = n("years accessor is deprecated. Use year instead", Oe), mn.zone = n("moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/", function (e, t) { return null != e ? ("string" != typeof e && (e = -e), this.utcOffset(e, t), this) : -this.utcOffset() }), mn.isDSTShifted = n("isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information", function () { if (!l(this._isDSTShifted)) return this._isDSTShifted; var e = {}; if (w(e, this), (e = Ot(e))._a) { var t = e._isUTC ? y(e._a) : bt(e._a); this._isDSTShifted = this.isValid() && 0 < a(e._a, t.toArray()) } else this._isDSTShifted = !1; return this._isDSTShifted }); var yn = P.prototype; function gn(e, t, n, s) { var i = ht(), r = y().set(s, t); return i[n](r, e) } function vn(e, t, n) { if (h(e) && (t = e, e = void 0), e = e || "", null != t) return gn(e, t, n, "month"); var s, i = []; for (s = 0; s < 12; s++)i[s] = gn(e, s, n, "month"); return i } function pn(e, t, n, s) { t = ("boolean" == typeof e ? h(t) && (n = t, t = void 0) : (t = e, e = !1, h(n = t) && (n = t, t = void 0)), t || ""); var i, r = ht(), a = e ? r._week.dow : 0; if (null != n) return gn(t, (n + a) % 7, s, "day"); var o = []; for (i = 0; i < 7; i++)o[i] = gn(t, (i + a) % 7, s, "day"); return o } yn.calendar = function (e, t, n) { var s = this._calendar[e] || this._calendar.sameElse; return b(s) ? s.call(t, n) : s }, yn.longDateFormat = function (e) { var t = this._longDateFormat[e], n = this._longDateFormat[e.toUpperCase()]; return t || !n ? t : (this._longDateFormat[e] = n.replace(/MMMM|MM|DD|dddd/g, function (e) { return e.slice(1) }), this._longDateFormat[e]) }, yn.invalidDate = function () { return this._invalidDate }, yn.ordinal = function (e) { return this._ordinal.replace("%d", e) }, yn.preparse = _n, yn.postformat = _n, yn.relativeTime = function (e, t, n, s) { var i = this._relativeTime[n]; return b(i) ? i(e, t, n, s) : i.replace(/%d/i, e) }, yn.pastFuture = function (e, t) { var n = this._relativeTime[0 < e ? "future" : "past"]; return b(n) ? n(t) : n.replace(/%s/i, t) }, yn.set = function (e) { var t, n; for (n in e) b(t = e[n]) ? this[n] = t : this["_" + n] = t; this._config = e, this._dayOfMonthOrdinalParseLenient = new RegExp((this._dayOfMonthOrdinalParse.source || this._ordinalParse.source) + "|" + /\d{1,2}/.source) }, yn.months = function (e, t) { return e ? o(this._months) ? this._months[e.month()] : this._months[(this._months.isFormat || We).test(t) ? "format" : "standalone"][e.month()] : o(this._months) ? this._months : this._months.standalone }, yn.monthsShort = function (e, t) { return e ? o(this._monthsShort) ? this._monthsShort[e.month()] : this._monthsShort[We.test(t) ? "format" : "standalone"][e.month()] : o(this._monthsShort) ? this._monthsShort : this._monthsShort.standalone }, yn.monthsParse = function (e, t, n) { var s, i, r; if (this._monthsParseExact) return function (e, t, n) { var s, i, r, a = e.toLocaleLowerCase(); if (!this._monthsParse) for (this._monthsParse = [], this._longMonthsParse = [], this._shortMonthsParse = [], s = 0; s < 12; ++s)r = y([2e3, s]), this._shortMonthsParse[s] = this.monthsShort(r, "").toLocaleLowerCase(), this._longMonthsParse[s] = this.months(r, "").toLocaleLowerCase(); return n ? "MMM" === t ? -1 !== (i = Ye.call(this._shortMonthsParse, a)) ? i : null : -1 !== (i = Ye.call(this._longMonthsParse, a)) ? i : null : "MMM" === t ? -1 !== (i = Ye.call(this._shortMonthsParse, a)) ? i : -1 !== (i = Ye.call(this._longMonthsParse, a)) ? i : null : -1 !== (i = Ye.call(this._longMonthsParse, a)) ? i : -1 !== (i = Ye.call(this._shortMonthsParse, a)) ? i : null }.call(this, e, t, n); for (this._monthsParse || (this._monthsParse = [], this._longMonthsParse = [], this._shortMonthsParse = []), s = 0; s < 12; s++) { if (i = y([2e3, s]), n && !this._longMonthsParse[s] && (this._longMonthsParse[s] = new RegExp("^" + this.months(i, "").replace(".", "") + "$", "i"), this._shortMonthsParse[s] = new RegExp("^" + this.monthsShort(i, "").replace(".", "") + "$", "i")), n || this._monthsParse[s] || (r = "^" + this.months(i, "") + "|^" + this.monthsShort(i, ""), this._monthsParse[s] = new RegExp(r.replace(".", ""), "i")), n && "MMMM" === t && this._longMonthsParse[s].test(e)) return s; if (n && "MMM" === t && this._shortMonthsParse[s].test(e)) return s; if (!n && this._monthsParse[s].test(e)) return s } }, yn.monthsRegex = function (e) { return this._monthsParseExact ? (m(this, "_monthsRegex") || Ne.call(this), e ? this._monthsStrictRegex : this._monthsRegex) : (m(this, "_monthsRegex") || (this._monthsRegex = Le), this._monthsStrictRegex && e ? this._monthsStrictRegex : this._monthsRegex) }, yn.monthsShortRegex = function (e) { return this._monthsParseExact ? (m(this, "_monthsRegex") || Ne.call(this), e ? this._monthsShortStrictRegex : this._monthsShortRegex) : (m(this, "_monthsShortRegex") || (this._monthsShortRegex = Fe), this._monthsShortStrictRegex && e ? this._monthsShortStrictRegex : this._monthsShortRegex) }, yn.week = function (e) { return Ie(e, this._week.dow, this._week.doy).week }, yn.firstDayOfYear = function () { return this._week.doy }, yn.firstDayOfWeek = function () { return this._week.dow }, yn.weekdays = function (e, t) { var n = o(this._weekdays) ? this._weekdays : this._weekdays[e && !0 !== e && this._weekdays.isFormat.test(t) ? "format" : "standalone"]; return !0 === e ? je(n, this._week.dow) : e ? n[e.day()] : n }, yn.weekdaysMin = function (e) { return !0 === e ? je(this._weekdaysMin, this._week.dow) : e ? this._weekdaysMin[e.day()] : this._weekdaysMin }, yn.weekdaysShort = function (e) { return !0 === e ? je(this._weekdaysShort, this._week.dow) : e ? this._weekdaysShort[e.day()] : this._weekdaysShort }, yn.weekdaysParse = function (e, t, n) { var s, i, r; if (this._weekdaysParseExact) return function (e, t, n) { var s, i, r, a = e.toLocaleLowerCase(); if (!this._weekdaysParse) for (this._weekdaysParse = [], this._shortWeekdaysParse = [], this._minWeekdaysParse = [], s = 0; s < 7; ++s)r = y([2e3, 1]).day(s), this._minWeekdaysParse[s] = this.weekdaysMin(r, "").toLocaleLowerCase(), this._shortWeekdaysParse[s] = this.weekdaysShort(r, "").toLocaleLowerCase(), this._weekdaysParse[s] = this.weekdays(r, "").toLocaleLowerCase(); return n ? "dddd" === t ? -1 !== (i = Ye.call(this._weekdaysParse, a)) ? i : null : "ddd" === t ? -1 !== (i = Ye.call(this._shortWeekdaysParse, a)) ? i : null : -1 !== (i = Ye.call(this._minWeekdaysParse, a)) ? i : null : "dddd" === t ? -1 !== (i = Ye.call(this._weekdaysParse, a)) ? i : -1 !== (i = Ye.call(this._shortWeekdaysParse, a)) ? i : -1 !== (i = Ye.call(this._minWeekdaysParse, a)) ? i : null : "ddd" === t ? -1 !== (i = Ye.call(this._shortWeekdaysParse, a)) ? i : -1 !== (i = Ye.call(this._weekdaysParse, a)) ? i : -1 !== (i = Ye.call(this._minWeekdaysParse, a)) ? i : null : -1 !== (i = Ye.call(this._minWeekdaysParse, a)) ? i : -1 !== (i = Ye.call(this._weekdaysParse, a)) ? i : -1 !== (i = Ye.call(this._shortWeekdaysParse, a)) ? i : null }.call(this, e, t, n); for (this._weekdaysParse || (this._weekdaysParse = [], this._minWeekdaysParse = [], this._shortWeekdaysParse = [], this._fullWeekdaysParse = []), s = 0; s < 7; s++) { if (i = y([2e3, 1]).day(s), n && !this._fullWeekdaysParse[s] && (this._fullWeekdaysParse[s] = new RegExp("^" + this.weekdays(i, "").replace(".", "\\.?") + "$", "i"), this._shortWeekdaysParse[s] = new RegExp("^" + this.weekdaysShort(i, "").replace(".", "\\.?") + "$", "i"), this._minWeekdaysParse[s] = new RegExp("^" + this.weekdaysMin(i, "").replace(".", "\\.?") + "$", "i")), this._weekdaysParse[s] || (r = "^" + this.weekdays(i, "") + "|^" + this.weekdaysShort(i, "") + "|^" + this.weekdaysMin(i, ""), this._weekdaysParse[s] = new RegExp(r.replace(".", ""), "i")), n && "dddd" === t && this._fullWeekdaysParse[s].test(e)) return s; if (n && "ddd" === t && this._shortWeekdaysParse[s].test(e)) return s; if (n && "dd" === t && this._minWeekdaysParse[s].test(e)) return s; if (!n && this._weekdaysParse[s].test(e)) return s } }, yn.weekdaysRegex = function (e) { return this._weekdaysParseExact ? (m(this, "_weekdaysRegex") || Qe.call(this), e ? this._weekdaysStrictRegex : this._weekdaysRegex) : (m(this, "_weekdaysRegex") || (this._weekdaysRegex = qe), this._weekdaysStrictRegex && e ? this._weekdaysStrictRegex : this._weekdaysRegex) }, yn.weekdaysShortRegex = function (e) { return this._weekdaysParseExact ? (m(this, "_weekdaysRegex") || Qe.call(this), e ? this._weekdaysShortStrictRegex : this._weekdaysShortRegex) : (m(this, "_weekdaysShortRegex") || (this._weekdaysShortRegex = Je), this._weekdaysShortStrictRegex && e ? this._weekdaysShortStrictRegex : this._weekdaysShortRegex) }, yn.weekdaysMinRegex = function (e) { return this._weekdaysParseExact ? (m(this, "_weekdaysRegex") || Qe.call(this), e ? this._weekdaysMinStrictRegex : this._weekdaysMinRegex) : (m(this, "_weekdaysMinRegex") || (this._weekdaysMinRegex = Be), this._weekdaysMinStrictRegex && e ? this._weekdaysMinStrictRegex : this._weekdaysMinRegex) }, yn.isPM = function (e) { return "p" === (e + "").toLowerCase().charAt(0) }, yn.meridiem = function (e, t, n) { return 11 < e ? n ? "pm" : "PM" : n ? "am" : "AM" }, ut("en", { dayOfMonthOrdinalParse: /\d{1,2}(th|st|nd|rd)/, ordinal: function (e) { var t = e % 10; return e + (1 === D(e % 100 / 10) ? "th" : 1 === t ? "st" : 2 === t ? "nd" : 3 === t ? "rd" : "th") } }), c.lang = n("moment.lang is deprecated. Use moment.locale instead.", ut), c.langData = n("moment.langData is deprecated. Use moment.localeData instead.", ht); var wn = Math.abs; function Mn(e, t, n, s) { var i = jt(t, n); return e._milliseconds += s * i._milliseconds, e._days += s * i._days, e._months += s * i._months, e._bubble() } function kn(e) { return e < 0 ? Math.floor(e) : Math.ceil(e) } function Sn(e) { return 4800 * e / 146097 } function Dn(e) { return 146097 * e / 4800 } function Yn(e) { return function () { return this.as(e) } } var On = Yn("ms"), Tn = Yn("s"), bn = Yn("m"), xn = Yn("h"), Pn = Yn("d"), Wn = Yn("w"), Cn = Yn("M"), Hn = Yn("Q"), Rn = Yn("y"); function Un(e) { return function () { return this.isValid() ? this._data[e] : NaN } } var Fn = Un("milliseconds"), Ln = Un("seconds"), Nn = Un("minutes"), Gn = Un("hours"), Vn = Un("days"), En = Un("months"), In = Un("years"); var An = Math.round, jn = { ss: 44, s: 45, m: 45, h: 22, d: 26, M: 11 }; var Zn = Math.abs; function zn(e) { return (0 < e) - (e < 0) || +e } function $n() { if (!this.isValid()) return this.localeData().invalidDate(); var e, t, n = Zn(this._milliseconds) / 1e3, s = Zn(this._days), i = Zn(this._months); t = S((e = S(n / 60)) / 60), n %= 60, e %= 60; var r = S(i / 12), a = i %= 12, o = s, u = t, l = e, h = n ? n.toFixed(3).replace(/\.?0+$/, "") : "", d = this.asSeconds(); if (!d) return "P0D"; var c = d < 0 ? "-" : "", f = zn(this._months) !== zn(d) ? "-" : "", m = zn(this._days) !== zn(d) ? "-" : "", _ = zn(this._milliseconds) !== zn(d) ? "-" : ""; return c + "P" + (r ? f + r + "Y" : "") + (a ? f + a + "M" : "") + (o ? m + o + "D" : "") + (u || l || h ? "T" : "") + (u ? _ + u + "H" : "") + (l ? _ + l + "M" : "") + (h ? _ + h + "S" : "") } var qn = Ht.prototype; return qn.isValid = function () { return this._isValid }, qn.abs = function () { var e = this._data; return this._milliseconds = wn(this._milliseconds), this._days = wn(this._days), this._months = wn(this._months), e.milliseconds = wn(e.milliseconds), e.seconds = wn(e.seconds), e.minutes = wn(e.minutes), e.hours = wn(e.hours), e.months = wn(e.months), e.years = wn(e.years), this }, qn.add = function (e, t) { return Mn(this, e, t, 1) }, qn.subtract = function (e, t) { return Mn(this, e, t, -1) }, qn.as = function (e) { if (!this.isValid()) return NaN; var t, n, s = this._milliseconds; if ("month" === (e = H(e)) || "quarter" === e || "year" === e) switch (t = this._days + s / 864e5, n = this._months + Sn(t), e) { case "month": return n; case "quarter": return n / 3; case "year": return n / 12 } else switch (t = this._days + Math.round(Dn(this._months)), e) { case "week": return t / 7 + s / 6048e5; case "day": return t + s / 864e5; case "hour": return 24 * t + s / 36e5; case "minute": return 1440 * t + s / 6e4; case "second": return 86400 * t + s / 1e3; case "millisecond": return Math.floor(864e5 * t) + s; default: throw new Error("Unknown unit " + e) } }, qn.asMilliseconds = On, qn.asSeconds = Tn, qn.asMinutes = bn, qn.asHours = xn, qn.asDays = Pn, qn.asWeeks = Wn, qn.asMonths = Cn, qn.asQuarters = Hn, qn.asYears = Rn, qn.valueOf = function () { return this.isValid() ? this._milliseconds + 864e5 * this._days + this._months % 12 * 2592e6 + 31536e6 * D(this._months / 12) : NaN }, qn._bubble = function () { var e, t, n, s, i, r = this._milliseconds, a = this._days, o = this._months, u = this._data; return 0 <= r && 0 <= a && 0 <= o || r <= 0 && a <= 0 && o <= 0 || (r += 864e5 * kn(Dn(o) + a), o = a = 0), u.milliseconds = r % 1e3, e = S(r / 1e3), u.seconds = e % 60, t = S(e / 60), u.minutes = t % 60, n = S(t / 60), u.hours = n % 24, o += i = S(Sn(a += S(n / 24))), a -= kn(Dn(i)), s = S(o / 12), o %= 12, u.days = a, u.months = o, u.years = s, this }, qn.clone = function () { return jt(this) }, qn.get = function (e) { return e = H(e), this.isValid() ? this[e + "s"]() : NaN }, qn.milliseconds = Fn, qn.seconds = Ln, qn.minutes = Nn, qn.hours = Gn, qn.days = Vn, qn.weeks = function () { return S(this.days() / 7) }, qn.months = En, qn.years = In, qn.humanize = function (e) { if (!this.isValid()) return this.localeData().invalidDate(); var t, n, s, i, r, a, o, u, l, h, d, c = this.localeData(), f = (n = !e, s = c, i = jt(t = this).abs(), r = An(i.as("s")), a = An(i.as("m")), o = An(i.as("h")), u = An(i.as("d")), l = An(i.as("M")), h = An(i.as("y")), (d = r <= jn.ss && ["s", r] || r < jn.s && ["ss", r] || a <= 1 && ["m"] || a < jn.m && ["mm", a] || o <= 1 && ["h"] || o < jn.h && ["hh", o] || u <= 1 && ["d"] || u < jn.d && ["dd", u] || l <= 1 && ["M"] || l < jn.M && ["MM", l] || h <= 1 && ["y"] || ["yy", h])[2] = n, d[3] = 0 < +t, d[4] = s, function (e, t, n, s, i) { return i.relativeTime(t || 1, !!n, e, s) }.apply(null, d)); return e && (f = c.pastFuture(+this, f)), c.postformat(f) }, qn.toISOString = $n, qn.toString = $n, qn.toJSON = $n, qn.locale = Xt, qn.localeData = en, qn.toIsoString = n("toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)", $n), qn.lang = Kt, I("X", 0, 0, "unix"), I("x", 0, 0, "valueOf"), ue("x", se), ue("X", /[+-]?\d+(\.\d{1,3})?/), ce("X", function (e, t, n) { n._d = new Date(1e3 * parseFloat(e, 10)) }), ce("x", function (e, t, n) { n._d = new Date(D(e)) }), c.version = "2.24.0", e = bt, c.fn = mn, c.min = function () { return Wt("isBefore", [].slice.call(arguments, 0)) }, c.max = function () { return Wt("isAfter", [].slice.call(arguments, 0)) }, c.now = function () { return Date.now ? Date.now() : +new Date }, c.utc = y, c.unix = function (e) { return bt(1e3 * e) }, c.months = function (e, t) { return vn(e, t, "months") }, c.isDate = d, c.locale = ut, c.invalid = p, c.duration = jt, c.isMoment = k, c.weekdays = function (e, t, n) { return pn(e, t, n, "weekdays") }, c.parseZone = function () { return bt.apply(null, arguments).parseZone() }, c.localeData = ht, c.isDuration = Rt, c.monthsShort = function (e, t) { return vn(e, t, "monthsShort") }, c.weekdaysMin = function (e, t, n) { return pn(e, t, n, "weekdaysMin") }, c.defineLocale = lt, c.updateLocale = function (e, t) { if (null != t) { var n, s, i = st; null != (s = ot(e)) && (i = s._config), (n = new P(t = x(i, t))).parentLocale = it[e], it[e] = n, ut(e) } else null != it[e] && (null != it[e].parentLocale ? it[e] = it[e].parentLocale : null != it[e] && delete it[e]); return it[e] }, c.locales = function () { return s(it) }, c.weekdaysShort = function (e, t, n) { return pn(e, t, n, "weekdaysShort") }, c.normalizeUnits = H, c.relativeTimeRounding = function (e) { return void 0 === e ? An : "function" == typeof e && (An = e, !0) }, c.relativeTimeThreshold = function (e, t) { return void 0 !== jn[e] && (void 0 === t ? jn[e] : (jn[e] = t, "s" === e && (jn.ss = t - 1), !0)) }, c.calendarFormat = function (e, t) { var n = e.diff(t, "days", !0); return n < -6 ? "sameElse" : n < -1 ? "lastWeek" : n < 0 ? "lastDay" : n < 1 ? "sameDay" : n < 2 ? "nextDay" : n < 7 ? "nextWeek" : "sameElse" }, c.prototype = mn, c.HTML5_FMT = { DATETIME_LOCAL: "YYYY-MM-DDTHH:mm", DATETIME_LOCAL_SECONDS: "YYYY-MM-DDTHH:mm:ss", DATETIME_LOCAL_MS: "YYYY-MM-DDTHH:mm:ss.SSS", DATE: "YYYY-MM-DD", TIME: "HH:mm", TIME_SECONDS: "HH:mm:ss", TIME_MS: "HH:mm:ss.SSS", WEEK: "GGGG-[W]WW", MONTH: "YYYY-MM" }, c });
\ No newline at end of file
diff --git a/miniprogram/utils/objectUtils.js b/miniprogram/utils/objectUtils.js
new file mode 100644
index 0000000..6c0fb1a
--- /dev/null
+++ b/miniprogram/utils/objectUtils.js
@@ -0,0 +1,13 @@
+function mergePages(...pages) {
+ let pageData = {}
+ let pageObject = {}
+ for (let page of pages) {
+ pageData = Object.assign({}, pageData, page.data)
+ pageObject = Object.assign({}, pageObject, page)
+ }
+ pageObject.data = pageData
+ return pageObject
+}
+
+
+module.exports = mergePages
\ No newline at end of file
diff --git a/miniprogram/utils/qqmap-wx-jssdk.min.js b/miniprogram/utils/qqmap-wx-jssdk.min.js
new file mode 100755
index 0000000..3323249
--- /dev/null
+++ b/miniprogram/utils/qqmap-wx-jssdk.min.js
@@ -0,0 +1,2 @@
+var _createClass=function(){function a(e,c){for(var b=0;b",
+ "description": "Runtime for Regenerator-compiled generator and async functions.",
+ "version": "0.13.1",
+ "main": "runtime.js",
+ "keywords": [
+ "regenerator",
+ "runtime",
+ "generator",
+ "async"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/facebook/regenerator/tree/master/packages/regenerator-runtime"
+ },
+ "license": "MIT"
+}
diff --git a/miniprogram/utils/regenerator-runtime/path.js b/miniprogram/utils/regenerator-runtime/path.js
new file mode 100755
index 0000000..ced878b
--- /dev/null
+++ b/miniprogram/utils/regenerator-runtime/path.js
@@ -0,0 +1,11 @@
+/**
+ * Copyright (c) 2014-present, Facebook, Inc.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+exports.path = require("path").join(
+ __dirname,
+ "runtime.js"
+);
diff --git a/miniprogram/utils/regenerator-runtime/runtime.js b/miniprogram/utils/regenerator-runtime/runtime.js
new file mode 100755
index 0000000..9cec7ae
--- /dev/null
+++ b/miniprogram/utils/regenerator-runtime/runtime.js
@@ -0,0 +1,711 @@
+/**
+ * Copyright (c) 2014-present, Facebook, Inc.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+var regeneratorRuntime = (function (exports) {
+ "use strict";
+
+ var Op = Object.prototype;
+ var hasOwn = Op.hasOwnProperty;
+ var undefined; // More compressible than void 0.
+ var $Symbol = typeof Symbol === "function" ? Symbol : {};
+ var iteratorSymbol = $Symbol.iterator || "@@iterator";
+ var asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator";
+ var toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag";
+
+ function wrap(innerFn, outerFn, self, tryLocsList) {
+ // If outerFn provided and outerFn.prototype is a Generator, then outerFn.prototype instanceof Generator.
+ var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator;
+ var generator = Object.create(protoGenerator.prototype);
+ var context = new Context(tryLocsList || []);
+
+ // The ._invoke method unifies the implementations of the .next,
+ // .throw, and .return methods.
+ generator._invoke = makeInvokeMethod(innerFn, self, context);
+
+ return generator;
+ }
+ exports.wrap = wrap;
+
+ // Try/catch helper to minimize deoptimizations. Returns a completion
+ // record like context.tryEntries[i].completion. This interface could
+ // have been (and was previously) designed to take a closure to be
+ // invoked without arguments, but in all the cases we care about we
+ // already have an existing method we want to call, so there's no need
+ // to create a new function object. We can even get away with assuming
+ // the method takes exactly one argument, since that happens to be true
+ // in every case, so we don't have to touch the arguments object. The
+ // only additional allocation required is the completion record, which
+ // has a stable shape and so hopefully should be cheap to allocate.
+ function tryCatch(fn, obj, arg) {
+ try {
+ return { type: "normal", arg: fn.call(obj, arg) };
+ } catch (err) {
+ return { type: "throw", arg: err };
+ }
+ }
+
+ var GenStateSuspendedStart = "suspendedStart";
+ var GenStateSuspendedYield = "suspendedYield";
+ var GenStateExecuting = "executing";
+ var GenStateCompleted = "completed";
+
+ // Returning this object from the innerFn has the same effect as
+ // breaking out of the dispatch switch statement.
+ var ContinueSentinel = {};
+
+ // Dummy constructor functions that we use as the .constructor and
+ // .constructor.prototype properties for functions that return Generator
+ // objects. For full spec compliance, you may wish to configure your
+ // minifier not to mangle the names of these two functions.
+ function Generator() {}
+ function GeneratorFunction() {}
+ function GeneratorFunctionPrototype() {}
+
+ // This is a polyfill for %IteratorPrototype% for environments that
+ // don't natively support it.
+ var IteratorPrototype = {};
+ IteratorPrototype[iteratorSymbol] = function () {
+ return this;
+ };
+
+ var getProto = Object.getPrototypeOf;
+ var NativeIteratorPrototype = getProto && getProto(getProto(values([])));
+ if (NativeIteratorPrototype &&
+ NativeIteratorPrototype !== Op &&
+ hasOwn.call(NativeIteratorPrototype, iteratorSymbol)) {
+ // This environment has a native %IteratorPrototype%; use it instead
+ // of the polyfill.
+ IteratorPrototype = NativeIteratorPrototype;
+ }
+
+ var Gp = GeneratorFunctionPrototype.prototype =
+ Generator.prototype = Object.create(IteratorPrototype);
+ GeneratorFunction.prototype = Gp.constructor = GeneratorFunctionPrototype;
+ GeneratorFunctionPrototype.constructor = GeneratorFunction;
+ GeneratorFunctionPrototype[toStringTagSymbol] =
+ GeneratorFunction.displayName = "GeneratorFunction";
+
+ // Helper for defining the .next, .throw, and .return methods of the
+ // Iterator interface in terms of a single ._invoke method.
+ function defineIteratorMethods(prototype) {
+ ["next", "throw", "return"].forEach(function(method) {
+ prototype[method] = function(arg) {
+ return this._invoke(method, arg);
+ };
+ });
+ }
+
+ exports.isGeneratorFunction = function(genFun) {
+ var ctor = typeof genFun === "function" && genFun.constructor;
+ return ctor
+ ? ctor === GeneratorFunction ||
+ // For the native GeneratorFunction constructor, the best we can
+ // do is to check its .name property.
+ (ctor.displayName || ctor.name) === "GeneratorFunction"
+ : false;
+ };
+
+ exports.mark = function(genFun) {
+ if (Object.setPrototypeOf) {
+ Object.setPrototypeOf(genFun, GeneratorFunctionPrototype);
+ } else {
+ genFun.__proto__ = GeneratorFunctionPrototype;
+ if (!(toStringTagSymbol in genFun)) {
+ genFun[toStringTagSymbol] = "GeneratorFunction";
+ }
+ }
+ genFun.prototype = Object.create(Gp);
+ return genFun;
+ };
+
+ // Within the body of any async function, `await x` is transformed to
+ // `yield regeneratorRuntime.awrap(x)`, so that the runtime can test
+ // `hasOwn.call(value, "__await")` to determine if the yielded value is
+ // meant to be awaited.
+ exports.awrap = function(arg) {
+ return { __await: arg };
+ };
+
+ function AsyncIterator(generator) {
+ function invoke(method, arg, resolve, reject) {
+ var record = tryCatch(generator[method], generator, arg);
+ if (record.type === "throw") {
+ reject(record.arg);
+ } else {
+ var result = record.arg;
+ var value = result.value;
+ if (value &&
+ typeof value === "object" &&
+ hasOwn.call(value, "__await")) {
+ return Promise.resolve(value.__await).then(function(value) {
+ invoke("next", value, resolve, reject);
+ }, function(err) {
+ invoke("throw", err, resolve, reject);
+ });
+ }
+
+ return Promise.resolve(value).then(function(unwrapped) {
+ // When a yielded Promise is resolved, its final value becomes
+ // the .value of the Promise<{value,done}> result for the
+ // current iteration.
+ result.value = unwrapped;
+ resolve(result);
+ }, function(error) {
+ // If a rejected Promise was yielded, throw the rejection back
+ // into the async generator function so it can be handled there.
+ return invoke("throw", error, resolve, reject);
+ });
+ }
+ }
+
+ var previousPromise;
+
+ function enqueue(method, arg) {
+ function callInvokeWithMethodAndArg() {
+ return new Promise(function(resolve, reject) {
+ invoke(method, arg, resolve, reject);
+ });
+ }
+
+ return previousPromise =
+ // If enqueue has been called before, then we want to wait until
+ // all previous Promises have been resolved before calling invoke,
+ // so that results are always delivered in the correct order. If
+ // enqueue has not been called before, then it is important to
+ // call invoke immediately, without waiting on a callback to fire,
+ // so that the async generator function has the opportunity to do
+ // any necessary setup in a predictable way. This predictability
+ // is why the Promise constructor synchronously invokes its
+ // executor callback, and why async functions synchronously
+ // execute code before the first await. Since we implement simple
+ // async functions in terms of async generators, it is especially
+ // important to get this right, even though it requires care.
+ previousPromise ? previousPromise.then(
+ callInvokeWithMethodAndArg,
+ // Avoid propagating failures to Promises returned by later
+ // invocations of the iterator.
+ callInvokeWithMethodAndArg
+ ) : callInvokeWithMethodAndArg();
+ }
+
+ // Define the unified helper method that is used to implement .next,
+ // .throw, and .return (see defineIteratorMethods).
+ this._invoke = enqueue;
+ }
+
+ defineIteratorMethods(AsyncIterator.prototype);
+ AsyncIterator.prototype[asyncIteratorSymbol] = function () {
+ return this;
+ };
+ exports.AsyncIterator = AsyncIterator;
+
+ // Note that simple async functions are implemented on top of
+ // AsyncIterator objects; they just return a Promise for the value of
+ // the final result produced by the iterator.
+ exports.async = function(innerFn, outerFn, self, tryLocsList) {
+ var iter = new AsyncIterator(
+ wrap(innerFn, outerFn, self, tryLocsList)
+ );
+
+ return exports.isGeneratorFunction(outerFn)
+ ? iter // If outerFn is a generator, return the full iterator.
+ : iter.next().then(function(result) {
+ return result.done ? result.value : iter.next();
+ });
+ };
+
+ function makeInvokeMethod(innerFn, self, context) {
+ var state = GenStateSuspendedStart;
+
+ return function invoke(method, arg) {
+ if (state === GenStateExecuting) {
+ throw new Error("Generator is already running");
+ }
+
+ if (state === GenStateCompleted) {
+ if (method === "throw") {
+ throw arg;
+ }
+
+ // Be forgiving, per 25.3.3.3.3 of the spec:
+ // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-generatorresume
+ return doneResult();
+ }
+
+ context.method = method;
+ context.arg = arg;
+
+ while (true) {
+ var delegate = context.delegate;
+ if (delegate) {
+ var delegateResult = maybeInvokeDelegate(delegate, context);
+ if (delegateResult) {
+ if (delegateResult === ContinueSentinel) continue;
+ return delegateResult;
+ }
+ }
+
+ if (context.method === "next") {
+ // Setting context._sent for legacy support of Babel's
+ // function.sent implementation.
+ context.sent = context._sent = context.arg;
+
+ } else if (context.method === "throw") {
+ if (state === GenStateSuspendedStart) {
+ state = GenStateCompleted;
+ throw context.arg;
+ }
+
+ context.dispatchException(context.arg);
+
+ } else if (context.method === "return") {
+ context.abrupt("return", context.arg);
+ }
+
+ state = GenStateExecuting;
+
+ var record = tryCatch(innerFn, self, context);
+ if (record.type === "normal") {
+ // If an exception is thrown from innerFn, we leave state ===
+ // GenStateExecuting and loop back for another invocation.
+ state = context.done
+ ? GenStateCompleted
+ : GenStateSuspendedYield;
+
+ if (record.arg === ContinueSentinel) {
+ continue;
+ }
+
+ return {
+ value: record.arg,
+ done: context.done
+ };
+
+ } else if (record.type === "throw") {
+ state = GenStateCompleted;
+ // Dispatch the exception by looping back around to the
+ // context.dispatchException(context.arg) call above.
+ context.method = "throw";
+ context.arg = record.arg;
+ }
+ }
+ };
+ }
+
+ // Call delegate.iterator[context.method](context.arg) and handle the
+ // result, either by returning a { value, done } result from the
+ // delegate iterator, or by modifying context.method and context.arg,
+ // setting context.delegate to null, and returning the ContinueSentinel.
+ function maybeInvokeDelegate(delegate, context) {
+ var method = delegate.iterator[context.method];
+ if (method === undefined) {
+ // A .throw or .return when the delegate iterator has no .throw
+ // method always terminates the yield* loop.
+ context.delegate = null;
+
+ if (context.method === "throw") {
+ // Note: ["return"] must be used for ES3 parsing compatibility.
+ if (delegate.iterator["return"]) {
+ // If the delegate iterator has a return method, give it a
+ // chance to clean up.
+ context.method = "return";
+ context.arg = undefined;
+ maybeInvokeDelegate(delegate, context);
+
+ if (context.method === "throw") {
+ // If maybeInvokeDelegate(context) changed context.method from
+ // "return" to "throw", let that override the TypeError below.
+ return ContinueSentinel;
+ }
+ }
+
+ context.method = "throw";
+ context.arg = new TypeError(
+ "The iterator does not provide a 'throw' method");
+ }
+
+ return ContinueSentinel;
+ }
+
+ var record = tryCatch(method, delegate.iterator, context.arg);
+
+ if (record.type === "throw") {
+ context.method = "throw";
+ context.arg = record.arg;
+ context.delegate = null;
+ return ContinueSentinel;
+ }
+
+ var info = record.arg;
+
+ if (! info) {
+ context.method = "throw";
+ context.arg = new TypeError("iterator result is not an object");
+ context.delegate = null;
+ return ContinueSentinel;
+ }
+
+ if (info.done) {
+ // Assign the result of the finished delegate to the temporary
+ // variable specified by delegate.resultName (see delegateYield).
+ context[delegate.resultName] = info.value;
+
+ // Resume execution at the desired location (see delegateYield).
+ context.next = delegate.nextLoc;
+
+ // If context.method was "throw" but the delegate handled the
+ // exception, let the outer generator proceed normally. If
+ // context.method was "next", forget context.arg since it has been
+ // "consumed" by the delegate iterator. If context.method was
+ // "return", allow the original .return call to continue in the
+ // outer generator.
+ if (context.method !== "return") {
+ context.method = "next";
+ context.arg = undefined;
+ }
+
+ } else {
+ // Re-yield the result returned by the delegate method.
+ return info;
+ }
+
+ // The delegate iterator is finished, so forget it and continue with
+ // the outer generator.
+ context.delegate = null;
+ return ContinueSentinel;
+ }
+
+ // Define Generator.prototype.{next,throw,return} in terms of the
+ // unified ._invoke helper method.
+ defineIteratorMethods(Gp);
+
+ Gp[toStringTagSymbol] = "Generator";
+
+ // A Generator should always return itself as the iterator object when the
+ // @@iterator function is called on it. Some browsers' implementations of the
+ // iterator prototype chain incorrectly implement this, causing the Generator
+ // object to not be returned from this call. This ensures that doesn't happen.
+ // See https://github.com/facebook/regenerator/issues/274 for more details.
+ Gp[iteratorSymbol] = function() {
+ return this;
+ };
+
+ Gp.toString = function() {
+ return "[object Generator]";
+ };
+
+ function pushTryEntry(locs) {
+ var entry = { tryLoc: locs[0] };
+
+ if (1 in locs) {
+ entry.catchLoc = locs[1];
+ }
+
+ if (2 in locs) {
+ entry.finallyLoc = locs[2];
+ entry.afterLoc = locs[3];
+ }
+
+ this.tryEntries.push(entry);
+ }
+
+ function resetTryEntry(entry) {
+ var record = entry.completion || {};
+ record.type = "normal";
+ delete record.arg;
+ entry.completion = record;
+ }
+
+ function Context(tryLocsList) {
+ // The root entry object (effectively a try statement without a catch
+ // or a finally block) gives us a place to store values thrown from
+ // locations where there is no enclosing try statement.
+ this.tryEntries = [{ tryLoc: "root" }];
+ tryLocsList.forEach(pushTryEntry, this);
+ this.reset(true);
+ }
+
+ exports.keys = function(object) {
+ var keys = [];
+ for (var key in object) {
+ keys.push(key);
+ }
+ keys.reverse();
+
+ // Rather than returning an object with a next method, we keep
+ // things simple and return the next function itself.
+ return function next() {
+ while (keys.length) {
+ var key = keys.pop();
+ if (key in object) {
+ next.value = key;
+ next.done = false;
+ return next;
+ }
+ }
+
+ // To avoid creating an additional object, we just hang the .value
+ // and .done properties off the next function object itself. This
+ // also ensures that the minifier will not anonymize the function.
+ next.done = true;
+ return next;
+ };
+ };
+
+ function values(iterable) {
+ if (iterable) {
+ var iteratorMethod = iterable[iteratorSymbol];
+ if (iteratorMethod) {
+ return iteratorMethod.call(iterable);
+ }
+
+ if (typeof iterable.next === "function") {
+ return iterable;
+ }
+
+ if (!isNaN(iterable.length)) {
+ var i = -1, next = function next() {
+ while (++i < iterable.length) {
+ if (hasOwn.call(iterable, i)) {
+ next.value = iterable[i];
+ next.done = false;
+ return next;
+ }
+ }
+
+ next.value = undefined;
+ next.done = true;
+
+ return next;
+ };
+
+ return next.next = next;
+ }
+ }
+
+ // Return an iterator with no values.
+ return { next: doneResult };
+ }
+ exports.values = values;
+
+ function doneResult() {
+ return { value: undefined, done: true };
+ }
+
+ Context.prototype = {
+ constructor: Context,
+
+ reset: function(skipTempReset) {
+ this.prev = 0;
+ this.next = 0;
+ // Resetting context._sent for legacy support of Babel's
+ // function.sent implementation.
+ this.sent = this._sent = undefined;
+ this.done = false;
+ this.delegate = null;
+
+ this.method = "next";
+ this.arg = undefined;
+
+ this.tryEntries.forEach(resetTryEntry);
+
+ if (!skipTempReset) {
+ for (var name in this) {
+ // Not sure about the optimal order of these conditions:
+ if (name.charAt(0) === "t" &&
+ hasOwn.call(this, name) &&
+ !isNaN(+name.slice(1))) {
+ this[name] = undefined;
+ }
+ }
+ }
+ },
+
+ stop: function() {
+ this.done = true;
+
+ var rootEntry = this.tryEntries[0];
+ var rootRecord = rootEntry.completion;
+ if (rootRecord.type === "throw") {
+ throw rootRecord.arg;
+ }
+
+ return this.rval;
+ },
+
+ dispatchException: function(exception) {
+ if (this.done) {
+ throw exception;
+ }
+
+ var context = this;
+ function handle(loc, caught) {
+ record.type = "throw";
+ record.arg = exception;
+ context.next = loc;
+
+ if (caught) {
+ // If the dispatched exception was caught by a catch block,
+ // then let that catch block handle the exception normally.
+ context.method = "next";
+ context.arg = undefined;
+ }
+
+ return !! caught;
+ }
+
+ for (var i = this.tryEntries.length - 1; i >= 0; --i) {
+ var entry = this.tryEntries[i];
+ var record = entry.completion;
+
+ if (entry.tryLoc === "root") {
+ // Exception thrown outside of any try block that could handle
+ // it, so set the completion value of the entire function to
+ // throw the exception.
+ return handle("end");
+ }
+
+ if (entry.tryLoc <= this.prev) {
+ var hasCatch = hasOwn.call(entry, "catchLoc");
+ var hasFinally = hasOwn.call(entry, "finallyLoc");
+
+ if (hasCatch && hasFinally) {
+ if (this.prev < entry.catchLoc) {
+ return handle(entry.catchLoc, true);
+ } else if (this.prev < entry.finallyLoc) {
+ return handle(entry.finallyLoc);
+ }
+
+ } else if (hasCatch) {
+ if (this.prev < entry.catchLoc) {
+ return handle(entry.catchLoc, true);
+ }
+
+ } else if (hasFinally) {
+ if (this.prev < entry.finallyLoc) {
+ return handle(entry.finallyLoc);
+ }
+
+ } else {
+ throw new Error("try statement without catch or finally");
+ }
+ }
+ }
+ },
+
+ abrupt: function(type, arg) {
+ for (var i = this.tryEntries.length - 1; i >= 0; --i) {
+ var entry = this.tryEntries[i];
+ if (entry.tryLoc <= this.prev &&
+ hasOwn.call(entry, "finallyLoc") &&
+ this.prev < entry.finallyLoc) {
+ var finallyEntry = entry;
+ break;
+ }
+ }
+
+ if (finallyEntry &&
+ (type === "break" ||
+ type === "continue") &&
+ finallyEntry.tryLoc <= arg &&
+ arg <= finallyEntry.finallyLoc) {
+ // Ignore the finally entry if control is not jumping to a
+ // location outside the try/catch block.
+ finallyEntry = null;
+ }
+
+ var record = finallyEntry ? finallyEntry.completion : {};
+ record.type = type;
+ record.arg = arg;
+
+ if (finallyEntry) {
+ this.method = "next";
+ this.next = finallyEntry.finallyLoc;
+ return ContinueSentinel;
+ }
+
+ return this.complete(record);
+ },
+
+ complete: function(record, afterLoc) {
+ if (record.type === "throw") {
+ throw record.arg;
+ }
+
+ if (record.type === "break" ||
+ record.type === "continue") {
+ this.next = record.arg;
+ } else if (record.type === "return") {
+ this.rval = this.arg = record.arg;
+ this.method = "return";
+ this.next = "end";
+ } else if (record.type === "normal" && afterLoc) {
+ this.next = afterLoc;
+ }
+
+ return ContinueSentinel;
+ },
+
+ finish: function(finallyLoc) {
+ for (var i = this.tryEntries.length - 1; i >= 0; --i) {
+ var entry = this.tryEntries[i];
+ if (entry.finallyLoc === finallyLoc) {
+ this.complete(entry.completion, entry.afterLoc);
+ resetTryEntry(entry);
+ return ContinueSentinel;
+ }
+ }
+ },
+
+ "catch": function(tryLoc) {
+ for (var i = this.tryEntries.length - 1; i >= 0; --i) {
+ var entry = this.tryEntries[i];
+ if (entry.tryLoc === tryLoc) {
+ var record = entry.completion;
+ if (record.type === "throw") {
+ var thrown = record.arg;
+ resetTryEntry(entry);
+ }
+ return thrown;
+ }
+ }
+
+ // The context.catch method must only be called with a location
+ // argument that corresponds to a known catch block.
+ throw new Error("illegal catch attempt");
+ },
+
+ delegateYield: function(iterable, resultName, nextLoc) {
+ this.delegate = {
+ iterator: values(iterable),
+ resultName: resultName,
+ nextLoc: nextLoc
+ };
+
+ if (this.method === "next") {
+ // Deliberately forget the last sent value so that we don't
+ // accidentally pass it on to the delegate.
+ this.arg = undefined;
+ }
+
+ return ContinueSentinel;
+ }
+ };
+
+ // Regardless of whether this script is executing as a CommonJS module
+ // or not, return the runtime object so that we can declare the variable
+ // regeneratorRuntime in the outer scope, which allows this module to be
+ // injected easily by `bin/regenerator --include-runtime script.js`.
+ return exports;
+
+}(
+ // If this script is executing as a CommonJS module, use module.exports
+ // as the regeneratorRuntime namespace. Otherwise create a new empty
+ // object. Either way, the resulting object will be used to initialize
+ // the regeneratorRuntime variable at the top of this file.
+ typeof module === "object" ? module.exports : {}
+));
diff --git a/miniprogram/utils/util.js b/miniprogram/utils/util.js
new file mode 100644
index 0000000..dbadbb8
--- /dev/null
+++ b/miniprogram/utils/util.js
@@ -0,0 +1,19 @@
+const formatTime = date => {
+ const year = date.getFullYear()
+ const month = date.getMonth() + 1
+ const day = date.getDate()
+ const hour = date.getHours()
+ const minute = date.getMinutes()
+ const second = date.getSeconds()
+
+ return [year, month, day].map(formatNumber).join('/') + ' ' + [hour, minute, second].map(formatNumber).join(':')
+}
+
+const formatNumber = n => {
+ n = n.toString()
+ return n[1] ? n : '0' + n
+}
+
+module.exports = {
+ formatTime: formatTime
+}
diff --git a/miniprogram/utils/wxmlify/wxmlify.js b/miniprogram/utils/wxmlify/wxmlify.js
new file mode 100644
index 0000000..498d2ac
--- /dev/null
+++ b/miniprogram/utils/wxmlify/wxmlify.js
@@ -0,0 +1,8 @@
+/*
+ * Wxmlify v1.2.0
+ * https://github.com/zhanziyang/wxmlify
+ *
+ * Copyright (c) 2018 zhanziyang
+ * Released under the ISC license
+ */
+"use strict"; function startsWith(t, e, r) { return t.substr(r || 0, e.length) === e } function endsWith(t, e, r) { var n = (r || t.length) - e.length, a = t.lastIndexOf(e, n); return -1 !== a && a === n } function stringIncludes(t, e, r) { return -1 !== t.indexOf(e, r || 0) } function isRealNaN(t) { return "number" == typeof t && isNaN(t) } function arrayIncludes(t, e, r) { var n = t.length; if (0 === n) return !1; for (var a = 0 | r, i = isRealNaN(e), s = a >= 0 ? a : n + a; s < n;) { var o = t[s++]; if (o === e) return !0; if (i && isRealNaN(o)) return !0 } return !1 } var _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (t) { return typeof t } : function (t) { return t && "function" == typeof Symbol && t.constructor === Symbol && t !== Symbol.prototype ? "symbol" : typeof t }, slicedToArray = function () { return function (t, e) { if (Array.isArray(t)) return t; if (Symbol.iterator in Object(t)) return function (t, e) { var r = [], n = !0, a = !1, i = void 0; try { for (var s, o = t[Symbol.iterator](); !(n = (s = o.next()).done) && (r.push(s.value), !e || r.length !== e); n = !0); } catch (t) { a = !0, i = t } finally { try { !n && o.return && o.return() } finally { if (a) throw i } } return r }(t, e); throw new TypeError("Invalid attempt to destructure non-iterable instance") } }(), toConsumableArray = function (t) { if (Array.isArray(t)) { for (var e = 0, r = Array(t.length); e < t.length; e++)r[e] = t[e]; return r } return Array.from(t) }; function lexer(t, e) { var r = { str: t, options: e, cursor: 0, tokens: [] }; return lex(r), r.tokens } function lex(t) { for (var e = t.str, r = e.length; t.cursor < r;) { if ("<" !== e.charAt(t.cursor)) lexText(t); else if (startsWith(e, "!--", t.cursor + 1)) lexComment(t); else { var n = lexTag(t); if (n) { var a = n.toLowerCase(); arrayIncludes(t.options.childlessTags, a) && lexSkipTag(n, t) } } } } function lexText(t) { var e = t.str, r = t.cursor, n = e.indexOf("<", r), a = "text"; if (-1 === n) { var i = e.slice(r); return t.cursor = e.length, void t.tokens.push({ type: a, content: i }) } if (n !== r) { var s = e.slice(r, n); t.cursor = n, t.tokens.push({ type: a, content: s }) } } function lexComment(t) { t.cursor += 4; var e = t.str, r = t.cursor, n = e.indexOf("--\x3e", r), a = "comment"; if (-1 === n) { var i = e.slice(r); return t.cursor = e.length, void t.tokens.push({ type: a, content: i }) } var s = e.slice(r, n); t.cursor = n + 3, t.tokens.push({ type: a, content: s }) } function lexTag(t) { var e = t.str, r = "/" === e.charAt(t.cursor + 1); t.tokens.push({ type: "tag-start", close: r }), t.cursor += r ? 2 : 1; var n = lexTagName(t); lexTagAttributes(t); var a = "/" === e.charAt(t.cursor); return t.tokens.push({ type: "tag-end", close: a }), t.cursor += a ? 2 : 1, n } var whitespace = /\s/; function isWhitespaceChar(t) { return whitespace.test(t) } function lexTagName(t) { for (var e = t.str, r = t.cursor, n = e.length, a = r; a < n;) { var i = e.charAt(a); if (!(isWhitespaceChar(i) || "/" === i || ">" === i)) break; a++ } for (var s = a + 1; s < n;) { var o = e.charAt(s); if (!!(isWhitespaceChar(o) || "/" === o || ">" === o)) break; s++ } t.cursor = s; var l = e.slice(a, s); return t.tokens.push({ type: "tag", content: l }), l } function lexTagAttributes(t) { for (var e = t.str, r = t.tokens, n = t.cursor, a = null, i = n, s = [], o = e.length; n < o;) { var l = e.charAt(n); if (a) { l === a && (a = null), n++ } else { if ("/" === l || ">" === l) { n !== i && s.push(e.slice(i, n)); break } if (isWhitespaceChar(l)) n !== i && s.push(e.slice(i, n)), i = n + 1, n++; else "'" === l || '"' === l ? (a = l, n++) : n++ } } t.cursor = n; for (var c = s.length, u = "attribute", f = 0; f < c; f++) { var p = s[f]; if (p && p.length) { if (-1 === p.indexOf("=")) { var h = s[f + 1]; if (h && startsWith(h, "=")) { if (h.length > 1) { var y = p + h; r.push({ type: u, content: y }), f += 1; continue } var d = s[f + 2]; if (f += 1, d) { var g = p + "=" + d; r.push({ type: u, content: g }), f += 1; continue } } } if (endsWith(p, "=")) { var m = s[f + 1]; if (m && !stringIncludes(m, "=")) { var v = p + m; r.push({ type: u, content: v }), f += 1; continue } var b = p.slice(0, -1); r.push({ type: u, content: b }) } else r.push({ type: u, content: p }) } } } function lexSkipTag(t, e) { for (var r = e.str, n = e.cursor, a = e.tokens, i = r.length, s = n; s < i;) { var o = r.indexOf("", s); if (-1 === o) { lexText(e); break } var l = { str: r, cursor: o + 2, tokens: [] }, c = lexTagName(l); if (t.toLowerCase() === c.toLowerCase()) { var u = r.slice(n, o); a.push({ type: "text", content: u }); lexTagAttributes(l), a.push.apply(a, [{ type: "tag-start", close: !0 }].concat(toConsumableArray(l.tokens), [{ type: "tag-end", close: !1 }])), e.cursor = l.cursor + 1; break } s = l.cursor } } function parser(t, e) { var r = { tagName: null, children: [] }; return parse$1({ tokens: t, options: e, cursor: 0, stack: [r] }), r.children } function hasTerminalParent(t, e, r) { var n = r[t]; if (n) for (var a = e.length - 1; a >= 0;) { var i = e[a].tagName; if (i === t) break; if (arrayIncludes(n, i)) return !0; a-- } return !1 } function parse$1(t) { for (var e = t.tokens, r = t.options, n = t.stack, a = n[n.length - 1].children, i = e.length, s = t.cursor; s < i;) { var o = e[s]; if ("tag-start" === o.type) { var l = e[++s]; s++; var c = l.content.toLowerCase(); if (o.close) { for (var u = void 0; (u = n.pop()) && c !== u.tagName;); for (; s < i;) { if ("tag-end" !== e[s].type) break; s++ } break } var f = arrayIncludes(r.closingTags, c); if (f) f = !hasTerminalParent(c, n, r.closingTagAncestorBreakers); if (f) for (var p = n.length - 1; p > 0;) { if (c === n[p].tagName) { a = (n = n.slice(0, p))[p - 1].children; break } p -= 1 } for (var h = [], y = void 0; s < i && "tag-end" !== (y = e[s]).type;)h.push(y.content), s++; s++; var d = []; if (a.push({ type: "element", tagName: l.content, attributes: h, children: d }), !(y.close || arrayIncludes(r.voidTags, c))) { n.push({ tagName: c, children: d }); var g = { tokens: e, options: r, cursor: s, stack: n }; parse$1(g), s = g.cursor } } else a.push(o), s++ } t.cursor = s } function format(t) { return t.map(function (t) { var e = capitalize(t.type); return "Element" === e ? { type: e, tagName: t.tagName.toLowerCase(), attributes: formatAttributes(t.attributes), children: format(t.children) } : { type: e, content: t.content } }) } function capitalize(t) { return t.charAt(0).toUpperCase() + t.slice(1) } function camelCase(t) { return t.split("-").reduce(function (t, e) { return t + e.charAt(0).toUpperCase() + e.slice(1) }) } function castValue(t) { if ("string" != typeof t) return t; if ("" === t) return t; var e = +t; return isNaN(e) ? t : e } function unquote(t) { var e = t.charAt(0), r = t.length - 1; return ('"' === e || "'" === e) && e === t.charAt(r) ? t.slice(1, r) : t } function splitHead(t, e) { var r = t.indexOf(e); return -1 === r ? [t] : [t.slice(0, r), t.slice(r + e.length)] } function formatAttributes(t) { return t.reduce(function (t, e) { var r = splitHead(e.trim(), "="), n = slicedToArray(r, 2), a = n[0], i = n[1]; if (i = i ? unquote(i) : a, "class" === a) t.className = i.split(" "); else if ("style" === a) t.style = formatStyles(i); else if (startsWith(a, "data-")) { t.dataset = t.dataset || {}; var s = camelCase(a.slice(5)); t.dataset[s] = castValue(i) } else t[camelCase(a)] = castValue(i); return t }, {}) } function formatStyles(t) { return t.trim().split(";").map(function (t) { return splitHead(t.trim(), ":") }).reduce(function (t, e) { var r = slicedToArray(e, 2), n = r[0], a = r[1]; if (a) { var i = camelCase(n.trim()), s = castValue(a.trim()); t[i] = s } return t }, {}) } var childlessTags = ["style", "script", "template"], closingTags = ["html", "head", "body", "p", "dt", "dd", "li", "option", "thead", "th", "tbody", "tr", "td", "tfoot", "colgroup"], closingTagAncestorBreakers = { li: ["ul", "ol", "menu"], dt: ["dl"], dd: ["dl"], tbody: ["table"], thead: ["table"], tfoot: ["table"], tr: ["table"], td: ["table"] }, voidTags = ["!doctype", "area", "base", "br", "col", "command", "embed", "hr", "img", "input", "keygen", "link", "meta", "param", "source", "track", "wbr"], parseDefaults = { voidTags: voidTags, closingTags: closingTags, closingTagAncestorBreakers: closingTagAncestorBreakers, childlessTags: childlessTags, format: format }; function parse$$1(t) { var e = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : parseDefaults; return format(parser(lexer(t, e), e), e) } var index = { parse: parse$$1, parseDefaults: parseDefaults }, src = Object.freeze({ parseDefaults: parseDefaults, parse: parse$$1, default: index }), util = { BLOCK_ELEMENTS: ["h1", "h2", "h3", "h4", "h5", "h6", "p", "div", "pre", "table", "tbody", "tfoot", "tr", "ul", "ol", "li", "video", "dl", "dt", "dd", "hr", "blockquote"], INHERIT_STYLE: ["borderCollapse", "borderSpacing", "captionSide", "color", "cursor", "direction", "elevation", "empty-cells", "fontFamily", "fontSize", "fontStyle", "fontVariant", "fontWeight", "font", "letterSpacing", "lineHeight", "listStyleImage", "listStylePosition", "listStyleType", "listStyle", "stress", "textAlign", "textIndent", "textTrasform", "visibility", "whiteSpace", "wordSpacing"], decodeHTMLEntities: function (t) { var e = { amp: "&", apos: "'", "#x27": "'", "#x2F": "/", "#39": "'", "#47": "/", lt: "<", gt: ">", nbsp: " ", quot: '"' }; return t.replace(/&([^;]+);/gm, function (t, r) { return e[r] || t }) }, copy: function (t) { if ("object" !== (void 0 === t ? "undefined" : _typeof(t))) return t; var e = {}; for (var r in t) t.hasOwnProperty(r) && (e[r] = t[r]); return e }, assign: function (t, e) { if (null == t) throw new TypeError("Cannot convert undefined or null to object"); for (var r = Object(t), n = 1; n < arguments.length; n++) { var a = arguments[n]; if (null != a) for (var i in a) Object.prototype.hasOwnProperty.call(a, i) && (r[i] = a[i]) } return r }, omit: function (t, e) { if ("object" !== (void 0 === t ? "undefined" : _typeof(t)) || "[object Array]" !== Object.prototype.toString.call(e)) return t; var r = {}; for (var n in t) t.hasOwnProperty(n) && e.indexOf(n) < 0 && (r[n] = t[n]); return r }, pick: function (t, e) { if ("object" !== (void 0 === t ? "undefined" : _typeof(t)) || "[object Array]" !== Object.prototype.toString.call(e)) return t; var r = {}; for (var n in t) t.hasOwnProperty(n) && e.indexOf(n) >= 0 && (r[n] = t[n]); return r }, validateHtmlString: function (t) { return !0 } }, noop = function () { }, options = { preserveStyles: "all", dataKey: "wxmlified", disableImagePreivew: !1, onImageTap: noop }, himalaya = src && index || src; function Wxmlify(t, e, r) { if ("string" != typeof t) throw TypeError("Wxmlify 的第一个参数必须是字符串,代表要解析的HTML代码"); if (util.validateHtmlString(t) || console.warn("HTML代码格式不合法或不规范,解析结果可能不符合预期"), "object" !== (void 0 === e ? "undefined" : _typeof(e)) || "function" != typeof e.setData) throw TypeError("Wxmlify 的第二个参数必须是微信小程序的一个页面实例"); this.html = t, this.page = e, r = r || {}, this.options = util.assign({}, options, r), this.fullNodes = himalaya.parse(t), this.images = [], this.init() } Wxmlify.prototype.init = function () { this.traverse(), this.bindEvents(), this.exec() }, Wxmlify.prototype.exec = function () { for (var t = [], e = 0, r = this.fullNodes.length; e < r; e++) { var n = this.fullNodes[e]; if ("Element" == n.type && n.children.length) { n.children.forEach(function (t) { t.parentTag = n.tagName }); var a = []; "table" === n.tagName ? this.getTableDescendants(n, a) : (this.getDescendants(n, a), a.length && (n.descendants = a)), t.push(n) } else ("Text" != n.type || n.content.trim()) && (n.styles = this.getStyles(n), n.styleString = this.stringifyStyle(n.styles), t.push(n)) } var i = {}; i[this.options.dataKey] = t, this.page.setData(i) }, Wxmlify.prototype.bindEvents = function () { this.page.__wxmlifyImageTapHandler = this.imageTapHandler.bind(this) }, Wxmlify.prototype.imageTapHandler = function (t) { var e = t.currentTarget.dataset.attributes || {}; this.page; this.options.disableImagePreivew || wx.previewImage({ current: e.src, urls: this.images }), this.options.onImageTap && this.options.onImageTap(t) }, Wxmlify.prototype.getFullNodes = function () { return this.fullNodes }, Wxmlify.prototype.getHTML = function () { return this.html }, Wxmlify.prototype.getImages = function () { return this.images }, Wxmlify.prototype.getDescendants = function (t, e) { var r = t.children || [], n = this.getStyles(t); t.styles = n, t.styleString = this.stringifyStyle(n); for (var a = 0, i = r.length; a < i; a++) { var s = r[a]; s.styles = util.pick(n, util.INHERIT_STYLE), s.styleString = this.stringifyStyle(n), s.children && s.children.length ? (s.children.forEach(function (t) { t.parentTag = s.tagName }), "table" === s.tagName ? this.getTableDescendants(s, e) : (this.getDescendants(s, e), util.BLOCK_ELEMENTS.indexOf(s.tagName) >= 0 && e.push({ type: "BIB", tagName: s.tagName, styles: {}, styleString: "", parentTag: t.tagName }))) : ("Text" != s.type || s.content.trim()) && e.push(s) } }, Wxmlify.prototype.getTableDescendants = function (t, e) { var r = this.getStyles(t); t.styles = r, t.styleString = this.stringifyStyle(r), t.table = !0; var n = []; this.findAllCertanTypeOfTagIn(t, n, ["tr"]), n.forEach(function (t) { this.manageTableRow(t) }.bind(this)), t.rows = n }, Wxmlify.prototype.findAllCertanTypeOfTagIn = function (t, e, r) { if (t.children) for (var n = t.children, a = n.length, i = 0; i < a; i++) { var s = n[i]; s && r.indexOf(s.tagName) >= 0 ? e.push(s) : this.findAllCertanTypeOfTagIn(s, e, r) } }, Wxmlify.prototype.manageTableRow = function (t) { var e = []; this.findAllCertanTypeOfTagIn(t, e, ["td", "th"]), t.cells = e.map(function (t) { var e = []; return this.getDescendants(t, e), t.descendants = e, t }.bind(this)), t.isHead = e[0] && "th" === e[0].tagName }, Wxmlify.prototype.getStyles = function (t) { var e = util.copy(t.styles) || {}; this.addTagStyles(e, t.tagName); var r = this.options.preserveStyles || []; if (t.attributes && t.attributes.style) { var n = t.attributes.style; for (var a in n) n.hasOwnProperty(a) && ("all" == r || r.indexOf(a) >= 0) && (e[a] = n[a]) } return e }, Wxmlify.prototype.addTagStyles = function (t, e) { "b" != e && "strong" != e || (t.fontWeight = "bold"), "i" != e && "em" != e || (t.fontStyle = "italic"), "s" == e && (t["text-decoration"] = "underline"), "del" == e && (t["text-decoration"] = "line-through") }, Wxmlify.prototype.stringifyStyle = function (t) { var e = ""; for (var r in t) { if (t.hasOwnProperty(r)) e += r.replace(/[A-Z]/, function (t) { return "-" + t.toLowerCase() }) + ": " + t[r] + "; " } return e }, Wxmlify.prototype.traverse = function () { this.fullNodes = this.fullNodes || []; for (var t = this, e = function (e) { "img" == e.tagName && t.images.push(e.attributes.src), "Text" == e.type && (e.content = util.decodeHTMLEntities(e.content)) }, r = 0, n = this.fullNodes.length; r < n; r++) { var a = this.fullNodes[r]; e(a), function t(r) { for (var n = r.children || [], a = 0, i = n.length; a < i; a++) { var s = n[a]; e(s), t(s) } }(a) } }; var wxmlify = Wxmlify; module.exports = wxmlify;
diff --git a/miniprogram/utils/wxmlify/wxmlify.wxml b/miniprogram/utils/wxmlify/wxmlify.wxml
new file mode 100644
index 0000000..10f2bf3
--- /dev/null
+++ b/miniprogram/utils/wxmlify/wxmlify.wxml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{item.content}}
+
+
+
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 0000000..a3ac33e
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,541 @@
+{
+ "requires": true,
+ "lockfileVersion": 1,
+ "dependencies": {
+ "@cloudbase/database": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/@cloudbase/database/-/database-0.1.1.tgz",
+ "integrity": "sha512-r6tSlzrDKvu27K9tlQYG6qFphw3ZmGECuch7J2ZKW93iLlqpaBVQdy5kBNKZkpjxrpVw9cZKoC2+k0wMqaTWtQ==",
+ "requires": {
+ "bson": "^4.0.2"
+ }
+ },
+ "@protobufjs/aspromise": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz",
+ "integrity": "sha1-m4sMxmPWaafY9vXQiToU00jzD78="
+ },
+ "@protobufjs/base64": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz",
+ "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg=="
+ },
+ "@protobufjs/codegen": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz",
+ "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg=="
+ },
+ "@protobufjs/eventemitter": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz",
+ "integrity": "sha1-NVy8mLr61ZePntCV85diHx0Ga3A="
+ },
+ "@protobufjs/fetch": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz",
+ "integrity": "sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=",
+ "requires": {
+ "@protobufjs/aspromise": "^1.1.1",
+ "@protobufjs/inquire": "^1.1.0"
+ }
+ },
+ "@protobufjs/float": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz",
+ "integrity": "sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E="
+ },
+ "@protobufjs/inquire": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz",
+ "integrity": "sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik="
+ },
+ "@protobufjs/path": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz",
+ "integrity": "sha1-bMKyDFya1q0NzP0hynZz2Nf79o0="
+ },
+ "@protobufjs/pool": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz",
+ "integrity": "sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q="
+ },
+ "@protobufjs/utf8": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz",
+ "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA="
+ },
+ "@types/long": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.0.tgz",
+ "integrity": "sha512-1w52Nyx4Gq47uuu0EVcsHBxZFJgurQ+rTKS3qMHxR1GY2T8c2AJYd6vZoZ9q1rupaDjU0yT+Jc2XTyXkjeMA+Q=="
+ },
+ "@types/node": {
+ "version": "10.14.13",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-10.14.13.tgz",
+ "integrity": "sha512-yN/FNNW1UYsRR1wwAoyOwqvDuLDtVXnaJTZ898XIw/Q5cCaeVAlVwvsmXLX5PuiScBYwZsZU4JYSHB3TvfdwvQ=="
+ },
+ "ajv": {
+ "version": "6.10.2",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz",
+ "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==",
+ "requires": {
+ "fast-deep-equal": "^2.0.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ }
+ },
+ "asn1": {
+ "version": "0.2.4",
+ "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
+ "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==",
+ "requires": {
+ "safer-buffer": "~2.1.0"
+ }
+ },
+ "assert-plus": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+ "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU="
+ },
+ "asynckit": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+ "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
+ },
+ "aws-sign2": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
+ "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg="
+ },
+ "aws4": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz",
+ "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ=="
+ },
+ "base64-js": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz",
+ "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw=="
+ },
+ "bcrypt-pbkdf": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
+ "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
+ "requires": {
+ "tweetnacl": "^0.14.3"
+ }
+ },
+ "bson": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/bson/-/bson-4.0.2.tgz",
+ "integrity": "sha512-rBdCxMBCg2aR420e1oKUejjcuPZLTibA7zEhWAlliFWEwzuBCC9Dkp5r7VFFIQB2t1WVsvTbohry575mc7Xw5A==",
+ "requires": {
+ "buffer": "^5.1.0",
+ "long": "^4.0.0"
+ }
+ },
+ "buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.2.1.tgz",
+ "integrity": "sha512-c+Ko0loDaFfuPWiL02ls9Xd3GO3cPVmUobQ6t3rXNUk304u6hGq+8N/kFi+QEIKhzK3uwolVhLzszmfLmMLnqg==",
+ "requires": {
+ "base64-js": "^1.0.2",
+ "ieee754": "^1.1.4"
+ }
+ },
+ "caseless": {
+ "version": "0.12.0",
+ "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
+ "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw="
+ },
+ "combined-stream": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+ "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+ "requires": {
+ "delayed-stream": "~1.0.0"
+ }
+ },
+ "core-util-is": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
+ "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
+ },
+ "dashdash": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
+ "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
+ "requires": {
+ "assert-plus": "^1.0.0"
+ }
+ },
+ "delayed-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+ "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
+ },
+ "ecc-jsbn": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
+ "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
+ "requires": {
+ "jsbn": "~0.1.0",
+ "safer-buffer": "^2.1.0"
+ }
+ },
+ "extend": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
+ "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
+ },
+ "extsprintf": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
+ "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU="
+ },
+ "fast-deep-equal": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz",
+ "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk="
+ },
+ "fast-json-stable-stringify": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz",
+ "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I="
+ },
+ "forever-agent": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
+ "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE="
+ },
+ "form-data": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
+ "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
+ "requires": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.6",
+ "mime-types": "^2.1.12"
+ }
+ },
+ "function-bind": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
+ },
+ "getpass": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
+ "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
+ "requires": {
+ "assert-plus": "^1.0.0"
+ }
+ },
+ "har-schema": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
+ "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI="
+ },
+ "har-validator": {
+ "version": "5.1.3",
+ "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz",
+ "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==",
+ "requires": {
+ "ajv": "^6.5.5",
+ "har-schema": "^2.0.0"
+ }
+ },
+ "has": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
+ "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+ "requires": {
+ "function-bind": "^1.1.1"
+ }
+ },
+ "http-signature": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
+ "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
+ "requires": {
+ "assert-plus": "^1.0.0",
+ "jsprim": "^1.2.2",
+ "sshpk": "^1.7.0"
+ }
+ },
+ "ieee754": {
+ "version": "1.1.13",
+ "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz",
+ "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg=="
+ },
+ "is-regex": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz",
+ "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=",
+ "requires": {
+ "has": "^1.0.1"
+ }
+ },
+ "is-typedarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
+ "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo="
+ },
+ "isstream": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
+ "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo="
+ },
+ "jsbn": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
+ "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM="
+ },
+ "json-schema": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
+ "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM="
+ },
+ "json-schema-traverse": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="
+ },
+ "json-stringify-safe": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
+ "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus="
+ },
+ "jsprim": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
+ "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
+ "requires": {
+ "assert-plus": "1.0.0",
+ "extsprintf": "1.3.0",
+ "json-schema": "0.2.3",
+ "verror": "1.10.0"
+ }
+ },
+ "lodash.merge": {
+ "version": "4.6.2",
+ "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
+ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="
+ },
+ "long": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz",
+ "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA=="
+ },
+ "mime-db": {
+ "version": "1.40.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz",
+ "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA=="
+ },
+ "mime-types": {
+ "version": "2.1.24",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz",
+ "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==",
+ "requires": {
+ "mime-db": "1.40.0"
+ }
+ },
+ "oauth-sign": {
+ "version": "0.9.0",
+ "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
+ "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ=="
+ },
+ "performance-now": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
+ "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns="
+ },
+ "protobufjs": {
+ "version": "6.8.8",
+ "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.8.8.tgz",
+ "integrity": "sha512-AAmHtD5pXgZfi7GMpllpO3q1Xw1OYldr+dMUlAnffGTAhqkg72WdmSY71uKBF/JuyiKs8psYbtKrhi0ASCD8qw==",
+ "requires": {
+ "@protobufjs/aspromise": "^1.1.2",
+ "@protobufjs/base64": "^1.1.2",
+ "@protobufjs/codegen": "^2.0.4",
+ "@protobufjs/eventemitter": "^1.1.0",
+ "@protobufjs/fetch": "^1.1.0",
+ "@protobufjs/float": "^1.0.2",
+ "@protobufjs/inquire": "^1.1.0",
+ "@protobufjs/path": "^1.1.2",
+ "@protobufjs/pool": "^1.1.0",
+ "@protobufjs/utf8": "^1.1.0",
+ "@types/long": "^4.0.0",
+ "@types/node": "^10.1.0",
+ "long": "^4.0.0"
+ }
+ },
+ "psl": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/psl/-/psl-1.2.0.tgz",
+ "integrity": "sha512-GEn74ZffufCmkDDLNcl3uuyF/aSD6exEyh1v/ZSdAomB82t6G9hzJVRx0jBmLDW+VfZqks3aScmMw9DszwUalA=="
+ },
+ "punycode": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
+ "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A=="
+ },
+ "qs": {
+ "version": "6.5.2",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
+ "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA=="
+ },
+ "request": {
+ "version": "2.88.0",
+ "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz",
+ "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==",
+ "requires": {
+ "aws-sign2": "~0.7.0",
+ "aws4": "^1.8.0",
+ "caseless": "~0.12.0",
+ "combined-stream": "~1.0.6",
+ "extend": "~3.0.2",
+ "forever-agent": "~0.6.1",
+ "form-data": "~2.3.2",
+ "har-validator": "~5.1.0",
+ "http-signature": "~1.2.0",
+ "is-typedarray": "~1.0.0",
+ "isstream": "~0.1.2",
+ "json-stringify-safe": "~5.0.1",
+ "mime-types": "~2.1.19",
+ "oauth-sign": "~0.9.0",
+ "performance-now": "^2.1.0",
+ "qs": "~6.5.2",
+ "safe-buffer": "^5.1.2",
+ "tough-cookie": "~2.4.3",
+ "tunnel-agent": "^0.6.0",
+ "uuid": "^3.3.2"
+ }
+ },
+ "safe-buffer": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz",
+ "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg=="
+ },
+ "safer-buffer": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
+ },
+ "sax": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
+ "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw=="
+ },
+ "sshpk": {
+ "version": "1.16.1",
+ "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz",
+ "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==",
+ "requires": {
+ "asn1": "~0.2.3",
+ "assert-plus": "^1.0.0",
+ "bcrypt-pbkdf": "^1.0.0",
+ "dashdash": "^1.12.0",
+ "ecc-jsbn": "~0.1.1",
+ "getpass": "^0.1.1",
+ "jsbn": "~0.1.0",
+ "safer-buffer": "^2.0.2",
+ "tweetnacl": "~0.14.0"
+ }
+ },
+ "tcb-admin-node": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/tcb-admin-node/-/tcb-admin-node-1.9.0.tgz",
+ "integrity": "sha512-TYoBo66CEIIw1QzgK4Jq43G45zvBE6ZB35LbDV8wwLQvg6CiZHlmOTVZkgj2YZ8O87ELi+ZE3UBVNZM3nFa6lQ==",
+ "requires": {
+ "@cloudbase/database": "0.1.1",
+ "is-regex": "^1.0.4",
+ "lodash.merge": "^4.6.1",
+ "request": "^2.87.0",
+ "xml2js": "^0.4.19"
+ }
+ },
+ "tough-cookie": {
+ "version": "2.4.3",
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz",
+ "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==",
+ "requires": {
+ "psl": "^1.1.24",
+ "punycode": "^1.4.1"
+ },
+ "dependencies": {
+ "punycode": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
+ "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4="
+ }
+ }
+ },
+ "tslib": {
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz",
+ "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ=="
+ },
+ "tunnel-agent": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
+ "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
+ "requires": {
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "tweetnacl": {
+ "version": "0.14.5",
+ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
+ "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q="
+ },
+ "uri-js": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz",
+ "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==",
+ "requires": {
+ "punycode": "^2.1.0"
+ }
+ },
+ "uuid": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz",
+ "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA=="
+ },
+ "verror": {
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
+ "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
+ "requires": {
+ "assert-plus": "^1.0.0",
+ "core-util-is": "1.0.2",
+ "extsprintf": "^1.2.0"
+ }
+ },
+ "wx-server-sdk": {
+ "version": "0.8.1",
+ "resolved": "https://registry.npmjs.org/wx-server-sdk/-/wx-server-sdk-0.8.1.tgz",
+ "integrity": "sha512-mE7O3E7GtRhqk1ukWw2+NiykaO5DaJYiMFCeHrwvekYTVL5Z2nFXnSrUx6nPg/vZ7LWWQbCgQlGOygBjj2+hkQ==",
+ "requires": {
+ "protobufjs": "6.8.8",
+ "tcb-admin-node": "1.9.0",
+ "tslib": "^1.9.3"
+ }
+ },
+ "xml2js": {
+ "version": "0.4.19",
+ "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz",
+ "integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==",
+ "requires": {
+ "sax": ">=0.6.0",
+ "xmlbuilder": "~9.0.1"
+ }
+ },
+ "xmlbuilder": {
+ "version": "9.0.7",
+ "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz",
+ "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0="
+ }
+ }
+}
diff --git a/project.config.json b/project.config.json
new file mode 100644
index 0000000..a26d20d
--- /dev/null
+++ b/project.config.json
@@ -0,0 +1,62 @@
+{
+ "miniprogramRoot": "miniprogram/",
+ "cloudfunctionRoot": "cloudfunctions/",
+ "setting": {
+ "urlCheck": true,
+ "es6": true,
+ "postcss": true,
+ "minified": true,
+ "newFeature": true,
+ "coverView": true,
+ "nodeModules": true,
+ "autoAudits": false,
+ "checkInvalidKey": true,
+ "checkSiteMap": true,
+ "uploadWithSourceMap": true,
+ "babelSetting": {
+ "ignore": [],
+ "disablePlugins": [],
+ "outputPath": ""
+ }
+ },
+ "appid": "wxcc12aa97f16b2ade",
+ "projectname": "cake_wxapp",
+ "libVersion": "2.8.3",
+ "simulatorType": "wechat",
+ "simulatorPluginLibVersion": {},
+ "cloudfunctionTemplateRoot": "cloudfunctionTemplate",
+ "condition": {
+ "search": {
+ "current": -1,
+ "list": []
+ },
+ "conversation": {
+ "current": -1,
+ "list": []
+ },
+ "plugin": {
+ "current": -1,
+ "list": []
+ },
+ "game": {
+ "list": []
+ },
+ "miniprogram": {
+ "current": 1,
+ "list": [
+ {
+ "id": -1,
+ "name": "db guide",
+ "pathName": "pages/databaseGuide/databaseGuide",
+ "query": ""
+ },
+ {
+ "id": -1,
+ "name": "pages/orders/orders",
+ "pathName": "pages/orders/orders",
+ "scene": null
+ }
+ ]
+ }
+ }
+}
\ No newline at end of file