Пример #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);
        }
Пример #2
0
 /// <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);
 }
Пример #3
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);
 }
Пример #4
0
        public void testXls()
        {
            SBillTaskResult result = new SBillTaskResult();
            SBillTaskInfo   info   = new SBillTaskInfo();

            parseXlsContent($"D:\\code\\FKCashier\\FKCashierBank\\bin\\x86\\Debug\\test\\detailabc20170727.xls", ref result, info);
        }
Пример #5
0
        /// <summary>
        /// 获取查询POST 正文参数
        /// </summary>
        /// <param name="info"></param>
        /// <returns></returns>
        private string GetAutoBillPostContent(SBillTaskInfo info, int pageNumber = 1)
        {
            // 如下是获取流水必须的参数,对于不懂得参数一律直接传

            /*
             * ACC_NO=6217004220011286774& ->卡号(一个账户下可以挂多个卡号,所以需要提供卡号)
             * ACC_SIGN =0101010& ->不懂
             * TXCODE =310200& ->不懂
             * SKEY =lL4XRK& ->这个在登录后首页隐藏的input可以获取到
             * USERID =450326199308192729& ->同上
             * ACCTYPE2 =12& ->不懂
             * PAGE=1& ->页数
             * CURRENT_PAGE=1&->页数
             * LUGANGTONG =0&->不懂
             * START_DATE =20160711&->开始日期
             * END_DATE =20170718->结束日期
             */

            // POST参数表
            Dictionary <string, string> postContent = new Dictionary <string, string>();

            // 固定参数
            postContent.Add("ACC_SIGN", "0101010");
            postContent.Add("TXCODE", "310200");
            postContent.Add("ACCTYPE2", "12");
            postContent.Add("PAGE", $"{pageNumber}");
            if (pageNumber == 1)
            {
                postContent.Add("flagnext", $"1");
            }
            else
            {
                postContent.Add("flagnext", $"4");
            }
            postContent.Add("CURRENT_PAGE", $"1");
            postContent.Add("LUGANGTONG", "0");
            // 非固定参数
            try
            {
                postContent.Add("ACC_NO", info.accountNumber);
                postContent.Add("START_DATE", info.startTime.Substring(0, 8));
                postContent.Add("END_DATE", info.endTime.Substring(0, 8));
                // 如下路径是通过firebug获取,网页如果有调整此处需要相应调整
                // 否则无法获取到对应的element
                postContent.Add("SKEY", FKWebDriver.GetInstance.GetAttributeByXPath("/html/body/div[6]/div[24]/div[3]/form/input[3]", "value"));
                postContent.Add("USERID", FKWebDriver.GetInstance.GetAttributeByXPath("/html/body/div[6]/div[24]/div[3]/form/input[4]", "value"));
            }
            catch (Exception e)
            {
                LOGGER.WARN($"Parser CCB bank post data failed. Error = {e.ToString()}");
                return(string.Empty);
            }

            // POST参数拼接
            return(string.Join("&", postContent.Select(x => x.Key + "=" + x.Value).ToArray()));
        }
Пример #6
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);
        }
Пример #7
0
        /// <summary>
        /// 获取 查询POST 内容数据
        /// </summary>
        /// <param name="info"></param>
        /// <returns></returns>
        private string GetAutoBillPostContent(SBillTaskInfo info)
        {
            // 如下是获取流水必须的参数,对于不懂得参数一律直接传

            /* PSessionId=088c8ed8ffff005abb5246f007a67eeb&
             *  x-channel=0&
             *  menuCode=P002000&
             *  step=batchDownLoad&
             *  cardNo=3d6fe2168b70566a7aa44c124f3265cd&
             *  selectCardNo=6222623210002390520&
             *  startDate=20160723&
             *  endDate=20170822&
             *  acoAcRecord=&
             *  queryType=&
             *  serialNo=&
             *  page=1
             */
            var cardInfo = getCardInfo();

            if (string.IsNullOrEmpty(cardInfo.cardNo))
            {
                return(null);
            }
            // POST参数表
            Dictionary <string, string> postContent = new Dictionary <string, string>();

            postContent.Add("x-channel", "0");
            postContent.Add("menuCode", "P002000");
            postContent.Add("step", "batchDownLoad");
            postContent.Add("acoAcRecord", "");
            postContent.Add("queryType", "");
            postContent.Add("serialNo", "");
            postContent.Add("page", "1");
            // 非固定参数
            try
            {
                postContent.Add("PSessionId", cardInfo.PSessionId);
                postContent.Add("cardNo", cardInfo.uuid);
                postContent.Add("selectCardNo", cardInfo.cardNo);
                postContent.Add("startDate", info.startTime.Substring(0, 8));
                postContent.Add("endDate", info.endTime.Substring(0, 8));
            }
            catch (Exception e)
            {
                LOGGER.WARN($"Parser BCM bank post data failed. Error = {e.ToString()}");
                return(string.Empty);
            }

            // POST参数拼接
            return(string.Join("&", postContent.Select(x => x.Key + "=" + x.Value).ToArray()));
        }
        /// <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;
        }
