Exemple #1
0
        /// <summary>
        /// 判断当前已打开的IE中账号 与 当前任务账号 是否一致
        /// </summary>
        /// <param name="info"></param>
        /// <returns></returns>
        private bool IsSameAccount(SBillTaskInfo info)
        {
            // 未登录,直接登录即可
            if (!s_bIsLogining)
            {
                return(true);
            }

            try
            {
                var currUser = getCardInfo();
                if (currUser.userName == info.username)
                {
                    LOGGER.INFO($"当前在线用户[{FKBaseUtils.FKStringHelper.MaskString(info.username)}]和登录用户一致");
                    return(true);
                }
            }
            catch
            {
                LOGGER.INFO($"新登录用户[{FKBaseUtils.FKStringHelper.MaskString(info.username)}], 当前在线用户可能不是BCM用户");
                return(false);
            }
            LOGGER.INFO($"新登录用户[{FKBaseUtils.FKStringHelper.MaskString(info.username)}], 当前在线用户可能不是BCM用户");
            return(false);
        }
Exemple #2
0
        /// <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>
 /// 判断当前已打开的IE中账号 与 当前任务账号 是否一致
 /// </summary>
 /// <param name="info"></param>
 /// <returns></returns>
 private bool IsSameAccount(SBillTaskInfo info)
 {
     // 未登录,直接登录即可
     if (!s_bIsLogining)
     {
         return(true);
     }
     // 已登录,从页面获取account
     try
     {
         FKWebDriver.GetInstance.SwitchToFrameByID("contentFrame");
         // 这是判断abc,如果不是abc,此项将为0,获取失败
         string accountNumber = FKWebDriver.GetInstance.GetAttributeByXPath("//*[@id=\"debit\"]", "data-acctid");
         if (String.IsNullOrEmpty(accountNumber))
         {
             LOGGER.INFO($"当前登录用户为空,需要重新登录");
             return(false);
         }
         if (String.Compare(info.accountNumber, accountNumber, true) != 0)
         {
             LOGGER.INFO($"新登录用户[{FKBaseUtils.FKStringHelper.MaskString(info.accountNumber)}], 当前在线用户[{FKBaseUtils.FKStringHelper.MaskString(accountNumber)}]");
             return(false);
         }
         FKWebDriver.GetInstance.SwitchToParentFrame();
     }
     catch
     {
         LOGGER.INFO($"新登录用户[{FKBaseUtils.FKStringHelper.MaskString(info.accountNumber)}], 当前在线用户可能不是ABC用户");
         return(false);
     }
     LOGGER.INFO($"当前在线用户[{FKBaseUtils.FKStringHelper.MaskString(info.accountNumber)}]和登录用户一致");
     return(true);
 }
        /// <summary>
        /// 获取验证码字符串
        /// </summary>
        /// <returns></returns>
        private string GetVerificationCodeString()
        {
            string tmpFile = System.IO.Path.GetTempFileName();

            // 保存图片文件
            if (!SaveVerificationCodeFile(tmpFile))
            {
                return("");
            }

            // 使用自定义方式解析出字符串
            string CustomString = CustomGetStringByImage(tmpFile);
            // 使用OCR解析出字符串
            string ORCString = "";// OCRGetStringByImage(tmpFile);

            CustomString = CustomString.Replace("*", "");
            ORCString    = ORCString.Replace("*", "");

            LOGGER.INFO($"验证码:FK = {CustomString} OCR = {ORCString}");
            // 删除图片文件
            File.Delete(tmpFile);

            if (CustomString.Length != 4 && ORCString.Length == 4)
            {
                return(ORCString);
            }
            else if (CustomString.Length == 4 && ORCString.Length != 4)
            {
                return(CustomString);
            }
            else
            {
                return(CustomString);   // 优先自定义
            }
        }
Exemple #5
0
        /// <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);
            }
        }
Exemple #6
0
        /// <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");
                }
            }
        }
