Forráskód Böngészése

已集成微信支付

zhengqiang 5 éve
szülő
commit
6bded3b3d3

+ 1 - 1
config/index.js

@@ -54,7 +54,7 @@ module.exports = {
     // Paths
     assetsRoot: path.resolve(__dirname, '../dist'),
     assetsSubDirectory: 'static',
-    assetsPublicPath: '/',
+    assetsPublicPath: './', //改为相对路径
 
     /**
      * Source Maps

+ 2 - 1
config/prod.env.js

@@ -1,4 +1,5 @@
 'use strict'
 module.exports = {
-  NODE_ENV: '"production"'
+  NODE_ENV: '"production"',
+  BACKEND_URL:'"http://www.wzgh.org/epay-server"'
 }

+ 1 - 1
index.html

@@ -3,7 +3,7 @@
   <head>
     <meta charset="utf-8">
     <meta name="viewport" content="width=device-width,initial-scale=1.0">
-    <title>ammeter</title>
+    <title>智能电表缴费</title>
   </head>
   <body>
     <div id="app"></div>

+ 1 - 1
package.json

@@ -5,7 +5,7 @@
   "author": "vonin <vonmrs@163.com>",
   "private": true,
   "scripts": {
-    "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
+    "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js --host 0.0.0.0",
     "start": "npm run dev",
     "unit": "jest --config test/unit/jest.conf.js --coverage",
     "e2e": "node test/e2e/runner.js",

+ 20 - 0
src/api/remoteApi.js

@@ -15,6 +15,26 @@ var remoteApi = {
     },
     queryRoomDetail : function(roomId){
         return request.get(basePath + `/mobileApi/queryRoomDetail?roomId=${roomId}`);
+    },
+    prepareWXPay: function(roomId,buyType,num,amount){
+        var formData = new FormData()
+
+        formData.append("roomId",roomId);
+        formData.append("buyType",buyType);
+        formData.append("num",num);
+        formData.append("amount",amount);
+
+        return request.post(basePath + `/mobileApi/prepareWXPay`,formData);
+    },
+    getWXConfigParam : function(code){
+        return request.get(basePath + `/mobileApi/getWXConfigParam?code=${code}`);
+    },
+    wxPay : function(recordId,openId){
+        return request.get(basePath + "/wxPay/webPay",{
+            params:{
+                recordId,openId
+            }
+        });
     }
 }
 

+ 42 - 58
src/components/Pay.vue

@@ -12,7 +12,7 @@
           <span class="m-left10" v-html="room.name">601</span>
         </van-cell>
         <div class="fyyinput">
-          <input type="text" placeholder="请输入要充值的电量度数" v-model="kwh"/>
+          <input type="number" placeholder="请输入要充值的电量度数" v-model="kwh"/>
           <span class="input-right">度</span>
         </div>
         <p class="fyy-h6">价格标准:<span v-html="price"></span>元/度</p>
@@ -22,16 +22,15 @@
           <span class="iconfont color-red fyy-icon">&#xe648;</span>
           选择支付方式
         </van-cell>
-        
         <van-radio-group v-model="payType" class="fyyradio-pay">
           <van-cell-group>
-            <van-cell clickable @click="payType = '1'">
-              <img src="@/assets/img/zhifubao.png" />
-              <van-radio slot="right-icon" name="1" />
-            </van-cell>
-            <van-cell clickable @click="payType = '2'">
+            <van-cell clickable @click="payType = 'weipay'">
               <img src="@/assets/img/weixin.png" />
-              <van-radio slot="right-icon" name="2" />
+              <van-radio slot="right-icon" name='weipay'/>
+            </van-cell>
+            <van-cell clickable @click="payType = 'alipay'">
+              <img src="@/assets/img/zhifubao.png" />
+              <van-radio slot="right-icon" name='alipay'/>
             </van-cell>
           </van-cell-group>
         </van-radio-group>
@@ -51,8 +50,6 @@
 
 <script>
 import remoteApi from '@/api/remoteApi'
-import wx from 'weixin-js-sdk'
-import hex_sha1 from 'hex-sha1'
 
 export default {
   data() {
@@ -63,7 +60,7 @@ export default {
       price:0,
       roomId : null,
       kwh : 0,
-      payType: '1'
+      payType: 'weipay'
     }
   },
   methods: {
@@ -74,58 +71,45 @@ export default {
       this.$router.push("/")
     },
     pay() {
-      
+      var self = this
+
+      if(self.payType=='weipay'){
+        //首先要获取openid
+        self.$toast.loading({
+          message: '处理中...',
+          forbidClick: true,
+          loadingType: 'spinner',
+          duration: 10000
+        });
+
+        remoteApi.prepareWXPay(self.roomId,self.payType,self.kwh,self.total).then(resp=>{
+          self.$toast.clear()
+
+          if(resp.result) {
+            var appId = resp.data.appId
+            var redirectUri = encodeURIComponent(window.location.href.split('#')[0] + '#WXPay')
+            var state = resp.data.recordId
+
+            var url = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appId}&redirect_uri=${redirectUri}&response_type=code&scope=snsapi_userinfo&state=${state}#wechat_redirect`
+            
+            alert(url)
+            window.location.href = url
+          }
+          else{
+            self.$toast.fail(resp.message)
+          }
+        });
+      }
     }
   },
   computed: {
     total (){
-      return (this.kwh* this.price).toFixed(2);
+      return (this.kwh * this.price).toFixed(2);
     }
   },
-  created () {
-    var appId = 'wxe598c699aa68cffe'
-    var timestamp = (new Date()).getTime()
-
-    var fullStr = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678'
-    var nonceStr = ''
-
-    for(var i=0;i<10;i++){
-      nonceStr += fullStr.charAt(Math.floor(Math.random()*fullStr.length))
-    }
-
-    var url = window.location.href.split('#')[0]
-
-    //服务器端通过access_token获取 https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi
-    var ticket = 'sM4AOVdWfPE4DxkXGEs8VAMadDORtDxQLtMKXqk9xSQE7OmFwIWBf7X3rxflmFXgENu66LRawd1bYAjz89QM2w'
-
-    //注意这里noncestr中的s是小写
-    var plainText = `noncestr=${nonceStr}&jsapi_ticket=${ticket}&timestamp=${timestamp}&url=${url}`
-    
-    console.log(`plainText="${plainText}"`)
-  
-    var signature = hex_sha1(plainText)
-
-    console.log(`signature=${signature}`)
-
-    wx.config({
-      debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印
-      appId: appId, // 必填,公众号的唯一标识
-      timestamp: timestamp, // 必填,生成签名的时间戳
-      nonceStr: nonceStr, // 必填,生成签名的随机串
-      signature: signature,// 必填,签名
-      jsApiList: ['checkJsApi','chooseWXPay'] // 必填,需要使用的JS接口列表
-    });
-
-    wx.ready(function(){
-
-    });
-
-    wx.error((error)=>{
-      console.log(error)
-    });
-  },
   mounted () {
-    var roomId = this.$route.query.roomId;
+    // 当前页面是否获取到了openid?
+    this.roomId = this.$route.query.roomId;
 
     this.$toast.loading({
       message: '加载中...',
@@ -136,13 +120,13 @@ export default {
 
     var self = this;
 
-    remoteApi.queryRoomDetail(roomId).then((resp)=>{
+    remoteApi.queryRoomDetail(this.roomId).then((resp)=>{
       console.log(resp);
 
       this.$toast.clear();
 
       if(resp.result){
-        self.$toast.success('查询成功!')
+        //self.$toast.success('查询成功!')
 
         var jsonData = resp.data
         self.area = jsonData.area

+ 116 - 0
src/components/WXPay.vue

@@ -0,0 +1,116 @@
+<template>
+  <div :html="retMsg"></div>
+</template>
+<script>
+import remoteApi from '@/api/remoteApi'
+import wx from 'weixin-js-sdk'
+import hex_sha1 from 'hex-sha1'
+import getQueryString from '@/utils/querystring'
+
+export default {
+    data () {
+        return {
+            retMsg : "",
+            code : getQueryString("code"),
+            openId : '',
+            recordId: getQueryString("state")
+        }
+    },
+    mounted (){
+        var self = this
+        
+        self.$toast.loading({
+            message: '初始化...',
+            forbidClick: true,
+            loadingType: 'spinner',
+            duration: 10000
+        });
+
+        remoteApi.getWXConfigParam(self.code).then(resp=>{
+            if(resp.result){
+                var appId = resp.data.appId
+                var timestamp = (new Date()).getTime()
+                
+                self.openId = resp.data.openId
+
+                var fullStr = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678'
+                var nonceStr = ''
+
+                for(var i=0;i<10;i++){
+                nonceStr += fullStr.charAt(Math.floor(Math.random()*fullStr.length))
+                }
+
+                var url = window.location.href.split('#')[0]
+
+                //服务器端通过access_token获取 https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi
+                var ticket = resp.data.ticket
+
+                //注意这里noncestr中的s是小写
+                var plainText = `jsapi_ticket=${ticket}&noncestr=${nonceStr}&timestamp=${timestamp}&url=${url}`
+                
+                console.log(`plainText="${plainText}"`)
+            
+                var signature = hex_sha1(plainText)
+
+                console.log(`signature=${signature}`)
+
+                wx.config({
+                    debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印
+                    appId: appId, // 必填,公众号的唯一标识
+                    timestamp: timestamp, // 必填,生成签名的时间戳
+                    nonceStr: nonceStr, // 必填,生成签名的随机串
+                    signature: signature,// 必填,签名
+                    jsApiList: ['checkJsApi','chooseWXPay'] // 必填,需要使用的JS接口列表
+                });
+            }
+            else{
+                self.$toast.clear();
+                self.$toast.fail("获取参数失败!" + resp.message)
+            }
+        });
+
+        wx.ready(function(){
+            self.$toast.clear();
+
+            self.$toast.loading({
+                message: '支付准备中...',
+                forbidClick: true,
+                loadingType: 'spinner',
+                duration: 10000
+            });
+
+            remoteApi.wxPay(self.recordId,self.openId).then(resp=>{
+                console.log(resp);
+                self.retMsg = JSON.stringify(resp)
+                
+                if(resp.result){
+                    var data = resp.data;
+                   
+                    wx.chooseWXPay({
+                        //注意这里的返回参数是timeStamp,不是timestamp
+                        "timestamp": data.timeStamp, // 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符
+                        "nonceStr": data.nonceStr,  // 支付签名随机串,不长于 32 位
+                        "package": data.package,   // 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=\*\*\*)
+                        "signType": data.signType, // 签名方式,默认为'SHA1',使用新版支付需传入'MD5'
+                        "paySign": data.paySign,    // 支付签名
+                        success: function (res) {
+                            // 支付成功后的回调函数,跳转到订单列表
+
+                        }
+                    });
+                }
+                else{
+                    self.$toast.fail("生成预支付订单失败!");
+                }
+            },"json");
+        });
+
+        wx.error((error)=>{
+            console.log(error)
+        });
+    }
+}
+</script>
+<style>
+
+</style>

+ 4 - 0
src/router/index.js

@@ -20,6 +20,10 @@ export default new Router({
       name: 'Pay',
       component: Pay
     },
+    {
+      path: '/WXPay',
+      component: (resolve) => require(['@/components/WXPay.vue'], resolve)
+    },
     {
       path: '/Paylist',
       name: 'Paylist',

+ 9 - 0
src/utils/querystring.js

@@ -0,0 +1,9 @@
+
+function getQueryString(name) {
+    var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
+    var r = window.location.search.substr(1).match(reg);
+    if (r != null) return unescape(r[2]);
+    return null;
+}
+
+export default getQueryString