using System; using System.Collections.Generic; using System.Web; using System.Data; using System.Threading.Tasks; using Newtonsoft.Json.Linq; using BP.Sys; using BP.DA; using Newtonsoft.Json; using System.Linq; using System.Xml; using System.Net; using BP.Port; using System.Runtime.CompilerServices; namespace BP.Cloud.WeXinAPI { public class Glo2021 { /// /// 执行安装 /// /// /// public static string MainBuess(XmlDocument xd) { string infoType = xd.FirstChild["InfoType"].InnerText; //推送suite_ticket协议每十分钟微信推送一次,判断是推送ticket的情况,取得ticket保存到缓存中 if (infoType.Equals("suite_ticket")) { string suitTicket = xd.FirstChild["SuiteTicket"].InnerText; Glo.Suite_ticket = suitTicket; HttpContext.Current.Cache.Insert("suitTicket", suitTicket); //HttpContext.Current.Response.Write("success"); return "success"; } //授权成功通知回调 if (infoType.Equals("create_auth")) { //授权成功通知回调推送给服务商. string authCode = xd.FirstChild["AuthCode"].InnerText; HttpContext.Current.Cache.Insert("authcode", authCode); try { //根据临时授权码,获得永久授权码并安装应用. return BP.Cloud.WeXinAPI.Glo.InstallIt(authCode); } catch (Exception ex) { return "err@安装失败,失败信息:" + ex.Message; } } //取消安装的,安装修改. if (infoType.Equals("cancel_auth")) { string authCorpId = xd.FirstChild["AuthCorpId"].InnerText; BP.Cloud.Org org = new BP.Cloud.Org(); int i = org.Retrieve("CorpID", authCorpId); if (i == 1) org.DoDelete(); return "成功卸载,欢迎下次使用."; } //授权变更. if (infoType.Equals("change_auth")) { string authCode = xd.FirstChild["AuthCode"].InnerText; HttpContext.Current.Cache.Insert("authcode", authCode); return "change_auth执行成功."; } //通讯录变更 if (infoType.Equals("change_contact")) { string changeType = xd.FirstChild["ChangeType"].InnerText; string SuiteId = xd.FirstChild["SuiteId"].InnerText;//第三方应用ID string corpID = xd.FirstChild["AuthCorpId"].InnerText;//授权企业的CorpID BP.Cloud.Org org = new BP.Cloud.Org(); int i = org.Retrieve(BP.Cloud.OrgAttr.CorpID, corpID); if (i == 0) return "err@不应该查询不到 AuthCorpId= " + corpID + "的数据."; switch (changeType) { case "create_user": //新建成员 return BP.Cloud.WeXinAPI.Glo.changeConCreateUser(xd, org); case "update_user": //变更成员信息 return BP.Cloud.WeXinAPI.Glo.changeConUpdateUser(xd, org); case "delete_user": //删除成员 return BP.Cloud.WeXinAPI.Glo.changeConUpdateUser(xd, org); case "create_party": //新增部门 return BP.Cloud.WeXinAPI.Glo.changeConCreateDept(xd, org); case "update_party": //更新部门 return BP.Cloud.WeXinAPI.Glo.changeConUpdateDept(xd, org); case "delete_party": //删除部门 return BP.Cloud.WeXinAPI.Glo.changeConDelDept(xd, org); default: return "err@没有判断的类型" + changeType; } } return "err@没有执行的判断." + infoType; } #region 通用的配置项 web.config 配置信息. private static BP.WF.HttpWebResponseUtility _httpWebResponseUtility = null; public static BP.WF.HttpWebResponseUtility HttpWebResponseUtility { get { if (_httpWebResponseUtility == null) _httpWebResponseUtility = new BP.WF.HttpWebResponseUtility(); return _httpWebResponseUtility; } } /// /// 企业ID /// public static string CorpID { get { return BP.Difference.SystemConfig.AppSettings["CorpID"]; } } /// /// 推广包ID /// public static string TemplateId { get { return BP.Difference.SystemConfig.AppSettings["TemplateId"]; } } /// /// 服务器域名 /// public static string Domain { get { return BP.Difference.SystemConfig.AppSettings["Domain"]; } } /// /// 服务商ProviderSecret /// public static string ProviderSecret { get { return BP.Difference.SystemConfig.AppSettings["ProviderSecret"]; } } /// /// 服务商应用ID-SuiteID /// public static string SuiteID { get { return BP.Difference.SystemConfig.AppSettings["SuiteID"]; } } /// /// 服务商应用ID-密钥 /// public static string SuiteID_Secret { get { return BP.Difference.SystemConfig.AppSettings["SuiteID_Secret"]; } } /// /// 我们应用的值 /// public static string Token { get { return BP.Difference.SystemConfig.AppSettings["Token"]; } } /// /// 用于消息内容加密 EncodingAESKey /// public static string EncodingAESKey { get { return BP.Difference.SystemConfig.AppSettings["EncodingAESKey"]; } } #endregion web.config配置信息. /// /// 动态的凭证(经常用)(全局) /// private static string _Suite_ticket = null; public static string Suite_ticket { get { if (_Suite_ticket == null) _Suite_ticket = HttpContext.Current.Cache["suitTicket"] as string; return _Suite_ticket; } set { _Suite_ticket = value; HttpContext.Current.Cache.Insert("suitTicket", value); } } /// /// 获取第三方应用凭证 /// 检查表里是否有SuitAccessToken,如果存在并有效则返回 /// /// public static string getSuitAccessToken() { String accessToken = ""; GloVar glovar = new GloVar(); glovar.No = "suiteAccessToken"; GloVar glovarEx = new GloVar(); glovarEx.No = "suiteAccessTokenExpiresIn"; if (glovar.RetrieveFromDBSources() > 0) { //有效则返回 if (glovarEx.RetrieveFromDBSources() > 0) { if (DataType.IsNullOrEmpty(glovarEx.Val) == false && DateTime.Compare(Convert.ToDateTime(DateTime.Now), Convert.ToDateTime(glovarEx.Val)) < 0) { //如果没有失效,就直接返回表里数据. accessToken = glovar.Val; } else { Dictionary dd = getSuitAccessToken_S(); //失效,重新取,更新 string suitToken = (string)dd["suite_access_token"]; string expiresIn = (string)dd["expires_in"]; glovar.Val = suitToken; glovar.GroupKey = "WeiXin"; glovar.Update(); DateTime ss = DateTime.Now.AddSeconds(double.Parse(expiresIn)); glovarEx.Val = ss.ToString("yyyy-MM-dd HH:mm:ss"); glovarEx.GroupKey = "WeiXin"; glovarEx.Update(); } } } else { //不存在,获取插入 Dictionary dd = getSuitAccessToken_S(); //失效,重新取,更新 string suitToken = (string)dd["suite_access_token"]; string expiresIn = (string)dd["expires_in"]; glovar.Val = suitToken; glovar.GroupKey = "WeiXin"; glovar.Insert(); DateTime ss = DateTime.Now.AddSeconds(double.Parse(expiresIn)); glovarEx.Val = ss.ToString("yyyy-MM-dd HH:mm:ss"); glovarEx.GroupKey = "WeiXin"; glovarEx.Insert(); } return accessToken; } /// /// 获取第三方应用凭证,服务器IP地址一定要先加入服务商的IP白明达中,否则验证失败。 /// /// public static Dictionary getSuitAccessToken_S() { //获取第三方应用凭证,获得suite_access_token以获取预授权码 IDictionary parameters = new Dictionary(); parameters.Add("suite_id", HttpUtility.UrlEncode(BP.Cloud.WeXinAPI.Glo.SuiteID));//应用suiteId parameters.Add("suite_secret", HttpUtility.UrlEncode(BP.Cloud.WeXinAPI.Glo.SuiteID_Secret));//应用suiteSecret parameters.Add("suite_ticket", BP.Cloud.WeXinAPI.Glo.Suite_ticket);//suite_ticket string suiteUrl = "https://qyapi.weixin.qq.com/cgi-bin/service/get_suite_token"; //根据参数:获得资源. string res = Glo.HttpWebResponseUtility.HttpResponsePost_Json(suiteUrl, JsonConvert.SerializeObject(parameters)); Dictionary dd = res.Trim(new char[] { '{', '}' }).Split(',').ToDictionary(s => s.Split(':')[0].Trim('"'), s => (object)s.Split(':')[1].Trim('"')); return dd; } /// /// 获取预授权码 /// 该API用于获取预授权码。预授权码用于企业授权时的第三方服务商安全验证。 /// /// public static void getPreAuthCode() { //获取第三方应用凭证 string suitAccessToken = getSuitAccessToken(); if (string.IsNullOrEmpty(suitAccessToken)) return; string yuUrl = "https://qyapi.weixin.qq.com/cgi-bin/service/get_pre_auth_code?suite_access_token=" + suitAccessToken; string res = Glo.HttpWebResponseUtility.HttpResponseGet(yuUrl); Dictionary dd = res.Trim(new char[] { '{', '}' }).Split(',').ToDictionary(s => s.Split(':')[0].Trim('"'), s => (object)s.Split(':')[1].Trim('"')); string preAuthCode = (string)dd["pre_auth_code"]; if (string.IsNullOrEmpty(preAuthCode)) { return; } //设置授权配置,该接口可对某次授权进行配置。可支持测试模式(应用未发布时)。 string resS = setSessionInfo(suitAccessToken, preAuthCode); Dictionary ddresS = resS.Trim(new char[] { '{', '}' }).Split(',').ToDictionary(s => s.Split(':')[0].Trim('"'), s => (object)s.Split(':')[1].Trim('"')); string errcode = (string)ddresS["errcode"]; if (!errcode.Equals("0")) { return; } } /// ///设置授权配置 ///该接口可对某次授权进行配置。可支持测试模式(应用未发布时)。 ///请求方式:POST(HTTPS) ///请求地址: https://qyapi.weixin.qq.com/cgi-bin/service/set_session_info?suite_access_token=SUITE_ACCESS_TOKEN /// public static string setSessionInfo(string suitAccessToken, string preAuthCode) { string url = "https://qyapi.weixin.qq.com/cgi-bin/service/set_session_info?suite_access_token=" + suitAccessToken; string parameters = "{\"pre_auth_code\":\"" + preAuthCode + "\",\"session_info\":{\"appid\":[],\"auth_type\":0}}"; string res = Glo.HttpWebResponseUtility.HttpResponsePost_Json(url, parameters); return res; } /// /// 获取企业凭证 第三方服务商在取得企业的永久授权码后,通过此接口可以获取到企业的access_token。 ///获取后可通过通讯录、应用、消息等企业接口来运营这些应用。 /// /// public static string getAccessToken(BP.Cloud.Org org, string permanentCode) { //获取第三方应用凭证 string suitAccessToken = getSuitAccessToken(); // string permanentCode = CreateOrg();//获取永久授权码 IDictionary parameters = new Dictionary(); parameters.Add("auth_corpid", org.CorpID);//授权方corpid parameters.Add("permanent_code", permanentCode);//永久授权码,通过get_permanent_code获取 string accessTokenUrl = "https://qyapi.weixin.qq.com/cgi-bin/service/get_corp_token?suite_access_token=" + suitAccessToken; string res = Glo.HttpWebResponseUtility.HttpResponsePost_Json(accessTokenUrl, JsonConvert.SerializeObject(parameters)); Dictionary dd = res.Trim(new char[] { '{', '}' }).Split(',').ToDictionary(s => s.Split(':')[0].Trim('"'), s => (object)s.Split(':')[1].Trim('"')); string accessToken = (string)dd["access_token"];//授权方(企业)access_token,最长为512字节 string expires_in = (string)dd["expires_in"]; DateTime ss = DateTime.Now.AddSeconds(double.Parse(expires_in)); //更新accessToken到org表中 //BP.Cloud.Org org = new BP.Cloud.Org(corpid); org.AccessToken = accessToken; org.AccessTokenExpiresIn = ss.ToString("yyyy-MM-dd HH:mm:ss"); //org.Update(); return accessToken; } /// /// 组装安装授权页连接地址 /// public static string getInstallUr() { //获取第三方应用凭证 string suitAccessToken = getSuitAccessToken(); if (string.IsNullOrEmpty(suitAccessToken)) { return ""; } string yuUrl = "https://qyapi.weixin.qq.com/cgi-bin/service/get_pre_auth_code?suite_access_token=" + suitAccessToken; string res = Glo.HttpWebResponseUtility.HttpResponseGet(yuUrl); Dictionary dd = res.Trim(new char[] { '{', '}' }).Split(',').ToDictionary(s => s.Split(':')[0].Trim('"'), s => (object)s.Split(':')[1].Trim('"')); string preAuthCode = (string)dd["pre_auth_code"]; if (string.IsNullOrEmpty(preAuthCode)) { return ""; } //设置授权配置,该接口可对某次授权进行配置。可支持测试模式(应用未发布时)。 string resS = setSessionInfo(suitAccessToken, preAuthCode); Dictionary ddresS = resS.Trim(new char[] { '{', '}' }).Split(',').ToDictionary(s => s.Split(':')[0].Trim('"'), s => (object)s.Split(':')[1].Trim('"')); string errcode = (string)ddresS["errcode"]; if (!errcode.Equals("0")) { return ""; } string redirect_uri = HttpUtility.UrlEncode(Glo.Domain + "WeChat/CallReg.aspx"); //跳转链接中,第三方服务商需提供suite_id、预授权码、授权完成回调URI和state参数。其中redirect_uri是授权完成后的回调网址,redirect_uri需要经过一次urlencode作为参数;state可填a - zA - Z0 - 9的参数值(不超过128个字节),用于第三方自行校验session,防止跨域攻击。 string urlInstall = "https://open.work.weixin.qq.com/3rdapp/install?suite_id=" + Glo.SuiteID + "&pre_auth_code=" + preAuthCode + "&redirect_uri=" + redirect_uri + "&state=1"; return urlInstall; } /// /// 获取相应子节点的值 /// /// public static string JSON_SeleteNode(JToken json, string ReName) { try { string result = ""; if (json == null) { return result; } //这里6.0版块可以用正则匹配 var node = json.SelectToken("$.." + ReName); if (node != null) { //判断节点类型 if (node.Type == JTokenType.String || node.Type == JTokenType.Integer || node.Type == JTokenType.Float) { //返回string值 result = node.Value().ToString(); } if (node.Type == JTokenType.Object) { result = node.Value().ToString(); } } return result; } catch (Exception ex) { return ""; } } public static JToken ReadJSON(string jsonStr) { if (string.IsNullOrEmpty(jsonStr)) { return null; } JObject jobj = JObject.Parse(jsonStr); JToken result = jobj as JToken; return result; } /// /// 应用提供商的provider_access_token /// /// public static string getProviderAccessToken() { string provider_access_token = ""; IDictionary parameters = new Dictionary(); parameters.Add("corpid", BP.Cloud.WeXinAPI.Glo.CorpID); parameters.Add("provider_secret", BP.Cloud.WeXinAPI.Glo.ProviderSecret); string url = "https://qyapi.weixin.qq.com/cgi-bin/service/get_provider_token"; //获得返回的数据. string res = Glo.HttpWebResponseUtility.HttpResponsePost_Json(url, JsonConvert.SerializeObject(parameters)); Dictionary ddresS = res.Trim(new char[] { '{', '}' }).Split(',').ToDictionary(s => s.Split(':')[0].Trim('"'), s => (object)s.Split(':')[1].Trim('"')); /*string errcode = (string)ddresS["errcode"]; if (!errcode.Equals("0")) { return ""; }*/ provider_access_token = (string)ddresS["provider_access_token"];//授权方(企业)access_token,最长为512字节 string expires_in = (string)ddresS["expires_in"]; return provider_access_token; } /// /// /// 获取永久授权码 /// 引导用户进入授权页 ///用户确认授权后,会进入回调URI(即redirect_uri),并在URI参数中带上临时授权码、过期时间以及state参数。第三方服务商据此获得临时授权码 ///redirect_uri?auth_code=xxx&expires_in=600&state=xx /// /// public static string InstallIt(string authCode) { //获取第三方应用凭证 string suitAccessToken = getSuitAccessToken(); IDictionary parameters = new Dictionary(); parameters.Add("auth_code", authCode);//临时授权码 string codeUrl = "https://qyapi.weixin.qq.com/cgi-bin/service/get_permanent_code?suite_access_token=" + suitAccessToken; //获得返回的数据. string res = Glo.HttpWebResponseUtility.HttpResponsePost_Json(codeUrl, JsonConvert.SerializeObject(parameters)); //获取企业新信息,插入数据库 //解析返回的json串 JObject jobj = JObject.Parse(res); JToken resJtoken = jobj as JToken; //把数据写入log. string errcode = Glo.JSON_SeleteNode(resJtoken, "errcode"); if (string.IsNullOrEmpty(errcode) == false && errcode.Equals("0") == false) { return "err@获取永久授权码错误,错误码为:" + errcode; } string permanentCode = Glo.JSON_SeleteNode(resJtoken, "permanent_code"); //授权方(企业)access_token string accessToken = Glo.JSON_SeleteNode(resJtoken, "access_token"); #region 企业信息 string authCorpInfo = Glo.JSON_SeleteNode(resJtoken, "auth_corp_info"); JToken authCorpInfoJtoken = Glo.ReadJSON(authCorpInfo); string corpId = Glo.JSON_SeleteNode(authCorpInfoJtoken, "corpid"); //授权方企业微信id string CorpSquareLogoUrl = Glo.JSON_SeleteNode(authCorpInfoJtoken, "corp_square_logo_url");//授权方企业方形头像 SaveImgByUrl(CorpSquareLogoUrl, BP.Difference.SystemConfig.PathOfDataUser + "ICONOrg/", corpId + "_CorpSquareLogo.png");//上传头像 string CorpRoundLogoUrl = Glo.JSON_SeleteNode(authCorpInfoJtoken, "corp_round_logo_url");//授权方企业圆形头像 SaveImgByUrl(CorpRoundLogoUrl, BP.Difference.SystemConfig.PathOfDataUser + "ICONOrg/", corpId + "_CorpRoundLogo.png");//上传头像 #endregion BP.Web.WebUser.No = "admin"; BP.Web.WebUser.Name = "admin"; BP.Web.WebUser.FK_Dept = "100"; BP.Web.WebUser.OrgNo = "ccs"; BP.Cloud.Org org = new BP.Cloud.Org(); //执行登录. // BP.WF.Dev2Interface.Port_Login("admin", "", "ccs"); //写入到 Port_Org org = Insert_Port_Org(org, authCorpInfoJtoken, corpId, permanentCode, accessToken); #region 授权信息。如果是通讯录应用,且没开启实体应用,是没有该项的。通讯录应用拥有企业通讯录的全部信息读写权限 string authInfo = Glo.JSON_SeleteNode(resJtoken, "auth_info"); JToken authInfoJtoken = Glo.ReadJSON(authInfo); //授权的应用信息,注意是一个数组,但仅旧的多应用套件授权时会返回多个agent,对新的单应用授权,永远只返回一个agent string agentid = Glo.JSON_SeleteNode(authInfoJtoken, "agentid");//授权方应用id org.AgentId = agentid; org.AgentName = Glo.JSON_SeleteNode(authInfoJtoken, "name");//授权方应用名字 //保存img 的 log 数据. string SquareLogoUrl = Glo.JSON_SeleteNode(authInfoJtoken, "square_logo_url");//授权方应用方形头像 SaveImgByUrl(SquareLogoUrl, BP.Difference.SystemConfig.PathOfDataUser + "ICONOrg/", corpId + "_SquareLogo.png");//上传头像 string RoundLogoUrl = Glo.JSON_SeleteNode(authInfoJtoken, "round_logo_url");//授权方应用圆形头像 SaveImgByUrl(RoundLogoUrl, BP.Difference.SystemConfig.PathOfDataUser + "ICONOrg/", corpId + "_RoundLogo.png");//上传头像 #endregion //获取应用的管理员列表 InsertPort_OrgAdminer(corpId, agentid, suitAccessToken, org); //获取企业凭证 第三方服务商在取得企业的永久授权码后,通过此接口可以获取到企业的access_token。更新org表 getAccessToken(org, permanentCode); //更新企业信息. org.Update(); //获取部门列表,插入数据库. createDept(org, permanentCode); //检查是否有部门跟目录,没有就增加一个. Glo2021.Install_CheckHaveDeptRoot(org, authInfoJtoken); //把数据同步到中心库. DTS_Data_Passport(org, "", "", ""); //执行登出.. BP.WF.Dev2Interface.Port_SigOut(); //获取人员信息,插入数据库. return permanentCode; } /// /// 同步到用户中心库. /// /// 组织编号 /// 注册人 public static void DTS_Data_Passport(Org org, string urlFrom, string userNo, string userName) { //定义一个数据容器. DataSet ds = new DataSet(); ds.Tables.Add(org.ToDataTableField("Port_Org")); Emps emps = new Emps(); emps.Retrieve(DeptAttr.OrgNo, org.No); ds.Tables.Add(emps.ToDataTableField("Port_Emp")); Depts depts = new Depts(); depts.Retrieve(DeptAttr.OrgNo, org.No); ds.Tables.Add(depts.ToDataTableField("Port_Dept")); //DeptEmps des = new DeptEmps(); //des.Retrieve(DeptAttr.OrgNo, orgNo); //ds.Tables.Add(des.ToDataTableField("Port_DeptEmp")); //管理员. BP.WF.Port.Admin2Group.OrgAdminers oas = new BP.WF.Port.Admin2Group.OrgAdminers(); oas.Retrieve(DeptAttr.OrgNo, org.No); ds.Tables.Add(oas.ToDataTableField("Port_OrgAdminer")); #region 把数据注册到用户中心. string paras = "&CurrDB=" + BP.Difference.SystemConfig.AppSettings["CurrDB"]; paras += "&UserNo=" + userNo; paras += "&UrlFrom=" + urlFrom; paras += "&UserName=" + userName; paras += "&MM=11"; string json = BP.Tools.Json.ToJson(ds); string data = PassportDoWhat("QYWX_Create", paras, json); if (data.IndexOf("err@") == 0) throw new Exception("err@写入组织信息到中心库失败:" + data); #endregion 把数据注册到用户中心. } /// /// 让用户登陆u. /// /// /// /// public static string LetQYWXUserLogin(string userNo, string corpID) { string data = PassportDoWhat("LetQYWXUserLogin", "&UserNo=" + userNo + "&CorpID=" + corpID, null); return data; } public static string PassportDoWhat(string doWhat, string paras, string json) { string url = "http://passport." + BP.Cloud.Glo.SaasHost + "/Handler.ashx?DoType=" + doWhat + paras + "&t=" + DBAccess.GenerGUID(); if (json == null) return DataType.ReadURLContext(url); string data = BP.WF.Glo.HttpPostConnect(url, json); return data; //if (data.IndexOf("err@") == 0) // throw new Exception("err@写入组织信息到中心库失败:" + data); } /// 获得部门数据. /// /// 组织实体 /// 永久授权码 public static void createDept(BP.Cloud.Org org, string permanentCode) { //如果AccessToken接近失效,要重新获取,更新. if (DataType.IsNullOrEmpty(org.AccessTokenExpiresIn) == false && DateTime.Compare(Convert.ToDateTime(DateTime.Now), Convert.ToDateTime(org.AccessTokenExpiresIn)) > 0) { //如果失效了,就直接更新一下. org.AccessToken = getAccessToken(org, permanentCode);//获取企业凭证,更新失效时间 } //获得部门数据. string yuUrl = "https://qyapi.weixin.qq.com/cgi-bin/department/list?access_token=" + org.AccessToken + "&id="; string res = Glo.HttpWebResponseUtility.HttpResponseGet(yuUrl); //解析或得到的资源. Newtonsoft.Json.Linq.JObject jObject = Newtonsoft.Json.Linq.JObject.Parse(res); Newtonsoft.Json.Linq.JArray jArray = Newtonsoft.Json.Linq.JArray.Parse(jObject.SelectToken("department").ToString()); //插入部门信息? foreach (Newtonsoft.Json.Linq.JToken item in jArray.Children()) { string id = item["id"].ToString();//部门ID string name = item["name"].ToString(); string parentid = org.No + "_" + item["parentid"].ToString(); string order = item["order"].ToString(); //写入Port_Dept #region 开始同步部门信息. BP.Cloud.Dept deptRoot = new BP.Cloud.Dept(); deptRoot.No = org.No + "_" + id; deptRoot.Name = name; deptRoot.ParentNo = parentid; deptRoot.OrgNo = org.No; deptRoot.RefID = item["id"].ToString(); deptRoot.RefParentID = item["parentid"].ToString(); //如果是根目录. if (deptRoot.RefParentID.Equals("0") == true) { deptRoot.ParentNo = "100"; deptRoot.Name = org.Name; deptRoot.NameOfPath = org.Name; deptRoot.No = org.No; } //如果是二级部门,其他级别的部门就不处理了. if (deptRoot.RefParentID.Equals("1") == true) deptRoot.ParentNo = org.No; deptRoot.Insert(); //获得部门下人员信息,写入人员表. CreateEmp(org, id, deptRoot); #endregion 开始同步部门信息. //取得标签信息 createTag(org); //递归数据. // CreateDeptDiGui(item, org); } } /// /// 获得部门下人员信息,写入人员表 /// /// public static string CreateEmp(BP.Cloud.Org org, string id, BP.Cloud.Dept dept) { //构造url。 string url = "https://qyapi.weixin.qq.com/cgi-bin/user/list?access_token=" + org.AccessToken + "&department_id=" + id + "&fetch_child=0"; string res = DataType.ReadURLContext(url); //httpWebResponseUtility.HttpResponseGet(yuUrl); //解析资源. Newtonsoft.Json.Linq.JObject jObject = Newtonsoft.Json.Linq.JObject.Parse(res); Newtonsoft.Json.Linq.JArray jArray = Newtonsoft.Json.Linq.JArray.Parse(jObject.SelectToken("userlist").ToString()); foreach (Newtonsoft.Json.Linq.JToken item in jArray.Children()) { string main_department = item["main_department"].ToString();//主部门 /* string sql = "SELECT No FROM Port_Dept WHERE RefID='" + main_department + "' AND OrgNo='" + org.No + "'"; string mainDeptStr = DBAccess.RunSQLReturnStringIsNull(sql, null); */ //插入Port_Emp中 BP.Cloud.EmpWX emp = new BP.Cloud.EmpWX(); emp.No = org.No + "_" + item["userid"].ToString(); //人员ID //open_userid全局唯一。对于同一个服务商,不同应用获取到企业内同一个成员的open_userid是相同的,最多64个字节。仅第三方应用可获取 emp.OpenID = item["open_userid"].ToString(); if (emp.RetrieveFromDBSources() == 0) { emp.Name = item["name"].ToString(); emp.UserID = item["userid"].ToString(); emp.FK_Dept = org.No + "_" + main_department; //如果主部门是部门的根目录. if (main_department.Equals("1") == true) { emp.FK_Dept = org.No; } emp.OrgNo = org.No; emp.Insert(); //处理多个部门. string deptStrs = item["department"].ToString(); deptStrs = deptStrs.Replace("[", ""); deptStrs = deptStrs.Replace("]", ""); string[] strs = deptStrs.Split(','); //处理一下分割. foreach (string str in strs) { string deptNo = str.Replace("\r\n ", ""); if (DataType.IsNullOrEmpty(deptNo) == true) continue; //找到真实的部门编号. /*sql = "SELECT No FROM Port_Dept WHERE RefID='" + str + "' AND OrgNo='" + org.No + "'"; string deptNo = DBAccess.RunSQLReturnStringIsNull(sql, null); if (deptNo == null) continue; //说明部门不存在,不应该出现的问题. */ DeptEmp de = new DeptEmp(); //如果是根目录. if (deptNo.Trim().Equals("1") == true) { de.FK_Dept = org.No; } else { de.FK_Dept = org.No + "_" + deptNo.Trim(); } de.FK_Emp = emp.UserID; //使用userID. de.setMyPK(org.No + "_" + deptNo.Trim() + "_" + de.FK_Emp); de.OrgNo = org.No; //组织信息. // de.EmpNo = emp.No; de.Insert(); } } } return ""; } /// /// 取得标签列表 /// public static void createTag(BP.Cloud.Org org) { //构造url。 string url = "https://qyapi.weixin.qq.com/cgi-bin/tag/list?access_token=" + org.AccessToken; string res = DataType.ReadURLContext(url); //httpWebResponseUtility.HttpResponseGet(yuUrl); //解析资源. Newtonsoft.Json.Linq.JObject jObject = Newtonsoft.Json.Linq.JObject.Parse(res); //标签列表 Newtonsoft.Json.Linq.JArray jArray = Newtonsoft.Json.Linq.JArray.Parse(jObject.SelectToken("taglist").ToString()); foreach (Newtonsoft.Json.Linq.JToken item in jArray.Children()) { string tagid = item["tagid"].ToString();//标签id string tagname = item["tagname"].ToString();//标签名 //根据标签id取得下属人员 getTagEmp(org.AccessToken, tagid); } } /// /// /// public static void getTagEmp(string accessToken, string tagid) { //构造url。 string url = "https://qyapi.weixin.qq.com/cgi-bin/tag/get?access_token=" + accessToken + "&tagid=" + tagid; string res = DataType.ReadURLContext(url); //httpWebResponseUtility.HttpResponseGet(yuUrl); //解析资源. Newtonsoft.Json.Linq.JObject jObject = Newtonsoft.Json.Linq.JObject.Parse(res); //标签下人员列表 Newtonsoft.Json.Linq.JArray jArray = Newtonsoft.Json.Linq.JArray.Parse(jObject.SelectToken("userlist").ToString()); foreach (Newtonsoft.Json.Linq.JToken item in jArray.Children()) { string userid = item["userid"].ToString();//成员帐号 string name = item["name"].ToString();//成员名称,此字段从2019年12月30日起,对新创建第三方应用不再返回,2020年6月30日起,对所有历史第三方应用不再返回,后续第三方仅通讯录应用可获取,第三方页面需要通过通讯录展示组件来展示名字 string partylist = item["partylist"].ToString();//标签中包含的部门id列表 TeamEmp teamEmp = new TeamEmp(); teamEmp.FK_Emp = userid; teamEmp.FK_Team = tagid; teamEmp.Insert(); } } /// /// 判断是否选择了部门 /// /// /// public static string Install_CheckHaveDeptRoot(Org org, JToken authInfoJtoken) { BP.Cloud.Depts depts = new BP.Cloud.Depts(); depts.Retrieve("OrgNo", org.No); if (depts.Count == 0) { //插入部门做root. BP.Cloud.Dept dept = new BP.Cloud.Dept(); dept.No = org.No; dept.Name = org.Name; dept.ParentNo = "100"; dept.OrgNo = org.No; dept.Insert(); } //d定义变量.. BP.Cloud.Emp emp = new BP.Cloud.Emp(); //增加管理员. BP.WF.Port.Admin2Group.OrgAdminers admins = new BP.WF.Port.Admin2Group.OrgAdminers(); admins.Retrieve("OrgNo", org.No); foreach (BP.WF.Port.Admin2Group.OrgAdminer admin in admins) { if (emp.IsExit("OrgNo", org.No, "UserID", admin.FK_Emp) == true) continue; emp.FK_Dept = org.No; emp.Name = admin.FK_Emp; emp.No = admin.FK_Emp; /* if (DataType.IsMobile(emp.No) == true) emp.No = emp.No; else*/ emp.No = org.No + "_" + emp.No; emp.UserID = admin.FK_Emp; emp.OrgNo = org.No; //获得OpenID. string openID = GetOpenIDByUserID(org.AccessToken, emp.UserID); if (openID != null) emp.OpenID = openID; emp.Insert(); //给他分配部门. DeptEmp de = new DeptEmp(); de.OrgNo = emp.OrgNo; de.FK_Dept = emp.FK_Dept; de.FK_Emp = emp.UserID; de.setMyPK(emp.FK_Dept + "_" + de.FK_Emp); // de.EmpNo = emp.No; de.Save(); } //把管理员,获得范围内人员. string privilege = Glo.JSON_SeleteNode(authInfoJtoken, "privilege");//应用对应的权限 //应用可见范围(成员) Newtonsoft.Json.Linq.JObject jObject = Newtonsoft.Json.Linq.JObject.Parse(privilege); Newtonsoft.Json.Linq.JArray jArray = Newtonsoft.Json.Linq.JArray.Parse(jObject.SelectToken("allow_user").ToString()); foreach (Newtonsoft.Json.Linq.JToken token in jArray.Children()) { string empNo = token.ToString(); if (emp.IsExit("OrgNo", org.No, "UserID", empNo) == true) continue; emp.No = empNo; emp.UserID = empNo; emp.FK_Dept = org.No; emp.Name = empNo; if (DataType.IsMobile(emp.No) == true) { emp.No = empNo; emp.Tel = empNo; } else { emp.No = org.No + "_" + empNo; } emp.OrgNo = org.No; //获得OpenID. string openID = GetOpenIDByUserID(org.AccessToken, emp.UserID); if (openID != null) emp.OpenID = openID; emp.Insert(); //给他分配部门. DeptEmp de = new DeptEmp(); de.OrgNo = emp.OrgNo; de.FK_Dept = emp.FK_Dept; de.FK_Emp = emp.No; de.setMyPK(emp.FK_Dept + "_" + de.FK_Emp); // de.EmpNo = emp.No; de.Insert(); } return "检查成功."; } /// /// 根据userid获取企业微信openid /// 如果有权限问题,就获取不到。 /// /// /// /// public static string GetOpenIDByUserID(string tooken, string userID) { //根据uiserID,获得openID. IDictionary parametersAdm = new Dictionary(); parametersAdm.Add("userid", HttpUtility.UrlEncode(userID)); string url = "https://qyapi.weixin.qq.com/cgi-bin/user/convert_to_openid?access_token=" + tooken; string docs = HttpWebResponseUtility.HttpResponsePost_Json(url, JsonConvert.SerializeObject(parametersAdm)); Dictionary dd = docs.Trim(new char[] { '{', '}' }).Split(',').ToDictionary(s => s.Split(':')[0].Trim('"'), s => (object)s.Split(':')[1].Trim('"')); string code = (string)dd["errcode"]; if (code.Equals("0") == true) { string str = (string)dd["openid"]; return str; } return null; } /// /// 通讯录变更中用户新增事件 /// /// /// /// public static string changeConCreateUser(XmlDocument xd, Org org) { string userID = xd.FirstChild["UserID"].InnerText;//成员UserID、变更信息的成员UserID string Name = xd.FirstChild["Name"].InnerText;//成员名称。2020年6月30日起,对所有历史第三方应用不再返回真实name,使用userid代替name,后续第三方仅通讯录应用可获取,第三方页面需要通过通讯录展示组件来展示名字 string Department = xd.FirstChild["Department"].InnerText;//更新后成员所在部门列表,仅返回该应用有查看权限的部门id string MainDepartment = xd.FirstChild["MainDepartment"].InnerText;//主部门 string strUserID = userID; if (BP.DA.DataType.IsMobile(userID) == false) strUserID = org.No + "_" + userID; //创建用户. BP.Cloud.Emp emp = new BP.Cloud.Emp(); emp.No = strUserID; if (emp.RetrieveFromDBSources() == 0) { emp.Name = userID; emp.UserID = userID; //处理多个部门. string deptStrs = Department; deptStrs = deptStrs.Replace("[", ""); deptStrs = deptStrs.Replace("]", ""); string[] strs = deptStrs.Split(','); //处理一下分割. foreach (string str in strs) { if (DataType.IsNullOrEmpty(str) == true) continue; DeptEmp de = new DeptEmp(); de.FK_Dept = org.No + "_" + str; de.FK_Emp = emp.No; de.setMyPK(de.FK_Dept + "_" + de.FK_Emp); de.OrgNo = org.No; //组织信息. de.Insert(); } emp.FK_Dept = org.No + "_" + MainDepartment; emp.OrgNo = org.No; emp.Insert(); } else { //处理多个部门. string deptStrs = Department; deptStrs = deptStrs.Replace("[", ""); deptStrs = deptStrs.Replace("]", ""); string[] strs = deptStrs.Split(','); //处理一下分割. foreach (string str in strs) { if (DataType.IsNullOrEmpty(str) == true) continue; DeptEmp de = new DeptEmp(); de.FK_Dept = org.No + "_" + str; de.FK_Emp = emp.No; de.setMyPK(de.FK_Dept + "_" + de.FK_Emp); de.OrgNo = org.No; //组织信息. de.Insert(); } emp.FK_Dept = org.No + "_" + MainDepartment; emp.OrgNo = org.No; emp.Update(); } return "用户[" + emp.Name + "]新增成功."; } /// /// 通讯录变更中用户变更事件 /// /// /// public static string changeConUpdateUser(XmlDocument xd, Org org) { string userID = xd.FirstChild["UserID"].InnerText;//成员UserID、变更信息的成员UserID string newUserID = "";//新的UserID,变更时推送(userid由系统生成时可更改一次) if (xd.FirstChild["NewUserID"] == null) newUserID = userID; else newUserID = xd.FirstChild["NewUserID"].InnerText; //创建en. BP.Cloud.Emp emp = new BP.Cloud.Emp(); //说明:主键ID, 没有变化. if (userID.Equals(newUserID) == true) { //是一个手机号. if (BP.DA.DataType.IsMobile(userID) == true) { emp.No = userID; } else emp.No = org.No + "_" + userID; //组合主键. int num = emp.RetrieveFromDBSources(); //从数据库把他查询出来. if (num == 0) { emp.Name = userID; emp.Insert(); //不应该出现的情况. } } //主键ID,变化了. if (userID.Equals(newUserID) == false) { string strNewUserID = newUserID; if (BP.DA.DataType.IsMobile(newUserID) == false) strNewUserID = org.No + "_" + newUserID; string strUserID = userID; if (BP.DA.DataType.IsMobile(userID) == false) strUserID = org.No + "_" + userID; //修改主键. string sql = "UPDATE Port_Emp SET No='" + strNewUserID + "' WHERE No='" + strUserID + "' AND OrgNo='" + org.No + "' "; DBAccess.RunSQL(sql); emp.No = strNewUserID; emp.RetrieveFromDBSources(); } //string Name = xd.FirstChild["Name"].InnerText;//成员名称。2020年6月30日起,对所有历史第三方应用不再返回真实name,使用userid代替name,后续第三方仅通讯录应用可获取,第三方页面需要通过通讯录展示组件来展示名字 string Department = xd.FirstChild["Department"].InnerText;//更新后成员所在部门列表,仅返回该应用有查看权限的部门id string MainDepartment = xd.FirstChild["MainDepartment"].InnerText;//主部门 //处理多个部门. string deptStrs = Department; deptStrs = deptStrs.Replace("[", ""); deptStrs = deptStrs.Replace("]", ""); string[] strs = deptStrs.Split(','); //处理一下分割. foreach (string str in strs) { if (DataType.IsNullOrEmpty(str) == true) continue; DeptEmp de = new DeptEmp(); de.FK_Dept = org.No + "_" + str; de.FK_Emp = emp.No; de.setMyPK(de.FK_Dept + "_" + de.FK_Emp); de.OrgNo = org.No; //组织信息. de.Update(); } emp.FK_Dept = org.No + "_" + MainDepartment; emp.OrgNo = org.No; emp.Update(); return "更新[" + emp.No + "]成功."; } /// /// 通讯录变更中用户删除事件 /// /// /// public static string changeConDeleteUser(XmlDocument xd, Org org) { string userID = xd.FirstChild["UserID"].InnerText;//成员UserID、变更信息的成员UserID if (BP.DA.DataType.IsMobile(userID) == false) userID = org.No + "_" + userID; BP.Cloud.Emp emp = new BP.Cloud.Emp(); emp.No = userID; //人员ID if (emp.RetrieveFromDBSources() != 0) emp.Delete(); //删除部门对应关系. DeptEmps des = new DeptEmps(); des.Delete("FK_Emp", emp.UserID, "OrgNo", org.No); //删除部门角色对应关系. DeptEmpStations dess = new DeptEmpStations(); dess.Delete("FK_Emp", emp.UserID, "OrgNo", org.No); return "删除[" + emp.No + "]成功."; } /// /// 通讯录变更中部门新增事件 /// /// /// public static string changeConCreateDept(XmlDocument xd, Org org) { string id = xd.FirstChild["Id"].InnerText;//部门Id string Name = xd.FirstChild["Name"].InnerText;//部门名称,此字段从2019年12月30日起,对新创建第三方应用不再返回,2020年6月30日起,对所有历史第三方应用不再返回真实Name字段,使用Id字段代替Name字段,后续第三方仅通讯录应用可获取,第三方页面需要通过通讯录展示组件来展示名字 string parentId = xd.FirstChild["ParentId"].InnerText;//父部门id if (parentId.Equals("0") == true) { parentId = "100"; id = org.No; } else { parentId = org.No + "_" + parentId; id = org.No + "_" + id; } string idx = xd.FirstChild["Order"].InnerText;//部门排序 BP.Cloud.Dept dept = new BP.Cloud.Dept(); dept.No = id; if (dept.RetrieveFromDBSources() == 0) { dept.Name = xd.FirstChild["Id"].InnerText; //1,2,3的ID. dept.ParentNo = parentId; dept.OrgNo = org.No; dept.Idx = int.Parse(idx); //关联的父部门. dept.RefParentID = xd.FirstChild["ParentId"].InnerText;//父部门id dept.Insert(); } else { dept.ParentNo = parentId; dept.OrgNo = org.No; dept.Idx = int.Parse(idx); //关联的父部门. dept.RefParentID = xd.FirstChild["ParentId"].InnerText;//父部门id dept.Update(); } return "创建部门[" + dept.No + "]成功."; } /// /// 通讯录变更中部门修改事件 /// /// /// public static string changeConUpdateDept(XmlDocument xd, Org org) { string id = xd.FirstChild["Id"].InnerText;//部门Id string parentId = xd.FirstChild["ParentId"].InnerText;//父部门id if (parentId.Equals("0") == true) { parentId = "100"; id = org.No; } else { parentId = org.No + "_" + parentId; id = org.No + "_" + id; } string idx = xd.FirstChild["Order"].InnerText;//部门排序 BP.Cloud.Dept dept = new BP.Cloud.Dept(); dept.No = id; if (dept.RetrieveFromDBSources() != 0) { dept.ParentNo = parentId; dept.OrgNo = org.No; dept.Idx = int.Parse(idx); //关联的父部门. dept.RefParentID = xd.FirstChild["ParentId"].InnerText;//父部门id dept.Update(); } return "修改部门[" + dept.No + "]成功."; } /// /// 通讯录变更中部门删除事件 /// /// /// public static string changeConDelDept(XmlDocument xd, Org org) { string id = xd.FirstChild["Id"].InnerText;//部门Id string parentId = xd.FirstChild["ParentId"].InnerText;//父部门id if (parentId.Equals("0") == true) { parentId = "100"; id = org.No; } else { parentId = org.No + "_" + parentId; id = org.No + "_" + id; } BP.Cloud.Dept dept = new BP.Cloud.Dept(); dept.No = id; dept.Delete(); return "删除部门[" + dept.No + "]成功."; } /// /// 保存文件 /// /// url路径 /// 保存到目录 /// 保存的文件名 public static void SaveImgByUrl(string url, string saveToDir, string fileName) { if (string.IsNullOrEmpty(url)) return; WebRequest imgRequest = WebRequest.Create(url); HttpWebResponse res; try { res = (HttpWebResponse)imgRequest.GetResponse(); } catch (WebException ex) { res = (HttpWebResponse)ex.Response; } if (res.StatusCode.ToString() == "OK") { System.Drawing.Image downImage = System.Drawing.Image.FromStream(imgRequest.GetResponse().GetResponseStream()); if (!System.IO.Directory.Exists(saveToDir)) { System.IO.Directory.CreateDirectory(saveToDir); } downImage.Save(saveToDir + fileName); downImage.Dispose(); } } /// /// 编辑org信息写入 /// /// /// /// /// /// public static Org Insert_Port_Org(Org org, JToken authCorpInfoJtoken, string corpId, string permanentCode, string accessToken) { string url = "http://passport." + BP.Cloud.Glo.SaasHost + "/Handler.ashx?DoWhat=GenerQYWXOrgNo&CorpID=" + corpId; string orgNo = DataType.ReadURLContext(url, 90000); //判断是否注册过,如果注册过,就把它删除掉. int i = org.Retrieve(BP.Cloud.OrgAttr.CorpID, corpId); if (i == 1) org.DoDelete(); //微信状态是使用中. org.WXUseSta = 1; //来源:微信 org.RegFrom = 1; //赋值名称. org.Name = Glo.JSON_SeleteNode(authCorpInfoJtoken, "corp_name"); //授权方企业名称,即企业简称 org.NameFull = Glo.JSON_SeleteNode(authCorpInfoJtoken, "corp_full_name"); //授权方企业的主体名称(仅认证或验证过的企业有),即企业全称。 if (DataType.IsNullOrEmpty(org.NameFull) == true) org.NameFull = org.Name; //首先按照组织的简称计算. org.CorpID = corpId;//授权方企业微信id // org.Name = JSON_SeleteNode(authCorpInfoJtoken, "corp_name"); //授权方企业名称,即企业简称 // org.NameFull = JSON_SeleteNode(authCorpInfoJtoken, "corp_full_name"); //授权方企业的主体名称(仅认证或验证过的企业有),即企业全称。 org.Addr = Glo.JSON_SeleteNode(authCorpInfoJtoken, "location");//企业所在地信息, 为空时表示未知 org.PermanentCode = permanentCode; //永久授权码. org.AccessToken = accessToken; org.CorpUserMax = Glo.JSON_SeleteNode(authCorpInfoJtoken, "corp_user_max");//授权方企业用户规模 org.CorpAgentMax = Glo.JSON_SeleteNode(authCorpInfoJtoken, "corp_agent_max");//授权方企业应用数上限 org.CorpFullName = Glo.JSON_SeleteNode(authCorpInfoJtoken, "corp_full_name");//授权方企业的主体名称 org.SubjectType = Glo.JSON_SeleteNode(authCorpInfoJtoken, "subject_type");//企业类型,1. 企业; 2. 政府以及事业单位; 3. 其他组织, 4.团队号 org.VerifiedEndTime = Glo.JSON_SeleteNode(authCorpInfoJtoken, "verified_end_time");//认证到期时间 org.CorpScale = Glo.JSON_SeleteNode(authCorpInfoJtoken, "corp_scale");//企业规模。当企业未设置该属性时,值为空 org.CorpIndustry = Glo.JSON_SeleteNode(authCorpInfoJtoken, "corp_industry");//企业所属行业。当企业未设置该属性时,值为空 org.CorpSubIndustry = Glo.JSON_SeleteNode(authCorpInfoJtoken, "corp_sub_industry");//企业所属子行业。当企业未设置该属性时,值为空 org.Location = Glo.JSON_SeleteNode(authCorpInfoJtoken, "location"); //企业所在地信息, 为空时表示未知 org.WXUseSta = 1; //使用状态. org.DTReg = DataType.CurrentDateTime; org.RegFrom = 1; //注册来源微信. org.No = orgNo; //BP.Cloud.Org.GenerNewOrgNo(); // BP.DA.Log.DebugWriteInfo("========" + org.No); org.Insert(); //初始化数据. org.Init_OrgDatas(); return org; } /// /// 获得应用的管理员并插入Port_OrgAdminer中 /// /// /// /// /// public static void InsertPort_OrgAdminer(string corpId, string agentid, string suitAccessToken, Org org) { IDictionary parametersAdm = new Dictionary(); parametersAdm.Add("auth_corpid", HttpUtility.UrlEncode(corpId)); parametersAdm.Add("agentid", HttpUtility.UrlEncode(agentid));//授权方安装的应用agentid string codeUrlAdm = "https://qyapi.weixin.qq.com/cgi-bin/service/get_admin_list?suite_access_token=" + suitAccessToken; string resAdm = Glo.HttpWebResponseUtility.HttpResponsePost_Json(codeUrlAdm, JsonConvert.SerializeObject(parametersAdm)); //解析获取管理员 JToken resAdmJtoken = Glo.ReadJSON(resAdm); if (Glo.JSON_SeleteNode(resAdmJtoken, "errcode").Equals("0")) { //插入Port_OrgAdminer中 BP.WF.Port.Admin2Group.OrgAdminer orgAdminer = new BP.WF.Port.Admin2Group.OrgAdminer(); Newtonsoft.Json.Linq.JObject jObject = Newtonsoft.Json.Linq.JObject.Parse(resAdm); Newtonsoft.Json.Linq.JArray jArray = Newtonsoft.Json.Linq.JArray.Parse(jObject.SelectToken("admin").ToString()); foreach (Newtonsoft.Json.Linq.JToken item in jArray.Children()) { orgAdminer = new BP.WF.Port.Admin2Group.OrgAdminer(); orgAdminer.FK_Emp = item["userid"].ToString();//管理员 orgAdminer.OrgNo = org.No; orgAdminer.Insert(); } // org.Adminer = adminer;//获得管理员. } } public static void SendMsg(string sender, string toUserIDs, string title, string docs, string url, string orgNo) { BP.DA.Log.DebugWriteInfo("+++++++++++进入SendMsg方法++++++++++++++++"); //httppost请求 BP.WF.HttpWebResponseUtility httpWebResponseUtility = new BP.WF.HttpWebResponseUtility(); //根据orgNo取得AccessToken BP.Cloud.Org org = new BP.Cloud.Org(); org.No = orgNo; if (org.RetrieveFromDBSources() == 0) return; //如果AccessToken接近失效,要重新获取,更新 string accessToken = ""; if (DataType.IsNullOrEmpty(org.AccessTokenExpiresIn) == false && DateTime.Compare(Convert.ToDateTime(DateTime.Now), Convert.ToDateTime(org.AccessTokenExpiresIn)) > 0) { // BP.DA.Log.DefaultLogWriteLineInfo("++++++++++进入获取getAccessToken++++++++++++++++"); //如果失效了,就直接更新一下. //BP.Cloud.HttpHandler.App_Org handler = new HttpHandler.App_Org(); //accessToken = handler.getAccessToken(org);//获取企业凭证,更新失效时间 //BP.DA.Log.DefaultLogWriteLineInfo("++++++++++获取getAccessToken:"+ accessToken + "++++++++++++++++"); } else { accessToken = org.AccessToken; } //组织发送信息的参数 if (DataType.IsNullOrEmpty(toUserIDs) == true) return; toUserIDs = toUserIDs.Replace(",", "|"); toUserIDs = toUserIDs.Replace(",", "|"); string[] strs = toUserIDs.Split('|'); string mystr = ""; foreach (string item in strs) { if (DataType.IsNullOrEmpty(item) == true) continue; /* if (BP.DA.DataType.IsMobile(item) == false) mystr += "" + org.No + "_" + item + "|"; else*/ mystr += item + "|"; } mystr = mystr.Substring(0, mystr.Length - 1); /*touser:指定接收消息的成员,成员ID列表(多个接收者用‘|’分隔,最多支持1000个)。特殊情况:指定为”@all”,则向该企业应用的全部成员发送 *toparty:指定接收消息的部门,部门ID列表,多个接收者用‘|’分隔,最多支持100个。 当touser为”@all”时忽略本参数 *totag:指定接收消息的标签,标签ID列表,多个接收者用‘|’分隔,最多支持100个。 当touser为”@all”时忽略本参数 *msgtype:消息类型,此时固定为:text *agentid:企业应用的id,整型。企业内部开发,可在应用的设置页面查看;第三方服务商,可通过接口 获取企业授权信息 获取该参数值 *text:消息内容,最长不超过2048个字节,超过将截断(支持id转译) *safe:表示是否是保密消息,0表示否,1表示是,默认0 *enable_id_trans:表示是否开启id转译,0表示否,1表示是,默认0 *enable_duplicate_check:表示是否开启重复消息检查,0表示否,1表示是,默认0 *duplicate_check_interval:表示是否重复消息检查的时间间隔,默认1800s,最大不超过4小时*/ string sendUrl = "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=" + accessToken; string msgJson = "{\"touser\":\"" + mystr + "\",\"toparty\":\"\",\"totag\":\"\",\"msgtype\":\"text\","; msgJson += "\"agentid\": " + org.AgentId + ","; msgJson += "\"text\": { \"content\": \"" + docs + "\" },"; msgJson += " \"safe\":0, \"enable_id_trans\":0, \"enable_duplicate_check\":0,"; msgJson += " \"duplicate_check_interval\":1800"; msgJson += "}"; //BP.DA.Log.DefaultLogWriteLineInfo("++++++++++msgJson:" + msgJson + "++++++++++++++++"); //获得返回的数据. string res = httpWebResponseUtility.HttpResponsePost_Json(sendUrl, msgJson); BP.DA.Log.DebugWriteInfo("++++++++++res:" + res + "++++++++++++++++"); //获取企业新信息,插入数据库 //解析返回的json串 Dictionary dd = res.Trim(new char[] { '{', '}' }).Split(',').ToDictionary(s => s.Split(':')[0].Trim('"'), s => (object)s.Split(':')[1].Trim('"')); string errcode = (string)dd["errcode"]; if (errcode.Equals("0")) { /* * 如果部分接收人无权限或不存在,发送仍然执行,但会返回无效的部分(即invaliduser或invalidparty或invalidtag), * 常见的原因是接收人不在应用的可见范围内。 * 如果全部接收人无权限或不存在,则本次调用返回失败,errcode为81013。 * 返回包中的userid,不区分大小写,统一转为小写 */ string invaliduser = (string)dd["invaliduser"];//发送的接收人中无效的用户名 string invalidparty = (string)dd["invalidparty"];//发送的接收人中无效的部门 string invalidtag = (string)dd["invalidtag"];//发送的接收人中无效的标签 return; } //如果全部接收人无权限或不存在,则本次调用返回失败,errcode为81013。 if (errcode.Equals("81013")) { return; } return; } /// /// 检查是否是手机号 /// /// /// public static bool IsMobile(string str) { return BP.DA.DataType.IsMobile(str); } } }