You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1543 lines
66 KiB
Plaintext

11 months ago
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
{
/// <summary>
/// 执行安装
/// </summary>
/// <param name="xd"></param>
/// <returns></returns>
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;
}
}
/// <summary>
/// 企业ID
/// </summary>
public static string CorpID
{
get
{
return BP.Difference.SystemConfig.AppSettings["CorpID"];
}
}
/// <summary>
/// 推广包ID
/// </summary>
public static string TemplateId
{
get
{
return BP.Difference.SystemConfig.AppSettings["TemplateId"];
}
}
/// <summary>
/// 服务器域名
/// </summary>
public static string Domain
{
get
{
return BP.Difference.SystemConfig.AppSettings["Domain"];
}
}
/// <summary>
/// 服务商ProviderSecret
/// </summary>
public static string ProviderSecret
{
get
{
return BP.Difference.SystemConfig.AppSettings["ProviderSecret"];
}
}
/// <summary>
/// 服务商应用ID-SuiteID
/// </summary>
public static string SuiteID
{
get
{
return BP.Difference.SystemConfig.AppSettings["SuiteID"];
}
}
/// <summary>
/// 服务商应用ID-密钥
/// </summary>
public static string SuiteID_Secret
{
get
{
return BP.Difference.SystemConfig.AppSettings["SuiteID_Secret"];
}
}
/// <summary>
/// 我们应用的值
/// </summary>
public static string Token
{
get
{
return BP.Difference.SystemConfig.AppSettings["Token"];
}
}
/// <summary>
/// 用于消息内容加密 EncodingAESKey
/// </summary>
public static string EncodingAESKey
{
get
{
return BP.Difference.SystemConfig.AppSettings["EncodingAESKey"];
}
}
#endregion web.config配置信息.
/// <summary>
/// 动态的凭证(经常用)(全局)
/// </summary>
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);
}
}
/// <summary>
/// 获取第三方应用凭证
/// 检查表里是否有SuitAccessToken如果存在并有效则返回
/// </summary>
/// <returns></returns>
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<string, object> 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<string, object> 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;
}
/// <summary>
/// 获取第三方应用凭证,服务器IP地址一定要先加入服务商的IP白明达中否则验证失败。
/// </summary>
/// <returns></returns>
public static Dictionary<string, object> getSuitAccessToken_S()
{
//获取第三方应用凭证获得suite_access_token以获取预授权码
IDictionary<string, string> parameters = new Dictionary<string, string>();
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<string, object> dd = res.Trim(new char[] { '{', '}' }).Split(',').ToDictionary(s => s.Split(':')[0].Trim('"'), s => (object)s.Split(':')[1].Trim('"'));
return dd;
}
/// <summary>
/// 获取预授权码
/// 该API用于获取预授权码。预授权码用于企业授权时的第三方服务商安全验证。
/// </summary>
/// <returns></returns>
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<string, object> 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<string, object> 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;
}
}
///<summary>
///设置授权配置
///该接口可对某次授权进行配置。可支持测试模式(应用未发布时)。
///请求方式POSTHTTPS
///请求地址: https://qyapi.weixin.qq.com/cgi-bin/service/set_session_info?suite_access_token=SUITE_ACCESS_TOKEN
/// </summary>
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;
}
/// <summary>
/// 获取企业凭证 第三方服务商在取得企业的永久授权码后通过此接口可以获取到企业的access_token。
///获取后可通过通讯录、应用、消息等企业接口来运营这些应用。
/// </summary>
/// <returns></returns>
public static string getAccessToken(BP.Cloud.Org org, string permanentCode)
{
//获取第三方应用凭证
string suitAccessToken = getSuitAccessToken();
// string permanentCode = CreateOrg();//获取永久授权码
IDictionary<string, string> parameters = new Dictionary<string, string>();
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<string, object> 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;
}
/// <summary>
/// 组装安装授权页连接地址
/// </summary>
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<string, object> 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<string, object> 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;
}
/// <summary>
/// 获取相应子节点的值
/// </summary>
/// <param name="childnodelist"></param>
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<object>().ToString();
}
if (node.Type == JTokenType.Object)
{
result = node.Value<object>().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;
}
/// <summary>
/// 应用提供商的provider_access_token
/// </summary>
/// <returns></returns>
public static string getProviderAccessToken()
{
string provider_access_token = "";
IDictionary<string, string> parameters = new Dictionary<string, string>();
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<string, object> 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;
}
///
/// <summary>
/// 获取永久授权码
/// 引导用户进入授权页
///用户确认授权后会进入回调URI(即redirect_uri)并在URI参数中带上临时授权码、过期时间以及state参数。第三方服务商据此获得临时授权码
///redirect_uri?auth_code=xxx&expires_in=600&state=xx
/// </summary>
/// <returns></returns>
public static string InstallIt(string authCode)
{
//获取第三方应用凭证
string suitAccessToken = getSuitAccessToken();
IDictionary<string, string> parameters = new Dictionary<string, string>();
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;
}
/// <summary>
/// 同步到用户中心库.
/// </summary>
/// <param name="orgNo">组织编号</param>
/// <param name="urlFrom">注册人</param>
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 把数据注册到用户中心.
}
/// <summary>
/// 让用户登陆u.
/// </summary>
/// <param name="userNo"></param>
/// <param name="corpID"></param>
/// <returns></returns>
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);
}
/// 获得部门数据.
/// </summary>
/// <param name="org">组织实体</param>
/// <param name="permanentCode">永久授权码</param>
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);
}
}
/// <summary>
/// 获得部门下人员信息,写入人员表
/// </summary>
/// <param name="res"></param>
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; //说明部门不存在,不应该出现的问题.
*/
BP.Cloud.DeptEmp de = new BP.Cloud.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 "";
}
/// <summary>
/// 取得标签列表
/// </summary>
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);
}
}
/// <summary>
///
/// </summary>
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();
}
}
/// <summary>
/// 判断是否选择了部门
/// </summary>
/// <param name="org"></param>
/// <returns></returns>
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.UserID;
de.setMyPK(emp.FK_Dept + "_" + de.FK_Emp);
de.EmpNo = emp.No;
de.Insert();
}
return "检查成功.";
}
/// <summary>
/// 根据userid获取企业微信openid
/// 如果有权限问题,就获取不到。
/// </summary>
/// <param name="tooken"></param>
/// <param name="userID"></param>
/// <returns></returns>
public static string GetOpenIDByUserID(string tooken, string userID)
{
//根据uiserID,获得openID.
IDictionary<string, string> parametersAdm = new Dictionary<string, string>();
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<string, object> 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;
}
/// <summary>
/// 通讯录变更中用户新增事件
/// </summary>
/// <param name="xd"></param>
/// <param name="org"></param>
/// <returns></returns>
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;
BP.Cloud.DeptEmp de = new BP.Cloud.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;
BP.Cloud.DeptEmp de = new BP.Cloud.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 + "]新增成功.";
}
/// <summary>
/// 通讯录变更中用户变更事件
/// </summary>
/// <param name="xd"></param>
/// <param name="org"></param>
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;
BP.Cloud.DeptEmp de = new BP.Cloud.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 + "]成功.";
}
/// <summary>
/// 通讯录变更中用户删除事件
/// </summary>
/// <param name="xd"></param>
/// <param name="org"></param>
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();
//删除部门对应关系.
BP.Cloud.DeptEmps des = new BP.Cloud.DeptEmps();
des.Delete("FK_Emp", emp.UserID, "OrgNo", org.No);
//删除部门角色对应关系.
BP.Cloud.DeptEmpStations dess = new BP.Cloud.DeptEmpStations();
dess.Delete("FK_Emp", emp.UserID, "OrgNo", org.No);
return "删除[" + emp.No + "]成功.";
}
/// <summary>
/// 通讯录变更中部门新增事件
/// </summary>
/// <param name="xd"></param>
/// <param name="org"></param>
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 + "]成功.";
}
/// <summary>
/// 通讯录变更中部门修改事件
/// </summary>
/// <param name="xd"></param>
/// <param name="org"></param>
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 + "]成功.";
}
/// <summary>
/// 通讯录变更中部门删除事件
/// </summary>
/// <param name="xd"></param>
/// <param name="org"></param>
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 + "]成功.";
}
/// <summary>
/// 保存文件
/// </summary>
/// <param name="url">url路径</param>
/// <param name="saveToDir">保存到目录</param>
/// <param name="fileName">保存的文件名</param>
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();
}
}
/// <summary>
/// 编辑org信息写入
/// </summary>
/// <param name="org"></param>
/// <param name="authCorpInfoJtoken"></param>
/// <param name="corpId"></param>
/// <param name="permanentCode"></param>
/// <param name="accessToken"></param>
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;
}
/// <summary>
/// 获得应用的管理员并插入Port_OrgAdminer中
/// </summary>
/// <param name="corpId"></param>
/// <param name="agentid"></param>
/// <param name="suitAccessToken"></param>
/// <param name="org"></param>
public static void InsertPort_OrgAdminer(string corpId, string agentid, string suitAccessToken, Org org)
{
IDictionary<string, string> parametersAdm = new Dictionary<string, string>();
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<string, object> 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;
}
/// <summary>
/// 检查是否是手机号
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
public static bool IsMobile(string str)
{
return BP.DA.DataType.IsMobile(str);
}
}
}