[关闭]
@Aiti 2020-03-12T02:28:38.000000Z 字数 9311 阅读 190

微信开发

微信开发


需求:通过关注微信号获取第三方平台的任务

1、服务号或者公众号
2、自己的服务器
3、第三方平台

1.服务号配置

  1. 接口配置信息
    请填写接口配置信息,此信息需要你有自己的服务器资源,填写的URL需要正确响应微信发送的Token验证
    URL:http://js.wx.bim999.cn/WeiXin/Message
    Token:bim999

  2. JS接口安全域名
    设置JS接口安全域后,通过关注该测试号,开发者即可在该域名下调用微信开放的JS接口
    域名:js.wx.bim999.cn


2.服务器配置(基于MVC开发)

  1. 基本信息配置.Json
  1. {
  2. "AppSettings": {
  3. "DbConnectionString": "Data Source=192.168.1.240;Initial Catalog=BimWeixin;User Id=sa;Password=cx1234;",
  4. "AppId": "wxfb1254572c7bac44",
  5. "AppSecret": "2632267b19bd3373f87ad15c84f6cf68",
  6. "RedirectUri": "http://js.wx.bim999.cn/weixin/oauth"
  7. },
  8. "ApplicationInsights": {
  9. "InstrumentationKey": ""
  10. },
  11. "Logging": {
  12. "IncludeScopes": false,
  13. "LogLevel": {
  14. "Default": "Debug",
  15. "System": "Information",
  16. "Microsoft": "Information"
  17. }
  18. }
  19. }