Пример #9
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);
 }
Пример #10
0
        private bool QueryAutoBill(SBillTaskInfo info, ref SBillTaskResult result)
        {
            //return true;
            if (!s_bIsLogining)
            {
                // 未登录
                return(false);
            }
            result.taskID = info.taskID;
            try
            {
                // 实际测试过程中发现这个链接是随着账号改变,需要在首页中获取
                string postUrl = $"https://pbank.95559.com.cn/personbank/account/acTranRecordQuery.stream";
                if (string.IsNullOrEmpty(postUrl))
                {
                    result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_AutoProcessFailed;
                    result.msg    = "BCM Post url获取失败";
                    return(false);
                }
                // 构造post content
                var postContentString = GetAutoBillPostContent(info);
                if (string.IsNullOrEmpty(postContentString))
                {
                    result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_AutoProcessFailed;
                    result.msg    = "BCM Post content构造失败";
                    return(false);
                }
                // 构造post header
                var postHeader = GetAutoBillPostHeader();

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

                parseXlsContent(tmpFile, ref result, info);
            }
            catch (Exception e)
            {
                result.msg = $"QueryAutoBill抛出异常[{e.Message}]";
                return(false);
            }
            return(true);
        }
Пример #11
0
        /// <summary>
        /// 获取 查询POST 内容数据
        /// </summary>
        /// <param name="info"></param>
        /// <returns></returns>
        private string GetAutoBillPostContent(SBillTaskInfo info)
        {
            // 如下是获取流水必须的参数,对于不懂得参数一律直接传

            /* acctId=6228482568556511677&acctOpenBankId=34905&acctType=401&provCode=12&acctCurCode=156&oofeFlg=0&trnStartDt=20160804&trnEndDt=20170727'
             *
             * acctId           卡号 从传入参数中获取
             * acctOpenBankId   开户行 需要从页面提取
             * acctType         不懂 但是应该是账户相关 需要从页面提取
             * provCode         省份code 页面提取
             * acctCurCode      不懂 页面提取
             * oofeFlg          不懂 传0
             * trnStartDt       开始日期
             * trnEndDt         结束日期
             */

            // POST参数表
            Dictionary <string, string> postContent = new Dictionary <string, string>();

            // 固定参数,经过实测 只需要acctType 但是这个无法从页面获取 先写死
            //postContent.Add("acctOpenBankId", "34905");
            postContent.Add("acctType", "401");
            //postContent.Add("provCode", "12");
            //postContent.Add("acctCurCode", "156");
            //postContent.Add("oofeFlg", "0");

            // 非固定参数
            try
            {
                postContent.Add("acctId", info.accountNumber);
                postContent.Add("trnStartDt", info.startTime.Substring(0, 8));
                postContent.Add("trnEndDt", info.endTime.Substring(0, 8));
            }
            catch (Exception e)
            {
                LOGGER.WARN($"Parser ABC bank post data failed. Error = {e.ToString()}");
                return(string.Empty);
            }

            // POST参数拼接
            return(string.Join("&", postContent.Select(x => x.Key + "=" + x.Value).ToArray()));
        }
Пример #12
0
        /// <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);
        }
