待优化

<script>
import wepy from 'wepy'
import api from '../api/api'
import wxPay from '../api/wxPay'
import teamNamingConventions from '../api/teamNamingConventions'
import config from '../config'
import CryptoJS from '../utils/crypto-js/crypto-js'
import util from '../utils/util'
const MD5 = require('../utils/crypto-js/md5')
export default class recharge extends wepy.page {
config = {
navigationBarTitleText: '账户充值'
}
data = {
notHere: {},
apiRes: {},
amountTab: {
currentType: 0,
amountType: [],
payType: 0
},
wxUserInfo: {}
}
async getAccountBalance() {
const backEndRequire = {
method: 'POST',
header: {
'Content-Type': 'application/x-www-form-urlencoded'
}
}
let q = backEndRequire
q.query = {
uid: this.$parent.UID.uid,
}
const r = await api.getAccountBalance(q)
this.apiRes.AccountBalance = r.data.data
this.$apply()
}
phoneCall(e) {
wx.makePhoneCall({
phoneNumber: e.currentTarget.dataset.replyPhone,
success() {}
})
}
onTap(e) {
const k = e.currentTarget.dataset.key
const v = e.currentTarget.dataset.val
this.amountTab[k] = v
}
getOpenId() {
const that = this
wx.login({
success: function(res) {
if (res.code) {
const resCode = res.code
console.log(res.code)
const url = 'https://api.weixin.qq.com/sns/jscode2session?appid=' + config.APP.appid + '&secret=' + config.KEY.app + '&js_code=' + resCode + '&grant_type=authorization_code'
wx.request({
url: url,
success: function(res) {
console.log(url)
console.log(res)
that.wxUserInfo.openid = res.data.openid
},
})
} else {
console.log('登录失败!' + res.errMsg)
}
}
})
}
getAmountItemDescribe() {
const cottoncandy = this.amountTab.amountType[this.amountTab.currentType]
return '付款' + cottoncandy[0] + '元送' + cottoncandy[1] + '币'
}
pay() {
console.log(this)
switch (this.amountTab.payType) {
case 0:
this.wxPay()
break
case 1:
this.aliPay()
break
}
}
aliPay() {
let insecurePayUrl = config.PayUrl.AliInsecureJumpUrl
console.log('test--->')
const testExchangeRate = 1000 * 100
const moneyInfo = this.amountTab.amountType[this.amountTab.currentType]
const total_fee = moneyInfo[0] / testExchangeRate // 订单价格 单位是 分
const nonce_str = 'fsDGfg' + util.randomNumStr(5) + '5ASxcvx'
const stringSignTemp = 'amount=' + total_fee + '&nonce_str=' + nonce_str + '&p_id=' + moneyInfo[2] + '&uid=' + this.$parent.UID.uid
const sign = MD5(stringSignTemp + '&key=' + config.KEY.aliPayJumpUrlKey).toString().toUpperCase()
const wholeStr = stringSignTemp + '@' + sign
const Utf8Str = CryptoJS.enc.Utf8.parse(wholeStr)
const Base64Str = CryptoJS.enc.Base64.stringify(Utf8Str)
const originUrl = insecurePayUrl + '/' + stringSignTemp
const resultUrl = insecurePayUrl + '/' + Base64Str
console.log(originUrl)
console.log(resultUrl)
console.log('<---test')
insecurePayUrl += Base64Str
let tip = "
亲支付链接已经复制
粘贴到浏览器支付吧
"
tip += this.getAmountItemDescribe()
const title = '支付'
wx.setClipboardData({
data: insecurePayUrl,
success: function(res) {
wx.getClipboardData({
success: function(res) {
console.log(res.data)
wx.showModal({
title: title,
content: tip,
icon: 'success',
duration: 1500
})
}
})
}
})
}
wxPay() {
const openid = this.wxUserInfo.openid
let obj = config.APP
obj.spbill_create_ip = '1.2.3.4' //
obj.body = this.getAmountItemDescribe() // 商品描述
obj.notify_url = config.PayUrl.WXNotifyUrl // 支付成功的回调地址 可访问 不带参数
obj.nonce_str = ((new Date().getTime()) + '1add1a30ac87aa2db72f57a2375d8fec').slice(0, 32) // 随机字符串
obj.out_trade_no = teamNamingConventions.payOrderNO() // 商户订单号
const moneyInfo = this.amountTab.amountType[this.amountTab.currentType]
const testExchangeRate = 1000 * 100
obj.total_fee = moneyInfo[0] * 100 / testExchangeRate // 订单价格 单位是 分
obj.openid = openid
obj.device_info = '1000'
const wx_biz_attach = 'uid@' + this.$parent.UID.uid + ';p_id@' + moneyInfo[2] + ';'
obj.attach = wx_biz_attach
console.log(obj)
const APPKeySign = wxPay.Sign(obj, 'PayKey')
let bodyData = '<xml>'
bodyData += '<appid>' + obj.appid + '</appid>' // 小程序ID
bodyData += '<body>' + obj.body + '</body>' // 商品描述
bodyData += '<mch_id>' + obj.mch_id + '</mch_id>' // 商户号
bodyData += '<device_info>' + obj.device_info + '</device_info>' // 商户号
bodyData += '<nonce_str>' + obj.nonce_str + '</nonce_str>' // 随机字符串
bodyData += '<notify_url>' + obj.notify_url + '</notify_url>' // 支付成功的回调地址
bodyData += '<openid>' + obj.openid + '</openid>' // 用户标识
bodyData += '<out_trade_no>' + obj.out_trade_no + '</out_trade_no>' // 商户订单号
bodyData += '<spbill_create_ip>' + obj.spbill_create_ip + '</spbill_create_ip>' // 终端IP
bodyData += '<total_fee>' + obj.total_fee + '</total_fee>' // 总金额 单位为分
bodyData += '<trade_type>' + obj.trade_type + '</trade_type>' // 交易类型 小程序取值如下:JSAPI
bodyData += '<attach>' + obj.attach + '</attach>'
bodyData += '<sign>' + APPKeySign + '</sign>'
bodyData += '</xml>'
console.log(bodyData)
const that = this
wx.request({
url: 'https://api.mch.weixin.qq.com/pay/unifiedorder',
method: "POST",
data: bodyData,
success: function(res) {
console.log(res)
const i = res.data.indexOf('prepay_id><![CDATA[')
const j = res.data.indexOf(']]></prepay_id')
const prepay_id = res.data.slice(i + 'prepay_id><![CDATA['.length, j)
const objPay = {}
objPay.appId = config.APP.appid
objPay.nonceStr = obj.nonce_str
objPay.package = 'prepay_id=' + prepay_id
objPay.signType = 'MD5'
objPay.timeStamp = String(new Date().getTime())
const paySign = wxPay.Sign(objPay, 'PayKey')
wx.requestPayment({
'timeStamp': objPay.timeStamp,
'nonceStr': objPay.nonceStr,
'package': objPay.package,
'signType': objPay.signType,
'paySign': paySign,
'success': function(res) {
console.log(res)
wx.showToast({
title: '充值成功',
icon: 'success',
duration: 1500
})
that.getAccountBalance()
console.log('that.getAccountBalance()')
},
'fail': function(res) {
console.log(res)
wx.showToast({
title: '充值失败',
icon: 'success',
duration: 1500
})
},
'complete': function(res) {
console.log(res)
}
})
}
})
}
async getAmountType() {
const r = await api.getAmountType({})
const d = r.data.data
let arr = []
for (const v of d) {
if (v.p_id < 100 && v.status !== -1) {
arr.push([v.p_price, v.p_give, v.p_id])
}
}
this.amountTab.amountType = arr
this.$apply()
}
onLoad() {
this.notHere.commonCfg = wepy.$appConfig.common
this.getAccountBalance()
this.getOpenId()
this.getAmountType()
}
}
</script>
<template>
<view class="root_">
<view>
<view>账户余额
<text class="question-mark">?</text>
</view>
<view>
<view class="balance"><text>¥</text><text class="balance-num"> {{apiRes.AccountBalance['1'].val}} </text> <text>币</text></view>
</view>
</view>
<view class="clear_both">充值金额</view>
<view class="amountType-container">
<repeat for="{{amountTab.amountType}}" key="index" index="index" item="item">
<view class="amountType-item {{index===amountTab.currentType ? 'amount-item_select-after' :'amount-item_select-before'}}" @tap="onTap" data-key="currentType" data-val={{index}}>
<view class="amountType-gift">{{item[1]===0 ? ' ': '送'+item[1]+'币'}}</view>
<!-- 注意view初始为display:block; -->
<!-- <view class="amountType-gift" style="display:{{item[1]===0 ? 'none': 'block'}}">{{'送'+item[1]+'币'}}</view> -->
<view class="amountType-exchange-rate">
<text>{{item[0]}}</text><text>元</text>=<text>{{item[0]+item[1]}}</text><text>币</text>
</view>
</view>
</repeat>
</view>
<view class="clear_both">支付方式</view>
<view class="pay-type">
<view class="payType_img-separation">
<view class="pay-type_select-before {{amountTab.payType === 0 ? 'pay-type_select-after' : ''}}">
<image @tap="onTap" data-key="payType" data-val={{0}} class="pay-type_img-width-height" src="{{notHere.commonCfg.localImgPath}}payWeixin.jpg"></image>
</view>
</view>
<view class="payType_img-separation">
<view class="pay-type_select-before {{amountTab.payType === 1 ? 'pay-type_select-after' : ''}}">
<image @tap="onTap" data-key="payType" data-val={{1}} class="pay-type_img-width-height" src="{{notHere.commonCfg.localImgPath}}payAli.jpg"></image>
</view>
</view>
</view>
<view class="pay-number">应付金额
<text>{{amountTab.amountType[amountTab.currentType][0]}}</text>元
</view>
<view>
<button class="weui-btn weui-btn_mini weui-btn_primary recharge_button" @tap=pay()>立即充值</button>
</view>
<view class="contact">购买套餐,一键咨询:
<text class="phone-number" data-reply-phone="0755123" bindtap="phoneCall">0755-123</text>
</view>
</view>
</template>
<style lang="less">
// WXSS · 小程序 https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxss.html
@wx- 750rpx; // TODO 全局统一;2018年10月2日 16:29:42
@wx-width_px: 750;
@wx-width_rpx-num: 750;
@wx-width_one-unit: @wx-width/@wx-width_rpx-num;
@color-main_red: #F00;
@color-main_blue: #2CABE2;
@color-main_gray: #ADADAD;
@root_padding-horizontal: @wx-width_one-unit*12;
@wx-width_subtract-padding- @wx-width - @root_padding-horizontal*2;
@common_border- @wx-width_one-unit; // 选中项的边框
@common_select-after-font-size: @wx-width_one-unit*24; // 选中项的after-content字体大小
.root_ {
padding: @root_padding-horizontal;
}
.clear_both {
clear: both;
}
.balance {
font-size: @wx-width_one-unit*25;
.balance-num {
font-weight: normal;
color: @color-main_red;
}
}
.question-mark {
border: @wx-width_one-unit solid @color-main_gray;
color: @color-main_gray;
border-radius: 50%;
text-align: center;
}
.mixin_change-border-color(@c: @color-main_gray) {
border: @common_border-width solid @c;
}
.mixin_item_select-before() {
.mixin_change-border-color(@c: @color-main_gray);
} // 没有点击选中前的公共样式;
.mixin_item_select-after(@font-size: @common_select-after-font-size, @margin-top: @common_select-after-font-size) {
display: block;
float: right;
content: "√";
background-color: @color-main_blue;
color: #fff;
border-radius: 50%;
font-size: @font-size;
margin-top: -@margin-top;
} // 点击选中后的公共样式;
.amountType-container {
// 盒子模型;注意view初始为display:block;
@2items_margin- @wx-width_subtract-padding-width*0.02; // 并排的2个选项区域的外围margin;
@item-separation-margin- @wx-width_subtract-padding-width*0.05; // 2个选项横排;选项margin水平间距;
@item-border- @common_border-width; // 2个选项的border宽度;
@item-available- @wx-width_subtract-padding-width - @2items_margin-width*2 - @item-border-width*4 - @item-separation-margin-width*4; // 待布局选项区域;
@item-render- @item-available-width/2; // 选项最终被渲染的宽度;
@item_select-after-font-size: @common_select-after-font-size;
margin: 0 @2items_margin-width; // @wx-width_one-unit;
background-color: green;
.amountType-item {
@item-render-width;
float: left;
margin: @common_select-after-font-size*0.8 @item-separation-margin-width;
.mixin_block-float(@f: right) {
display: block;
float: @f;
}
.amountType-gift {
.mixin_block-float(@f: right);
background-color: @color-main_red;
border-radius: 20% 0 0 30%;
color: #fff;
font-size: 80%; //TODO exact
}
.amountType-exchange-rate {
.mixin_block-float(@f: left);
@v: 700;
text:nth-last-child(2) {
color: @color-main_red;
font-weight: @v;
}
text:nth-child(1) {
font-weight: @v;
}
}
}
.amount-item_select-before {
.mixin_item_select-before();
}
.amount-item_select-after {
.mixin_change-border-color(@c: @color-main_blue);
&:after {
.mixin_item_select-after(@font-size: @common_select-after-font-size, @margin-top: @common_select-after-font-size);
}
}
}
.pay-type {
@pay-type_2imgs_padding-width : @wx-width_subtract-padding-width*0.05; // 并排的2项的区域的外围边框
@pay-type_img-available- @wx-width_subtract-padding-width - @pay-type_2imgs_padding-width*2 - @pay-type_border-width*4; // 待布局图片的区域
@pay-type_border- @common_border-width; // 无论是否被选中,项之间、选中前后都有相同的边框宽度;选中对边框的影响是改变边框颜色;
@pay-type_imgs_width-share: 0.8; // 图片宽度份额,其他留作2张图片间的水平margin;
@pay-type_img-margin- @pay-type_img-available-width*(1- @pay-type_imgs_width-share)/4; // 2张图之间的margin宽度
@pay-type_img-render- @pay-type_img-available-width*@pay-type_imgs_width-share/2; // 图片最终被渲染的宽度
@pay-type_img-width-divide-height: 98/40; // 原图 宽度 高度 98 40 像素 96*96 dpi;// 原2张图宽高像素比相同;//image-height("file.png");
@pay-type_img-render-height: @pay-type_img-render-width/@pay-type_img-width-divide-height; // 保持图片宽高比,图片最终被渲染的高度
@pay-type_amount-item_select-after-font-size: @common_select-after-font-size;
display: inline-flex;
padding: 0 @pay-type_2imgs_padding-width;
height: @pay-type_img-render-height + @pay-type_border-width;
.pay-type_img-width-height {
@pay-type_img-render-width;
height: @pay-type_img-render-height;
}
.payType_img-separation {
margin: 0 @pay-type_img-margin-width;
}
.pay-type_select-before {
.mixin_item_select-before()
}
.pay-type_select-after {
.mixin_change-border-color(@c: @color-main_blue);
&:after {
.mixin_item_select-after(@font-size: @common_select-after-font-size, @margin-top: @common_select-after-font-size);
}
}
}
.contact {
text-align: center;
.phone-number {
color: @color-main_blue;
}
}
.recharge_button {
90%;
border-radius: @wx-width_one-unit*8;
background-color: @color-main_blue;
color: #fff;
}
</style>