Exemple #7
0
        /// <summary>
        /// 按下执行消息
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button_DoCmd_Click(object sender, EventArgs e)
        {
            string strCmd = textBox_Cmd.Text;

            string[] strCmds = strCmd.Split(' ');
            if (strCmds.Length < 1)
            {
                button_Help_Click(null, null);
                return;
            }
            bool   bSuccessed = false;
            string strRet     = string.Empty;

            if (strCmds.Length == 1)
            {
                bSuccessed = DoCmd(strCmds[0], null, ref strRet);
            }
            else
            {
                bSuccessed = DoCmd(strCmds[0], strCmds.Skip(1).ToArray(), ref strRet);
            }
            if (bSuccessed)
            {
                LOGGER.INFO($"DoCmd {strCmds[0]} successed \n {strRet}");
            }
            else
            {
                LOGGER.WARN($"DoCmd {strCmds[0]} failed. \n {strRet}");
            }
        }
Exemple #8
0
 private bool IsSameAccount(SBillTaskInfo info)
 {
     // 未登录,直接登录即可
     if (!s_bIsLogining)
     {
         return(true);
     }
     // 已登录,从页面获取account
     try
     {
         // 这是判断ccb,如果不是ccb,此项将为0,获取失败
         string userName = FKWebDriver.GetInstance.GetAttributeByXPath("/html/body/div[6]/div[6]/div[1]/div[1]/p/b/span", "title");
         if (String.IsNullOrEmpty(userName))
         {
             return(false);
         }
         if (String.Compare(info.username, userName, true) != 0)
         {
             LOGGER.INFO($"新登录用户[{FKBaseUtils.FKStringHelper.MaskString(info.username)}], 当前在线用户[{FKBaseUtils.FKStringHelper.MaskString(userName)}]");
             return(false);
         }
     }
     catch {
         LOGGER.INFO($"新登录用户[{FKBaseUtils.FKStringHelper.MaskString(info.username)}], 当前在线用户可能不是CCB用户");
         return(false);
     }
     LOGGER.INFO($"当前在线用户[{FKBaseUtils.FKStringHelper.MaskString(info.username)}]和登录用户一致");
     return(true);
 }
        /// <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");
        }
Exemple #10
0
        /// <summary>
        /// 时间过滤器
        /// </summary>
        /// <param name="info"></param>
        /// <param name="oneBill"></param>
        /// <returns> false表示被过滤掉 true表示需保留</returns>
        public static bool TimeFilter(SBillTaskInfo info, string billTime)
        {
            string startTime = info.startTime;
            string endTime   = info.endTime;

            //一天以内数据不做过滤
            if (startTime.Substring(0, 8) == endTime.Substring(0, 8))
            {
                return(true);
            }
            DateTime dateTimeStart;
            bool     ret = DateTime.TryParseExact(startTime, "yyyyMMdd HH:mm:ss", null, DateTimeStyles.None, out dateTimeStart);

            if (!ret)
            {
                LOGGER.INFO($"过滤开始时间格式错误:{startTime}");
                return(true);
            }
            DateTime dateTimeEnd;

            ret = DateTime.TryParseExact(endTime, "yyyyMMdd HH:mm:ss", null, DateTimeStyles.None, out dateTimeEnd);
            if (!ret)
            {
                LOGGER.INFO($"过滤结束时间格式错误:{endTime}");
                return(true);
            }

            if (dateTimeEnd.CompareTo(dateTimeStart) < 0)
            {
                //LOGGER.INFO($"过滤结束时间:{endTime}早于开始时间:{startTime}");
                return(true);
            }
            DateTime dateTimeSumbmit;

            ret = DateTime.TryParseExact(billTime, "yyyy-MM-dd HH:mm:ss", null, DateTimeStyles.None, out dateTimeSumbmit);
            if (!ret)
            {
                LOGGER.INFO($"明细时间格式错误:{billTime}");
                return(true);
            }
            if (dateTimeSumbmit.CompareTo(dateTimeStart) < 0)
            {
                //LOGGER.INFO($"删除项时间[{billTime}],过滤开始时间[{startTime}]");
                return(false);
            }
            else if (dateTimeSumbmit.CompareTo(dateTimeEnd) > 0)
            {
                //LOGGER.INFO($"删除项时间[{billTime}],过滤结束时间[{endTime}]");
                return(false);
            }
            return(true);
        }
Exemple #11
0
        public void Check()
        {
            var now = DateTime.Now;

            int leftSeconds = secondsForEachCall - (int)now.Subtract(lastCallTime).TotalSeconds;

            if (leftSeconds > 0)
            {
                LOGGER.INFO($"调用频率限制,睡眠:{leftSeconds}s");
                Thread.Sleep(leftSeconds * 1000);
            }
            lastCallTime = DateTime.Now;
        }