Пример #13
0
        /// <summary>
        /// 查询流水
        /// </summary>
        /// <param name="info"></param>
        /// <param name="result"></param>
        /// <returns></returns>
        private bool QueryAutoBill(SBillTaskInfo info, ref SBillTaskResult result)
        {
            if (!s_bIsLogining)
            {
                // 未登录
                result.msg = "查流水前未登录";
                return(false);
            }
            result.taskID = info.taskID;
            try
            {
                // 实际测试过程中发现这个链接是随着账号改变,需要在首页中获取
                string postUrl = GetAutoBillPostUrl();
                //LOGGER.WARN($"===========================postUrl is {postUrl}");
                if (string.IsNullOrEmpty(postUrl))
                {
                    result.msg    = "获取流水url错误";
                    result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_AutoProcessFailed;
                    return(false);
                }

                for (int i = 1; true; i++)
                {
                    // 构造post header
                    var postHeader = GetAutoBillPostHeader();

                    // 构造post content
                    var postContentString = GetAutoBillPostContent(info, i);
                    //LOGGER.WARN($"============================postContentString is {postContentString}");
                    if (string.IsNullOrEmpty(postContentString))
                    {
                        result.msg    = "构造流水postContent错误";
                        result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_AutoProcessFailed;
                        return(false);
                    }

                    //string header = string.Join("\r\n", postHeader.Select(x => x.Key + ": " + x.Value).ToArray());
                    //LOGGER.INFO($"============================postHeader is {header}");


                    // 使用string的方式获取httpresponse
                    string postResult = FKHttp.FKHttpClient.POST(postUrl, postContentString, postHeader, 300000);
                    //LOGGER.INFO($"response is {postResult}");
                    // post response是一个Html页面
                    var doc = new HtmlDocument();
                    doc.LoadHtml(postResult);

                    /*
                     * string tmpFile = System.IO.Path.GetTempFileName();
                     * string postResult = FKHttp.FKHttpClient.POST(postUrl, postContentString, postHeader, 300000, tmpFile);
                     * //LOGGER.INFO($"response is {postResult}");
                     * // post response是一个Html页面
                     * var doc = new HtmlDocument();
                     * doc.Load(tmpFile,System.Text.Encoding.UTF8);
                     */
                    // 解析post response的Html页面
                    bool bRet = ParseAutoBillHtmlPage(doc, ref result, info);
                    LOGGER.INFO($"第{i}次获取流水之后条数{result.billsList.Count}");
                    if (bRet == false)
                    {
                        break;
                    }
                }
            }
            catch (Exception e)
            {
                result.msg = $"QueryAutoBill抛出异常{e.Message}";
                LOGGER.WARN($"Parse CCB bill html page failed. Error = {e.ToString()}");
                return(false);
            }
            return(true);
        }
Пример #14
0
        /// <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);
            }
        }
Пример #15
0
        /// <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);
        }
Пример #16
0
        /// <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);
            }

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

                // 等待出现登录界面
                var element = FKWebDriver.GetInstance.WaitUntilVisibleByXPath("//*[@id=\"fclogin\"]", 30000);
                if (element == null)
                {
                    result.msg    = "等待登录页超时";
                    result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_WaitElementTimeout;
                    return(false);
                }

                // CCB的登录页面是iframe内嵌html,需要首先switch
                FKWebDriver.GetInstance.SwitchToFrameByID("fclogin");

                // 填充登录账号
                FKWebDriver.GetInstance.SetTextByID("USERID", info.username);

                // 填充密码
                FKWebDriver.GetInstance.SetTextByID("LOGPASS", info.password);

                // 点击登录
                FKWebDriver.GetInstance.ClickByID("loginButton");

                // 超时
                element = FKWebDriver.GetInstance.WaitUntilVisibleByXPath("//*[@id=\"pnav_V6010000\"]", 30000);
                if (element == null)
                {
                    result.msg    = "等待主页超时";
                    result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_WaitElementTimeout;
                    return(false);
                }
                if (!FKWebDriver.GetInstance.ClickByID("pnav_V6020000"))
                {
                    result.msg    = "点击首页出错";
                    result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_LoginFailed;
                    return(false);
                }

                // 到了这里,将认为是成功了
                return(true);
            }
            catch (Exception e)
            {
                result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_LoginFailed;
                result.msg    = $"TryLogin抛出异常[{e.Message}]";
                return(false);
            }
        }
Пример #17
0
        /// <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);
            }
        }
Пример #18
0
        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);
        }
Пример #19
0
 public void testXls()
 {
     SBillTaskResult result = new SBillTaskResult();
     SBillTaskInfo   info   = new SBillTaskInfo();
 }
Пример #20
0
 public override bool AutoBill(int nTaskID, SBillTaskInfo info, ref SBillTaskResult result)
 {
     throw new NotImplementedException();
 }
