高度优化
待优化
<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 = "\r\n亲支付链接已经复制\r\n粘贴到浏览器支付吧\r\n" 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-width: 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-width: @wx-width - @root_padding-horizontal*2; @common_border-width: @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-width: @wx-width_subtract-padding-width*0.02; // 并排的2个选项区域的外围margin; @item-separation-margin-width: @wx-width_subtract-padding-width*0.05; // 2个选项横排;选项margin水平间距; @item-border-width: @common_border-width; // 2个选项的border宽度; @item-available-width: @wx-width_subtract-padding-width - @2items_margin-width*2 - @item-border-width*4 - @item-separation-margin-width*4; // 待布局选项区域; @item-render-width: @item-available-width/2; // 选项最终被渲染的宽度; @item_select-after-font-size: @common_select-after-font-size; margin: 0 @2items_margin-width; // width: @wx-width_one-unit; background-color: green; .amountType-item { width: @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-width: @wx-width_subtract-padding-width - @pay-type_2imgs_padding-width*2 - @pay-type_border-width*4; // 待布局图片的区域 @pay-type_border-width: @common_border-width; // 无论是否被选中,项之间、选中前后都有相同的边框宽度;选中对边框的影响是改变边框颜色; @pay-type_imgs_width-share: 0.8; // 图片宽度份额,其他留作2张图片间的水平margin; @pay-type_img-margin-width: @pay-type_img-available-width*(1- @pay-type_imgs_width-share)/4; // 2张图之间的margin宽度 @pay-type_img-render-width: @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 { width: @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 { width: 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 = "\r\n亲支付链接已经复制\r\n粘贴到浏览器支付吧\r\n" 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-width: 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-width: @wx-width - @root_padding-horizontal*2; @common_border-width: @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-width: @wx-width_subtract-padding-width*0.02; // 并排的2个选项区域的外围margin; @item-separation-margin-width: @wx-width_subtract-padding-width*0.05; // 2个选项横排;选项margin水平间距; @item-border-width: @common_border-width; // 2个选项的border宽度; @item-available-width: @wx-width_subtract-padding-width - @2items_margin-width*2 - @item-border-width*4 - @item-separation-margin-width*4; // 待布局选项区域; @item-render-width: @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; // width: @wx-width_one-unit; background-color: green; .amountType-item { width: @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-width: @wx-width_subtract-padding-width - @pay-type_2imgs_padding-width*2 - @pay-type_border-width*4; // 待布局图片的区域 @pay-type_border-width: @common_border-width; // 无论是否被选中,项之间、选中前后都有相同的边框宽度;选中对边框的影响是改变边框颜色; @pay-type_imgs_width-share: 0.8; // 图片宽度份额,其他留作2张图片间的水平margin; @pay-type_img-margin-width: @pay-type_img-available-width*(1- @pay-type_imgs_width-share)/4; // 2张图之间的margin宽度 @pay-type_img-render-width: @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 { width: @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 { width: 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 = "亲,支付链接已经复制,粘贴到浏览器支付吧\r\n" 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-width: 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-width: @wx-width - @root_padding-horizontal*2; @common_border-width: @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-width: @wx-width_subtract-padding-width*0.02; // 并排的2个选项区域的外围margin; @item-separation-margin-width: @wx-width_subtract-padding-width*0.05; // 2个选项横排;选项margin水平间距; @item-border-width: @common_border-width; // 2个选项的border宽度; @item-available-width: @wx-width_subtract-padding-width - @2items_margin-width*2 - @item-border-width*4 - @item-separation-margin-width*4; // 待布局选项区域; @item-render-width: @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; // width: @wx-width_one-unit; background-color: green; .amountType-item { width: @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-width: @wx-width_subtract-padding-width - @pay-type_2imgs_padding-width*2 - @pay-type_border-width*4; // 待布局图片的区域 @pay-type_border-width: @common_border-width; // 无论是否被选中,项之间、选中前后都有相同的边框宽度;选中对边框的影响是改变边框颜色; @pay-type_imgs_width-share: 0.8; // 图片宽度份额,其他留作2张图片间的水平margin; @pay-type_img-margin-width: @pay-type_img-available-width*(1- @pay-type_imgs_width-share)/4; // 2张图之间的margin宽度 @pay-type_img-render-width: @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 { width: @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 { width: 90%; border-radius: @wx-width_one-unit*8; background-color: @color-main_blue; color: #fff; } </style>
间距调整