zoukankan      html  css  js  c++  java
  • .net Core 调用微信Jsapi接口,H5解析二维码

    项目里需要用到扫描二维码,自己实现,不会。

    找到了两种解决方案:

    1. 通过reqrcode.js,这是一个前端解析二维码内容的js库。如果二维码比较清晰,用这种效果也不错
    2. 调用微信扫一扫功能,这种效果很好。但是调试接口超级麻烦。

    具体实现:前端代码(vue)(前端用到 vux

    <template>
    <div class="main">
      <group title="打印机参数" label-width="5.5em">
          <x-input title="名称" placeholder="输入打印机名称" v-model="model.name" :required="true" @on-change="check" ref="name"></x-input>
          <x-input title="MAC地址" placeholder="输入MAC地址" v-model="model.mac"  @on-change="check" ref="mac">
            <a slot="right-full-height" class="scan" @click="scan()" title="扫码"><x-icon type="android-expand" size="32"></x-icon></a>
          </x-input>
          <cell title="城市" :value="city"></cell>
          <cell title="经纬度" :value="location"></cell>
      </group>
      <iframe id="geoPage" width=0 height=0 frameborder=0  style="display:none;" scrolling="no"  src="https://apis.map.qq.com/tools/geolocation?key=212121U3F2Q&referer=3Dprint"></iframe>
      <x-button type="primary" @click.native="add()" :disabled.sync="disabled"> 添加打印机</x-button>
      <input type="file" accept="image/*" capture="camera" @change="show($event)" v-show="false" ref="file">
    </div>
    </template>
    <script>
    import {Group, XInput, XButton, Alert, Range, XSwitch, Cell, InlineXSwitch, ChinaAddressV4Data} from 'vux'
    export default {
      components: {Group, XInput, XButton, Alert, Range, XSwitch, Cell, InlineXSwitch, ChinaAddressV4Data},
      data () {
        return {
          addressData: ChinaAddressV4Data,
          disabled: true,
          city: '',
          location: '',
          sys: false, // 扫一扫调用
          model: {
            name: '',
            mac: '',
            status: false,
            citys: [],
            city: '',
            address: '',
            memory: '',
            temperature: 0,
            modelName: '',
            location: '',
            ver: '',
            step: 0,
            plantTemperature: '',
            userId: 0
          }
        }
      },
      mounted () {
        // this.getLocation()
        let that = this
        window.addEventListener('message', function (event) {  
          var loc = event.data
          if (loc) {
            that.city = loc.nation + ' ' + loc.province + ' ' + loc.city
            that.location = loc.lat + ' , ' + loc.lng
            that.model.address = that.city
            that.model.location = that.location
          }
          console.log('location', loc)
        }, false)
        this.initConifig()
      },
      methods: {
        add () {
          let that = this
          this.model.userId = sessionStorage["userId"]
          this.model.status = this.model.status ? 1 : 0
          this.model.city = this.model.citys.join()
         // console.log(this.model.city)
          console.log(this.$store.state.user)
          this.Ajax.post('/api/services/app/Print/Create', this.model).then(function (result) {
            // console.log(that.model)
            if (result.success) {
              that.go('/user/prints')
            } else {
              that.$vux.toast.show({text: result.error.message, type: 'cancel'})
            }
          })
        },
        check () {
          this.disabled = !(this.model.name !== '' && this.model.mac !== '')
        },
        initConifig () {
          let that = this
          /* global wx */
          this.Ajax.get('/WX/GetConfig?url=' + location.href).then((r) => {
            let data = r.result
            console.log(data)
            wx.config({
              debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
              appId: data.appId, // 必填,公众号的唯一标识
              timestamp: data.timestamp, // 必填,生成签名的时间戳
              nonceStr: data.noncestr, // 必填,生成签名的随机串
              signature: data.signature, // 必填,签名,见附录1
              jsApiList: ['scanQRCode'] // 必填,需要使用的JS接口列表,所有JS接口2
            })
            that.sys = true
            wx.error((r) => {
              console.log(r)
              that.sys = false
              alert('微信调用异常:' + r.errMsg)
            })
          })
        },
        wxScan () {
          let that = this
           /* global wx */
          wx.scanQRCode({
            needResult: 1,
            desc: 'scanQRCode desc',
            success: (r) => {
              console.log(r)
              let msg = r.resultStr
              if (msg.length === 29) {
                let mac = msg.substring(17, 29)
                let arrs = []
                console.log(mac)
                for (let i = 0; i < 6; i++) {
                  arrs.push(mac.substring(i * 2, i * 2 + 2))
                }
                that.model.mac = arrs.join(':')
                console.log(msg, that.model.mac)
              } else {
                that.$vux.toast.show({text: 'mac解析失败:' + msg, type: 'cancel'})
              }
            }
          })
        },
        scan () {
          if (this.sys) {
            this.wxScan()
          } else {
            this.$refs.file.click()
          }
        },
        go (link) {
          this.$router.push({path: link})
        },
        show (send) {
          // var file = console.log(send)
          /* global qrcode */
          let file = send.target.files[0]
          qrcode.decode(this.getUrl(file))
          var that = this
          qrcode.callback = function (msg) {
            if (msg.length === 29) {
              let mac = msg.substring(17, 29)
              let arrs = []
              console.log(mac)
              for (let i = 0; i < 6; i++) {
                arrs.push(mac.substring(i * 2, i * 2 + 2))
              }
              that.model.mac = arrs.join(':')
              console.log(msg, that.model.mac)
            } else {
              that.$vux.toast.show({text: 'mac解析失败:' + msg, type: 'cancel'})
            }
          }
        },
        getUrl (file) {
          let url = null
          if (window.createObjectURL !== undefined) {
            url = window.createObjectURL(file)
          } else if (window.URL !== undefined) {
            url = window.URL.createObjectURL(file)
          } else if (window.webkitURL !== undefined) {
            url = window.webkitURL.createObjectURL(file)
          }
          return url
        },
        getLocation () {
          if (navigator.geolocation) {
            navigator.geolocation.getCurrentPosition(function (p) {
              console.log(p)
            })
          } else {
            alert('不支持定位')
          }
        }
      }
    }
    </script>
    <style  scoped>
    .ptitle{ background: #efeff4;padding: 10px 20px; font-size: 16px; font-weight: bold; border-bottom: #d8d8dd;}
    a.add:hover{ color: #4086ff;fill: #4086ff;cursor: pointer;}
    .main{padding: 0 10px;}
    a.scan{ fill: #4086ff; cursor: pointer;}
    </style>

    通用.net core 微信授权获取方法。

    using System;
    using System.Net.Http;
    using System.Security.Cryptography;
    using System.Text;
    using Newtonsoft.Json;
    
    namespace PrintServe.Web.Host.Core
    {
        public static class WXApi
        {
            /// <summary>
            /// 过期时间
            /// </summary>
            public static DateTime OutDateTime { get; set; }
            /// <summary>
            /// 凭据
            /// </summary>
            public static string Token { get; set; }
            /// <summary>
            /// 船票
            /// </summary>
            public static string Ticket { get; set; }
            /// <summary>
            /// 获取微信api接口船票
            /// </summary>
            /// <param name="url">请求页面地址</param>
            /// <param name="appId">开发者Id</param>
            /// <param name="secret">开发者密码</param>
            /// <returns></returns>
            public static dynamic  GetConfig(string url,string appId,string secret)
            {
                var timestamp = CreatenTimestamp();
                var noncestr = CreatenNonce_str();
                var ticket = Ticket;
                if (DateTime.Now > OutDateTime)
                {
                    var token = GetToken(appId, secret);
                    if (!string.IsNullOrEmpty(token))
                    {
                        OutDateTime = DateTime.Now.AddMinutes(90);
                        Token = token;
                        Ticket = GetTickect(Token);
                        ticket = Ticket;
                    }
                }
                var signature = GetSignature(ticket, noncestr, timestamp, url, out var str);
                return new
                {
                    ticket,
                    appId,
                    url,
                    timestamp,
                    noncestr,
                    signature,
                    str
                };
            }
            /// <summary>
            /// 获取凭据
            /// </summary>
            /// <param name="appid"></param>
            /// <param name="secret"></param>
            /// <returns></returns>
            public static string GetToken(string appid,string secret)
            {
                var url = string.Format("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={0}&secret={1}",appid,secret);
                var client = new HttpClient();
                var result = client.GetAsync(url).Result;
                if (!result.IsSuccessStatusCode) return string.Empty;
                var jsTicket = result.Content.ReadAsStringAsync().Result;
                var v = JsonConvert.DeserializeObject<dynamic>(jsTicket);
                return v.access_token.ToString();
            }
            /// <summary>
            /// 获取船票
            /// </summary>
            /// <param name="token"></param>
            /// <returns></returns>
            public static string GetTickect(string token)
            {
                var url = string.Format("https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token={0}&type=jsapi", token);
                var client = new HttpClient();
                var result = client.GetAsync(url).Result;
                if (!result.IsSuccessStatusCode) return string.Empty;
                var jsTicket = result.Content.ReadAsStringAsync().Result;
                var v = JsonConvert.DeserializeObject<dynamic>(jsTicket);
                return v.ticket.ToString();
            }
            /// <summary>
            /// 获取时间戳
            /// </summary>
            /// <returns></returns>
            public static long CreatenTimestamp()
            {
                return (DateTime.Now.ToUniversalTime().Ticks - 621355968000000000) / 10000000;
            }
    
            ///  <summary>
            ///  签名算法
            /// 本代码来自开源微信SDK项目:https://github.com/night-king/weixinSDK
            ///  </summary>
            ///  <param name="jsapi_ticket">jsapi_ticket</param>
            ///  <param name="noncestr">随机字符串(必须与wx.config中的nonceStr相同)</param>
            ///  <param name="timestamp">时间戳(必须与wx.config中的timestamp相同)</param>
            ///  <param name="url">当前网页的URL,不包含#及其后面部分(必须是调用JS接口页面的完整URL)</param>
            /// <param name="string1"></param>
            /// <returns></returns>
            public static string GetSignature(string jsapi_ticket, string noncestr, long timestamp, string url, out string string1)
            {
                url = url.Split('#')[0];
                var string1Builder = new StringBuilder();
                string1Builder.Append("jsapi_ticket=").Append(jsapi_ticket).Append("&")
                    .Append("noncestr=").Append(noncestr).Append("&")
                    .Append("timestamp=").Append(timestamp).Append("&")
                    .Append("url=").Append(url);
                string1 = string1Builder.ToString();
                return Sha1(string1);
            }
            /// <summary>
            /// 创建随机字符串
            ///本代码来自开源微信SDK项目:https://github.com/night-king/weixinSDK
            /// </summary>
            /// <returns></returns>
            public static string CreatenNonce_str()
            {
                var strs = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".ToCharArray();
                Random r = new Random();
                var sb = new StringBuilder();
                var length = strs.Length;
                for (int i = 0; i < 15; i++)
                {
                    sb.Append(strs[r.Next(length - 1)]);
                }
                return sb.ToString();
            }
            /// <summary>
            /// HMAC-SHA1加密算法
            /// </summary>
            /// <param name="str">加密字符串</param>
            /// <returns></returns>
            public static string Sha1(string str)
            {
                var sha1 = SHA1.Create();
                var hash = sha1.ComputeHash(Encoding.UTF8.GetBytes(str));
                string byte2String = string.Empty;
                foreach (var t in hash)
                {
                    byte2String += t.ToString("x2");
                }
                return byte2String;
            }
        }
    }

    controller调用

    using System;
    using Abp.AspNetCore.Mvc.Controllers;
    using Microsoft.AspNetCore.Hosting;
    using Microsoft.AspNetCore.Mvc;
    using Microsoft.Extensions.Configuration;
    using PrintServe.Configuration;
    using PrintServe.Web.Host.Core;
    
    namespace PrintServe.Web.Host.Controllers
    {
        public class WXController : AbpController
        {
            private readonly IConfigurationRoot _configuration;
            public WXController(IHostingEnvironment env)
            {
                _configuration = env.GetAppConfiguration();
            }
            public dynamic GetConfig(string url)
            {
                var appId = _configuration["wx:appid"];
                var secret = _configuration["wx:secret"];
    //            Logger.Error("出现异常");
                return WXApi.GetConfig(url,appId,secret);
            }
            [HttpGet]
            public string Test(string input)
            {
                return WXApi.Sha1(input);
            }
           
        }
    }

    在主页面要添加微信接口js调用

    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=0">
        <title>3D打印</title>
        <script src="./static/js/reqrcode.js"></script>
        <!-- <script src="./static/js/vconsole.min.js"></script> -->
        <!-- <script src="http://res.wx.qq.com/open/js/jweixin-1.4.0.js"></script> -->
        <script src="http://res.wx.qq.com/open/js/jweixin-1.1.0.js"></script>
      </head>
      <body>
        <div id="app-box"></div>
        <!-- built files will be auto injected -->
      </body>
    </html>

    调用微信api接口:

    1:Ip,和域名都要加到微信公众平台里,缺一不可,在这里被坑了很久。

    设置域名,一个月只能设置3次,要慎重。

    2:调试时候,最好在开发机器上用花生壳绑定个域名,以便开发。本地没有域名,不能调试。可以下载微信开发者工具,进行调试,错误提示比较清晰。

    微信开发者工具地址:地址

    参考文章:

    微信公众号开发之调起微信扫一扫接口

    微信公众号开发:调用微信扫一扫功能

    qrcode.js的识别解析二维码图片和生成二维码图片

  • 相关阅读:
    Android Overlay学习
    为WinForm combox控件增加自动完成功能
    职业理想
    How to become a hacerk.黑客
    .net程序员常用网站
    面向对象设计原则
    net开源cms系统
    如何:禁用 Windows 窗体 DataGridView 控件的按钮列中的按钮(摘录)
    计算机编码(百度百科)
    .net winform 从资源文件中引用图片资源
  • 原文地址:https://www.cnblogs.com/henq/p/9916935.html
Copyright © 2011-2022 走看看