Пример #21
0
        private bool TryLogin(SBillTaskInfo info, ref SBillTaskResult result)
        {
            if (s_bIsLogining == false)
            {
                try
                {
                    //FKWebDriver webDriver = FKWebDriver.GetInstance;
                    string loginUrl = FKConfig.BCMLoginUrl;
                    // 此部分代码根据现有交行的页面设计
                    // 如果交行个人银行网页改版,此处可能需要根据新页面做相应调整

                    FKWebAutomatic.FKWebDriver.GetInstance.OpenUrl(loginUrl);

                    // 等待出现登录界面
                    var element = FKWebAutomatic.FKWebDriver.GetInstance.WaitUntilVisibleByXPath("/html/body/div[2]/div/div/div[2]/input", 10000);
                    if (element == null)
                    {
                        result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_WaitElementTimeout;
                        result.msg    = $"等待登录页面超时";
                        return(false);
                    }

                    // 填充登录账号
                    FKWebAutomatic.FKWebDriver.GetInstance.SetTextByID("alias", info.username);

                    // 填充密码
                    LoginPassword(info.password);
                    // FKWebAutomatic.FKWebDriver.GetInstance.SetTextByID("password", info.password);

                    if (FKWebAutomatic.FKWebDriver.GetInstance.IsElementVisiableByID("input_captcha"))
                    {
                        int retryCount = 20;
                        for (int i = 0; i < retryCount; i++)
                        {
                            string ocr = GetVerificationCodeString();

                            // 如果识别个数都不对 没必要输入了 重刷验证码再识别
                            if (ocr.Length == 5)
                            {
                                FKWebAutomatic.FKWebDriver.GetInstance.SetTextByID("input_captcha", ocr);
                                //移走焦点
                                FKWebAutomatic.FKWebDriver.GetInstance.ClickByID("alias");
                                // 填充完成后等待识别验证码打钩
                                Thread.Sleep(5000);
                                // 第一次此元素为隐藏,等待出现
                                FKWebAutomatic.FKWebDriver.GetInstance.WaitUntilVisibleByXPath("//*[@id=\"captchaFlg\"]", 10000);
                                // 识别结果获取
                                string successString = FKWebAutomatic.FKWebDriver.GetInstance.GetAttributeByXPath("//*[@id=\"captchaFlg\"]", "class");
                                if (successString == "right-cpt")
                                {
                                    break;
                                }
                                Console.WriteLine($"successString = {successString}");
                            }
                            // 失败 重新刷新验证码
                            FKWebAutomatic.FKWebDriver.GetInstance.ClickByXPath("//*[@class=\"captchas-img-bg\"]");
                            Thread.Sleep(1000);
                        }
                    }

                    // 点击登录
                    FKWebAutomatic.FKWebDriver.GetInstance.ClickByID("loginBtn");
                    element = FKWebAutomatic.FKWebDriver.GetInstance.WaitUntilVisibleByXPath("//*[@id=\"prepareForm\"]", 6000);
                    if (element != null)
                    {
                        var url = FKWebAutomatic.FKWebDriver.GetInstance.GetAttributeByXPath("//*[@id=\"prepareForm\"]", "action");
                        LOGGER.INFO($"当前url:{url}");
                        if (url.Contains("syVerifyCustomerNewControl.do") == true)
                        {
                            LOGGER.INFO($"U盾未绑定:{url}");
                            result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_WaitElementTimeout;
                            result.msg    = $"U盾未绑定";
                            return(false);
                        }
                    }

                    // 超时
                    element = FKWebAutomatic.FKWebDriver.GetInstance.WaitUntilVisibleByXPath("//*[@id=\"frameMain\"]", 60000);
                    if (element == null)
                    {
                        result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_WaitElementTimeout;
                        result.msg    = $"等待主页超时";
                        return(false);
                    }
                    LOGGER.INFO("登录成功");

                    Thread.Sleep(1000);
                    if (FKWebAutomatic.FKWebDriver.GetInstance.SwitchToFrameByID("frameMain") == false)
                    {
                        LOGGER.INFO("切换iframe到frameMain失败");
                        result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_WaitElementTimeout;
                        result.msg    = $"切换iframe失败";
                        return(false);
                    }
                    string PSessionId = FKWebAutomatic.FKWebDriver.GetInstance.GetAttributeByXPath("//*[@name=\"PSessionId\"]", "value");
                    LOGGER.INFO($"切换iframe到frameMain成功,PSessionId is {PSessionId}");
                    //string ReqSafeFields = FKWebAutomatic.FKWebDriver.GetInstance.GetAttributeByXPath("//*[@name=\"ReqSafeFields\"]", "value");
                    //LOGGER.INFO($"切换iframe到frameMain成功,ReqSafeFields is {ReqSafeFields}");
                    s_bIsLogining = true;
                }
                catch (Exception e)
                {
                    result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_LoginFailed;
                    result.msg    = $"TryLogin error [{e.Message}]";
                    return(false);
                }

                return(true);
            }
            return(s_bIsLogining);
        }
