diff --git a/app.json b/app.json
index fb2e7e5..ff9cfdf 100644
--- a/app.json
+++ b/app.json
@@ -12,5 +12,8 @@
"enablePullDownRefresh": false,
"navigationStyle": "custom"
},
- "sitemapLocation": "sitemap.json"
+ "sitemapLocation": "sitemap.json",
+ "navigateToMiniProgramAppIdList": [
+ "wx959c8c1fb2d877b5"
+ ]
}
\ No newline at end of file
diff --git a/components/payjs/payjs.js b/components/payjs/payjs.js
new file mode 100644
index 0000000..e4b4990
--- /dev/null
+++ b/components/payjs/payjs.js
@@ -0,0 +1,108 @@
+// componenets/payjs/payjs.js
+Component({
+ /**
+ * 组件的属性列表
+ */
+ properties: {
+ params: { // 支付订单参数
+ type: Object,
+ value: null
+ },
+ envVersion: {
+ type: String,
+ value: "release"
+ }
+ },
+
+ /**
+ * 组件的初始数据
+ */
+ data: {
+ showPayModal: false,
+ paying: false
+ },
+
+ /**
+ * 组件的方法列表
+ */
+ methods: {
+ setPaying(newPayingData) {
+ this.setData({
+ paying: newPayingData
+ })
+ this.triggerEvent('dataChange', { paying: newPayingData })
+ },
+ onTapCancel () {
+ // 用户点击了支付组件外的地方(灰色地方)
+ console.log('[PAYJS] 跳转到 PAYJS 小程序失败 - 用户点击了提醒窗体以外的地方')
+ this.triggerEvent('fail', { navigateSuccess: false })
+ this.triggerEvent('complete')
+ },
+ navigateSuccess () {
+ console.log('[PAYJS] 跳转到 PAYJS 小程序成功')
+ // 成功跳转:标记支付中状态
+ this.setPaying(true)
+ },
+ navigateFail (e) {
+ // 跳转失败
+ console.log('[PAYJS] 跳转到 PAYJS 小程序失败 - 失败回调', e)
+ this.triggerEvent('fail', { navigateSuccess: false, info: e })
+ this.triggerEvent('complete')
+ }
+ },
+
+ /**
+ * 组件生命周期
+ */
+ lifetimes: {
+ attached() {
+ this.setPaying(false)
+ if (!this.data.params) {
+ console.error('[PAYJS] 跳转到 PAYJS 小程序失败 - 错误:没有传递跳转参数', r)
+ this.triggerEvent('fail', { error: true, navigateSuccess: false })
+ this.triggerEvent('complete')
+ }
+
+ // 监听 app.onShow 事件
+ wx.onAppShow(appOptions => {
+ if (!this.data.paying) return;
+
+ // 恢复支付前状态
+ this.setPaying(false)
+
+ if (appOptions.scene === 1038 && appOptions.referrerInfo.appId === 'wx959c8c1fb2d877b5') {
+ // 来源于 PAYJS 小程序返回
+ console.log('[PAYJS] 确认来源于 PAYJS 回调返回')
+ let extraData = appOptions.referrerInfo.extraData
+ if (extraData.success) {
+ this.triggerEvent('success', extraData)
+ this.triggerEvent('complete')
+ } else {
+ this.triggerEvent('fail', { navigateSuccess: true, info: extraData })
+ this.triggerEvent('complete')
+ }
+ }
+ })
+
+ // 尝试直接跳转到 PAYJS 发起小程序支付
+ wx.navigateToMiniProgram({
+ appId: 'wx959c8c1fb2d877b5',
+ path: 'pages/pay',
+ extraData: this.data.params,
+ envVersion: this.data.envVersion,
+ success: r => {
+ console.log('[PAYJS] 跳转到 PAYJS 小程序成功', r)
+ // 成功跳转:标记支付中状态
+ this.setPaying(true)
+ },
+ fail: e => {
+ // 跳转失败:弹出提示组件引导用户跳转
+ console.log('[PAYJS] 跳转到 PAYJS 小程序失败 - 准备弹窗提醒跳转', e)
+ this.setData({
+ showPayModal: true
+ })
+ }
+ })
+ }
+ }
+})
diff --git a/components/payjs/payjs.json b/components/payjs/payjs.json
new file mode 100644
index 0000000..e8cfaaf
--- /dev/null
+++ b/components/payjs/payjs.json
@@ -0,0 +1,4 @@
+{
+ "component": true,
+ "usingComponents": {}
+}
\ No newline at end of file
diff --git a/components/payjs/payjs.wxml b/components/payjs/payjs.wxml
new file mode 100644
index 0000000..9c90687
--- /dev/null
+++ b/components/payjs/payjs.wxml
@@ -0,0 +1,5 @@
+
+
+ 支付需要跳转到第三方平台进行
+ 确认跳转
+
\ No newline at end of file
diff --git a/components/payjs/payjs.wxss b/components/payjs/payjs.wxss
new file mode 100644
index 0000000..87c56cd
--- /dev/null
+++ b/components/payjs/payjs.wxss
@@ -0,0 +1,44 @@
+.bg {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100vw;
+ height: 100vh;
+
+ background-color: black;
+ opacity: 0.5;
+}
+
+.button {
+ background: none;
+}
+
+.button::after {
+ border: none;
+}
+
+.modal {
+ position: fixed;
+ left: 10vw;
+ top: 30vh;
+ width: 80vw;
+ height: 20vh;
+
+ background-color: white;
+ border-radius: 5rpx;
+
+ text-align: center;
+ line-height: 10vh;
+}
+
+.modal .content {
+ height: 10vh;
+ color: #9d9d9d;
+ font-size: 28rpx;
+}
+
+.modal .button {
+ height: 10vh;
+ color: #3cc51f;
+ font-size: 36rpx;
+}
\ No newline at end of file
diff --git a/lib/api.js b/lib/api.js
index 44dad23..f1eccf0 100644
--- a/lib/api.js
+++ b/lib/api.js
@@ -96,7 +96,6 @@ const delCode = (id, callBack) => {
sign: util.getMD5(id)
},
success: function (res) {
- console.log(res)
if (res.data.errcode !== 200) {
wx.hideLoading();
wx.showToast({
diff --git a/lib/util.js b/lib/util.js
index 624eb63..6f6feac 100644
--- a/lib/util.js
+++ b/lib/util.js
@@ -38,8 +38,8 @@ const getMD5 = obj => {
const checkFlag = (arg,flag, callBack) => {
flag--
- console.log(arg)
- console.log(flag)
+ // console.log(arg)
+ // console.log(flag)
if(flag == 0) {
callBack && callBack()
}
@@ -49,22 +49,64 @@ const checkFlag = (arg,flag, callBack) => {
const checkInput = (type,content) => {
switch(type) {
case 'alcode': {
- return 'alcode'
+ if(content.indexOf('qr.alipay.com') != -1) {
+ return content
+ } else if (content.indexOf('QR.ALIPAY.COM') != -1) {
+ return content
+ } else {
+ wx.showToast({
+ title: '请扫描合格的支付宝收款码',
+ icon: 'none'
+ })
+ return ''
+ }
}
case 'qqcode': {
- return 'qqcode'
+ if(content.indexOf('qianbao.qq.com') != -1) {
+ return content
+ } else {
+ wx.showToast({
+ title:'请扫描合格的QQ收款码',
+ icon: 'none'
+ })
+ return ''
+ }
}
case 'wxcode': {
- return 'wxcode'
+ if(content.indexOf('wxp') != -1) {
+ return content
+ } else if(content.indexOf('payapp.weixin.qq.com') != -1) {
+ return content
+ } else {
+ wx.showToast({
+ title: '请扫描合格的微信收款码',
+ icon: 'none'
+ })
+ return ''
+ }
}
case 'username': {
- return 'username'
+ content = content.replace(/"/gi,'')
+ content = content.replace(/ /gi,'')
+ content = content.replace(/'/gi,'')
+ content = content.replace(/\$/gi,'')
+ return content
}
case 'node': {
- return 'node'
+ content = content.replace(/"/gi,'')
+ content = content.replace(/'/gi,'')
+ content = content.replace(/\$/gi,'')
+ content = content.replace(/ /gi,'')
+ return content
}
case 'month': {
- return 'month'
+ content = parseInt(content)
+ if(content) {
+ if(0 < content && content < 13) {
+ return content
+ }
+ }
+ return ''
}
}
}
@@ -104,7 +146,7 @@ const checkSubmit = (c) => {
data['openId'] = c.openId
data['node'] = c.node
data['timeout'] = ((new Date()).getTime() + 1000*60*60*24*30*c.month).toString()
- var totalFee = c.month * 0.5
+ var totalFee = c.month * 0.5 * 100
return {
data: data,
totalFee: totalFee
diff --git a/pages/home/home.js b/pages/home/home.js
index 92179aa..4853be7 100644
--- a/pages/home/home.js
+++ b/pages/home/home.js
@@ -34,7 +34,10 @@ Page({
node: '',
timeout: '',
month: 0
- }
+ },
+ orderParams: {}, // 支付发起参数
+ preparePay: false, // 控制 payjs 组件的创建与销毁
+ paying: false, // 可选:如需知晓用户是否「已经跳转到了 PAYJS 小程序还未返回」的状态则可通过事件处理函数监听事件内的 paying 数据
},
/**
@@ -105,23 +108,72 @@ Page({
showUtils: function(e) {
var type = e.currentTarget.dataset.type
if(this.data.animating) return
+ if(type == 'maked' && this.data.codes.length == 0) {
+ wx.showToast({
+ title: '空空如也呢',
+ icon: 'none'
+ })
+ return
+ }
var that = this
this.data.animating = true
if(this.data.show) {
//拉起主页
- this.data.codeSrc = null
- let display = this.data.display
- for(var i in display) {
- if(i != 'createBox') display[i] = false
+ // 如果是start页先弹窗问是否返回, 是就清除数据
+ if(this.data.display['start']) {
+ wx.showModal({
+ title: '警告',
+ content: '此时返回将清除已录入的数据',
+ success (res) {
+ if (res.confirm) {
+ that.data.createCode = {
+ wxcode: '',
+ qqcode: '',
+ alcode: '',
+ username: '',
+ openId: wx.getStorageSync('openid'),
+ node: '',
+ timeout: '',
+ month: 0
+ }
+ that.setData({
+ createCode: that.data.createCode,
+ orderParams:{}
+ })
+ that.data.codeSrc = null
+ let display = that.data.display
+ for(var i in display) {
+ if(i != 'createBox') display[i] = false
+ }
+ display['createBox'] = true
+ that.setData({
+ display: display,
+ show:false
+ })
+ setTimeout(function(){
+ that.data.animating = false
+ },500)
+ } else if (res.cancel) {
+ console.log('用户点击取消')
+ that.data.animating = false
+ }
+ }
+ })
+ } else {
+ this.data.codeSrc = null
+ let display = this.data.display
+ for(var i in display) {
+ if(i != 'createBox') display[i] = false
+ }
+ display['createBox'] = true
+ this.setData({
+ display: display,
+ show:false
+ })
+ setTimeout(function(){
+ that.data.animating = false
+ },500)
}
- display['createBox'] = true
- this.setData({
- display: display,
- show:false
- })
- setTimeout(function(){
- that.data.animating = false
- },500)
} else {
//拉起utils页
//阻止点击返回键
@@ -143,12 +195,19 @@ Page({
})
that.data.animating = false
if(type == 'example') that.rouseQRcode(true,null)
+ if(type == 'start') {
+ wx.showModal({
+ title: '提示',
+ content: '由于技术原因,将于下个版本支持苹果手机',
+ showCancel: false
+ })
+ }
},500)
}
},
//处理数据
- manageCodes:function() {
+ manageCodes:function(callBack) {
let codes = wx.getStorageSync('codes')
for( let i in codes) {
let end = this.TimeDown(codes[i]['timeout'])
@@ -157,6 +216,7 @@ Page({
this.setData({
codes: codes
})
+ callBack && callBack()
},
//时间处理辅助轮
TimeDown: function(arg) {
@@ -180,7 +240,7 @@ Page({
//删除二维码
delCode:function(e) {
var id = e.currentTarget.dataset.id
- console.log(id)
+ var that = this
wx.showModal({
title: '警告',
content: '此操作不可恢复,并且不会返还费用',
@@ -191,8 +251,14 @@ Page({
mask:true
})
api.delCode(id,function(){
- wx.showToast({
- title: "删除成功"
+ //刷新并处理数据
+ api.reflash(wx.getStorageSync('openid'),function(info) {
+ wx.setStorageSync('codes', info);
+ that.manageCodes(function(){
+ wx.showToast({
+ title: "删除成功"
+ })
+ })
})
})
} else if (res.cancel) {
@@ -216,6 +282,7 @@ Page({
title: '绘制中',
mask:true
})
+ this.data.animating = true
if(isExample) {
var status = {
wx: true,
@@ -236,7 +303,6 @@ Page({
this.setData({
display:display
})
- console.log(this.data.display)
// data 的内容是一条记录的row
var id = data._id['$oid']
var text = data.username
@@ -306,13 +372,13 @@ Page({
destHeight: 2108,
canvasId: 'qrcode',
success: function (res) {
- console.log(res)
that.data.codeSrc = res.tempFilePath
- console.log(that.data.codeSrc)
wx.hideLoading()
+ that.data.animating = false
wx.showModal({
title: '提示',
content: '单击图片即可预览,预览界面长按即可保存',
+ showCancel: false
})
}
})
@@ -325,7 +391,6 @@ Page({
},
preview: function() {
- console.log(this.data.codeSrc)
wx.previewImage({
urls: [this.data.codeSrc],
})
@@ -340,18 +405,20 @@ Page({
//utils里边写个校验,返回true false
//写入
var check = util.checkInput(type,res.result)
- console.log(check)
- that.data.createCode[type] = res.result
- that.setData({
- createCode: that.data.createCode
- })
- wx.showToast({
- title: '录入成功',
- icon: 'success',
- })
+ if(check) {
+ that.data.createCode[type] = check
+ that.setData({
+ createCode: that.data.createCode
+ })
+ wx.showToast({
+ title: '录入成功',
+ icon: 'success',
+ })
+ }else {
+ return
+ }
},
fail (err) {
- console.log(err)
wx.showToast({
title: '扫码失败',
icon: 'none',
@@ -365,23 +432,139 @@ Page({
var type = e.currentTarget.dataset.type
var value = e.detail.value
var check = util.checkInput(type,value)
- console.log(check)
- this.data.createCode[type] = value
- this.setData({
- createCode: this.data.createCode
- })
- //utils校验,返回的东西直接装进createCode
- //return value
- console.log(e)
+ if(check) {
+ this.data.createCode[type] = check
+ this.setData({
+ createCode: this.data.createCode
+ })
+ }
+ return check
},
//提交
submit: function() {
+ if (Object.keys(this.data.orderParams).length != 0) {
+ this.setData({
+ preparePay: true
+ })
+ return
+ }
+ var that = this;
var res = util.checkSubmit(this.data.createCode)
if (!res) return
console.log(res)
- //showLoading
- //api.newOrder
+ wx.showLoading({
+ title: '订单创建中',
+ mask:true
+ })
+ api.createOder(res.totalFee,res.data,function(parms) {
+ that.setData({
+ preparePay: true,
+ orderParams: parms
+ })
+ wx.hideLoading()
+ })
+
+
+ },
+
+ /**
+ * 支付成功的事件处理函数
+ *
+ * res.detail 为 PAYJS 小程序返回的订单信息
+ *
+ * 可通过 res.detail.payjsOrderId 拿到 PAYJS 订单号
+ * 可通过 res.detail.responseData 拿到详细支付信息
+ */
+ bindPaySuccess (res) {
+ wx.showLoading({
+ title: '订单查询中',
+ mask:true
+ });
+ var that = this
+ console.log('success', res)
+ console.log('[支付成功] PAYJS 订单号:', res.detail.payjsOrderId)
+ console.log('outTradeNo', res.detail.outTradeNo)
+ // 进行checkOrder
+ api.checkOrder(res.detail.outTradeNo,function(order_id) {
+ //重置createCode
+ var data = that.data.createCode
+ data._id = {}
+ data._id['$oid'] = order_id
+ that.data.createCode = {
+ wxcode: '',
+ qqcode: '',
+ alcode: '',
+ username: '',
+ openId: wx.getStorageSync('openid'),
+ node: '',
+ timeout: '',
+ month: 0
+ }
+ that.setData({
+ createCode: that.data.createCode,
+ orderParams:{}
+ })
+ //调起绘制二维码的界面
+ wx.hideLoading()
+ that.rouseQRcode(false,data)
+ })
+
+ //刷新并处理数据
+ api.reflash(wx.getStorageSync('openid'),function(info) {
+ wx.setStorageSync('codes', info);
+ that.manageCodes()
+ })
+ },
+ /**
+ * 支付失败的事件处理函数
+ *
+ * res.detail.error 为 true 代表传入小组件的参数存在问题
+ * res.detail.navigateSuccess 代表了是否成功跳转到 PAYJS 小程序
+ * res.detail.info 可能存有失败的原因
+ *
+ * 如果下单成功但是用户取消支付则可在 res.detail.info.payjsOrderId 拿到 payjs 订单号
+ */
+ bindPayFail (res) {
+ console.log('fail', res)
+ if (res.detail.error) {
+ // 后端订单生成完成
+ // !!!!苹果手机会卡在这里!!!
+ console.error('发起支付失败', res.detail.info)
+
+ } else if (res.detail.navigateSuccess) {
+ // 跳转到了付款界面但是没付款
+ console.log('[取消支付] PAYJS 订单号:', res.detail.info.payjsOrderId)
+
+ } else {
+ // 用户放弃了付款,没跳转,再次跳转还可以进行支付
+ // 目测啥都不用干
+ }
+ },
+ /**
+ * 支付完毕的事件处理函数
+ *
+ * 无论支付成功或失败均会执行
+ * 应当在此销毁 payjs 组件
+ */
+ bindPayComplete () {
+ console.log('complete')
+ this.setData({
+ preparePay: false, // 销毁 payjs 组件
+ })
+ },
+ /**
+ * 【可选】组件内部数据被修改时的事件
+ *
+ * 当前仅用于监听 paying 数据
+ * 当用户跳转到 PAYJS 小程序并等待返回的过程中 paying 值为 true
+ */
+ bindDataChange (res) {
+ if (res.detail.paying) {
+ this.setData({
+ paying: res.detail.paying
+ })
+ }
}
})
diff --git a/pages/home/home.json b/pages/home/home.json
index 8835af0..a1bde67 100644
--- a/pages/home/home.json
+++ b/pages/home/home.json
@@ -1,3 +1,5 @@
{
- "usingComponents": {}
+ "usingComponents": {
+ "payjs": "../../components/payjs/payjs"
+ }
}
\ No newline at end of file
diff --git a/pages/home/home.wxml b/pages/home/home.wxml
index 6f9406c..4b4c697 100644
--- a/pages/home/home.wxml
+++ b/pages/home/home.wxml
@@ -76,16 +76,16 @@
标题
-
+
备注
-
+
- 使用时长(月)
+ 使用时长(0.5元/月)
@@ -106,4 +106,5 @@
{{codes.length}} 个
-
\ No newline at end of file
+
+
\ No newline at end of file
diff --git a/pages/home/home.wxss b/pages/home/home.wxss
index fb842c1..79fe305 100644
--- a/pages/home/home.wxss
+++ b/pages/home/home.wxss
@@ -95,6 +95,21 @@ page {
justify-content: flex-end;
}
+.main .main-box .main-warning text {
+ width: 30rpx;
+ height: 30rpx;
+ background-image: url("data:image/svg+xml,%3Csvg t='1573649986989' class='icon' viewBox='0 0 1025 1024' version='1.1' xmlns='http://www.w3.org/2000/svg' p-id='2146' width='200' height='200'%3E%3Cpath d='M999.126733 754.39104L646.123213 118.1696c-31.46752-56.61696-80.42496-89.09824-134.30784-89.09824-53.9648 0-102.93248 32.52224-134.30784 89.20064L24.872653 754.33984C-6.103347 810.20928-8.212787 869.08928 19.066573 915.87584c27.36128 46.92992 79.6672 73.85088 143.52384 73.85088h698.89024c63.88736 0 116.19328-26.92096 143.4624-73.7792 27.33056-46.72512 25.21088-105.61536-5.81632-161.55648zM924.548813 869.0688c-10.20928 17.53088-33.18784 27.58656-63.06816 27.58656H162.590413c-29.87008 0-52.86912-10.07616-63.11936-27.648-10.3424-17.73568-7.85408-43.07968 6.79936-69.5296l352.64512-636.08832c14.51008-26.20416 33.80224-41.23648 52.89984-41.23648 19.08736 0 38.38976 15.03232 52.95104 41.216l352.9728 636.17024c14.68416 26.4704 17.17248 51.79392 6.8096 69.5296z' fill='%23F15533' p-id='2147'%3E%3C/path%3E%3Cpath d='M512.020173 634.07104a46.53056 46.53056 0 0 0 46.5408-46.44864V370.25792a46.52032 46.52032 0 0 0-46.5408-46.44864 46.53056 46.53056 0 0 0-46.5408 46.44864v217.35424a46.53056 46.53056 0 0 0 46.5408 46.45888zM512.020173 680.6016a62.09536 62.09536 0 0 0-62.0544 62.0544c0 34.2016 27.78112 62.0544 62.0544 62.0544 34.2016 0 62.0544-27.78112 62.0544-62.0544 0-34.2016-27.78112-62.0544-62.0544-62.0544z' fill='%23F15533' p-id='2148'%3E%3C/path%3E%3C/svg%3E");
+ background-size: 100% 100%;
+ display: inline-block;
+ margin-right: 20rpx;
+}
+
+.main .main-box .main-warning span {
+ font-size: 25rpx;
+ line-height: 50rpx;
+}
+
+
.main .create-warp {
background: #fff;
border-radius: 20rpx;