Exemple #12
0
        /// <summary>
        /// 解析流水页面
        /// </summary>
        /// <param name="html"></param>
        /// <param name="result"></param>
        /// <returns></returns>
        private bool ParseAutoBillHtmlPage(HtmlDocument html, ref SBillTaskResult result, SBillTaskInfo info)
        {
            try
            {
                var nodes = html.DocumentNode.SelectSingleNode("./table/tbody");
                if (nodes == null)
                {
                    LOGGER.INFO("未找到有效流水数据,可能已经查到最后一页");
                    return(false);
                }
                var items = nodes.SelectNodes("./tr");
                if (items == null)
                {
                    LOGGER.INFO("未找到有效流水数据,可能已经查到最后一页");
                    return(false);
                }
                if (items.Count == 0)
                {
                    LOGGER.INFO("未找到有效流水数据,可能已经查到最后一页");
                    return(false);
                }

                foreach (var node in nodes.SelectNodes("./tr"))
                {
                    SBillTaskResult.SBankBillInfo billItem = new SBillTaskResult.SBankBillInfo();
                    // 解析单一流水对象
                    if (ParseOneBillHtmlPage(node, ref billItem) == false)
                    {
                        continue;
                    }
                    // citic明细没有时间,一律不过滤

                    /*if (ResultFilter.TimeFilter(info, billItem.submitTime))
                     * {
                     *  result.billsList.Add(billItem);
                     * }*/

                    result.billsList.Add(billItem);
                }

                result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_Successed;
            }
            catch (Exception e)
            {
                result.msg    = "CITIC解析返回html错误";
                result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_AutoProcessFailed;
                LOGGER.WARN($"CITIC解析返回html错误:{e.Message}");
                return(false);
            }
            return(true);
        }
        /// <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;
        }
Exemple #14
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.");
 }
Exemple #15
0
        /// <summary>
        /// 释放
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        private void FKClose()
        {
            // 关闭心跳
            StopHeartbeat();
            // 申请从服务器注销
            UnregsiterFromServer();
            // 关闭Web服务器监听
            StopWebServer();
            // 关闭逻辑线程
            StopLogicThread();
            // 强杀IEDriver
            ForceShutdownIE();

            LOGGER.INFO("Form close done.");
        }
Exemple #16
0
        /// <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;
        }
Exemple #17
0
        /// <summary>
        /// 安全释放App
        /// </summary>
        internal void SafeShutdown()
        {
            LOGGER.INFO($"Begin to safe shutdown. NodeID = {GetCurCashierNodeID()}");

            try
            {
                // 计划下一部清除行为
                FKClose();
                // 清空所有的Key
                RSAKeyContainer.GetInstance.Clear();
            }
            catch (Exception e)
            {
                LOGGER.WARN($"Safe shutdown failed, we will force close. Error = {e.ToString()}");
            }
        }
Exemple #18
0
        /// <summary>
        /// Form 启动初始化函数
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MainForm_Load(object sender, System.EventArgs e)
        {
            LOGGER.INFO("System init done, begin main form load.");

            // 设置标题
            this.Text = GetAppDescption();
            // 设置本线程名
            Thread.CurrentThread.Name = "FKMainThread";
            // 初次调用单例,创建RSA公私钥对
            RSAKeyContainer.GetInstance.ToString();

            m_InitTimer          = new System.Windows.Forms.Timer();
            m_InitTimer.Interval = 1000;
            m_InitTimer.Tick    += new EventHandler(OnTimer_Init);
            m_InitTimer.Start();
        }
Exemple #19
0
 /// <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);
 }
Exemple #20
0
        /// <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;
        }