Пример #22
0
        /// <summary>
        /// 查询流水
        /// </summary>
        /// <param name="info"></param>
        /// <param name="result"></param>
        /// <returns></returns>
        private bool QueryAutoBill(SBillTaskInfo info, ref SBillTaskResult result)
        {
            if (!s_bIsLogining)
            {
                // 未登录
                return(false);
            }
            result.taskID = info.taskID;
            try
            {
                for (int i = 1; true; i++)
                {
                    string postUrl = $"{FKConfig.CITICBillUrl}?EMP_SID={getEMPSID()}";
                    if (string.IsNullOrEmpty(postUrl))
                    {
                        result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_AutoProcessFailed;
                        return(false);
                    }
                    // 构造post content
                    var postContentString = GetAutoBillPostContent(info, i);
                    if (string.IsNullOrEmpty(postContentString))
                    {
                        result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_AutoProcessFailed;
                        return(false);
                    }
                    // 构造post header
                    var    postHeader       = GetAutoBillPostHeader();
                    string postHeaderString = string.Join(";", postHeader.Select(x => x.Key + "=" + x.Value).ToArray());
                    string tmpFile          = System.IO.Path.GetTempFileName();
                    // 获取post response
                    string postResult = (string)FKHttp.FKHttpClient.POST(postUrl, postContentString, postHeader, 300000, tmpFile);
                    Console.WriteLine(postResult);
                    var doc = new HtmlDocument();
                    doc.Load(tmpFile);
                    var titleNode = doc.DocumentNode.SelectSingleNode("//title");
                    if (titleNode != null && titleNode.InnerHtml.Trim().Contains($"超时"))
                    {
                        result.msg = "刷新功能正常,获取链接出现主页超时";
                        LOGGER.WARN(result.msg);
                        s_bIsLogining = false;
                        result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_AutoProcessFailed;
                        return(false);
                    }
                    //bool bRet = ParseAutoBillHtmlPage(doc, ref result, info);

                    var  content    = File.ReadAllLines(tmpFile, System.Text.Encoding.GetEncoding("gb2312"));
                    var  allContent = String.Join(" ", content);
                    bool bRet       = ParseAutoBillRegex(allContent, ref result, info);
                    LOGGER.INFO($"第{i}次获取流水之后条数{result.billsList.Count}");
                    if (bRet == false)
                    {
                        break;
                    }
                }
            }
            catch (Exception e)
            {
                result.msg    = $"QueryAutoBill抛出异常{e.Message}";
                result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_AutoProcessFailed;
                LOGGER.WARN($"Parse CCB bill html page failed. Error = {e.ToString()}");
                return(false);
            }

            if (result.billsList.Count == 0)
            {
                result.msg = $"未获取到流水数据";
                LOGGER.WARN(result.msg);
                result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_AutoProcessFailed;
                return(false);
            }
            result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_Successed;
            return(true);
        }
Пример #23
0
 /// <summary>
 /// 添加一个新流水查询任务到等待队列
 /// </summary>
 /// <param name="info"></param>
 internal void AddBillTaskToWaitQueue(SBillTaskInfo info)
 {
     LOGGER.INFO($"Add a new bill task to queue. TaskID = {info.taskID}, Time = {info.startTime}-{info.endTime}");
     m_BillTasksList.Enqueue(info);
 }
Пример #24
0
 /// <summary>
 /// 银行执行自动查流水任务入口函数
 /// </summary>
 /// <param name="nTaskID">任务ID</param>
 /// <param name="info">信息详细情况:例如登录密码,收款时间限制等</param>
 /// <param name="result">过程中捕获的详细信息:例如流水情况等</param>
 /// <returns></returns>
 public abstract bool AutoBill(int nTaskID, SBillTaskInfo info, ref SBillTaskResult result);
Пример #25
0
 public S2CMessage_GetBillRequest()
 {
     timestamp = 0;
     signature = "";
     info      = new SBillTaskInfo();
 }