2.验证接口配置并验证(浏览器直接打开http://js.wx.bim999.cn/WeiXin/Message

  1. //控制器WeiXin.CS
  2. MVC是先调用控制器,再根据控制器调用页面(不是根据页面调用控制器)。控制器默认进入先Index
  3. public IActionResult Index()
  4. {
  5. return View();
  6. }
  7. private const string VerifyToken = "bim999";
  8. public IActionResult Message(string signature, string timestamp, string nonce, string echostr)
  9. {
  10. //返回随机字符串则表示验证通过
  11. //using Senparc.Weixin.MP.CheckSignature.Check(检查签名是否正确);
  12. if (CheckSignature.Check(signature, timestamp, nonce, VerifyToken))
  13. return Content(echostr);
  14. return View();
  15. }
  1. //页面Message.cxhtml
  2. @{
  3. ViewBag.Title = "微信回调地址";
  4. }
  5. <h4>如果您在浏览器中看到这条信息,表明此Url可以填入微信后台</h4>

3.第三方平台配置

  1. 关注服务号,并扫码绑定系统(即把系统的账号和微信号进行关联绑定)
  1. protected void Page_Load(object sender, EventArgs e)
  2. {
  3. var url = $"https://js.wx.bim999.cn/weixin/getoauthurl?pid={ pid }&uid={ uid }";
  4. var request = (HttpWebRequest)WebRequest.Create(url);
  5. //获取接受到网址的内容
  6. using (var response = (HttpWebResponse)request.GetResponse())
  7. {
  8. using (var sr = new System.IO.StreamReader(response.GetResponseStream(), Encoding.UTF8))
  9. {
  10. //获取二维码地址
  11. // QRImg.ImageUrl = sr.ReadToEnd();
  12. //获取值生成二维码
  13. CreateQR(HttpUtility.UrlDecode(sr.ReadToEnd()));
  14. }
  15. }
  16. }
  17. private void CreateQR(string nr)
  18. {
  19. Bitmap bt;
  20. if (!string.IsNullOrEmpty(nr))
  21. {
  22. string filename = Guid.NewGuid().ToString().ToUpper();
  23. QRCodeEncoder qrCodeEncoder = new QRCodeEncoder();
  24. qrCodeEncoder.QRCodeVersion = 0;
  25. bt = qrCodeEncoder.Encode(nr, Encoding.UTF8);
  26. string imgPath = Server.MapPath("~/ImageQR/") + filename + ".jpg";
  27. try
  28. {
  29. bt.Save(imgPath);
  30. QRImg.ImageUrl = "~/ImageQR/" + filename + ".jpg";
  31. }
  32. catch (Exception)
  33. {
  34. }
  35. }
  36. }

4.服务器逻辑处理

  1. //扫码绑定调用的是
  2. public string GetOAuthUrl(int pid, string uid)
  3. {
  4. if (pid <= 0) return "非法参数";
  5. uid = (uid + "").Trim();
  6. if (uid.Length <= 0) return "非法参数";
  7. var requestId = Guid.NewGuid().ToString("N");
  8. //写入绑定请求
  9. using (var conn = SqlHelper.GetConn())
  10. {
  11. conn.Execute("INSERT INTO BindRequest(RequestId,Pid,Uid,DoTime) VALUES(@requestId,@pid,@uid,GETDATE());", new { requestId, pid, uid });
  12. }
  13. //此处验证是否关注服务号,关注了就跳转到配置信息中RedirectUri="http://js.wx.bim999.cn/weixin/OAuth"
  14. var url = OAuthApi.GetAuthorizeUrl(BimWxConfig.AppId, BimWxConfig.RedirectUri, requestId,
  15. OAuthScope.snsapi_userinfo);
  16. //返回值 去本地生成二维码
  17. return Uri.EscapeDataString(url);
  18. }
  19. public IActionResult OAuth(string code, string state, string returnUrl)
  20. {
  21. if ((code = code + "").Length > 3) //获取 AccessToken
  22. {
  23. var token = OAuthApi.GetAccessToken(BimWxConfig.AppId, BimWxConfig.AppSecret, code);
  24. if (token.errcode != ReturnCode.请求成功)
  25. {
  26. ViewBag.Message = token.errcode.ToString();
  27. }
  28. else //处理授权结果
  29. {
  30. string wxOpenId = token.openid;
  31. if ((state = state + "").Length == 32)
  32. {
  33. #region 绑定用户
  34. using (var conn = SqlHelper.GetConn())
  35. {
  36. conn.Open();
  37. var request = conn.Query("SELECT Pid,Uid,RequestId FROM BindRequest WHERE RequestId=@state", new { state }).FirstOrDefault();
  38. if (request == null)
  39. {
  40. ViewBag.Message = "绑定用户失败,请重新登录PC平台扫描二维码!";
  41. }
  42. else
  43. {
  44. var trans = conn.BeginTransaction();
  45. var bindUser = new
  46. {
  47. request.RequestId,
  48. request.Pid,
  49. request.Uid,
  50. WxOpenId = token.openid
  51. };
  52. conn.Execute("UPDATE BindRequest SET SuccessTime=GETDATE() WHERE RequestId=@RequestId", bindUser, trans);
  53. conn.Execute("DELETE FROM PlatformUser WHERE Pid=@Pid AND Uid=@Uid", bindUser, trans);
  54. conn.Execute("INSERT INTO PlatformUser(WxOpenId,Pid,Uid) VALUES(@WxOpenId,@Pid,@Uid)", bindUser, trans);
  55. trans.Commit();
  56. }
  57. }
  58. wxOpenId = token.openid;
  59. #endregion
  60. }
  61. #region [异步] 更新微信用户信息
  62. Task.Factory.StartNew(() =>
  63. {
  64. var user = OAuthApi.GetUserInfo(token.access_token, token.openid);
  65. if (user.openid != token.openid) return;
  66. //将获取到的用户信息更新到数据库中
  67. using (var conn = SqlHelper.GetConn())
  68. {
  69. conn.Open();
  70. var trans = conn.BeginTransaction();
  71. conn.Execute("DELETE FROM WxUser WHERE WxOpenId=@openid", user, trans);
  72. conn.Execute(
  73. "INSERT INTO WxUser(WxOpenId,Nick,Sex,Province,City,Country,HeadImgUrl) VALUES(@openid,@nickname,@sex,@province,@city,@country,@headimgurl)",
  74. user, trans);
  75. trans.Commit();
  76. }
  77. });
  78. #endregion
  79. //有效的 WxOpenid,设置 Session 并跳转到 MyJob 页面
  80. if (wxOpenId != null)
  81. {
  82. HttpContext.Session.SetString("WxOpenId", token.openid);
  83. if (!string.IsNullOrEmpty(returnUrl))
  84. {
  85. return Redirect(returnUrl);
  86. }else
  87. return RedirectToAction("myjob");
  88. }
  89. }
  90. }
  91. return View();
  92. }
  93. public IActionResult MyJob()
  94. {
  95. var wxOpenId = HttpContext.Session.GetString("WxOpenId");
  96. if (string.IsNullOrWhiteSpace(wxOpenId)) //没有 OpenId 跳转到微信授权重新获取
  97. return Redirect(OAuthApi.GetAuthorizeUrl(BimWxConfig.AppId, BimWxConfig.RedirectUri, nameof(MyJob), OAuthScope.snsapi_userinfo));
  98. List<dynamic> jobs;
  99. //获取平台信息
  100. using (var conn = SqlHelper.GetConn())
  101. {
  102. jobs = conn.Query(@"SELECT a.Uid,b.ShortName 'JobName',b.ServerUrl 'Content'
  103. FROM PlatformUser a JOIN Platform b ON a.Pid=b.Id
  104. WHERE a.WxOpenId=@wxOpenId", new { wxOpenId }).ToList();
  105. }
  106. //请求平台API,获取具体的内容
  107. foreach (var job in jobs)
  108. {
  109. job.Content = HttpHelper.HttpGet(job.Content, "uid=" + job.Uid);
  110. }
  111. return View(jobs);
  112. }
  1. //获取任务页面MyJob.cshtml
  2. @model List<dynamic>
  3. @{
  4. ViewBag.Title = "我的任务";
  5. }
  6. @if (Model.Count > 0)
  7. {
  8. <ul class="collapsible popout" data-collapsible="accordion">
  9. @foreach (var job in Model)
  10. {
  11. <li>
  12. <div class="collapsible-header">@job.JobName</div>
  13. <div class="collapsible-body">@Html.Raw(job.Content)</div>
  14. </li>
  15. }
  16. <li>
  17. <div class="collapsible-header">建党平台</div>
  18. <div class="collapsible-body">这里是建党平台放回的数据内容</div>
  19. </li>
  20. </ul>
  21. }
  22. else
  23. {
  24. <h4>当前微信号无法查看任务!</h4>
  25. }
  26. @section script{
  27. <script>
  28. $(function () {
  29. $(".collapsible-header").first().addClass("active");
  30. $(".collapsible").collapsible();
  31. })
  32. </script>
  33. }



需求:获取微信定位用于签到

1、服务号

  1. //控制器
  2. namespace Bim999.Weixin.Controllers
  3. {
  4. public class SignController : Controller
  5. {
  6. // GET: /<controller>/
  7. public void Index(int id)
  8. {
  9. var state="bim999_" + DateTime.Now.Millisecond;
  10. HttpContext.Session.SetString("State", state) ;//储存随机数到Session
  11. var url=(OAuthApi.GetAuthorizeUrl(BimWxConfig.AppId, BimWxConfig.RedirectUri+ "?returnUrl=/sign/sign?id=" + id, state, OAuthScope.snsapi_userinfo));
  12. Response.WriteAsync($"<script>location.href='{url}';</script>");
  13. }
  14. public IActionResult Sign(string id)
  15. {
  16. var jssdk = JSSDKHelper.GetJsSdkUiPackage(BimWxConfig.AppId, BimWxConfig.AppSecret, HttpContext.Request.GetAbsoluteUri());
  17. ViewBag.TaskId = id;
  18. return View(jssdk);
  19. }
  20. public IActionResult SignPage(string id,string latitude,string longitude)
  21. {
  22. var wxOpenId = HttpContext.Session.GetString("WxOpenId");
  23. if (string.IsNullOrWhiteSpace(wxOpenId)) //没有 OpenId 跳转到微信授权重新获取
  24. return Redirect(OAuthApi.GetAuthorizeUrl(BimWxConfig.AppId, BimWxConfig.RedirectUri, nameof(Sign), OAuthScope.snsapi_userinfo));
  25. List<dynamic> jobs;
  26. //获取平台信息
  27. using (var conn = SqlHelper.GetConn())
  28. {
  29. jobs = conn.Query(@"SELECT a.Uid,b.ShortName 'JobName',b.ServerUrl 'Content'
  30. FROM PlatformUser a JOIN Platform b ON a.Pid=b.Id
  31. WHERE a.WxOpenId=@wxOpenId", new { wxOpenId }).ToList();
  32. }
  33. foreach (var job in jobs)
  34. {
  35. ViewBag.UId = job.Uid;
  36. ViewBag.Content = job.Content;
  37. ViewBag.TaskId = id;
  38. }
  39. var url = ViewBag.Content + "?UId=" + ViewBag.UId + "&TaskId=" + ViewBag.TaskId + "&latitude=" + latitude + "&longitude=" + longitude;
  40. ViewBag.Text = url;
  41. //后台请求第三方链接进行签到处理
  42. ViewBag.Textss = HttpHelper.HttpGet(url);
  43. return View();
  44. }
  45. }
  46. }

HttpHelper.HttpGet(url)

  1. /// <summary>
  2. /// 同步方式发起http get请求
  3. /// </summary>
  4. /// <param name="url">请求URL</param>
  5. /// <param name="queryString">参数字符串</param>
  6. /// <returns>请求返回值</returns>
  7. public static string HttpGet(string url, string queryString = null)
  8. {
  9. if (!string.IsNullOrEmpty(queryString))
  10. url += "?" + queryString.Trim(' ', '?', '&');
  11. var webRequest = WebRequest.Create(url) as HttpWebRequest;
  12. if (webRequest == null) return null;
  13. webRequest.Method = "GET";
  14. webRequest.ContinueTimeout = 200000;
  15. return WebResponseGet(webRequest);
  16. }
  17. /// <summary>
  18. /// 同步方式发起http post请求
  19. /// </summary>
  20. /// <param name="url">请求URL</param>
  21. /// <param name="queryString">参数字符串</param>
  22. /// <returns>请求返回值</returns>
  23. public static string HttpPost(string url, string queryString = null)
  24. {
  25. HttpWebRequest webRequest = WebRequest.Create(url) as HttpWebRequest;
  26. if (webRequest == null) return null;
  27. webRequest.Method = "POST";
  28. webRequest.ContentType = "application/x-www-form-urlencoded";
  29. webRequest.ContinueTimeout = 20000;
  30. //POST the data.
  31. using (var requestWriter = new StreamWriter(webRequest.GetRequestStreamAsync().Result))
  32. {
  33. requestWriter.Write(queryString);
  34. }
  35. return WebResponseGet(webRequest);
  36. }

//页面Sign.cshtml(页面调用微信Js)
(重点:本页面获取的经纬度,不能传到控制器,而且!而且!而且!在本页面通过Ajax请求第三方平台,存在跨域访问的问题,所以只能控制器(后台)中请求。所以跳转页面并传参。)

  1. @model Senparc.Weixin.MP.Helpers.JsSdkUiPackage
  2. @{ Layout = null;
  3. }
  4. <html>
  5. <head>
  6. <title>会议签到中...</title>
  7. <script src="https://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>
  8. <script src="//cdn.bootcss.com/jquery/3.1.1/jquery.min.js"></script>
  9. <script>
  10. wx.config({
  11. debug: false,
  12. appId: '@Model.AppId',
  13. timestamp:'@Model.Timestamp',
  14. nonceStr: '@Model.NonceStr',
  15. signature: '@Model.Signature',
  16. jsApiList: [
  17. 'checkJsApi',
  18. 'getLocation'
  19. ]
  20. });
  21. wx.ready(function () {
  22. wx.getLocation({
  23. type: 'wgs84', // 默认为wgs84的gps坐标,如果要返回直接给openLocation用的火星坐标,可传入'gcj02'
  24. success: function (res) {
  25. console.log(res);
  26. console.log(3);
  27. var latitude = res.latitude; // 纬度,浮点数,范围为90 ~ -90
  28. var longitude = res.longitude; // 经度,浮点数,范围为180 ~ -180。
  29. var speed = res.speed; // 速度,以米/每秒计
  30. var accuracy = res.accuracy; // 位置精度
  31. var url = "/sign/SignPage?id=" + '@ViewBag.TaskId' + "&latitude=" + latitude + "&longitude=" + longitude;
  32. location.href = url;
  33. }
  34. });
  35. });
  36. wx.error(function (res) {
  37. //res 出错信息
  38. console.log(res);
  39. });
  40. </script>
  41. </head>
  42. <body>
  43. <div id="box" style="text-align:center;font-size:100px"></div>
  44. </body>
  45. </html>

//页面SignPage.cshtml

  1. @{ Layout = null;
  2. }
  3. <html>
  4. <head>
  5. <title>会议签到</title>
  6. </head>
  7. <body>
  8. <div id="box" style="text-align:center;font-size:100px"> @ViewBag.Textss </div>
  9. </body>
  10. </html>
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注