优化点:
1、content的位置和显示与遮挡的部分;
2、商品选项的高度统一;
<script>
import wepy from 'wepy'
import api from '../api/api'
import wxPay from '../api/wxPay'
import teamNamingConventions from '../api/teamNamingConventions'
import config from '../config'
import CryptoJS from '../utils/crypto-js/crypto-js'
import util from '../utils/util'
const MD5 = require('../utils/crypto-js/md5')
export default class recharge extends wepy.page {
config = {
navigationBarTitleText: '账户充值'
}
data = {
notHere: {},
apiRes: {},
amountTab: {
currentType: 0,
amountType: [],
payType: 0
},
wxUserInfo: {}
}
async getAccountBalance() {
const backEndRequire = {
method: 'POST',
header: {
'Content-Type': 'application/x-www-form-urlencoded'
}
}
let q = backEndRequire
q.query = {
uid: this.$parent.UID.uid,
}
const r = await api.getAccountBalance(q)
this.apiRes.AccountBalance = r.data.data
this.$apply()
}
phoneCall(e) {
wx.makePhoneCall({
phoneNumber: e.currentTarget.dataset.replyPhone,
success() {}
})
}
onTap(e) {
const k = e.currentTarget.dataset.key
const v = e.currentTarget.dataset.val
this.amountTab[k] = v
}
getOpenId() {
const that = this
wx.login({
success: function(res) {
if (res.code) {
const resCode = res.code
console.log(res.code)
const url = 'https://api.weixin.qq.com/sns/jscode2session?appid=' + config.APP.appid + '&secret=' + config.KEY.app + '&js_code=' + resCode + '&grant_type=authorization_code'
wx.request({
url: url,
success: function(res) {
console.log(url)
console.log(res)
that.wxUserInfo.openid = res.data.openid
},
})
} else {
console.log('登录失败!' + res.errMsg)
}
}
})
}
getAmountItemDescribe() {
const cottoncandy = this.amountTab.amountType[this.amountTab.currentType]
return '付款' + cottoncandy[0] + '元送' + cottoncandy[1] + '币'
}
pay() {
console.log(this)
switch (this.amountTab.payType) {
case 0:
this.wxPay()
break
case 1:
this.aliPay()
break
}
}
aliPay() {
let insecurePayUrl = config.PayUrl.AliInsecureJumpUrl
console.log('test--->')
const testExchangeRate = 1000 * 100
const moneyInfo = this.amountTab.amountType[this.amountTab.currentType]
const total_fee = moneyInfo[0] / testExchangeRate // 订单价格 单位是 分
const nonce_str = 'fsDGfg' + util.randomNumStr(5) + '5ASxcvx'
const stringSignTemp = 'amount=' + total_fee + '&nonce_str=' + nonce_str + '&p_id=' + moneyInfo[2] + '&uid=' + this.$parent.UID.uid
const sign = MD5(stringSignTemp + '&key=' + config.KEY.aliPayJumpUrlKey).toString().toUpperCase()
const wholeStr = stringSignTemp + '@' + sign
const Utf8Str = CryptoJS.enc.Utf8.parse(wholeStr)
const Base64Str = CryptoJS.enc.Base64.stringify(Utf8Str)
const originUrl = insecurePayUrl + '/' + stringSignTemp
const resultUrl = insecurePayUrl + '/' + Base64Str
console.log(originUrl)
console.log(resultUrl)
console.log('<---test')
insecurePayUrl += Base64Str
let tip = "
亲支付链接已经复制
粘贴到浏览器支付吧
"
tip += this.getAmountItemDescribe()
const title = '支付'
wx.setClipboardData({
data: insecurePayUrl,
success: function(res) {
wx.getClipboardData({
success: function(res) {
console.log(res.data)
wx.showModal({
title: title,
content: tip,
icon: 'success',
duration: 1500
})
}
})
}
})
}
wxPay() {
const openid = this.wxUserInfo.openid
let obj = config.APP
obj.spbill_create_ip = '1.2.3.4' //
obj.body = this.getAmountItemDescribe() // 商品描述
obj.notify_url = config.PayUrl.WXNotifyUrl // 支付成功的回调地址 可访问 不带参数
obj.nonce_str = ((new Date().getTime()) + '1add1a30ac87aa2db72f57a2375d8fec').slice(0, 32) // 随机字符串
obj.out_trade_no = teamNamingConventions.payOrderNO() // 商户订单号
const moneyInfo = this.amountTab.amountType[this.amountTab.currentType]
const testExchangeRate = 1000 * 100
obj.total_fee = moneyInfo[0] * 100 / testExchangeRate // 订单价格 单位是 分
obj.openid = openid
obj.device_info = '1000'
const wx_biz_attach = 'uid@' + this.$parent.UID.uid + ';p_id@' + moneyInfo[2] + ';'
obj.attach = wx_biz_attach
console.log(obj)
const APPKeySign = wxPay.Sign(obj, 'PayKey')
let bodyData = '<xml>'
bodyData += '<appid>' + obj.appid + '</appid>' // 小程序ID
bodyData += '<body>' + obj.body + '</body>' // 商品描述
bodyData += '<mch_id>' + obj.mch_id + '</mch_id>' // 商户号
bodyData += '<device_info>' + obj.device_info + '</device_info>' // 商户号
bodyData += '<nonce_str>' + obj.nonce_str + '</nonce_str>' // 随机字符串
bodyData += '<notify_url>' + obj.notify_url + '</notify_url>' // 支付成功的回调地址
bodyData += '<openid>' + obj.openid + '</openid>' // 用户标识
bodyData += '<out_trade_no>' + obj.out_trade_no + '</out_trade_no>' // 商户订单号
bodyData += '<spbill_create_ip>' + obj.spbill_create_ip + '</spbill_create_ip>' // 终端IP
bodyData += '<total_fee>' + obj.total_fee + '</total_fee>' // 总金额 单位为分
bodyData += '<trade_type>' + obj.trade_type + '</trade_type>' // 交易类型 小程序取值如下:JSAPI
bodyData += '<attach>' + obj.attach + '</attach>'
bodyData += '<sign>' + APPKeySign + '</sign>'
bodyData += '</xml>'
console.log(bodyData)
const that = this
wx.request({
url: 'https://api.mch.weixin.qq.com/pay/unifiedorder',
method: "POST",
data: bodyData,
success: function(res) {
console.log(res)
const i = res.data.indexOf('prepay_id><![CDATA[')
const j = res.data.indexOf(']]></prepay_id')
const prepay_id = res.data.slice(i + 'prepay_id><![CDATA['.length, j)
const objPay = {}
objPay.appId = config.APP.appid
objPay.nonceStr = obj.nonce_str
objPay.package = 'prepay_id=' + prepay_id
objPay.signType = 'MD5'
objPay.timeStamp = String(new Date().getTime())
const paySign = wxPay.Sign(objPay, 'PayKey')
wx.requestPayment({
'timeStamp': objPay.timeStamp,
'nonceStr': objPay.nonceStr,
'package': objPay.package,
'signType': objPay.signType,
'paySign': paySign,
'success': function(res) {
console.log(res)
wx.showToast({
title: '充值成功',
icon: 'success',
duration: 1500
})
that.getAccountBalance()
console.log('that.getAccountBalance()')
},
'fail': function(res) {
console.log(res)
wx.showToast({
title: '充值失败',
icon: 'success',
duration: 1500
})
},
'complete': function(res) {
console.log(res)
}
})
}
})
}
async getAmountType() {
const r = await api.getAmountType({})
const d = r.data.data
let arr = []
for (const v of d) {
if (v.p_id < 100 && v.status !== -1) {
arr.push([v.p_price, v.p_give, v.p_id])
}
}
this.amountTab.amountType = arr
this.$apply()
}
onLoad() {
this.notHere.commonCfg = wepy.$appConfig.common
this.getAccountBalance()
this.getOpenId()
this.getAmountType()
}
}
</script>
<template>
<view class="root_">
<view>
<view>账户余额
<text class="question-mark">?</text>
</view>
<view>
<view class="balance"><text>¥</text><text class="balance-num"> {{apiRes.AccountBalance['1'].val}} </text> <text>币</text></view>
</view>
</view>
<view class="clear_both">充值金额</view>
<view class="amountType-container">
<repeat for="{{amountTab.amountType}}" key="index" index="index" item="item">
<view class="amountType-item {{index===amountTab.currentType ? 'amount-item_select-after' :'amount-item_select-before'}}" @tap="onTap" data-key="currentType" data-val={{index}}>
<view class="amountType-gift">{{item[1]===0 ? ' ': '送'+item[1]+'币'}}</view>
<!-- 注意view初始为display:block; -->
<!-- <view class="amountType-gift" style="display:{{item[1]===0 ? 'none': 'block'}}">{{'送'+item[1]+'币'}}</view> -->
<view class="amountType-exchange-rate">
<text>{{item[0]}}</text><text>元</text>=<text>{{item[0]+item[1]}}</text><text>币</text>
</view>
</view>
</repeat>
</view>
<view class="clear_both">支付方式</view>
<view class="pay-type">
<view class="payType_img-separation">
<view class="pay-type_select-before {{amountTab.payType === 0 ? 'pay-type_select-after' : ''}}">
<image @tap="onTap" data-key="payType" data-val={{0}} class="pay-type_img-width-height" src="{{notHere.commonCfg.localImgPath}}payWeixin.jpg"></image>
</view>
</view>
<view class="payType_img-separation">
<view class="pay-type_select-before {{amountTab.payType === 1 ? 'pay-type_select-after' : ''}}">
<image @tap="onTap" data-key="payType" data-val={{1}} class="pay-type_img-width-height" src="{{notHere.commonCfg.localImgPath}}payAli.jpg"></image>
</view>
</view>
</view>
<view class="pay-number">应付金额
<text>{{amountTab.amountType[amountTab.currentType][0]}}</text>元
</view>
<view>
<button class="weui-btn weui-btn_mini weui-btn_primary recharge_button" @tap=pay()>立即充值</button>
</view>
<view class="contact">购买套餐,一键咨询:
<text class="phone-number" data-reply-phone="0755123" bindtap="phoneCall">0755-123</text>
</view>
</view>
</template>
<style lang="less">
// WXSS · 小程序 https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxss.html
@wx- 750rpx; // TODO 全局统一;2018年10月2日 16:29:42
@wx-width_px: 750;
@wx-width_rpx-num: 750;
@wx-width_one-unit: @wx-width/@wx-width_rpx-num;
@color-main_red: #F00;
@color-main_blue: #2CABE2;
@color-main_gray: #ADADAD;
@root_padding-horizontal: @wx-width_one-unit*12;
@wx-width_subtract-padding- @wx-width - @root_padding-horizontal*2;
@common_border- @wx-width_one-unit; // 选中项的边框
@common_select-after-font-size: @wx-width_one-unit*24; // 选中项的after-content字体大小
.root_ {
padding: @root_padding-horizontal;
}
.clear_both {
clear: both;
}
.balance {
font-size: @wx-width_one-unit*25;
.balance-num {
font-weight: normal;
color: @color-main_red;
}
}
.question-mark {
border: @wx-width_one-unit solid @color-main_gray;
color: @color-main_gray;
border-radius: 50%;
text-align: center;
}
.mixin_change-border-color(@c: @color-main_gray) {
border: @common_border-width solid @c;
}
.mixin_item_select-before() {
.mixin_change-border-color(@c: @color-main_gray);
} // 没有点击选中前的公共样式;
.mixin_item_select-after(@font-size: @common_select-after-font-size, @margin-top: @common_select-after-font-size) {
display: block;
float: right;
content: "√";
background-color: @color-main_blue;
color: #fff;
border-radius: 50%;
font-size: @font-size;
margin-top: -@margin-top;
} // 点击选中后的公共样式;
.amountType-container {
// 盒子模型;注意view初始为display:block;
@2items_margin- @wx-width_subtract-padding-width*0.02; // 并排的2个选项区域的外围margin;
@item-separation-margin- @wx-width_subtract-padding-width*0.05; // 2个选项横排;选项margin水平间距;
@item-border- @common_border-width; // 2个选项的border宽度;
@item-available- @wx-width_subtract-padding-width - @2items_margin-width*2 - @item-border-width*4 - @item-separation-margin-width*4; // 待布局选项区域;
@item-render- @item-available-width/2; // 选项最终被渲染的宽度;
@item-render-height: @pay-type_img-render-height; // 选项最终被渲染的高度;使用和支付图标一定比例的高度;
@item_select-after-font-size: @common_select-after-font-size;
margin: 0 @2items_margin-width; // @wx-width_one-unit;
background-color: green;
.amountType-item {
@item-render-width;
height: @item-render-height;
float: left;
margin: @common_select-after-font-size*0.8 @item-separation-margin-width;
.mixin_block-float(@f: right) {
display: block;
float: @f;
}
.amountType-gift {
.mixin_block-float(@f: right);
background-color: @color-main_red;
border-radius: 20% 0 0 30%;
color: #fff;
font-size: 80%; //TODO exact
}
.amountType-exchange-rate {
.mixin_block-float(@f: left);
@v: 700;
text:nth-last-child(2) {
color: @color-main_red;
font-weight: @v;
}
text:nth-child(1) {
font-weight: @v;
}
}
}
.amount-item_select-before {
.mixin_item_select-before();
}
.amount-item_select-after {
.mixin_change-border-color(@c: @color-main_blue);
&:after {
.mixin_item_select-after(@font-size: @common_select-after-font-size, @margin-top: @common_select-after-font-size);
}
}
}
@pay-type_2imgs_padding-width : @wx-width_subtract-padding-width*0.05; // 并排的2项的区域的外围边框
@pay-type_img-available- @wx-width_subtract-padding-width - @pay-type_2imgs_padding-width*2 - @pay-type_border-width*4; // 待布局图片的区域
@pay-type_border- @common_border-width; // 无论是否被选中,项之间、选中前后都有相同的边框宽度;选中对边框的影响是改变边框颜色;
@pay-type_imgs_width-share: 0.8; // 图片宽度份额,其他留作2张图片间的水平margin;
@pay-type_img-margin- @pay-type_img-available-width*(1- @pay-type_imgs_width-share)/4; // 2张图之间的margin宽度
@pay-type_img-render- @pay-type_img-available-width*@pay-type_imgs_width-share/2; // 图片最终被渲染的宽度
@pay-type_img-width-divide-height: 98/40; // 原图 宽度 高度 98 40 像素 96*96 dpi;// 原2张图宽高像素比相同;//image-height("file.png");
@pay-type_img-render-height: @pay-type_img-render-width/@pay-type_img-width-divide-height; // 保持图片宽高比,图片最终被渲染的高度
@pay-type_amount-item_select-after-font-size: @common_select-after-font-size;
.pay-type {
display: inline-flex;
padding: 0 @pay-type_2imgs_padding-width;
height: @pay-type_img-render-height + @pay-type_border-width;
.pay-type_img-width-height {
@pay-type_img-render-width;
height: @pay-type_img-render-height;
}
.payType_img-separation {
margin: 0 @pay-type_img-margin-width;
}
.pay-type_select-before {
.mixin_item_select-before()
}
.pay-type_select-after {
.mixin_change-border-color(@c: @color-main_blue);
&:after {
.mixin_item_select-after(@font-size: @common_select-after-font-size, @margin-top: @common_select-after-font-size);
}
}
}
.contact {
text-align: center;
.phone-number {
color: @color-main_blue;
}
}
.recharge_button {
90%;
border-radius: @wx-width_one-unit*8;
background-color: @color-main_blue;
color: #fff;
}
</style>

