/// <summary> /// 填充对于指定功能模块数据的同步到其他站点的历史记录 /// </summary> /// <param name="userHandle"></param> /// <param name="dt"></param> /// <param name="progId"></param> /// <param name="internalId">内码</param> public static void FillSyncDataHistory(LibHandle userHandle, DataTable dt, string progId, string internalId) { if (userHandle == null || dt == null || string.IsNullOrEmpty(progId) || ExistAxpSyncDataInfo == false || ExistLinkSiteTable == false) { return; } try { if (string.IsNullOrEmpty(internalId) == false) { string sql = string.Format("select A.*,C.PERSONNAME,D.SHORTNAME from AXPSYNCDATAHISTORY A " + " left join AXPUSER B on A.USERID = B.USERID " + " left join COMPERSON C on B.PERSONID = C.PERSONID " + " left join AXPLINKSITE D on A.SITEID = D.SITEID " + " where A.PROGID = {0} and A.INTERNALID = {1} " + " order by A.SYNCTIME desc",// 时间降序 LibStringBuilder.GetQuotString(progId), LibStringBuilder.GetQuotString(internalId)); LibDataAccess dataAccess = new LibDataAccess(); dataAccess.ExecuteDataTable(sql, dt, true, 200);//取前200条 } dt.AcceptChanges(); } catch (Exception exp) { LibCommUtils.AddOutput(@"Error\CrossSiteCall", string.Format("error:{0}\r\nStacktrace:{1}", exp.Message, exp.StackTrace)); } }
public static bool Equals(LibHandle obj1, LibHandle obj2) { if (obj1.Handle == obj2.Handle) { return(true); } return(false); }
/// <summary> /// 获取指定用户的SSO令牌信息。如果本站点不是SSO管理站点,则从管理站点获取 /// </summary> /// <param name="userHandle"></param> /// <param name="timeOutMs"></param> /// <param name="dataAccess">可选参数:数据库访问器。如果调用时使用了数据库事务,需要将开启了事务的数据库访问器传递进来,避免在本方法中查询数据库时因事务锁表而死锁。</param> /// <returns></returns> public static string GetToken(LibHandle userHandle, int timeOutMs = 30 * 1000, LibDataAccess dataAccess = null) { if (userHandle == null || string.IsNullOrEmpty(userHandle.UserId)) { return(string.Empty); } if (EnvProvider.Default.IsSSOManageSite) { return(userHandle.GetToCheckToken()); } if (string.IsNullOrEmpty(EnvProvider.Default.SSOManageSiteUrl)) { return(string.Empty); } try { string url = string.Format("{0}/sysSvc/getTokenByUserId", EnvProvider.Default.SSOManageSiteUrl); string password = string.Empty; string sql = string.Format("select USERPASSWORD from AXPUSER where USERID={0} And ISUSE=1", LibStringBuilder.GetQuotString(userHandle.UserId)); if (dataAccess == null) { password = LibSysUtils.ToString((new LibDataAccess()).ExecuteScalar(sql)); } else { password = LibSysUtils.ToString(dataAccess.ExecuteScalar(sql)); } var postP = new { userId = userHandle.UserId, pwd = password }; string errorInfo = string.Empty; dynamic result = LibNetUtils.HttpPostCall <dynamic>(url, postP, out errorInfo, timeOutMs); if (string.IsNullOrEmpty(errorInfo) == false || result == null) { return(string.Empty); } else { return((string)result.GetTokenByUserIdResult); } } catch (Exception exp) { LibCommUtils.AddOutput("CrossSiteCall", string.Format("error:{0}\r\nStacktrace:{1}", exp.Message, exp.StackTrace)); return(string.Empty); } }
public override bool Equals(object obj) { LibHandle lb = obj as LibHandle; if (lb == null) { return(false); } if (this.Handle == lb.Handle) { return(true); } return(false); }
/// <summary> /// 向SSOManage站点发起校验令牌信息的请求 /// </summary> /// <param name="ssoInfo">包含令牌信息的参数</param> /// <param name="timeOutMs">超时时间,单位为毫秒,默认为5000毫秒</param> /// <returns>如果验证成功返回true,否则返回false</returns> public static bool CheckSSOLoginState(SSOInfo ssoInfo, int timeOutMs = 5000) { if (ssoInfo == null || string.IsNullOrEmpty(ssoInfo.UserId) || string.IsNullOrEmpty(ssoInfo.Token)) { return(false); } if (EnvProvider.Default.IsSSOManageSite) { LibHandle handle = LibHandleCache.Default.IsExistsHandle(LibHandeleType.PC, ssoInfo.UserId); if (handle != null) { return(handle.Token == ssoInfo.Token); } return(false); } if (string.IsNullOrEmpty(EnvProvider.Default.SSOManageSiteUrl)) { return(false); } try { string url = string.Format("{0}/sysSvc/CheckSSOLoginState", EnvProvider.Default.SSOManageSiteUrl); var postP = new { ssoInfo = ssoInfo }; string errorInfo = string.Empty; dynamic result = LibNetUtils.HttpPostCall <dynamic>(url, postP, out errorInfo, timeOutMs); if (string.IsNullOrEmpty(errorInfo) == false || result == null) { return(false); } else { // 私钥解密 string ret = LibRSAHelper.Decrypt((string)result.CheckSSOLoginStateResult);//对于直接返回基本类型的接口调用,结果会包装成方法名+Result return(ret == "0"); } } catch (Exception exp) { LibCommUtils.AddOutput("CrossSiteCall", string.Format("CheckSSOLoginState error:{0}\r\nStacktrace:{1}", exp.Message, exp.StackTrace)); return(false); } }
/// <summary> /// 填充指定用户对于指定功能模块数据的同步到其他站点的配置,如果没有则构造配置 /// </summary> /// <param name="userHandle"></param> /// <param name="dt"></param> /// <param name="progId"></param> public static void FillSyncDataSetting(LibHandle userHandle, DataTable dt, string progId) { if (userHandle == null || dt == null || string.IsNullOrEmpty(progId) || ExistAxpSyncDataInfo == false || ExistLinkSiteTable == false) { return; } //构建当前用户对所有站点的同步选项 Dictionary <string, LinkSiteInfo> linkSites = GetLinkSites(null, true); if (linkSites == null || linkSites.Count == 0) { return; } string siteIdStrs = string.Empty; foreach (string key in linkSites.Keys) { siteIdStrs += LibStringBuilder.GetQuotString(key) + ","; } siteIdStrs = siteIdStrs.Substring(0, siteIdStrs.Length - 1); try { string sql = string.Format("select A.*,C.PERSONNAME,D.SHORTNAME from AXPSYNCDATASETTING A " + " left join AXPUSER B on A.USERID = B.USERID " + " left join COMPERSON C on B.PERSONID = C.PERSONID " + " left join AXPLINKSITE D on A.SITEID = D.SITEID " + " where A.PROGID = {0} and A.USERID = {1} and A.SITEID in ({2})" + " order by A.SITEID asc",// 站点代码升序 LibStringBuilder.GetQuotString(progId), LibStringBuilder.GetQuotString(userHandle.UserId), siteIdStrs); LibDataAccess dataAccess = new LibDataAccess(); dataAccess.ExecuteDataTable(sql, dt); DataRow[] rows = null; if (dt.Rows.Count < linkSites.Count) { if (linkSites != null && linkSites.Count > 0) { dt.BeginLoadData(); try { DataRow newRow = null; foreach (string key in linkSites.Keys) { rows = dt.Select(string.Format("SITEID = {0}", LibStringBuilder.GetQuotString(key))); if (rows == null || rows.Length == 0) { //对于没有配置的站点,增加默认配置 并保存到数据库 newRow = dt.NewRow(); newRow.BeginEdit(); Guid guid = Guid.NewGuid(); newRow["SETTINGID"] = guid.ToString(); newRow["PROGID"] = progId; newRow["USERID"] = userHandle.UserId; newRow["ISSYNCTO"] = linkSites[key].IsSlave ? 1 : 0;//默认仅向子站点同步 newRow["SITEID"] = key; newRow["SHORTNAME"] = linkSites[key].ShortName; newRow.EndEdit(); dt.Rows.Add(newRow); string insertSql = string.Format("insert into AXPSYNCDATASETTING(SETTINGID,PROGID,USERID,ISSYNCTO,SITEID) " + "values({0},{1},{2},{3},{4})", LibStringBuilder.GetQuotString(guid.ToString()), LibStringBuilder.GetQuotString(progId), LibStringBuilder.GetQuotString(userHandle.UserId), linkSites[key].IsSlave ? 1 : 0,//默认仅向子站点同步 LibStringBuilder.GetQuotString(key) ); dataAccess.ExecuteNonQuery(insertSql); } } } finally { dt.EndLoadData(); } } } dt.AcceptChanges(); } catch (Exception exp) { LibCommUtils.AddOutput(@"Error\CrossSiteCall", string.Format("error:{0}\r\nStacktrace:{1}", exp.Message, exp.StackTrace)); } }
/// <summary> /// 向多个目标站点发起跨站Bcf方法调用请求。 /// 此方法执行时会阻塞 /// 如果有向多个站点请求执行,会同时(并发线程)向多个站点发起请求,请求完毕后再汇总执行结果返回 /// 如果参数有误会抛出异常 /// </summary> /// <param name="handle">当前用户的标识Handle</param> /// <param name="linkSiteIds">目标站点代码列表</param> /// <param name="callParams">包含SSO令牌信息、请求方法、请求参数等callParams</param> /// <param name="dataAccess">可选参数:数据库访问器。如果调用时使用了数据库事务,需要将开启了事务的数据库访问器传递进来,避免在本方法中查询数据库时因事务锁表而死锁。</param> /// <returns>返回执行结果字典,键值为目标站点Id,值为执行结果</returns> public static Dictionary <string, ExecuteBcfMethodResult> CrossSiteBcfCall(string handle, List <string> linkSiteIds, ExecuteBcfMethodParam callParams, LibDataAccess dataAccess = null) { if (string.IsNullOrEmpty(handle) || linkSiteIds == null || linkSiteIds.Count == 0 || callParams == null) { throw new ArgumentNullException("handle、linkSiteIds、callParams", "检查参数时发现有空参数。"); } LibHandle libHandle = LibHandleCache.Default.GetCurrentHandle(handle) as LibHandle; if (libHandle == null) { throw new Exception("该账户未登录。"); } callParams.IsCrossSiteCall = true; callParams.UserId = libHandle.UserId; callParams.Token = GetToken(libHandle, 30 * 1000, dataAccess); if (string.IsNullOrEmpty(callParams.Token)) { throw new Exception("获取跨站访问令牌信息失败。"); } Dictionary <string, string> urls = GetSiteUrls(linkSiteIds); if (urls == null || urls.Count == 0) { throw new Exception("查找到的站点Url为空。"); } Dictionary <string, ExecuteBcfMethodResult> dicResults = new Dictionary <string, ExecuteBcfMethodResult>(); string errorInfo = string.Empty; List <Task> tasks = new List <Task>(); foreach (string siteId in urls.Keys) { var url = urls[siteId]; if (string.IsNullOrEmpty(url)) { continue; } url = string.Format("{0}/billSvc/invorkBcf", url); var task = Task.Factory.StartNew(() => { try { var sendObj = new { param = callParams };//参数名必须一致 dynamic ret = LibNetUtils.HttpPostCall <dynamic>(url, sendObj, out errorInfo, callParams.TimeoutMillSecs); if (ret != null) { ExecuteBcfMethodResult result = JsonConvert.DeserializeObject <ExecuteBcfMethodResult>((string)ret.ExecuteBcfMethodResult); lock (dicResults) { dicResults.Add(siteId, result); } } else if (string.IsNullOrEmpty(errorInfo) == false) { ExecuteBcfMethodResult result = new ExecuteBcfMethodResult(); result.Messages.Add(new LibMessage() { MessageKind = LibMessageKind.Error, Message = string.Format("执行跨站请求出现异常:{0}", errorInfo) }); lock (dicResults) { dicResults.Add(siteId, result); } } } catch (Exception exp) { LibCommUtils.AddOutput(@"Error\CrossSiteCall", string.Format("CheckSSOLoginState error:{0}\r\nStacktrace:{1}", exp.Message, exp.StackTrace)); ExecuteBcfMethodResult result = new ExecuteBcfMethodResult(); result.Messages.Add(new LibMessage() { MessageKind = LibMessageKind.Error, Message = string.Format("执行跨站请求出现异常:{0}", exp.Message) }); lock (dicResults) { dicResults.Add(siteId, result); } } }); tasks.Add(task); } //循环检查等待所有task都执行完毕 int waitMillSecs = callParams.TimeoutMillSecs + 1000;//多等一秒 int waitCount = 0; //等待超时时间到来,或者全部已经执行完毕 while (waitCount < waitMillSecs) { bool isAllFinished = tasks.All(t => { return(t.IsCompleted); }); if (isAllFinished) { break; } waitCount += 100; Thread.Sleep(100); } return(dicResults); }