@Aiti
2020-03-12T02:28:38.000000Z
字数 9311
阅读 190
微信开发
1、服务号或者公众号
2、自己的服务器
3、第三方平台
接口配置信息
请填写接口配置信息,此信息需要你有自己的服务器资源,填写的URL需要正确响应微信发送的Token验证
URL:http://js.wx.bim999.cn/WeiXin/Message
Token:bim999
JS接口安全域名
设置JS接口安全域后,通过关注该测试号,开发者即可在该域名下调用微信开放的JS接口
域名:js.wx.bim999.cn
{
"AppSettings": {
"DbConnectionString": "Data Source=192.168.1.240;Initial Catalog=BimWeixin;User Id=sa;Password=cx1234;",
"AppId": "wxfb1254572c7bac44",
"AppSecret": "2632267b19bd3373f87ad15c84f6cf68",
"RedirectUri": "http://js.wx.bim999.cn/weixin/oauth"
},
"ApplicationInsights": {
"InstrumentationKey": ""
},
"Logging": {
"IncludeScopes": false,
"LogLevel": {
"Default": "Debug",
"System": "Information",
"Microsoft": "Information"
}
}
}
2.验证接口配置并验证(浏览器直接打开http://js.wx.bim999.cn/WeiXin/Message)
//控制器WeiXin.CS
MVC是先调用控制器,再根据控制器调用页面(不是根据页面调用控制器)。控制器默认进入先Index
public IActionResult Index()
{
return View();
}
private const string VerifyToken = "bim999";
public IActionResult Message(string signature, string timestamp, string nonce, string echostr)
{
//返回随机字符串则表示验证通过
//using Senparc.Weixin.MP.CheckSignature.Check(检查签名是否正确);
if (CheckSignature.Check(signature, timestamp, nonce, VerifyToken))
return Content(echostr);
return View();
}
//页面Message.cxhtml
@{
ViewBag.Title = "微信回调地址";
}
<h4>如果您在浏览器中看到这条信息,表明此Url可以填入微信后台</h4>
protected void Page_Load(object sender, EventArgs e)
{
var url = $"https://js.wx.bim999.cn/weixin/getoauthurl?pid={ pid }&uid={ uid }";
var request = (HttpWebRequest)WebRequest.Create(url);
//获取接受到网址的内容
using (var response = (HttpWebResponse)request.GetResponse())
{
using (var sr = new System.IO.StreamReader(response.GetResponseStream(), Encoding.UTF8))
{
//获取二维码地址
// QRImg.ImageUrl = sr.ReadToEnd();
//获取值生成二维码
CreateQR(HttpUtility.UrlDecode(sr.ReadToEnd()));
}
}
}
private void CreateQR(string nr)
{
Bitmap bt;
if (!string.IsNullOrEmpty(nr))
{
string filename = Guid.NewGuid().ToString().ToUpper();
QRCodeEncoder qrCodeEncoder = new QRCodeEncoder();
qrCodeEncoder.QRCodeVersion = 0;
bt = qrCodeEncoder.Encode(nr, Encoding.UTF8);
string imgPath = Server.MapPath("~/ImageQR/") + filename + ".jpg";
try
{
bt.Save(imgPath);
QRImg.ImageUrl = "~/ImageQR/" + filename + ".jpg";
}
catch (Exception)
{
}
}
}
//扫码绑定调用的是
public string GetOAuthUrl(int pid, string uid)
{
if (pid <= 0) return "非法参数";
uid = (uid + "").Trim();
if (uid.Length <= 0) return "非法参数";
var requestId = Guid.NewGuid().ToString("N");
//写入绑定请求
using (var conn = SqlHelper.GetConn())
{
conn.Execute("INSERT INTO BindRequest(RequestId,Pid,Uid,DoTime) VALUES(@requestId,@pid,@uid,GETDATE());", new { requestId, pid, uid });
}
//此处验证是否关注服务号,关注了就跳转到配置信息中RedirectUri="http://js.wx.bim999.cn/weixin/OAuth"
var url = OAuthApi.GetAuthorizeUrl(BimWxConfig.AppId, BimWxConfig.RedirectUri, requestId,
OAuthScope.snsapi_userinfo);
//返回值 去本地生成二维码
return Uri.EscapeDataString(url);
}
public IActionResult OAuth(string code, string state, string returnUrl)
{
if ((code = code + "").Length > 3) //获取 AccessToken
{
var token = OAuthApi.GetAccessToken(BimWxConfig.AppId, BimWxConfig.AppSecret, code);
if (token.errcode != ReturnCode.请求成功)
{
ViewBag.Message = token.errcode.ToString();
}
else //处理授权结果
{
string wxOpenId = token.openid;
if ((state = state + "").Length == 32)
{
#region 绑定用户
using (var conn = SqlHelper.GetConn())
{
conn.Open();
var request = conn.Query("SELECT Pid,Uid,RequestId FROM BindRequest WHERE RequestId=@state", new { state }).FirstOrDefault();
if (request == null)
{
ViewBag.Message = "绑定用户失败,请重新登录PC平台扫描二维码!";
}
else
{
var trans = conn.BeginTransaction();
var bindUser = new
{
request.RequestId,
request.Pid,
request.Uid,
WxOpenId = token.openid
};
conn.Execute("UPDATE BindRequest SET SuccessTime=GETDATE() WHERE RequestId=@RequestId", bindUser, trans);
conn.Execute("DELETE FROM PlatformUser WHERE Pid=@Pid AND Uid=@Uid", bindUser, trans);
conn.Execute("INSERT INTO PlatformUser(WxOpenId,Pid,Uid) VALUES(@WxOpenId,@Pid,@Uid)", bindUser, trans);
trans.Commit();
}
}
wxOpenId = token.openid;
#endregion
}
#region [异步] 更新微信用户信息
Task.Factory.StartNew(() =>
{
var user = OAuthApi.GetUserInfo(token.access_token, token.openid);
if (user.openid != token.openid) return;
//将获取到的用户信息更新到数据库中
using (var conn = SqlHelper.GetConn())
{
conn.Open();
var trans = conn.BeginTransaction();
conn.Execute("DELETE FROM WxUser WHERE WxOpenId=@openid", user, trans);
conn.Execute(
"INSERT INTO WxUser(WxOpenId,Nick,Sex,Province,City,Country,HeadImgUrl) VALUES(@openid,@nickname,@sex,@province,@city,@country,@headimgurl)",
user, trans);
trans.Commit();
}
});
#endregion
//有效的 WxOpenid,设置 Session 并跳转到 MyJob 页面
if (wxOpenId != null)
{
HttpContext.Session.SetString("WxOpenId", token.openid);
if (!string.IsNullOrEmpty(returnUrl))
{
return Redirect(returnUrl);
}else
return RedirectToAction("myjob");
}
}
}
return View();
}
public IActionResult MyJob()
{
var wxOpenId = HttpContext.Session.GetString("WxOpenId");
if (string.IsNullOrWhiteSpace(wxOpenId)) //没有 OpenId 跳转到微信授权重新获取
return Redirect(OAuthApi.GetAuthorizeUrl(BimWxConfig.AppId, BimWxConfig.RedirectUri, nameof(MyJob), OAuthScope.snsapi_userinfo));
List<dynamic> jobs;
//获取平台信息
using (var conn = SqlHelper.GetConn())
{
jobs = conn.Query(@"SELECT a.Uid,b.ShortName 'JobName',b.ServerUrl 'Content'
FROM PlatformUser a JOIN Platform b ON a.Pid=b.Id
WHERE a.WxOpenId=@wxOpenId", new { wxOpenId }).ToList();
}
//请求平台API,获取具体的内容
foreach (var job in jobs)
{
job.Content = HttpHelper.HttpGet(job.Content, "uid=" + job.Uid);
}
return View(jobs);
}
//获取任务页面MyJob.cshtml
@model List<dynamic>
@{
ViewBag.Title = "我的任务";
}
@if (Model.Count > 0)
{
<ul class="collapsible popout" data-collapsible="accordion">
@foreach (var job in Model)
{
<li>
<div class="collapsible-header">@job.JobName</div>
<div class="collapsible-body">@Html.Raw(job.Content)</div>
</li>
}
<li>
<div class="collapsible-header">建党平台</div>
<div class="collapsible-body">这里是建党平台放回的数据内容</div>
</li>
</ul>
}
else
{
<h4>当前微信号无法查看任务!</h4>
}
@section script{
<script>
$(function () {
$(".collapsible-header").first().addClass("active");
$(".collapsible").collapsible();
})
</script>
}
//控制器
namespace Bim999.Weixin.Controllers
{
public class SignController : Controller
{
// GET: /<controller>/
public void Index(int id)
{
var state="bim999_" + DateTime.Now.Millisecond;
HttpContext.Session.SetString("State", state) ;//储存随机数到Session
var url=(OAuthApi.GetAuthorizeUrl(BimWxConfig.AppId, BimWxConfig.RedirectUri+ "?returnUrl=/sign/sign?id=" + id, state, OAuthScope.snsapi_userinfo));
Response.WriteAsync($"<script>location.href='{url}';</script>");
}
public IActionResult Sign(string id)
{
var jssdk = JSSDKHelper.GetJsSdkUiPackage(BimWxConfig.AppId, BimWxConfig.AppSecret, HttpContext.Request.GetAbsoluteUri());
ViewBag.TaskId = id;
return View(jssdk);
}
public IActionResult SignPage(string id,string latitude,string longitude)
{
var wxOpenId = HttpContext.Session.GetString("WxOpenId");
if (string.IsNullOrWhiteSpace(wxOpenId)) //没有 OpenId 跳转到微信授权重新获取
return Redirect(OAuthApi.GetAuthorizeUrl(BimWxConfig.AppId, BimWxConfig.RedirectUri, nameof(Sign), OAuthScope.snsapi_userinfo));
List<dynamic> jobs;
//获取平台信息
using (var conn = SqlHelper.GetConn())
{
jobs = conn.Query(@"SELECT a.Uid,b.ShortName 'JobName',b.ServerUrl 'Content'
FROM PlatformUser a JOIN Platform b ON a.Pid=b.Id
WHERE a.WxOpenId=@wxOpenId", new { wxOpenId }).ToList();
}
foreach (var job in jobs)
{
ViewBag.UId = job.Uid;
ViewBag.Content = job.Content;
ViewBag.TaskId = id;
}
var url = ViewBag.Content + "?UId=" + ViewBag.UId + "&TaskId=" + ViewBag.TaskId + "&latitude=" + latitude + "&longitude=" + longitude;
ViewBag.Text = url;
//后台请求第三方链接进行签到处理
ViewBag.Textss = HttpHelper.HttpGet(url);
return View();
}
}
}
HttpHelper.HttpGet(url)
/// <summary>
/// 同步方式发起http get请求
/// </summary>
/// <param name="url">请求URL</param>
/// <param name="queryString">参数字符串</param>
/// <returns>请求返回值</returns>
public static string HttpGet(string url, string queryString = null)
{
if (!string.IsNullOrEmpty(queryString))
url += "?" + queryString.Trim(' ', '?', '&');
var webRequest = WebRequest.Create(url) as HttpWebRequest;
if (webRequest == null) return null;
webRequest.Method = "GET";
webRequest.ContinueTimeout = 200000;
return WebResponseGet(webRequest);
}
/// <summary>
/// 同步方式发起http post请求
/// </summary>
/// <param name="url">请求URL</param>
/// <param name="queryString">参数字符串</param>
/// <returns>请求返回值</returns>
public static string HttpPost(string url, string queryString = null)
{
HttpWebRequest webRequest = WebRequest.Create(url) as HttpWebRequest;
if (webRequest == null) return null;
webRequest.Method = "POST";
webRequest.ContentType = "application/x-www-form-urlencoded";
webRequest.ContinueTimeout = 20000;
//POST the data.
using (var requestWriter = new StreamWriter(webRequest.GetRequestStreamAsync().Result))
{
requestWriter.Write(queryString);
}
return WebResponseGet(webRequest);
}
//页面Sign.cshtml(页面调用微信Js)
(重点:本页面获取的经纬度,不能传到控制器,而且!而且!而且!在本页面通过Ajax请求第三方平台,存在跨域访问的问题,所以只能控制器(后台)中请求。所以跳转页面并传参。)
@model Senparc.Weixin.MP.Helpers.JsSdkUiPackage
@{ Layout = null;
}
<html>
<head>
<title>会议签到中...</title>
<script src="https://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>
<script src="//cdn.bootcss.com/jquery/3.1.1/jquery.min.js"></script>
<script>
wx.config({
debug: false,
appId: '@Model.AppId',
timestamp:'@Model.Timestamp',
nonceStr: '@Model.NonceStr',
signature: '@Model.Signature',
jsApiList: [
'checkJsApi',
'getLocation'
]
});
wx.ready(function () {
wx.getLocation({
type: 'wgs84', // 默认为wgs84的gps坐标,如果要返回直接给openLocation用的火星坐标,可传入'gcj02'
success: function (res) {
console.log(res);
console.log(3);
var latitude = res.latitude; // 纬度,浮点数,范围为90 ~ -90
var longitude = res.longitude; // 经度,浮点数,范围为180 ~ -180。
var speed = res.speed; // 速度,以米/每秒计
var accuracy = res.accuracy; // 位置精度
var url = "/sign/SignPage?id=" + '@ViewBag.TaskId' + "&latitude=" + latitude + "&longitude=" + longitude;
location.href = url;
}
});
});
wx.error(function (res) {
//res 出错信息
console.log(res);
});
</script>
</head>
<body>
<div id="box" style="text-align:center;font-size:100px"></div>
</body>
</html>
//页面SignPage.cshtml
@{ Layout = null;
}
<html>
<head>
<title>会议签到</title>
</head>
<body>
<div id="box" style="text-align:center;font-size:100px"> @ViewBag.Textss </div>
</body>
</html>