Пример #26
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);
        }
        private static List <SBillTaskInfo> ParseStructFromRequest(string strRequestString, string strCSharpPrivateKey)
        {
            JavaScriptSerializer js            = new JavaScriptSerializer();
            SBillTaskInfo        info          = new SBillTaskInfo();
            List <SBillTaskInfo> result        = new List <SBillTaskInfo>();
            List <string>        beginTimeList = new List <string>();
            List <string>        endTimeList   = new List <string>();

            dynamic data;

            try
            {
                data = js.Deserialize <dynamic>(strRequestString);   // 反序列化
            }
            catch (Exception e)
            {
                LOGGER.WARN($"Server get bill task request is not a invalid JSON format. \n Error = {e.ToString()} \n Request = {strRequestString}");
                result.Add(info);
                return(result);
            }

            string strLoginPassword = "";
            string strUKeyPassword  = "";

            try
            {
                info.taskID        = int.Parse(data["taskID"]);
                info.bankId        = data["bankId"];
                info.bankCode      = data["bankCode"];
                info.bankName      = data["bankName"];
                info.username      = data["username"];
                info.accountNumber = data["accountNumber"];
                strLoginPassword   = data["password"];
                strUKeyPassword    = data["uKeyPassword"];


                {   // 时间修正
                    // 优化时间 2016-09-11 10:59:59 - 2016-09-13 23:59:59
                    // 原有算法 [2016-09-11 10:59:59 - 2016-09-12 10:59:59] [2016-09-12 10:59:59 - 2016-09-13 23:59:59]
                    // 现有算法 [2016-09-11 10:59:59 - 2016-09-11 23:59:59] [2016-09-12 00:00:00 - 2016-09-12 23:59:59] [2016-09-13 00:00:00 - 2016-09-13 23:59:59]



                    long lStartTime = 0;
                    bool b1         = long.TryParse(data["startTime"], out lStartTime);
                    long lEndTime   = 0;
                    bool b2         = long.TryParse(data["endTime"], out lEndTime);

                    if (b1 && b2)
                    {
                        if ((lEndTime - lStartTime) > 86400000)
                        {
                            // 多日要开始分割
                            // 第一天
                            DateTime s = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1));
                            s = s.AddMilliseconds(lStartTime);
                            string strBeginDate = s.ToString("yyyyMMdd HH:mm:ss");

                            beginTimeList.Add(strBeginDate);
                            endTimeList.Add(strBeginDate.Substring(0, 8) + " 23:59:59");

                            s = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1));
                            s = s.AddMilliseconds(lEndTime);
                            string strEndDate = s.ToString("yyyyMMdd HH:mm:ss");
                            // 中间的天
                            DateTime middleStart = DateTime.ParseExact(
                                strBeginDate.Substring(0, 8) + " 23:59:59",
                                "yyyyMMdd HH:mm:ss", System.Globalization.CultureInfo.CurrentCulture);
                            DateTime middleEnd = DateTime.ParseExact(
                                strEndDate.Substring(0, 8) + " 00:00:00",
                                "yyyyMMdd HH:mm:ss", System.Globalization.CultureInfo.CurrentCulture);

                            s          = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1));
                            lStartTime = (long)middleStart.Subtract(s).TotalMilliseconds;
                            lEndTime   = (long)middleEnd.Subtract(s).TotalMilliseconds;
                            if (lEndTime > lStartTime)
                            {
                                long lTmpBegin = lStartTime;
                                long lTmpEnd   = lTmpBegin + 86400000 - 1000;
                                for (;;)
                                {
                                    s = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1));
                                    s = s.AddMilliseconds(lTmpBegin);
                                    beginTimeList.Add(s.ToString("yyyyMMdd HH:mm:ss"));

                                    s = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1));
                                    s = s.AddMilliseconds(lTmpEnd);
                                    endTimeList.Add(s.ToString("yyyyMMdd HH:mm:ss"));

                                    lTmpBegin = lTmpEnd + 1;
                                    lTmpEnd   = lTmpBegin + 86400000 - 1000;
                                    if (lTmpBegin >= lEndTime)
                                    {
                                        break;
                                    }
                                    if (lTmpEnd >= lEndTime)
                                    {
                                        lTmpEnd = lEndTime;
                                    }
                                }
                            }
                            // 最后一天
                            beginTimeList.Add(strEndDate.Substring(0, 8) + " 00:00:00");
                            endTimeList.Add(strEndDate);
                        }
                        else
                        {
                            // 一日之内
                            DateTime s = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1));
                            s = s.AddMilliseconds(lStartTime);
                            beginTimeList.Add(s.ToString("yyyyMMdd HH:mm:ss"));
                            s = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1));
                            s = s.AddMilliseconds(lEndTime);
                            endTimeList.Add(s.ToString("yyyyMMdd HH:mm:ss"));
                        }
                    }
                }
            }
            catch (Exception e)
            {
                LOGGER.WARN($"Parse server get bill task request failed. \n Error = {e.ToString()} \n Request = {strRequestString}");
                info.taskID = 0;     // 注意清零,外面靠该值判断是否解析成功的
                result.Add(info);
                return(result);
            }

            // 解析密码
            try
            {
                // 根据约定进行RSA解密密码
                string xmlKey = FKBaseUtils.FKRSAEncrypt.ConvertRSAPrivateKey_Java2DotNet(strCSharpPrivateKey);
                info.password = FKBaseUtils.FKRSAEncrypt.RSADecryptByDotNetPrivateKey(strLoginPassword, xmlKey);
                if (string.IsNullOrEmpty(info.password))
                {
                    LOGGER.WARN($"Decrypt password failed. Password = {strLoginPassword}");
                    info.taskID = 0;
                    result.Add(info);
                    return(result);
                }

                info.uKeyPassword = "";
                //request.info.uKeyPassword = FKBaseUtils.FKRSAEncrypt.RSADecryptByDotNetPrivateKey(strUKeyPassword, xmlKey);
                //if (string.IsNullOrEmpty(request.info.uKeyPassword))
                //{
                //    LOGGER.WARN($"Decrypt ukey password failed. Password = {strUKeyPassword}");
                //    request.info.taskID = 0;
                //    return request.info;
                //}
            }
            catch (Exception e)
            {
                LOGGER.WARN($"Decrypt passwords failed. \n Error = {e.ToString()} \n Request = {strRequestString}");
                info.taskID = 0;
                result.Add(info);
                return(result);
            }

            if (beginTimeList.Count != 0 && endTimeList.Count != 0 && beginTimeList.Count == endTimeList.Count)
            {
                for (int i = 0; i < beginTimeList.Count; ++i)
                {
                    SBillTaskInfo tmp = new SBillTaskInfo();
                    tmp           = (SBillTaskInfo)info.Clone();
                    tmp.startTime = beginTimeList[i];
                    tmp.endTime   = endTimeList[i];
                    result.Add(tmp);
                }
            }
            return(result);
        }
