/// <summary> /// 向服务器注册 /// </summary> private bool RegsiterToServer() { // 先尝试检查远程服务器是否可以ping通 bool bIsRomateCanPing = IsCanPingPass(); if (!bIsRomateCanPing) { LOGGER.ERROR("Can't pass server ip ping test, will not use registe node and heart-beat"); return(false); } // 开始注册 SRegisteNode node = new SRegisteNode(); node.bankCardNo = FKConfig.BankCardNo; node.ip = string.IsNullOrEmpty(FKConfig.LocalIP) ? FKBaseUtils.FKSystemEnviSettingHelper.GetLocalIPAddressByUri(FKConfig.ServerRegisteUrl) : FKConfig.LocalIP; node.publicKey = RSAKeyContainer.GetInstance.GetCSharpPublicKey(); LOGGER.INFO($"Begin to register to server. Bank card No = {node.bankCardNo}, Ip = {node.ip}"); HttpSendResult result = RequestSender.SendRequestToServer(node); if (result.IsSendSuccessed() && result.ErrorStatus == 1 && (!string.IsNullOrEmpty(result.publicKey))) { SetCurCashierNodeID(result.NodeID); RSAKeyContainer.GetInstance.SetJavaPublicKey(result.publicKey); LOGGER.INFO($"Register to server successed. Node id = {result.NodeID}"); return(true); } else { SetCurCashierNodeID(INVALID_NODE_ID); LOGGER.ERROR($"Register to server failed. but still use registe node and heart-beat. Node id = {GetCurCashierNodeID()}"); return(true); } }
/// <summary> /// 从服务器进行注销 /// </summary> /// <returns></returns> private bool UnregsiterFromServer() { try { SUnregisteNode node = new SUnregisteNode(); node.id = GetCurCashierNodeID(); HttpSendResult result = RequestSender.SendRequestToServer(node); if (result.IsSendSuccessed() && result.ErrorStatus == 1) { LOGGER.INFO($"Node unregiste successed. NodeID = {node.id}"); return(true); } else { LOGGER.WARN($"Node unregiste failed. NodeID = {node.id}"); return(false); } } catch (Exception e) { LOGGER.ERROR($"Node unregiste error occured. Error = {e.ToString()}"); return(false); } }
/// <summary> /// 创建Web服务器 /// </summary> private void CreateWebServer() { try { if (FKConfig.IsUseHttpServer) { m_WebServer = new FKHttp.FKHttpServer(this, RequestReciver.Func_OnRequest, FKConfig.IsUseHttpsWebServer, FKConfig.WebServerListenUrl); } } catch (Exception e) { LOGGER.ERROR($"Create web server failed. Error = {e.ToString()}", 0); } if (m_WebServer == null || !m_WebServer.IsRunning()) { LOGGER.WARN("Web server is not running."); } else { if (m_WebServer.IsSupportingSSL()) { LOGGER.INFO("Create web server successed. Support HTTPS"); } else { LOGGER.INFO("Create web server successed. Only support HTTP"); } } }
public override void CaclVerifyCode(string strCSharpPrivateKey) { try { info.timestamp = CaclTimestamp(); string strRet = ""; strRet += "bankCardNo="; strRet += info.bankCardNo; strRet += "&ip="; strRet += info.ip; strRet += "&publicKey="; strRet += info.publicKey; strRet += "×tamp="; strRet += info.timestamp; string strHashData = ""; FKBaseUtils.FKHash.GetHash(strRet, ref strHashData); info.signature = FKBaseUtils.FKRSASignature.RSASign(strCSharpPrivateKey, strHashData); // LOGGER.DEBUG($"Hash src = \n{strRet}\n dest = {strHashData}"); // LOGGER.DEBUG($"Sign key = \n{strCSharpPrivateKey}\n src = {strHashData}\n dest = {info.signature}"); } catch (Exception e) { LOGGER.ERROR($"Cacl verify code failed. Error = {e.ToString()}"); } }
public override void CaclVerifyCode(string strCSharpPrivateKey) { try { info.timestamp = CaclTimestamp(); string strRet = ""; strRet += "bankId="; strRet += info.bankId; strRet += "&msg="; strRet += info.msg; strRet += "&nodeID="; strRet += info.nodeID; strRet += "&status="; strRet += info.status; strRet += "&taskID="; strRet += info.taskID; strRet += "×tamp="; strRet += info.timestamp; string strHashData = ""; FKBaseUtils.FKHash.GetHash(strRet, ref strHashData); info.signature = FKBaseUtils.FKRSASignature.RSASign(strCSharpPrivateKey, strHashData); } catch (Exception e) { LOGGER.ERROR($"Cacl verify code failed. Error = {e.ToString()}"); } }
/// <summary> /// 解析消息获取其消息ID /// </summary> /// <param name="strMsg"></param> /// <returns></returns> private static int GetMsgIDFromResponse(string strMsg) { JavaScriptSerializer js = new JavaScriptSerializer(); dynamic data; try { data = js.Deserialize <dynamic>(strMsg); // 反序列化 } catch (Exception e) { LOGGER.ERROR($"Server request is not JSON format. \n Error = {e.ToString()} \n Respone = {strMsg}"); return(-1); } // 获取消息类型 int msgID = -1; try { msgID = int.Parse(data["msgID"]); } catch (Exception e) { LOGGER.ERROR($"Server request is not include invalid msgID. \n Error = {e.ToString()} \n Respone = {strMsg}"); return(-1); } return(msgID); }
/// <summary> /// 逻辑线程 /// </summary> private void LogicThreadMain() { int nIdleTime = FKConfig.LoginThreadIdleTime; LOGGER.INFO($"Start Logic thread. Idle time = {nIdleTime} millseconds."); // 建议最早更新时间:若早于该时间则一定不会进行更新事件通知 DateTime SuggestEarlistUpdateTime = DateTime.Now; string strBankType = string.Empty; int nOprationType = 0; // 0: Unknown 1: GetBill 2: Out while (!m_bIsNeedCloseLogicThread) { if (m_BillTasksList.Count > 0) { try { nOprationType = 1; strBankType = m_BillTasksList.Peek().bankCode; HandleBillTask(); } catch (Exception e) { LOGGER.ERROR($"Handle bill task failed. Error = {e.ToString()}"); } } else if (m_OutTasksList.Count > 0) { try { nOprationType = 2; strBankType = m_OutTasksList.Peek().fromBankCode; HandleOutTask(); } catch (Exception e) { LOGGER.ERROR($"Handle out task failed. Error = {e.ToString()}"); } } { // 每次无论出入账与否,都尝试进行一次刷新 try { // 根据上一次执行的任务进行update更新 SuggestEarlistUpdateTime = HandleUpdateTask(SuggestEarlistUpdateTime, nOprationType, strBankType); } catch (Exception e) { LOGGER.ERROR($"Handle update task failed. Error = {e.ToString()}"); } // 逻辑线程休眠 Thread.Sleep(nIdleTime); } } LOGGER.INFO($"Logic thread exit"); }
/// <summary> /// 收到的网络消息处理函数 /// </summary> /// <param name="mainForm"></param> /// <param name="request"></param> /// <param name="strRequestString"></param> /// <returns></returns> public static string Func_OnRequest(Form f, HttpListenerRequest request, string strRequestString) { MainForm mainForm = null; if (!(f is MainForm)) { LOGGER.ERROR("Can't get main form object."); return(DefaultErrorResponse(-1, -1)); } else { mainForm = f as MainForm; } if (mainForm == null) { LOGGER.ERROR("Can't get main form object."); return(DefaultErrorResponse(-1, -1)); } int nNodeID = mainForm.GetCurCashierNodeID(); int nErrorCode = -1; string strRespone = string.Empty; try { int nMsgID = GetMsgIDFromResponse(strRequestString); switch (nMsgID) { case (int)ENUM_S2CMsgID.eS2CMsgID_OutTaskRequest: nErrorCode = OutTaskRequestHandler.OnMsg(nNodeID, strRequestString, mainForm, ref strRespone); return(strRespone); case (int)ENUM_S2CMsgID.eS2CMsgID_GetTaskLogRequest: nErrorCode = GetTaskLogRequestHandler.OnMsg(nNodeID, strRequestString, mainForm, ref strRespone); break; case (int)ENUM_S2CMsgID.eS2CMsgID_ManageAction: break; case (int)ENUM_S2CMsgID.eS2CMsgID_GetBillTaskRequest: nErrorCode = GetBillTaskRequestHandler.OnMsg(nNodeID, strRequestString, mainForm, ref strRespone); break; default: LOGGER.WARN($"Unknown server request msg. \n Request = {strRequestString}"); break; } } catch (Exception e) { LOGGER.WARN($"Deal with server request msg error occured. Error = {e.ToString()} \n Request = {strRequestString}"); return(DefaultErrorResponse(nNodeID, nErrorCode)); } return(DefaultErrorResponse(nNodeID, nErrorCode)); }
/// <summary> /// 关闭逻辑线程 /// </summary> private void StopLogicThread() { m_bIsNeedCloseLogicThread = true; try { m_LogicThread.Abort(); } catch (Exception e) { LOGGER.ERROR($"Stop logic thread error occurred. Error = {e.ToString()}", 0); } }
/// <summary> /// 处理流水查询任务 /// </summary> private void HandleBillTask() { try { SBillTaskInfo info = m_BillTasksList.Peek(); // 取出消息,不删除 LOGGER.INFO($"Handle a new bill task:\n {info.ToLogString()} \n, still left {m_BillTasksList.Count - 1} tasks in queue."); SBillTaskResult dealResult = new SBillTaskResult(); dealResult.taskID = info.taskID; dealResult.nodeID = GetCurCashierNodeID(); dealResult.bankId = info.bankId; // 记录当前在处理的任务ID SetCurTaskID(info.taskID); // 开始处理 AutomationBill(info, ref dealResult); LOGGER.WARN($"Auto get bill task is done. Now ready to send msg to server. TaskID = {info.taskID}.", info.taskID); // 发送回馈消息给服务器完毕 HttpSendResult SendResult = RequestSender.SendRequestToServer(dealResult); if (SendResult.IsSendSuccessed()) { SetLastTaskID(info.taskID); SetCurTaskID(INVALID_TASK_ID); LOGGER.INFO($"Send get bill result successed. TaskID = {info.taskID}. \n {SendResult.ToLogString()}"); } else { // result = null; 无论是否发送给服务器成功,只要执行成功,就不允许清除 SetLastTaskID(INVALID_TASK_ID); SetCurTaskID(INVALID_TASK_ID); LOGGER.ERROR($"Send get bill result failed. TaskID = {info.taskID}. \n {SendResult.ToLogString()}", info.taskID); } LOGGER.WARN($"Get bill task deal over. TaskID = {info.taskID}.", info.taskID); } catch (Exception e) { LOGGER.ERROR($"HandleBillTask exception.msg: {e.Message}."); } finally { SetCurTaskID(INVALID_TASK_ID); m_BillTasksList.Dequeue(); // 无论如何,该任务必须删除 } return; }
static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); // 初始化 Console.WriteLine("[Info] Start ..."); if (!ResetConsole()) { return; } if (!HandleProcessExist()) { return; } if (!SetMinidumpHandle()) { return; } if (!CheckDotNetVersion()) { return; } if (!SetAutoRestart()) { return; } s_MainForm = new MainForm(); if (!ResetForm()) { return; } try { Application.Run(s_MainForm); } catch (Exception e) { LOGGER.ERROR($"Application has fetal error occured. Error = {e.ToString()}"); } finally { AppShutdown(FKConfig.IsAutoRestart); } }
/// <summary> /// 创建逻辑线程 /// </summary> private void StartLogicThread() { m_LogicThread = new Thread(LogicThreadMain); m_LogicThread.SetApartmentState(ApartmentState.STA); m_LogicThread.IsBackground = true; m_LogicThread.Name = "FKLogicThread"; try { m_LogicThread.Start(); } catch (Exception e) { LOGGER.ERROR($"Logic thread error occurred. Error = {e.ToString()}", 0); } }
/// <summary> /// 关闭Web服务器 /// </summary> private void StopWebServer() { try { if (m_WebServer != null) { m_WebServer.Stop(); } } catch (Exception e) { LOGGER.ERROR($"Stop web server failed. Error = {e.ToString()}", 0); } LOGGER.INFO("Stop web server successed."); }
private void GenCSharpKey() { try { string strXMLPublicKey = ""; string strXMLPrivateKey = ""; FKBaseUtils.FKRSAEncrypt.GenerateDotNetRSAKey(out strXMLPrivateKey, out strXMLPublicKey); m_strCSharpPublicKey = FKBaseUtils.FKRSAEncrypt.ConvertRSAPublicKey_DotNet2Java(strXMLPublicKey); m_strCSharpPrivateKey = FKBaseUtils.FKRSAEncrypt.ConvertRSAPrivateKey_DotNet2Java(strXMLPrivateKey); } catch (Exception e) { LOGGER.ERROR($"Create C# RSA key failed. Error = {e.ToString()}"); } }
public override string ToPostDataString(string strCSharpPrivateKey) { try { var serializer = new JavaScriptSerializer(); CaclVerifyCode(strCSharpPrivateKey); string strInfo = serializer.Serialize(this.info); return(strInfo); } catch (Exception e) { LOGGER.ERROR($"Format msg failed. Error = {e.ToString()}"); return(string.Empty); } }
/// <summary> /// 处理流水查询任务 /// </summary> private void HandleOutTask() { try { SOutTaskInfo info = m_OutTasksList.Peek(); // 取出消息,不删除 LOGGER.INFO($"Handle a new out task:\n {info.ToLogString()} \n, still left {m_OutTasksList.Count - 1} tasks in queue."); SOutTaskResult dealResult = new SOutTaskResult(); dealResult.taskID = info.taskID; dealResult.nodeID = GetCurCashierNodeID(); // 记录当前在处理的任务ID SetCurTaskID(info.taskID); // 开始处理 if (!AutomationOut(info, ref dealResult)) { } LOGGER.WARN($"Auto out task is done. Now ready to send msg to server. TaskID = {info.taskID}.", info.taskID); // 通知服务器处理结果 HttpSendResult sendResult = RequestSender.SendRequestToServer(dealResult); if (sendResult.IsSendSuccessed()) { SetLastTaskID(info.taskID); SetCurTaskID(INVALID_TASK_ID); LOGGER.INFO($"Send auto out task successed. TaskID = {info.taskID}. \n {sendResult.ToLogString()}"); } else { SetLastTaskID(INVALID_TASK_ID); SetCurTaskID(INVALID_TASK_ID); LOGGER.ERROR($"Send auto out task failed. TaskID = {info.taskID}. \n {sendResult.ToLogString()}", info.taskID); } LOGGER.WARN($"Out task deal over. TaskID = {info.taskID}.", info.taskID); } catch (Exception e) { LOGGER.ERROR($"Deal out task error occured. Error = {e.ToString()}"); } finally { SetCurTaskID(INVALID_TASK_ID); m_OutTasksList.Dequeue(); // 无论如何,该任务必须删除 } return; }
/// <summary> /// 启动心跳 /// </summary> /// <returns></returns> private bool StartHeartbeat() { try { m_nHeartBeatTimer = new System.Timers.Timer(FKConfig.HeartbeatIdleTime); m_nHeartBeatTimer.Elapsed += (sender, e) => OnHeartbeatTimerEvent(sender, e, FKConfig.ServerHeartbeatUrl, this); m_nHeartBeatTimer.AutoReset = true; m_nHeartBeatTimer.Enabled = true; } catch (Exception e) { LOGGER.ERROR($"Create heart-beat timer failed. Error = {e.ToString()}"); return(false); } LOGGER.INFO($"Start heart-beat successed. TickTime = {FKConfig.HeartbeatIdleTime} ms."); return(true); }
/// <summary> /// 刷新事件 /// </summary> public static void Update() { if (!s_bIsLogining) // 未登录,不做任何刷新 { return; } try { int retryCount = 3; for (int i = 0; i < retryCount; i++) { if (FKWebAutomatic.FKWebDriver.GetInstance.ClickByXPath("//*[@class=\"index_page\"]")) { var element = FKWebDriver.GetInstance.WaitUntilVisibleByXPath("//*[@class=\"each_card\"]", 30000); if (element != null) { LOGGER.INFO("CITIC刷新主页成功"); return; } else { LOGGER.ERROR($"刷新等待主页元素超时,等待重试"); } } else { // 出现任何异常,立即关闭浏览器设置为未登录,等待下次登录 LOGGER.INFO($"CITIC刷新主页,失败[ClickByID返回false],等待重试"); Thread.Sleep(5000); } } } catch (Exception e) { LOGGER.ERROR($"Update CITIC bank error occured, IE driver will shutdown. Error = {e.ToString()}"); // 出现任何异常,立即关闭浏览器设置为未登录,等待下次登录 FKWebDriver.GetInstance.Close(); ForceShutdownIE(); s_bIsLogining = false; } LOGGER.INFO($"CITIC刷新主页失败,清理ie等待下次重新登录"); FKWebDriver.GetInstance.Close(); ForceShutdownIE(); s_bIsLogining = false; }
/// <summary> /// 实际消息发送 /// </summary> /// <param name="strUrl"></param> /// <param name="strInfo"></param> /// <param name="strMsgInfo"></param> /// <param name="nTimeOut"></param> /// <returns></returns> private static HttpSendResult SendMsgToServer(string strUrl, string strInfo, string strMsgInfo, int nTimeOut) { try { HttpSendResult result = new HttpSendResult(); string strResponse = (string)FKHttp.FKHttpClient.POST(strUrl, strInfo, null, nTimeOut); bool bSuccess = false; string strErrorMsg = ""; int nID = 0; string strNewResponse = ""; int nStatus = 0; string strJavaPublicKey = ""; // 解析Respone ParserResponseMsg(strResponse, out strNewResponse, out bSuccess, out strErrorMsg, out nID, out nStatus, out strJavaPublicKey); result.RequestType = strMsgInfo; result.ServerUrl = strUrl; result.RequestMsg = strInfo; result.ResponseMsg = strNewResponse; result.bSuccess = bSuccess; result.ErrorMsg = strErrorMsg; result.NodeID = nID; result.ErrorStatus = nStatus; result.publicKey = strJavaPublicKey; if (bSuccess) { // 记录日志 LOGGER.DEBUG($"Send http msg type = {strMsgInfo}: \n-\nRequest = {strInfo} \n-\nResponse = {strNewResponse}"); } else { LOGGER.ERROR($"Send http msg type = {strMsgInfo}: \n-\nRequest = {strInfo} \n-\nResponse = {strNewResponse} \n-\nStatus = {nStatus} , Error = {strErrorMsg}"); } return(result); } catch (Exception e) { LOGGER.ERROR($"Send http request msg to server failed. Error = {e.ToString()}"); return(null); } }
public override string ToPostDataString(string strCSharpPrivateKey) { try { var serializer = new JavaScriptSerializer(); CaclVerifyCode(strCSharpPrivateKey); string strInfo = serializer.Serialize(info); int nLastPos = strInfo.LastIndexOf("}"); strInfo = strInfo.Substring(0, nLastPos); strInfo += ",\"timestamp\":"; strInfo += info.timestamp; strInfo += ",\"signature\":\""; strInfo += info.signature; strInfo += "\"}"; return(strInfo); } catch (Exception e) { LOGGER.ERROR($"Format msg failed. Error = {e.ToString()}"); return(string.Empty); } }
public override bool Init() { s_FreqLimit.Check(); try { // 如果没有登录过,清除前面残留的ie if (s_bIsLogining == false) { FKWebDriver.GetInstance.Close(); ForceShutdownIE(); Thread.Sleep(1000); } } catch (Exception e) { LOGGER.ERROR($"Init failed ... Error = {e.ToString()}"); FKWebDriver.GetInstance.Close(); ForceShutdownIE(); return(false); } return(true); }
/// <summary> /// 关闭心跳 /// </summary> /// <returns></returns> private bool StopHeartbeat() { try { if (m_nHeartBeatTimer != null) { m_nHeartBeatTimer.Stop(); m_nHeartBeatTimer.Close(); m_nHeartBeatTimer.Dispose(); LOGGER.INFO($"FKClose heart-beat successed."); } else { LOGGER.INFO($"We did't use heart-beat."); } } catch (Exception e) { LOGGER.ERROR($"FKClose heart-beat timer failed. Error = {e.ToString()}"); return(false); } return(true); }
public override void CaclVerifyCode(string strCSharpPrivateKey) { try { info.timestamp = CaclTimestamp(); string strRet = ""; strRet += "dianZiHuiDan="; strRet += info.dianZiHuiDan; strRet += "&moneyAfterTrade="; strRet += info.moneyAfterTrade; strRet += "&moneyBeforeTrade="; strRet += info.moneyBeforeTrade; strRet += "&msg="; strRet += info.msg; strRet += "&nodeID="; strRet += info.nodeID; strRet += "&status="; strRet += info.status; strRet += "&taskID="; strRet += info.taskID; strRet += "×tamp="; strRet += info.timestamp; strRet += "&tradeNo="; strRet += info.tradeNo; strRet += "&transactionTime="; strRet += info.transactionTime; string strHashData = ""; FKBaseUtils.FKHash.GetHash(strRet, ref strHashData); info.signature = FKBaseUtils.FKRSASignature.RSASign(strCSharpPrivateKey, strHashData); } catch (Exception e) { LOGGER.ERROR($"Cacl verify code failed. Error = {e.ToString()}"); } }
/// <summary> /// 解析XLS文件 /// </summary> /// <param name="filename"></param> /// <param name="result"></param> /// <returns></returns> private bool parseXlsContent(string filename, ref SBillTaskResult result, SBillTaskInfo info) { ExcelReader reader = ExcelReader.CreateReader(filename); try { List <object> recordList = new List <object>(); int i = 0; while (reader.Read(1, ++i, ref recordList)) { // 跳过前三行(标题 本账号信息 列表头) if (i <= 3) { recordList.Clear(); continue; } /* * 交易日期 交易时间 交易金额 本次余额 对方户名 对方账号 交易行 交易渠道 交易类型 交易用途 交易摘要 * 20160828 102524 +270.00 284.91 罗春波 6228270921220010475 江西省分行9999行 网上银行 转账 网银转账 */ SBillTaskResult.SBankBillInfo billItem = new SBillTaskResult.SBankBillInfo(); string date = (string)recordList.ElementAt(0); string time = (string)recordList.ElementAt(1); if (string.IsNullOrEmpty(time)) { time = "000000"; } string dateTime = $"{date}-{time}"; billItem.submitTime = GetTradeTime(dateTime); // 时间不为空的需要过滤 为空总是返回 防止漏掉 if (!string.IsNullOrEmpty((string)recordList.ElementAt(1))) { if (!ResultFilter.TimeFilter(info, billItem.submitTime)) { recordList.Clear(); continue; } } //billItem.amount = Double.Parse($"{(string)recordList.ElementAt(2)}"); //billItem.balance = Double.Parse($"{(string)recordList.ElementAt(3)}"); billItem.amount = ($"{(string)recordList.ElementAt(2)}"); billItem.balance = ($"{(string)recordList.ElementAt(3)}"); billItem.accountName = $"{(string)recordList.ElementAt(4)}"; billItem.accountNumber = $"{(string)recordList.ElementAt(5)}"; billItem.accountBankName = $"{(string)recordList.ElementAt(6)}"; billItem.tradeChannel = $"{(string)recordList.ElementAt(7)}"; billItem.digest = $"{(string)recordList.ElementAt(10)}"; billItem.tradeType = TransformTradeTypeFromSummary($"{(string)recordList.ElementAt(10)}", $"{(string)recordList.ElementAt(2)}"); billItem.tradeUsage = $"{(string)recordList.ElementAt(9)}"; billItem.additionalComment = $"{(string)recordList.ElementAt(10)}"; // 明细未提供 // billItem.currency = ? result.billsList.Add(billItem); recordList.Clear(); } } catch (Exception e) { LOGGER.ERROR($"解析 XLS 文件失败, Error = {e.ToString()}"); result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_AutoProcessFailed; result.msg = "解析 XLS 文件失败."; return(false); } finally { reader.Close(); } result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_Successed; result.msg = "Successed"; return(true); }
/// <summary> /// 实际自动处理一次流水查询 /// </summary> /// <param name="info"></param> /// <param name="result"></param> /// <returns></returns> private bool AutomationBill(SBillTaskInfo info, ref SBillTaskResult result) { // 检查是否支持该银行 int nBankTypeID = GetBillBankTypeIDByName(info.bankCode); if (nBankTypeID <= 0) { LOGGER.ERROR($"Auto bill failed: Unknown bank code - {info.bankCode}"); result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_UnsupportBankCode; return(false); } // 检查重要参数是否合法 if (string.IsNullOrEmpty(info.accountNumber) || string.IsNullOrEmpty(info.username) || string.IsNullOrEmpty(info.password)) { result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_ArgumentInvalid; LOGGER.ERROR($"Auto bill failed: account info invalid"); return(false); } // 先进行清理 // 为保持长期登录状态,现不进行清理 - added by Frankie.W 2017-07-19 //{ // FKWebAutomatic.FKWebDriver.GetInstance.FKClose(); // ForceShutdownIE(); // Thread.Sleep(1000); //} DateTime startTime = DateTime.Now; bool bSuccessed = false; BankAutoBillBase imp = null; try { switch (nBankTypeID) { case 1: imp = new CCB_AutoBill(); break; case 2: imp = new BCM_AutoBill(); break; case 3: imp = new CMB_AutoBill(); break; case 4: imp = new ABC_AutoBill(); break; case 5: imp = new CITIC_AutoBill(); break; default: break; } if (imp == null) { LOGGER.ERROR($"Auto bill failed: imp not found"); result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_UnknownError; bSuccessed = false; } else { LOGGER.INFO($"Auto bill start: id = {info.taskID}"); imp.Init(); bSuccessed = imp.AutoBill(info.taskID, info, ref result); imp.Clear(); LOGGER.INFO($"Auto bill finish: id = {info.taskID}"); } } catch (Exception e) { LOGGER.ERROR($"Auto bill error occured. Error = {e.ToString()}"); result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_UnknownError; bSuccessed = false; } DateTime endTime = DateTime.Now; TimeSpan span = endTime - startTime; if (!bSuccessed) { //LOGGER.ERROR($"Auto bill failed: imp.AutoBill() return false"); // 执行失败 result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_AutoProcessFailed; } // 无论成功与否,都要进行清理 // 为保持长期登录状态,现不进行清理 - added by Frankie.W 2017-07-19 //{ // FKWebAutomatic.FKWebDriver.GetInstance.FKClose(); // ForceShutdownIE(); //} // 并记录到日志时间数据库,以便日志查询 FKLog.FKSQLiteLogMgr.GetInstance.AddTaskTimeLog(info.taskID, DateTime.Now); return(bSuccessed); }
/// <summary> /// 从Node中解析一条流水 /// </summary> /// <param name="node"></param> /// <param name="billItem"></param> private bool ParseOneBillHtmlPage(HtmlNode node, ref SBillTaskResult.SBankBillInfo billItem) { try { billItem.submitTime = GetTradeTime(node.SelectSingleNode("./td[2]").InnerHtml.Trim()); if (string.IsNullOrEmpty(billItem.submitTime)) { LOGGER.ERROR("交易时间为空"); return(false); } // 支出cny string outMoney = GetTradeAmount(node.SelectSingleNode("./td[3]").InnerHtml.Trim()); // 收入cny string inMoney = GetTradeAmount(node.SelectSingleNode("./td[4]").InnerHtml.Trim()); if (string.IsNullOrEmpty(inMoney) && string.IsNullOrEmpty(outMoney)) { LOGGER.ERROR("收入支出项同时为空"); return(false); } if (string.IsNullOrEmpty(outMoney) && !string.IsNullOrEmpty(inMoney)) { //billItem.amount = Double.Parse(inMoney); billItem.amount = (inMoney); } else if (string.IsNullOrEmpty(inMoney) && !string.IsNullOrEmpty(outMoney)) { //billItem.amount = -Double.Parse(outMoney); billItem.amount = "-" + (outMoney); } else { LOGGER.INFO($"进出账同时为空[{inMoney}][{outMoney}]"); return(false); } // 余额cny string balance = GetTradeAmount(node.SelectSingleNode("./td[5]").InnerHtml.Trim()); //billItem.balance = Double.Parse(balance); billItem.balance = (balance); // 对方账号 billItem.accountNumber = GetBankCardNumber(node.SelectSingleNode("./script").InnerHtml.Trim()); // 对方用户名 billItem.accountName = GetUserName(node.SelectSingleNode("./td[6]").InnerHtml.Trim()); // 币种 string currency = GetCurrency(node.SelectSingleNode("./td[7]").InnerHtml.Trim()); billItem.currency = TransformCurrencyTypeFromString(currency); // 摘要 string summary = GetTradeSummary(node.SelectSingleNode("./td[8]").InnerHtml.Trim()); billItem.digest = summary; // 交易类型 billItem.tradeType = TransformTradeTypeFromSummary(summary, billItem.amount); // 附言 billItem.additionalComment = GetAdditionalComment(node.SelectSingleNode("./td[9]").InnerHtml.Trim()); } catch (Exception e) { LOGGER.WARN($"Parser CCB one bill failed. Error = {e.ToString()}"); return(false); } LOGGER.DEBUG($"Get one bill, info = {billItem.ToString()}"); return(true); }
// 刷新事件 public static void Update() { if (!s_bIsLogining) // 未登录,不做任何刷新 { return; } try { FKWebAutomatic.FKWebDriver.GetInstance.SwitchToParentFrame(); FKWebAutomatic.FKWebDriver.GetInstance.SwitchToFrameByID("frameMain"); Thread.Sleep(500); /* * string[] xpaths = * { * "/html/body", * "/html/body/div[2]", * "/html/body/div[2]/div[1]", * "/html/body/div[2]/div[1]/div[2]/", * "/html/body/div[2]/div[1]/div[2]/ul", * "/html/body/div[2]/div[1]/div[2]/ul/li[1]", * "/html/body/div[2]/div[1]/div[2]/ul/li[1]/a", * }; * foreach (var xpath in xpaths) * { * if (!FKWebAutomatic.FKWebDriver.GetInstance.ClickByXPath(xpath)) * { * LOGGER.ERROR($"点击{xpath}失败"); * } * }*/ int retryCount = 3; for (int i = 0; i < retryCount; i++) { if (FKWebAutomatic.FKWebDriver.GetInstance.ClickByXPath("/html/body/div[2]/div[1]/div[2]/ul/li[1]/a")) { var element = FKWebDriver.GetInstance.WaitUntilVisibleByXPath("//*[@id=\"tranArea\"]", 30000); if (element != null) { LOGGER.INFO("BCM刷新主页成功"); return; } else { LOGGER.ERROR($"刷新等待主页元素超时,等待重试"); } } else { // 出现任何异常,立即关闭浏览器设置为未登录,等待下次登录 LOGGER.INFO($"BCM刷新主页,失败[ClickByID返回false],等待重试"); } Thread.Sleep(5000); } } catch (Exception e) { LOGGER.ERROR($"Update BCM bank error occured, IE driver will shutdown. Error = {e.ToString()}"); // 出现任何异常,立即关闭浏览器设置为未登录,等待下次登录 FKWebDriver.GetInstance.Close(); ForceShutdownIE(); s_bIsLogining = false; } LOGGER.INFO($"BCM刷新主页失败,清理ie等待下次重新登录"); FKWebDriver.GetInstance.Close(); ForceShutdownIE(); s_bIsLogining = false; }
private bool ParseAutoBillRegex(string content, ref SBillTaskResult result, SBillTaskInfo info) { Regex reg = new Regex($"\\{{stdessvldt=(?<date>.*?), " + $"stdes2bref=(?<sumary>.*?), " + $"stdes1opna=(?<stdes1opna>.*?), " + $"stdsumtrsq=(?<serialnumber>.*?), " + $"equipmentNO=(?<ignore2>.*?), " + $"stdessrvfg=(?<stdessrvfg>.*?), " + $"std400desc=(?<std400desc>.*?), " + $"stdesstrno=(?<stdesstrno>.*?), " + $"stdes2opid=(?<stdes2opid>.*?), " + $"stdessdcfg=(?<stdessdcfg>.*?), " + $"stdes2bfcd=(?<stdes2bfcd>.*?), " + $"stdessctfg=(?<stdessctfg>.*?), " + $"stdes2opna=(?<stdes2opna>.*?), " + $"stdesstrdt=(?<stdesstrdt>.*?), " + $"stdoppacna=(?<username>.*?), " + $"stdesstram=(?<amount>.*?), " + $"stdessfnfg=(?<stdessfnfg>.*?), " + $"stdes1bfcd=(?<stdes1bfcd>.*?), " + $"stdessacbl=(?<balance>.*?), " + $"stdesstrtm=(?<time>.*?), " + $"stdes1opid=(?<stdes1opid>.*?), " + $"stdesstrcd=(?<stdesstrcd>.*?), " + $"fndoppacno=(?<cardnumber>.*?), " + $"stdoppbrna=(?<bankname>.*?)" + $"\\}}" + $""); var matches = reg.Matches(content); if (matches.Count == 0) { LOGGER.INFO("未找到有效流水数据,可能已经查到最后一页"); return(false); } foreach (Match one in matches) { SBillTaskResult.SBankBillInfo billItem = new SBillTaskResult.SBankBillInfo(); // 解析单一流水对象 billItem.submitTime = GetRegexTradeTime($"{one.Groups["date"].Value}-{one.Groups["time"].Value}"); billItem.serialNo = one.Groups["serialnumber"].Value; if (billItem.serialNo == "null") { billItem.serialNo = ""; } billItem.accountBankName = one.Groups["bankname"].Value; if (billItem.accountBankName == "null") { billItem.accountBankName = ""; } billItem.accountName = one.Groups["username"].Value; if (billItem.accountName == "null") { billItem.accountName = ""; } billItem.additionalComment = one.Groups["sumary"].Value; if (billItem.additionalComment == "null") { billItem.additionalComment = ""; } billItem.balance = one.Groups["balance"].Value; if (billItem.balance == "null") { billItem.balance = ""; } billItem.amount = one.Groups["amount"].Value; if (billItem.amount == "null") { billItem.amount = "0.0"; } billItem.accountNumber = one.Groups["cardnumber"].Value; var inOrOut = one.Groups["stdessdcfg"].Value; if (inOrOut == "C") { billItem.amount = "+" + billItem.amount; } else if (inOrOut == "D") { billItem.amount = "-" + billItem.amount; } else { LOGGER.ERROR($"未知存取类型[{inOrOut}]"); continue; } billItem.tradeType = TransformTradeTypeFromSummary(one.Groups["stdes2bfcd"].Value, inOrOut); if (ResultFilter.TimeFilter(info, billItem.submitTime)) { result.billsList.Add(billItem); } } return(true); }
/// <summary> /// 实际自动处理一次自动出款 /// </summary> /// <param name="info"></param> /// <param name="result"></param> /// <returns></returns> private bool AutomationOut(SOutTaskInfo info, ref SOutTaskResult result) { // 检查是否支持该银行 int nBankTypeID = GetOutBankTypeIDByName(info.fromBankCode); if (nBankTypeID <= 0) { result.status = (int)SOutTaskResult.ENUM_OutcomeActionStatus.eOutcomeActionStatus_UnsupportBankCode; return(false); } // 先进行清理 // 为保持长期登录状态,现不进行清理 - added by Frankie.W 2017-07-19 //{ // FKWebAutomatic.FKWebDriver.GetInstance.FKClose(); // ForceShutdownIE(); // Thread.Sleep(1000); //} DateTime startTime = DateTime.Now; bool bSuccessed = false; BankAutoOutBase imp = null; try { switch (nBankTypeID) { case 1: imp = new CMBC_AutoOut(); break; default: break; } if (imp == null) { LOGGER.ERROR($"Auto out failed."); result.status = (int)SOutTaskResult.ENUM_OutcomeActionStatus.eOutcomeActionStatus_UnknownError; bSuccessed = false; } else { imp.Init(); bSuccessed = imp.AutoDo(info.taskID, info, ref result); imp.Clear(); } } catch (Exception e) { LOGGER.ERROR($"Auto do error occured. Error = {e.ToString()}"); bSuccessed = false; } DateTime endTime = DateTime.Now; TimeSpan span = endTime - startTime; if (!bSuccessed) { LOGGER.ERROR($"Auto do failed."); // 执行失败 result.status = (int)SOutTaskResult.ENUM_OutcomeActionStatus.eOutcomeActionStatus_AutoProcessFailed; } // 无论成功与否,都要进行清理 // 为保持长期登录状态,现不进行清理 - added by Frankie.W 2017-07-19 //{ // FKWebAutomatic.FKWebDriver.GetInstance.FKClose(); // ForceShutdownIE(); //} // 并记录到日志时间数据库,以便日志查询 FKLog.FKSQLiteLogMgr.GetInstance.AddTaskTimeLog(info.taskID, DateTime.Now); return(bSuccessed); }
/// <summary> /// 心跳函数 /// </summary> private static void OnHeartbeatTimerEvent(Object source, ElapsedEventArgs e, string strHeartbeatUrl, MainForm form) { Thread.CurrentThread.Name = "FKHeartbeatThread"; if (!FKConfig.IsUseHttpServer) { return; } try { if (form.GetCurCashierNodeID() == INVALID_NODE_ID) { // NodeID无效,则重新注册 form.ClearLostHeartbeatCount(); SRegisteNode node = new SRegisteNode(); node.bankCardNo = FKConfig.BankCardNo; node.ip = string.IsNullOrEmpty(FKConfig.LocalIP) ? FKBaseUtils.FKSystemEnviSettingHelper.GetLocalIPAddressByUri(FKConfig.ServerRegisteUrl) : FKConfig.LocalIP; node.publicKey = RSAKeyContainer.GetInstance.GetCSharpPublicKey(); LOGGER.INFO($"Begin to register to server. Bank card No = {node.bankCardNo}, Ip = {node.ip}, C# public key = {node.publicKey}"); HttpSendResult result = RequestSender.SendRequestToServer(node); if (result.IsSendSuccessed() && result.ErrorStatus == 1 && (!string.IsNullOrEmpty(result.publicKey))) { form.SetCurCashierNodeID(result.NodeID); RSAKeyContainer.GetInstance.SetJavaPublicKey(result.publicKey); LOGGER.INFO($"Register to server successed. Node id = {result.NodeID}, Java public key = {RSAKeyContainer.GetInstance.GetJavaPublicKey()}"); return; } LOGGER.ERROR($"Register to server failed. Node id = {result.NodeID}, Java public key = {RSAKeyContainer.GetInstance.GetJavaPublicKey()}"); return; } else { // 有效NodeID,表示注册成功,则发送心跳 SHeartbeat node = new SHeartbeat(); node.id = form.GetCurCashierNodeID(); node.taskID = form.GetCurTaskID(); HttpSendResult result = RequestSender.SendRequestToServer(node); if (result.IsSendSuccessed() && result.ErrorStatus == 1 && result.NodeID > 0) { LOGGER.INFO($"Heart-beat successed. NodeID = {node.id}, TaskID = {node.taskID}"); return; } else { // 发送心跳失败 form.AddLostHeartbeatCount(); // 追加一次失败计数 if (form.GetLostHeartbeatCount() >= MAX_ALLOW_HEARTBEAT_FAILED_TIME) { // 心跳失联太多次 form.SetCurCashierNodeID(INVALID_NODE_ID); RSAKeyContainer.GetInstance.SetJavaPublicKey(string.Empty); LOGGER.WARN($"Heart-beat disconnect for a long time... Ready to register node again."); } else { // 心跳的确失联了,但还能忍 LOGGER.INFO($"Heart-beat connect failed {form.GetLostHeartbeatCount()} times. NodeID = {node.id}, TaskID = {node.taskID}"); } } } } catch (Exception ex) { LOGGER.ERROR($"Heart-beat error occured. Error = {ex.ToString()}"); } }