<script>
import wepy from 'wepy'
import api from '../api/api'
import wxPay from '../api/wxPay'
import teamConventions from '../api/teamConventions'
import config from '../config'
import CryptoJS from '../utils/crypto-js/crypto-js'
import util from '../utils/util'
const MD5 = require('../utils/crypto-js/md5')
export default class recharge extends wepy.page {
config = {
navigationBarTitleText: '账户充值'
}
data = {
notHere: {},
apiRes: {},
amountTab: {
currentType: 0,
amountType: [],
payType: 0
},
wxUserInfo: {}
}
async getAccountBalance() {
const backEndRequire = {
method: 'POST',
header: {
'Content-Type': 'application/x-www-form-urlencoded'
}
}
let q = backEndRequire
q.query = {
uid: this.$parent.UID.uid,
}
const r = await api.getAccountBalance(q)
this.apiRes.AccountBalance = r.data.data
this.$apply()
}
phoneCall(e) {
wx.makePhoneCall({
phoneNumber: e.currentTarget.dataset.replyPhone,
success() {}
})
}
onTap(e) {
const k = e.currentTarget.dataset.key
const v = e.currentTarget.dataset.val
this.amountTab[k] = v
}
getOpenId() {
const that = this
wx.login({
success: function(res) {
if (res.code) {
const resCode = res.code
console.log(res.code)
const url = 'https://api.weixin.qq.com/sns/jscode2session?appid=' + config.APP.appid + '&secret=' + config.KEY.app + '&js_code=' + resCode + '&grant_type=authorization_code'
wx.request({
url: url,
success: function(res) {
console.log(url)
console.log(res)
that.wxUserInfo.openid = res.data.openid
},
})
} else {
console.log('登录失败!' + res.errMsg)
}
}
})
}
getAmountItemDescribe() {
const cottoncandy = this.amountTab.amountType[this.amountTab.currentType]
return '付款' + cottoncandy[0] + '元送' + cottoncandy[1] + '币'
}
pay() {
console.log(this)
switch (this.amountTab.payType) {
case 0:
this.wxPay()
break
case 1:
this.aliPay()
break
}
}
aliPay() {
let insecurePayUrl = config.PayUrl.AliInsecureJumpUrl
console.log('test--->')
const testExchangeRate = 1000 * 100
const moneyInfo = this.amountTab.amountType[this.amountTab.currentType]
const total_fee = moneyInfo[0] / testExchangeRate // 订单价格 单位是 分
const nonce_str = 'fsDGfg' + util.randomNumStr(5) + '5ASxcvx'
const stringSignTemp = 'amount=' + total_fee + '&nonce_str=' + nonce_str + '&p_id=' + moneyInfo[2] + '&uid=' + this.$parent.UID.uid
const sign = MD5(stringSignTemp + '&key=' + config.KEY.aliPayJumpUrlKey).toString().toUpperCase()
const wholeStr = stringSignTemp + '@' + sign
const Utf8Str = CryptoJS.enc.Utf8.parse(wholeStr)
const Base64Str = CryptoJS.enc.Base64.stringify(Utf8Str)
const originUrl = insecurePayUrl + '/' + stringSignTemp
const resultUrl = insecurePayUrl + '/' + Base64Str
console.log(originUrl)
console.log(resultUrl)
console.log('<---test')
let tip = "亲,支付链接已经复制,粘贴到浏览器支付吧
"
tip += this.getAmountItemDescribe()
const title = '支付宝支付'
wx.setClipboardData({
data: resultUrl,
success: function(res) {
wx.getClipboardData({
success: function(res) {
console.log(res.data)
wx.showModal({
title: title,
content: tip,
icon: 'success',
duration: 1500
})
}
})
}
})
this.getAccountBalance()
}
wxPay() {
const openid = this.wxUserInfo.openid
let obj = config.APP
obj.spbill_create_ip = '1.2.3.4' //
obj.body = this.getAmountItemDescribe() // 商品描述
obj.notify_url = config.PayUrl.WXNotifyUrl // 支付成功的回调地址 可访问 不带参数
obj.nonce_str = ((new Date().getTime()) + '1add1a30ac87aa2db72f57a2375d8fec').slice(0, 32) // 随机字符串
obj.out_trade_no = teamConventions.payOrderNO() // 商户订单号
const moneyInfo = this.amountTab.amountType[this.amountTab.currentType]
const testExchangeRate = 1000 * 100
obj.total_fee = moneyInfo[0] * 100 / testExchangeRate // 订单价格 单位是 分
obj.openid = openid
obj.device_info = '1000'
const wx_biz_attach = {
uid: this.$parent.UID.uid,
p_id: moneyInfo[2]
}
obj.attach = teamConventions.wxPayNotifyUrlBizInfo(wx_biz_attach)
console.log(obj)
const APPKeySign = wxPay.Sign(obj, 'PayKey')
let bodyData = '<xml>'
bodyData += '<appid>' + obj.appid + '</appid>' // 小程序ID
bodyData += '<body>' + obj.body + '</body>' // 商品描述
bodyData += '<mch_id>' + obj.mch_id + '</mch_id>' // 商户号
bodyData += '<device_info>' + obj.device_info + '</device_info>' // 商户号
bodyData += '<nonce_str>' + obj.nonce_str + '</nonce_str>' // 随机字符串
bodyData += '<notify_url>' + obj.notify_url + '</notify_url>' // 支付成功的回调地址
bodyData += '<openid>' + obj.openid + '</openid>' // 用户标识
bodyData += '<out_trade_no>' + obj.out_trade_no + '</out_trade_no>' // 商户订单号
bodyData += '<spbill_create_ip>' + obj.spbill_create_ip + '</spbill_create_ip>' // 终端IP
bodyData += '<total_fee>' + obj.total_fee + '</total_fee>' // 总金额 单位为分
bodyData += '<trade_type>' + obj.trade_type + '</trade_type>' // 交易类型 小程序取值如下:JSAPI
bodyData += '<attach>' + obj.attach + '</attach>'
bodyData += '<sign>' + APPKeySign + '</sign>'
bodyData += '</xml>'
console.log(bodyData)
const that = this
wx.request({
url: 'https://api.mch.weixin.qq.com/pay/unifiedorder',
method: "POST",
data: bodyData,
success: function(res) {
console.log(res)
const i = res.data.indexOf('prepay_id><![CDATA[')
const j = res.data.indexOf(']]></prepay_id')
const prepay_id = res.data.slice(i + 'prepay_id><![CDATA['.length, j)
const objPay = {}
objPay.appId = config.APP.appid
objPay.nonceStr = obj.nonce_str
objPay.package = 'prepay_id=' + prepay_id
objPay.signType = 'MD5'
objPay.timeStamp = String(new Date().getTime())
const paySign = wxPay.Sign(objPay, 'PayKey')
wx.requestPayment({
'timeStamp': objPay.timeStamp,
'nonceStr': objPay.nonceStr,
'package': objPay.package,
'signType': objPay.signType,
'paySign': paySign,
'success': function(res) {
console.log(res)
wx.showToast({
title: '充值成功',
icon: 'success',
duration: 1500
})
that.getAccountBalance()
},
'fail': function(res) {
console.log(res)
wx.showToast({
title: '充值失败',
icon: 'success',
duration: 1500
})
},
'complete': function(res) {
console.log(res)
}
})
}
})
}
async getAmountType() {
const r = await api.getAmountType({})
const d = r.data.data
let arr = []
for (const v of d) {
if (v.p_id < 100 && v.status !== -1) {
arr.push([v.p_price, v.p_give, v.p_id])
}
}
this.amountTab.amountType = arr
this.$apply()
}
onLoad() {
this.notHere.commonCfg = wepy.$appConfig.common
this.getAccountBalance()
this.getOpenId()
this.getAmountType()
}
}
</script>
<template>
<view class="root_">
<view class="clear_both column-level-1">账户余额
<text class="question-mark">?</text>
</view>
<view>
<view class="balance"><text>¥</text><text class="balance-num"> {{apiRes.AccountBalance['1'].val}} </text> <text>币</text></view>
</view>
<view class="clear_both column-level-1">充值金额</view>
<view class="amountType-container">
<repeat for="{{amountTab.amountType}}" key="index" index="index" item="item">
<view class="amountType-item {{index===amountTab.currentType ? 'amount-item_select-after' :'amount-item_select-before'}}" @tap="onTap" data-key="currentType" data-val={{index}}>
<view class="amountType-gift">{{item[1]===0 ? ' ': '送'+item[1]+'币'}}</view>
<!-- 注意view初始为display:block; -->
<!-- <view class="amountType-gift" style="display:{{item[1]===0 ? 'none': 'block'}}">{{'送'+item[1]+'币'}}</view> -->
<view class="amountType-exchange-rate">
<text>{{item[0]}}</text><text>元</text>=<text>{{item[0]+item[1]}}</text><text>币</text>
</view>
</view>
</repeat>
</view>
<view class="clear_both column-level-1">支付方式</view>
<view class="pay-type">
<view class="payType_img-separation">
<view class="pay-type_select-before {{amountTab.payType === 0 ? 'pay-type_select-after' : ''}}">
<image @tap="onTap" data-key="payType" data-val={{0}} class="pay-type_img-width-height" src="{{notHere.commonCfg.localImgPath}}payWeixin.jpg"></image>
</view>
</view>
<view class="payType_img-separation">
<view class="pay-type_select-before {{amountTab.payType === 1 ? 'pay-type_select-after' : ''}}">
<image @tap="onTap" data-key="payType" data-val={{1}} class="pay-type_img-width-height" src="{{notHere.commonCfg.localImgPath}}payAli.jpg"></image>
</view>
</view>
</view>
<view class="amount-due">应付金额
<text>{{amountTab.amountType[amountTab.currentType][0]}}</text>元
</view>
<view class="clear_both column-level-1">
<button class="weui-btn weui-btn_mini weui-btn_primary recharge_button" @tap=pay()>立即充值</button>
</view>
<view class="clear_both column-level-1 contact">购买套餐,一键咨询:
<text class="phone-number" data-reply-phone="0755123" bindtap="phoneCall">0755-123</text>
</view>
</view>
</template>
<style lang="less">
// WXSS · 小程序 https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxss.html
@wx- 750rpx; // TODO 全局统一;2018年10月2日 16:29:42
@wx-width_px: 750;
@wx-width_rpx-num: 750;
@wx-width_one-unit: @wx-width/@wx-width_rpx-num;
@color-main_red: #F00;
@color-main_blue: #2CABE2;
@color-main_gray: #ADADAD;
@root_padding-horizontal: @wx-width_one-unit*12;
@wx-width_subtract-padding- @wx-width - @root_padding-horizontal*2;
@common_border- @wx-width_one-unit; // 选中项的边框
@common_select-after-font-size: @wx-width_one-unit*24; // 选中项的after-content字体大小
@font-size-column-level-1 : @wx-width_one-unit*40;
@margin-vertical-column-level-1 :@wx-width_one-unit*20;
.root_ {
padding: @root_padding-horizontal;
}
.clear_both {
clear: both;
}
.column-level-1 {
font-size: @font-size-column-level-1;
margin: @margin-vertical-column-level-1 0;
}
.amount-due {
margin: @margin-vertical-column-level-1*1.2 0 0 @margin-vertical-column-level-1*1.2;
}
.balance {
font-size: @wx-width_one-unit*30;
.balance-num {
font-weight: normal;
color: @color-main_red;
}
}
.question-mark {
border: @wx-width_one-unit solid @color-main_gray;
color: @color-main_gray;
border-radius: 50%;
text-align: center;
}
.mixin_change-border-color(@c: @color-main_gray) {
border: @common_border-width solid @c;
}
.mixin_item_select-before() {
.mixin_change-border-color(@c: @color-main_gray);
} // 没有点击选中前的公共样式;
.mixin_item_select-after(@font-size: @common_select-after-font-size, @margin-top: @common_select-after-font-size) {
display: block;
float: right;
content: "√";
background-color: @color-main_blue;
color: #fff;
border-radius: 50%;
font-size: @font-size;
margin-top: -@margin-top;
} // 点击选中后的公共样式;
.amountType-container {
// 盒子模型;注意view初始为display:block;
@2items_margin- @wx-width_subtract-padding-width*0.02; // 并排的2个选项区域的外围margin;
@item-separation-margin- @wx-width_subtract-padding-width*0.05; // 2个选项横排;选项margin水平间距;
@item-border- @common_border-width; // 2个选项的border宽度;
@item-available- @wx-width_subtract-padding-width - @2items_margin-width*2 - @item-border-width*4 - @item-separation-margin-width*4; // 待布局选项区域;
@item-render- @item-available-width/2; // 选项最终被渲染的宽度;
@item-render-height: @item-render-width*0.3; // TODO 设计图宽高比;
@item_select-after-font-size: @common_select-after-font-size;
margin: 0 @2items_margin-width; // @wx-width_one-unit;
background-color: green;
.amountType-item {
@item-render-width;
height: @item-render-height;
float: left;
margin: @common_select-after-font-size*0.8 @item-separation-margin-width;
.mixin_block-float(@f: right) {
display: block;
float: @f;
}
.amountType-gift {
.mixin_block-float(@f: right);
background-color: @color-main_red;
border-radius: 20% 0 0 30%;
color: #fff;
font-size: 80%; //TODO exact
}
.amountType-exchange-rate {
.mixin_block-float(@f: left);
@v: 700;
padding: @wx-width_one-unit*4;
text:nth-last-child(2) {
color: @color-main_red;
font-weight: @v;
}
text:nth-child(1) {
font-weight: @v;
}
}
}
.amount-item_select-before {
.mixin_item_select-before();
}
.amount-item_select-after {
.mixin_change-border-color(@c: @color-main_blue);
&:after {
.amountType-exchange-rate {
text:nth-child(2) {
.mixin_item_select-after(@font-size: @common_select-after-font-size, @margin-top: @common_select-after-font-size);
}
}
}
}
}
.pay-type {
@pay-type_2imgs_padding-width : @wx-width_subtract-padding-width*0.05; // 并排的2项的区域的外围边框
@pay-type_img-available- @wx-width_subtract-padding-width - @pay-type_2imgs_padding-width*2 - @pay-type_border-width*4; // 待布局图片的区域
@pay-type_border- @common_border-width; // 无论是否被选中,项之间、选中前后都有相同的边框宽度;选中对边框的影响是改变边框颜色;
@pay-type_imgs_width-share: 0.8; // 图片宽度份额,其他留作2张图片间的水平margin;
@pay-type_img-margin- @pay-type_img-available-width*(1- @pay-type_imgs_width-share)/4; // 2张图之间的margin宽度
@pay-type_img-render- @pay-type_img-available-width*@pay-type_imgs_width-share/2; // 图片最终被渲染的宽度
@pay-type_img-width-divide-height: 98/40; // 原图 宽度 高度 98 40 像素 96*96 dpi;// 原2张图宽高像素比相同;//image-height("file.png");
@pay-type_img-render-height: @pay-type_img-render-width/@pay-type_img-width-divide-height; // 保持图片宽高比,图片最终被渲染的高度;
@pay-type_amount-item_select-after-font-size: @common_select-after-font-size;
display: inline-flex;
padding: 0 @pay-type_2imgs_padding-width;
height: @pay-type_img-render-height + @pay-type_border-width;
.pay-type_img-width-height {
@pay-type_img-render-width;
height: @pay-type_img-render-height;
}
.payType_img-separation {
margin: 0 @pay-type_img-margin-width;
}
.pay-type_select-before {
.mixin_item_select-before()
}
.pay-type_select-after {
.mixin_change-border-color(@c: @color-main_blue);
&:after {
.mixin_item_select-after(@font-size: @common_select-after-font-size, @margin-top: @common_select-after-font-size);
}
}
}
.contact {
text-align: center;
.phone-number {
color: @color-main_blue;
}
}
.recharge_button {
90%;
border-radius: @wx-width_one-unit*8;
background-color: @color-main_blue;
color: #fff;
}
</style>
间距调整
