using MyCode.Project.Domain.Message.Response.EnterpriseWechat; using MyCode.Project.Domain.Message.Response.Wechat; using MyCode.Project.Infrastructure.Cache; using MyCode.Project.Infrastructure.Common; using MyCode.Project.Infrastructure.Constant; using MyCode.Project.Infrastructure.Exceptions; using MyCode.Project.Infrastructure.WebPost; using Senparc.CO2NET.Extensions; using Senparc.Weixin; using Senparc.Weixin.MP.Entities; using Senparc.Weixin.MP.Helpers; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Text; using System.Web; namespace MyCode.Project.OutSideService.Implementation { public class EnterpriseWechatService : IEnterpriseWechatService { private readonly string apiUrl = "https://qyapi.weixin.qq.com/"; private readonly IMyCodeCacheService _myCodeCacheService; public EnterpriseWechatService( IMyCodeCacheService myCodeCacheService ) { _myCodeCacheService = myCodeCacheService; } #region 基础辅助 #region Get(进一步封装Get方法) /// /// 进一步封装Get方法 /// /// /// /// private T Get(string url) where T : BaseEnterpriseResp { var webUtils = new WebUtils(); var resp = webUtils.DoGet(url, null); resp.CheckResult(); return resp; } #endregion #region ToDepartmentHasChild(部门转成含有子节点的结构) public List ToDepartmentHasChild(List listDepartmentInfo) { if (listDepartmentInfo == null || listDepartmentInfo.Count == 0) { return null; } //公司节点 var rootList = listDepartmentInfo.FindAll(p => p.Parentid == 0); var returnList = new List(); //子节点 foreach (var root in rootList) { var item = new DepartmentHasChild { Id = root.Id, Name = root.Name, Parentid = root.Parentid }; item.ListChild = GetDepartmentChild(listDepartmentInfo, root.Id); returnList.Add(item); } return returnList; } #endregion #region GetDepartmentChild(得到部门子节点) /// /// 得到子节点 /// /// /// /// public List GetDepartmentChild(List listDepartmentInfo, int parentId) { var list = listDepartmentInfo.FindAll(p => p.Parentid == parentId); var returnList = new List(); if (list == null || list.Count == 0) { return new List { }; } foreach (var child in list) { var item = new DepartmentHasChild { Id = child.Id, Name = child.Name, Parentid = child.Parentid, Order = child.Order }; item.ListChild = GetDepartmentChild(listDepartmentInfo, child.Id); returnList.Add(item); } return returnList; } #endregion #endregion #region GetAccessToken(得到AccessToken,有效期7200秒) /// /// 得到AccessToken,有效期7200秒 /// /// 企业id /// /// public string GetAccessToken(string corpId, string secret) { var cacheKey = $"{CacheKey.EnterpriseWechatTokenKey}{corpId}{secret}"; if (_myCodeCacheService.Exists(cacheKey)) { return _myCodeCacheService.Get(cacheKey); } var url = $"{apiUrl}cgi-bin/gettoken?corpid={corpId}&corpsecret={secret}"; var resp = Get(url); var token = resp.Access_token; _myCodeCacheService.Set(cacheKey, token, new TimeSpan(1, 0, 0)); return token; } #endregion #region GetTicket(获取企业微信Ticket) /// /// 获取企业微信Ticket /// /// 对应的应用的token /// private string GetTicket(string accessToken) { var cacheKey = $"{accessToken}"; if (_myCodeCacheService.Exists(cacheKey)) { return _myCodeCacheService.Get(cacheKey); } var url = string.Format(apiUrl + "cgi-bin/get_jsapi_ticket?access_token={0}", accessToken.AsUrlData()); JsApiTicketResult result = Senparc.CO2NET.HttpUtility.Get.GetJson(url); if (result.errcode != ReturnCode.请求成功) { throw new BaseException(result.ToJson()); } _myCodeCacheService.Set(cacheKey, result.ticket, new TimeSpan(1, 0, 0)); return result.ticket; } #endregion #region GetApplicationTicket(应用的jsapi_ticket) /// /// 应用的jsapi_ticket /// /// 对应的应用的token /// private string GetApplicationTicket(string accessToken) { var cacheKey = $"{accessToken}2"; if (_myCodeCacheService.Exists(cacheKey)) { return _myCodeCacheService.Get(cacheKey); } var url = string.Format(apiUrl + "cgi-bin/ticket/get?access_token={0}&type=agent_config", accessToken.AsUrlData()); JsApiTicketResult result = Senparc.CO2NET.HttpUtility.Get.GetJson(url); if (result.errcode != ReturnCode.请求成功) { throw new BaseException(result.ToJson()); } _myCodeCacheService.Set(cacheKey, result.ticket, new TimeSpan(1, 0, 0)); return result.ticket; } #endregion #region GetJsSdk(取得企业微信JsSdk相关参数值) /// /// 取得微信JsSdk相关参数值 /// /// 微信应用ID /// JsTicket /// 需要授权Url地址 /// private JsSdkResp GetJsSdk(string appId, string ticket, string url) { var decodeUrl = HttpUtility.UrlDecode(url); string timeStamp = JSSDKHelper.GetTimestamp(); string nonceStr = JSSDKHelper.GetNoncestr(); string signature = ""; var paySignReqHandler = new Senparc.Weixin.TenPay.V2.RequestHandler(null); paySignReqHandler.SetParameter("jsapi_ticket", ticket); paySignReqHandler.SetParameter("noncestr", nonceStr); paySignReqHandler.SetParameter("timestamp", timeStamp); paySignReqHandler.SetParameter("url", decodeUrl); signature = paySignReqHandler.CreateSHA1Sign(); return new JsSdkResp { AppId = appId, Timestamp = timeStamp, NonceStr = nonceStr, Signature = signature }; } #endregion #region 获取企业微信的JS-SDK权限验证的签名Signature /// /// 获取企业微信的JS-SDK权限验证的签名Signature /// /// jsapi_ticket /// 随机字符串(必须与wx.config中的nonceStr相同) /// 时间戳(必须与wx.config中的timestamp相同) /// 当前网页的URL,不包含#及其后面部分(必须是调用JS接口页面的完整URL) /// private string GetSignature(string jsapi_ticket, string noncestr, long timestamp, string url) { StringBuilder sb = new StringBuilder(); sb.Append("jsapi_ticket=").Append(jsapi_ticket).Append("&") .Append("noncestr=").Append(noncestr).Append("&") .Append("timestamp=").Append(timestamp).Append("&") .Append("url=").Append(url.IndexOf("#") >= 0 ? url.Substring(0, url.IndexOf("#")) : url); string dddd = sb.ToString(); LogHelper.Info("Signature: " + dddd); return Senparc.CO2NET.Helpers.EncryptHelper.GetSha1(sb.ToString()).ToLower(); } #endregion //#region GetJsSdk(取得企业微信某个应用的JsSdk相关参数值) ///// ///// 取得企业微信某个应用的JsSdk相关参数值 ///// ///// ///// 第一步传 1 第二步传2 ///// //public EnterpriseWechatJsSdkResp GetJsSdk(string url, int tokenType = 1) //{ // EnterpriseWechatJsSdkResp result = new EnterpriseWechatJsSdkResp(); // string corpId = companyConfig.Corpid; // string agentId = companyConfig.CustomerAgentidId.Replace("\r\n", ""); // string secret = companyConfig.CustomerDetailSecret; // string ticket = ""; // string token = GetAccessToken(corpId, secret); // long timeStamp = 0; // string nonceStr = ""; // if (tokenType == 1) // { // ticket = GetTicket(token); // timeStamp = long.Parse(JSSDKHelper.GetTimestamp()); // nonceStr = JSSDKHelper.GetNoncestr(); // } // else if (tokenType == 2) // { // result = _myCodeCacheService.Get(companyConfig.Corpid + "1"); // ticket = GetApplicationTicket(token); // timeStamp = long.Parse(result.Timestamp); // nonceStr = result.NonceStr; // } // else // { // return null; // } // //var decodeUrl = HttpUtility.UrlDecode(url); // string signature = GetSignature(ticket, nonceStr, timeStamp, url); // result.CorpId = corpId; // result.AgentId = agentId; // result.NonceStr = nonceStr; // result.Signature = signature; // result.Timestamp = timeStamp.ToString(); // //LogHelper.Info("result:"); // //LogHelper.Info(result); // _myCodeCacheService.Set(cacheKey, result, new TimeSpan(1, 0, 0)); // return result; //} //#endregion #region GetDepartmentList(得到部门列表) /// /// 取得通讯录的部门列表,使用通讯录Token /// /// Token /// public List GetDepartmentList(string accessToken, string corpId, string secret) { if (string.IsNullOrWhiteSpace(accessToken)) { accessToken = GetAccessToken(corpId, secret); } var url = $"{apiUrl}cgi-bin/department/list?access_token={accessToken}"; var resp = Get(url); if (resp.Department == null || resp.Department.Count == 0) { return new List { }; } return GetDepartmentChild(resp.Department, 0); } #endregion #region GetDepartmentMemberList(得到部门的员工列表) /// /// 得到部门的员工列表 /// /// 通讯录的token /// 部门id /// 是否递归获取子部门下面的成员:1-递归获取,0-只获取本部门 /// public List GetDepartmentMemberList(string accessToken, long departmentId, string corpId, string secret, int fetch_child = 0) { //if (departmentId == 0) { throw new BaseException("部门id不能为0"); } if (string.IsNullOrWhiteSpace(accessToken)) { accessToken = GetAccessToken(corpId, secret); } var url = $"{apiUrl}cgi-bin/user/simplelist?access_token={accessToken}&department_id={departmentId}&fetch_child={fetch_child}";//是否递归获取子部门下面的成员:1-递归获取,0-只获取本部门 var resp = Get(url); if (resp.Userlist == null || resp.Userlist.Count == 0) { return new List { }; } return resp.Userlist; } #endregion #region GetEmployeeInfo(获取员工信息) /// /// 获取员工信息 /// /// 员工id /// public EnterpriseEmployeeInfo GetEmployeeInfo(string userId, string corpId, string secret) { if (string.IsNullOrWhiteSpace(userId)) { throw new BaseException("员工id不能为空"); } var accessToken = GetAccessToken(corpId, secret); var url = $"{apiUrl}/cgi-bin/user/get?access_token={accessToken}&userid={userId}"; var webUtils = new WebUtils(); var resp = webUtils.DoGet(url, null); return resp; } #endregion //#region GetLoginUserInfo(获取登录用户信息) ///// ///// 获取登录用户信息 ///// ///// ///// ///// 自建应用secret ///// //public UserInfoResp GetLoginUserInfo(string code, string corpId = "", string secret = "") //{ // var accessToken = GetAccessToken(corpId, secret); // var url = $"{apiUrl}/cgi-bin/user/getuserinfo?access_token={accessToken}&code={code}"; // var result = Get(url); // return result; //} //#endregion #region 从url读取内容到内存Stream流中 /// /// 从url读取内容到内存Stream流中 /// /// /// public Stream DownLoadFielToStream(string url) { var wreq = HttpWebRequest.Create(url) as HttpWebRequest; HttpWebResponse response = wreq.GetResponse() as HttpWebResponse; MemoryStream ms = null; using (var stream = response.GetResponseStream()) { Byte[] buffer = new Byte[response.ContentLength]; int offset = 0, actuallyRead = 0; do { actuallyRead = stream.Read(buffer, offset, buffer.Length - offset); offset += actuallyRead; } while (actuallyRead > 0); ms = new MemoryStream(buffer); } response.Close(); return ms; } #endregion //#region openid转userid ///// ///// openid转userid ///// ///// ///// ///// 通讯录secret ///// //public OpenIdChangeUseridResp GetUseridByOpenid(string openid, string corpId = "", string secret = "") //{ // var accessToken = GetAccessToken(corpId, secret); // var url = $"{apiUrl}cgi-bin/user/convert_to_userid?access_token={accessToken}"; // var webUtils = new WebUtils(); // var resp = webUtils.DoGet(url, null); // return resp; //} //#endregion #region userid转openid /// /// userid转openid /// /// /// /// 通讯录secret /// public UserIdChangeOpenIdResp GetOpenidByUserid(string userId, string corpId = "", string secret = "") { var accessToken = GetAccessToken(corpId, secret); var url = $"{apiUrl}cgi-bin/user/convert_to_openid?access_token={accessToken}"; string json = $@"{{ ""userid"": ""{userId}"" }}"; var webUtils = new WebUtils(); var resp = webUtils.DoPostJson(url, json); UserIdChangeOpenIdResp resut = JsonHelper.ToObject(resp); return resut; } #endregion } }