Пример #28
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("//body/form").SelectSingleNode("//table");
                var items = nodes.SelectNodes("//tr[@class='td_span']");
                // 当获取的数据为空时仍然有一个td_span 但是里面的数据为空
                if (items.Count == 1)
                {
                    if (items[0].GetAttributeValue("zcsr", "") == "|")
                    {
                        return(false);
                    }
                }
                foreach (var node in nodes.SelectNodes("//tr[@class='td_span']"))
                {
                    SBillTaskResult.SBankBillInfo billItem = new SBillTaskResult.SBankBillInfo();
                    // 解析单一流水对象
                    if (ParseOneBillHtmlPage(node, ref billItem) == false)
                    {
                        continue;
                    }
                    if (ResultFilter.TimeFilter(info, billItem.submitTime))
                    {
                        result.billsList.Add(billItem);
                    }
                }

                result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_Successed;
            }
            catch (Exception e)
            {
                result.msg    = "CCB解析返回html错误";
                result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_AutoProcessFailed;
                LOGGER.WARN($"CCB解析返回html错误:{e.Message}");
                return(false);
            }
            return(true);
        }
Пример #29
0
        private string GetAutoBillPostContent(SBillTaskInfo info, int pageNumber)
        {
            // 如下是获取流水必须的参数,对于不懂得参数一律直接传

            /* accountNo=6217680704422380&  卡号 从传入参数中获取
             * largeAmount=12&              金额限定
             * opFlag=1&                    不懂 页面提取
             * pageType=1&                  页数相关
             * payAcctxt=6217680704422380&  卡号 从传入参数中获取
             * queryType=spacil&            页数相关
             * recordNum=10&                页数相关
             * recordSize=10&               页数相关
             * recordStart=11&              页数相关
             * stdessbgdt=20160804&         开始日期
             * stdesseddt=20170727&         结束日期
             * stdudfcyno=001&              不懂
             * argetPage=11                 页数相关
             *
             */

            // POST参数表

            Dictionary <string, string> postContent = new Dictionary <string, string>();

            /*if (File.Exists("data\\citic_auto_bill_content"))
             * {
             * var content = File.ReadAllLines("data\\citic_auto_bill_content");
             * foreach (var oneLine in content)
             * {
             *     var keyAndValue = oneLine.Split(' ');
             *     if (keyAndValue.Length >= 2)
             *     {
             *         postContent.Add(keyAndValue[0], keyAndValue[1]);
             *     }
             *     else
             *     {
             *         postContent.Add(keyAndValue[0], "");
             *     }
             * }
             *  int onePageNumber = 10;
             *  int recordStart = (onePageNumber * (pageNumber - 1) + 1);
             *  postContent.Add("recordStart", $"{recordStart}");
             *  postContent.Add("recordNum", $"{onePageNumber}");
             * }*/

            postContent.Add("currList", "");
            postContent.Add("std400pgqf", "N");
            postContent.Add("opFlag", "0");
            postContent.Add("queryType", "sapcil");

            // 非固定参数
            try
            {
                int onePageNumber = 10;
                int recordStart   = (onePageNumber * (pageNumber - 1) + 1);
                postContent.Add("recordStart", $"{recordStart}");
                postContent.Add("recordNum", $"{onePageNumber}");

                postContent.Add("accountNo", info.accountNumber);
                postContent.Add("payAcctxt", info.accountNumber);
                postContent.Add("stdessbgdt", info.startTime.Substring(0, 8));
                postContent.Add("stdesseddt", info.endTime.Substring(0, 8));
            }
            catch (Exception e)
            {
                LOGGER.WARN($"Parser CITIC bank post data failed. Error = {e.ToString()}");
                return(string.Empty);
            }


            // POST参数拼接
            return(string.Join("&", postContent.Select(x => x.Key + "=" + x.Value).ToArray()));
        }
