之前接到了一個項目,要求在關注公眾號的用戶,推廣下個用戶,實行獎勵模式(只有兩級!)。然而,一臉懵,網站開發推廣生成二維碼,我知道怎么做,大不了記錄用戶Id,生成二維碼,掃描的時候,獲取用戶Id,然后得到推薦者。微信公眾號的,還真不知道頭緒。好吧,那就先按照網站的思路進行開發,將存儲在數據庫中的用戶Id和要跳轉的地址拼接成最終的字符串,生成二維碼,開始開發(依舊沒有自信可以成功,┭┮﹏┭┮)。現實總是那個順應人意,果然是不可以的,推薦的用戶,如果沒有關注,是沒法直接跳轉相應的地址的,如果把跳轉地址去掉權限,那么,推薦的用戶就不能關注公眾號,也就是此推薦是無效的。。。(難過10分鍾),各種在網上找解決方案,問各路大神,貌似我都沒法解釋清楚問題(自己的表達能力有待提高。。。),然后,只能硬着頭皮再去查看微信公眾號開發平台的文檔了,抱着死馬當活馬醫的態度,竟然柳暗花明了,超開心,下面的圖,這個不就是我要的結果么(跳躍,開心)
目前有2種類型的二維碼,分別是臨時二維碼和永久二維碼,前者有過期時間,最大為1800秒,但能夠生成較多數量,后者無過期時間,數量較少(目前參數只支持1--100000)。兩種二維碼分別適用於帳號綁定、用戶來源統計等場景。

與用戶關聯,我在項目中使用的是長期有效二維碼,根據場景Id與用戶Id對應,然后將生成的長期二維碼圖片保存在服務器上,直接使用(但是無奈的是有數量限制)。
以下上代碼:
///
/// 二維碼分享 測試使用
///
public class ShareCodeController
{
// GET: ShareCode
public ActionResult Index()
{
return View();
}
/*生成永久二維碼*/
public void getPerpetualQR(String account)
{
var accessToken = AccessTokenContainer.TryGetAccessToken(AppId, AppSecret);
var ticketMessage = QrCode.Create(accessToken,0,100);
var urlFormat = "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket={0}";
GetTicketImage(ticketMessage.ticket, openId);
}
///
/// 通過ticket換取二維碼
///
///票據
///二維碼依照openId 命名
///相對路徑 @"\weixin\HuLu\erweima2"
/// 下載二維碼成功后的物理路徑:D:\XXXXXX.com\kkk\erweima2\201503031044566511190.jpg
public string GetTicketImage(string TICKET, string openId)
{
string content = string.Empty;
string strpath = string.Empty;//生成的URL 也就是 關注的URL
string savepath = string.Empty;//圖片保存的路徑
string stUrl = "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=" +(TICKET);
HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(stUrl);
req.Method = "GET";
using (WebResponse wr = req.GetResponse())
{
HttpWebResponse myResponse = (HttpWebResponse)req.GetResponse();
strpath = myResponse.ResponseUri.ToString();
WebClient mywebclient = new WebClient();
// @"
var path = AppDomain.CurrentDomain.SetupInformation.ApplicationBase;
var filePath = $"UploadImages\\ShareCode";
path = $"{path}{filePath}\\{DateTime.Now.ToString("yyy-MM")}";
if (!System.IO.Directory.Exists(path))
{
System.IO.Directory.CreateDirectory(path);//不存在就創建目錄
}
savepath = $"{path}\\{openId}.{myResponse.ContentType.Split('/')[1].ToString()}";
try
{
mywebclient.DownloadFile(strpath, savepath);//下載生成的二維碼圖片
}
catch (Exception ex)
{
savepath = ex.ToString();
}
}
return savepath.ToString();
}
}
如何識別呢? 就是在用戶關注的事件中,可以獲取到二維碼場景值,根據二維碼的場景值(在上面,已經將場景值和yoghurt一一對應存儲),可以獲取到用戶的Id,即可獲取到推廣者的信息。 以下用戶關注公眾號事件處理場景值Id代碼:
#region 用戶關注公眾號
///
/// 用戶關注公眾號
///
///
///
public async override Task OnEvent_SubscribeRequestAsync(RequestMessageEvent_Subscribe requestMessage)
{
try
{
if (AppID != null)
{
var userInfo = await UserApi.InfoAsync(AppID, base.WeixinOpenId);
if (userInfo == null)
{
Sprite.Agile.Logger.LoggerManager.Instance.Logger_Info($"獲取用戶信息失敗");
}
else
{
Sprite.Agile.Logger.LoggerManager.Instance.Logger_Info($"獲取用戶信息,OpenId:{userInfo.openid}, WeixinOpenId:{WeixinOpenId}");
}
#region 處理用戶信息
if (requestMessage.Event == Event.subscribe)
{
var user = usersRepository.GetUserByOpenId(userInfo.openid);
Sprite.Agile.Logger.LoggerManager.Instance.Logger_Info($"二維碼場景值{userInfo.qr_scene}");
if (user == null)
{
user = new YueSaoUser
{
OpenId = userInfo.openid,
WeChatNickName = userInfo.nickname,
HeadImg = userInfo.headimgurl,
Status = Sprite.Agile.Domain.Status.Disabled,
UserType=Sprite.Agile.Model.Domain.Entities.UserType.User,
IsSubscribe = true
};
//判斷是否通過掃描進入關注
if (userInfo.subscribe_scene == "ADD_SCENE_QR_CODE")
{
//暫時通過場景Id識別上級
var parent = usersRepository.GetUserByScanId(userInfo.qr_scene);
if(parent!=null)
{
user.ParentId = parent.Id;
}
}
usersRepository.AddUser(user);
}
else
{
user.OpenId = userInfo.openid;
user.HeadImg = userInfo.headimgurl;
user.WeChatNickName = userInfo.nickname;
user.IsSubscribe = true;
usersRepository.SaveUser(user);
}
}
#endregion
var responseMessage = requestMessage.CreateResponseMessage();
responseMessage.Content = $" 感謝您的關注";
return responseMessage;
}
else
{
Sprite.Agile.Logger.LoggerManager.Instance.Logger_Info($"用戶關注事件, 微信商戶信息為空:{requestMessage.ToUserName}");
return new ResponseMessageNoResponse();
}
}
catch (Exception ex)
{
Sprite.Agile.Logger.LoggerManager.Instance.Logger_Error(ex);
return new ResponseMessageNoResponse();
}
}
#endregion