Exemple #21
0
 private bool IsSameAccount(SBillTaskInfo info)
 {
     // 未登录,直接登录即可
     if (!s_bIsLogining)
     {
         return(true);
     }
     // 已登录,从页面获取account
     try
     {
         // 这是判断abc,如果不是abc,此项将为0,获取失败
         string cardCode = FKWebDriver.GetInstance.GetAttributeByXPath("//*[@class=\"each_card\"]", "cardcode");
         if (String.IsNullOrEmpty(cardCode))
         {
             LOGGER.INFO($"当前登录用户为空,需要重新登录");
             return(false);
         }
         string[] cardCodeArr = cardCode.Split('|');
         if (cardCodeArr.Length < 2)
         {
             LOGGER.INFO($"当前登录用户未找到,需要重新登录");
             return(false);
         }
         string accountNumber = cardCodeArr[1];
         if (String.IsNullOrEmpty(accountNumber))
         {
             LOGGER.INFO($"当前登录用户为空,需要重新登录");
             return(false);
         }
         if (String.Compare(info.accountNumber, accountNumber, true) != 0)
         {
             LOGGER.INFO($"新登录用户[{FKBaseUtils.FKStringHelper.MaskString(info.accountNumber)}], 当前在线用户[{FKBaseUtils.FKStringHelper.MaskString(accountNumber)}]");
             return(false);
         }
     }
     catch
     {
         LOGGER.INFO($"新登录用户[{FKBaseUtils.FKStringHelper.MaskString(info.accountNumber)}], 当前在线用户可能不是CITIC用户");
         return(false);
     }
     LOGGER.INFO($"当前在线用户[{FKBaseUtils.FKStringHelper.MaskString(info.accountNumber)}]和登录用户一致");
     return(true);
 }
Exemple #22
0
        /// <summary>
        /// 初始化
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        private void OnTimer_Init(object sender, EventArgs args)
        {
            // 计时器进行一次足够了
            if (m_InitTimer != null)
            {
                m_InitTimer.Stop();
            }
            // 创建Web服务器对象
            CreateWebServer();
            // 启动逻辑线程
            StartLogicThread();
            // 启动Web服务器监听
            StartWebServer();
            // 向服务器进行注册
            if (RegsiterToServer())
            {
                // 开始心跳
                StartHeartbeat();
            }

            LOGGER.INFO("Form init done.");
        }
Exemple #23
0
 /// <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);
 }
        /// <summary>
        /// 自动查询核心函数
        /// </summary>
        /// <param name="nTaskID"></param>
        /// <param name="info"></param>
        /// <param name="result"></param>
        /// <returns></returns>
        public override bool AutoBill(int nTaskID, SBillTaskInfo info, ref SBillTaskResult result)
        {
            // 判断当前是否是同一个账号
            if (!IsSameAccount(info))
            {
                FKWebDriver.GetInstance.Close();
                ForceShutdownIE();
                s_bIsLogining = false;
            }
            // 先尝试进行登录
            string logPrefix = $"银行代码[ABC]获取明细,TaskID[{info.taskID}],";

            LOGGER.INFO($"{logPrefix}正在尝试登录 ...");

            s_bIsLogining = TryLogin(info, ref result);
            if (!s_bIsLogining)
            {
                LOGGER.INFO($"{logPrefix}登录失败,失败原因[{result.msg}]");
                FKWebDriver.GetInstance.Close();
                ForceShutdownIE();
                return(false);
            }

            LOGGER.INFO($"{logPrefix}登录成功,开始获取明细");
            // 查询
            bool ret = QueryAutoBill(info, ref result);

            if (!ret)
            {
                LOGGER.INFO($"{logPrefix}获取明细失败,失败原因[{result.msg}]");
            }
            else
            {
                LOGGER.INFO($"{logPrefix}获取明细成功");
            }
            return(ret);
        }
        /// <summary>
        /// 刷新事件
        /// </summary>
        public static void Update()
        {
            if (!s_bIsLogining) // 未登录,不做任何刷新
            {
                return;
            }
            try
            {
                // 农行刷新时经常超时导致刷新失败,重试3次,有效减少超时导致的失败。
                int retryCount = 3;
                for (int i = 0; i < retryCount; i++)
                {
                    // 刷新首页按钮,保证登录状态
                    if (FKWebAutomatic.FKWebDriver.GetInstance.ClickByXPath("/html/body/div[5]/div/div[2]/ul/li[1]/span"))
                    {
                        LOGGER.INFO("ABC刷新主页成功");
                        return;
                    }
                    else
                    {
                        // 出现任何异常,立即关闭浏览器设置为未登录,等待下次登录
                        LOGGER.INFO($"ABC刷新主页,失败[ClickByID返回false],等待重试");
                        Thread.Sleep(5000);
                    }
                }
            }
            catch (Exception e)
            {
                LOGGER.INFO($"ABC刷新主页,失败[{e.Message}]");
            }

            LOGGER.INFO($"ABC刷新主页失败,清理ie等待下次重新登录");
            // 重试后仍然失败
            FKWebDriver.GetInstance.Close();
            ForceShutdownIE();
            s_bIsLogining = false;
        }