Пример #30
0
        /// <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);
            }

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

                // 等待出现登录界面
                var element = FKWebDriver.GetInstance.WaitUntilVisibleByXPath("/html/body/form[1]/div[2]/div[3]/div[1]/ul/li[4]", 20000);
                if (element == null)
                {
                    result.msg    = "等待登录页超时";
                    result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_WaitElementTimeout;
                    return(false);
                }


                if (FKWebDriver.GetInstance.IsElementVisiableByXPath("//*[@id=\"type2\"]"))
                {
                    LOGGER.INFO($"检测到U盾,跳过用户名输入");
                }
                else
                {
                    // 填充登录账号
                    FKWebDriver.GetInstance.SetTextByName("logonNoCert", info.accountNumber);
                }


                // 填充密码
                LoginPassword(info.password);

                var isOcrEnable = FKWebDriver.GetInstance.IsElementVisiableByXPath("//*[@class=\"loginInputVerity\"]");

                Console.WriteLine($"isOcrEnable {isOcrEnable}");
                var isOcrPass = false;
                // 处理验证码
                if (isOcrEnable)
                {
                    // 填充验证码
                    // 由于验证码可能识别失败,所以需要重试
                    int retryCount = 20;
                    for (int i = 0; i < retryCount; i++)
                    {
                        // 获取ocr
                        string ocr = getOCR();
                        // 如果识别个数都不对 没必要输入了 重刷验证码再识别
                        if (ocr.Length == 4)
                        {
                            FKWebAutomatic.FKWebDriver.GetInstance.SetTextByName("verifyCode", ocr.Replace("*", ""));
                            // 填充完成后等待识别验证码打钩
                            Thread.Sleep(1000);
                            EnterOCRErrorDialog();
                            // 识别结果获取
                            string rightSrc = FKWebAutomatic.FKWebDriver.GetInstance.GetAttributeByXPath("//*[@class=\"imgVeritySign\"]", "src");
                            // 判断验证码是否通过
                            if (rightSrc.Contains("images/default/start_button.gif"))
                            {
                                isOcrPass = true;
                                break;
                            }
                            Console.WriteLine($"src is [{rightSrc}]");
                        }

                        // 失败 重新刷新验证码
                        FKWebDriver.GetInstance.ClickByID("pinImg");
                        Thread.Sleep(1000);
                    }
                    if (!isOcrPass)
                    {
                        result.msg    = "验证码超过重试次数";
                        result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_WaitElementTimeout;
                        return(false);
                    }
                }

                bool logButton = FKWebDriver.GetInstance.DoubleClickByID("logonButton");
                // 点击登录
                Console.WriteLine($"log button {logButton}");

                // 中信银行最近改版,未通过手机绑定的用户会跳转到手机绑定页面 这里处理此页面直接跳过
                element = FKWebDriver.GetInstance.WaitUntilVisibleByXPath("//*[@class=\"tradingCon\"]", 30000);
                if (element == null)
                {
                    LOGGER.INFO($"未检测出验证页面");
                }
                else
                {
                    var a = element.FindElement(OpenQA.Selenium.By.TagName("a"));

                    if (a != null && a.Text == "跳过")
                    {
                        LOGGER.INFO($"检测出手机验证页面,点击跳过");
                        a.Click();
                        Thread.Sleep(2000);
                        FKWebDriver.GetInstance.ClickByID("jump");
                    }
                }

                // 超时
                element = FKWebDriver.GetInstance.WaitUntilVisibleByXPath("//*[@class=\"index_page\"]", 30000);
                if (element == null)
                {
                    result.msg    = "等待主页超时";
                    result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_WaitElementTimeout;
                    return(false);
                }

                // 到了这里,将认为是成功了
                return(true);
            }
            catch (Exception e)
            {
                result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_LoginFailed;
                result.msg    = $"TryLogin抛出异常[{e.Message}]";
                return(false);
            }
        }