Exemple #26
0
        /// <summary>
        /// 获取验证码字符串
        /// </summary>
        /// <returns></returns>
        private string GetVerificationCodeString()
        {
            string tmpFile = System.IO.Path.GetTempFileName();

            // 保存图片文件
            if (!SaveVerificationCodeFile(tmpFile))
            {
                LOGGER.INFO($"保存文件失败");
                return("");
            }

            // 使用自定义方式解析出字符串
            string CustomString = CustomGetStringByImage(tmpFile);
            // 使用OCR解析出字符串
            string ORCString = OCRGetStringByImage(tmpFile);

            CustomString = CustomString.Replace("*", "");
            ORCString    = ORCString.Replace("*", "");

            LOGGER.INFO($"验证码:FK = {CustomString} OCR = {ORCString}");
            // 删除图片文件
            File.Delete(tmpFile);
            int charCount = 5;

            if (CustomString.Length != charCount && ORCString.Length == charCount)
            {
                return(ORCString);
            }
            else if (CustomString.Length == charCount && ORCString.Length != charCount)
            {
                return(CustomString);
            }
            else
            {
                return(ORCString);   // 自定义训练好之前优先tesser
            }
        }
        /// <summary>
        /// 初始化函数
        /// </summary>
        /// <returns></returns>
        public override bool Init()
        {
            s_FreqLimit.Check();
            try {
                // 如果没有登录过,清除前面残留的ie
                if (s_bIsLogining == false)
                {
                    var bankCode = "ABC";
                    LOGGER.INFO($"银行代码为[{bankCode}]的账号未在线,清理当前在线账号");
                    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);
        }
Exemple #28
0
        private BCM_BankInfo getCardInfo()
        {
            string PSessionId = FKWebAutomatic.FKWebDriver.GetInstance.GetAttributeByXPath("//*[@name=\"PSessionId\"]", "value");
            Dictionary <string, string> getHeader = new Dictionary <string, string>();

            getHeader.Add("Cookie", FKWebAutomatic.FKWebDriver.GetInstance.GetAllCookies());
            getHeader.Add("Accept", "text/javascript;charset=utf-8");
            getHeader.Add("Referer", $"https://pbank.95559.com.cn/personbank/app/pebs.do?PSessionId={PSessionId}&x-channel=0&menuCode=&appId=&startMenu=&ibpsProtocolReq=&pebsUrl=&args=#1");
            getHeader.Add("Accept-Language", "zh-CN");
            getHeader.Add("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko");

            getHeader.Add("Content-Type", "application/x-www-form-urlencoded");
            getHeader.Add("Accept-Encoding", "gzip, deflate");
            getHeader.Add("Host", "pbank.95559.com.cn");

            string getUrl   = $"https://pbank.95559.com.cn/personbank/system/syCardList.ajax?PSessionId={PSessionId}&x-channel=0&menuCode=P002000";
            string jsonData = FKHttp.FKHttpClient.GET(getUrl, getHeader);

            LOGGER.INFO(FKHttp.FKHttpClient.GET(getUrl, getHeader));
            BCM_BankInfo bcm_BankInfo = new BCM_BankInfo();

            try
            {
                var o = JsonConvert.DeserializeObject <dynamic>(jsonData);
                bcm_BankInfo.userName   = (string)o.RSP_BODY.accounts[0].alias;
                bcm_BankInfo.PSessionId = (string)o.RSP_BODY.PSessionId;
                bcm_BankInfo.safeValue  = (string)o.RSP_BODY.safeValue;
                bcm_BankInfo.uuid       = (string)o.RSP_BODY.accounts[0].uuid;
                bcm_BankInfo.cardNo     = ((string)o.RSP_BODY.accounts[0].cardNo).Replace(" ", "");
            }
            catch { }

            LOGGER.INFO($"bcm_BankInfo is {bcm_BankInfo.ToString()}");

            return(bcm_BankInfo);
        }
        /// <summary>
        /// 尝试登录
        /// </summary>
        /// <param name="info"></param>
        /// <param name="result"></param>
        /// <returns></returns>
        private bool TryLogin(SBillTaskInfo info, ref SBillTaskResult result)
        {
            if (s_bIsLogining)
            {
                return(true);
            }

            bool isOCRPass = false;

            try
            {
                //FKWebDriver webDriver = FKWebDriver.GetInstance;
                string loginUrl = FKConfig.ABCLoginUrl;
                // 此部分代码根据现有网银官网的页面设计
                // 如果个人银行网页改版,此处可能需要根据新页面做相应调整
                FKWebAutomatic.FKWebDriver.GetInstance.OpenUrl(loginUrl);

                // 等待出现登录界面
                var element = FKWebAutomatic.FKWebDriver.GetInstance.WaitUntilVisibleByXPath("//*[@id=\"username\"]", 30000);
                if (element == null)
                {
                    result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_WaitElementTimeout;
                    result.msg    = "等待登录账号元素超时,可能页面未正常打开";
                    return(false);
                }

                // 填充登录账号
                FKWebAutomatic.FKWebDriver.GetInstance.SetTextByID("username", info.username);
                // 填充密码
                LoginPassword(info.password);
                // 填充验证码,由于验证码可能识别失败,所以需要重试
                int retryCount = 20;
                for (int i = 0; i < retryCount; i++)
                {
                    string ocr = GetVerificationCodeString();

                    // 如果识别个数都不对 没必要输入了 重刷验证码再识别
                    if (ocr.Length == 4)
                    {
                        FKWebAutomatic.FKWebDriver.GetInstance.SetTextByID("code", ocr);
                        //移走焦点
                        FKWebAutomatic.FKWebDriver.GetInstance.ClickByID("username");
                        // 填充完成后等待识别验证码打钩
                        Thread.Sleep(5000);
                        // 第一次此元素为隐藏,等待出现
                        FKWebAutomatic.FKWebDriver.GetInstance.WaitUntilVisibleByXPath("//*[@id=\"imgError\"]", 10000);
                        // 识别结果获取
                        string successString = FKWebAutomatic.FKWebDriver.GetInstance.GetAttributeByXPath("//*[@id=\"imgError\"]", "class");
                        if (successString == "v-code-error right")
                        {
                            // 点击登录
                            FKWebAutomatic.FKWebDriver.GetInstance.ClickByID("logo");
                            bool isInput = false;
                            // 用户名提示为空 重新输入
                            if (FKWebAutomatic.FKWebDriver.GetInstance.IsElementVisiableByXPath("//*[@id=\"username-error\"]"))
                            {
                                LOGGER.INFO("用户名为空,重新输入");
                                FKWebAutomatic.FKWebDriver.GetInstance.SetTextByID("username", info.username);
                                isInput = true;
                            }
                            // 密码提示为空 重新输入
                            if (FKWebAutomatic.FKWebDriver.GetInstance.IsElementVisiableByXPath("//*[@id=\"powerpass_ie_dyn_Msg\"]"))
                            {
                                LOGGER.INFO("密码为空或者不正确,重新输入");
                                LoginPassword(info.password, true);
                                isInput = true;
                            }

                            // 多次输入验证码失败后 银行重新清空用户名密码,重填
                            if (FKWebAutomatic.FKWebDriver.GetInstance.IsElementVisiableByXPath("/html/body/div[2]/div[5]/div/div[1]/div[5]/form/div[5]"))
                            {
                                FKWebAutomatic.FKWebDriver.GetInstance.SetTextByID("username", info.username);
                                LoginPassword(info.password, true);
                                isInput = true;
                            }
                            if (isInput)
                            {
                                // 输入后需要重新点击登录
                                FKWebAutomatic.FKWebDriver.GetInstance.ClickByID("logo");
                            }
                            isOCRPass = true;
                            break;
                        }
                        Console.WriteLine($"successString = {successString}");
                    }
                    // 失败 重新刷新验证码
                    FKWebAutomatic.FKWebDriver.GetInstance.ClickByID("vCode");
                    Thread.Sleep(1000);
                }

                if (!isOCRPass)
                {
                    result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_WaitElementTimeout;
                    result.msg    = "验证码超过重试次数";
                    return(false);
                }

                // 超时等待登陆成功
                element = FKWebAutomatic.FKWebDriver.GetInstance.WaitUntilVisibleByXPath("//*[@id=\"intro4-1\"]", 30000);
                if (element != null)
                {
                    LOGGER.INFO("成功获取登录element,登录成功");
                    return(true);
                }
                else
                {
                    result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_LoginFailed;
                    result.msg    = $"等待首页超时";
                    return(false);
                }
            }
            catch (Exception e)
            {
                result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_LoginFailed;
                result.msg    = $"TryLogin抛出异常[[{e.Message}]";
                return(false);
            }
        }
        /// <summary>
        /// 查询流水(在已登录成功后)
        /// </summary>
        /// <param name="info"></param>
        /// <param name="result"></param>
        /// <returns></returns>
        private bool QueryAutoBill(SBillTaskInfo info, ref SBillTaskResult result)
        {
            /** 完整的获取明细curl命令,此命令最终返回的是一个标准xls的文件,需要进一步解析文件才能提取出明细
             * ----------------------------------------------------------------------------------
             * curl 'https://perbank.abchina.com/EbankSite/AccountTradeDetailDownloadAct.do'
             * -H 'Accept:	text/html, application/xhtml+xml, *\/*'
             * - H 'Referer: https://perbank.abchina.com/EbankSite/AccountTradeDetailQueryInitAct.do'
             * - H 'Accept-Language: zh-CN'
             * - H 'User-Agent:	Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko'
             * - H 'Content-Type: application/x-www-form-urlencoded'
             * - H 'Accept-Encoding: gzip, deflate'
             * - H 'Host: perbank.abchina.com'
             * - H 'Content-Length: 136'
             * - H 'Connection: Keep-Alive'
             * - H 'Cookie:	WT_FPC=id=10.235.177.249-2296909152.30606638:lv=1500978056097:ss=1500977553848; ASP.NET_SessionId=elwlscn2t0puisyczziuwwdt; _ABCPerbankLogonCookie__=; BIGipServerpool_perbank_EbankSite=!Q5CBtVY5fUNWSa38cCqlIAZb8CxfUQboxPynXFLAUdu31cHrqqE7Bl6NuLXg8tH9gLUKWOZc2cVc9J8='
             * --data 'acctId=6228482568556511677&acctOpenBankId=34905&acctType=401&provCode=12&acctCurCode=156&oofeFlg=0&trnStartDt=20160804&trnEndDt=20170727'
             *
             * ----------------------------------------------------------------------------------
             * --data参数解释
             * acctId           卡号 从传入参数中获取
             * acctOpenBankId   开户行 需要从页面提取
             * acctType         不懂 但是应该是账户相关 需要从页面提取
             * provCode         省份code 页面提取
             * acctCurCode      不懂 页面提取
             * oofeFlg          不懂 传0
             * trnStartDt       开始日期
             * trnEndDt         结束日期
             * **/
            if (!s_bIsLogining)
            {
                // 未登录
                return(false);
            }
            result.taskID = info.taskID;
            try
            {
                // 实际测试过程中发现这个链接是随着账号改变,需要在首页中获取
                string postUrl = FKConfig.ABCBillUrl;
                if (string.IsNullOrEmpty(postUrl))
                {
                    result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_AutoProcessFailed;
                    result.msg    = "ABC Post url获取失败";
                    return(false);
                }
                // 构造post content
                var postContentString = GetAutoBillPostContent(info);
                if (string.IsNullOrEmpty(postContentString))
                {
                    result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_AutoProcessFailed;
                    result.msg    = "ABC Post content构造失败";
                    return(false);
                }
                // 构造post header
                var postHeader = GetAutoBillPostHeader();

                // POST获取文件
                string tmpFile    = System.IO.Path.GetTempFileName();
                string postResult = (string)FKHttp.FKHttpClient.POST(postUrl, postContentString, postHeader, 300000, tmpFile);

                if (File.Exists(tmpFile))
                {
                    bool bRet       = parseXlsContent(tmpFile, ref result, info);
                    int  nBillCount = 0;
                    if (result.billsList != null)
                    {
                        nBillCount = result.billsList.Count;
                    }
                    LOGGER.INFO($"XLS Tmp file = {tmpFile} InfoLen = {nBillCount}");
                    //delFile(tmpFile); // TODO: 前期测试不要删除,文件不太大的话,不会引发过多问题,之后版本删除
                    return(bRet);
                }
                else
                {
                    result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_AutoProcessFailed;
                    LOGGER.INFO($"Can't find XLS Tmp file = {tmpFile}");
                    return(false);
                }
            }
            catch (Exception e)
            {
                result.msg = $"QueryAutoBill抛出异常[{e.Message}]";
                return(false);
            }
        }