Example #1
0
        // 一次操作循环
        public override void Worker()
        {
            // 系统挂起的时候,不运行本线程
            // 2007/12/18
            //if (this.App.HangupReason == HangupReason.LogRecover)
            //    return;
            if (this.App.ContainsHangup("LogRecover") == true)
            {
                return;
            }

            // 2012/2/4
            if (this.App.PauseBatchTask == true)
            {
                return;
            }

            bool   bFirst   = true;
            string strError = "";
            int    nRet     = 0;

            BatchTaskStartInfo startinfo = this.StartInfo;

            if (startinfo == null)
            {
                startinfo = new BatchTaskStartInfo();   // 按照缺省值来
            }
            // 通用启动参数
            bool bLoop = true;

            nRet = ParseMessageMonitorParam(startinfo.Param,
                                            out bLoop,
                                            out strError);
            if (nRet == -1)
            {
                this.AppendResultText("启动失败: " + strError + "\r\n");
                return;
            }

            this.Loop = bLoop;

            string strID = "";

            nRet = ParseMessageMonitorStart(startinfo.Start,
                                            out strID,
                                            out strError);
            if (nRet == -1)
            {
                this.AppendResultText("启动失败: " + strError + "\r\n");
                this.Loop = false;
                return;
            }

            //
            bool   bPerDayStart   = false; // 是否为每日一次启动模式
            string strMonitorName = "messageMonitor";

            {
                string strLastTime = "";

                nRet = ReadLastTime(
                    strMonitorName,
                    out strLastTime,
                    out strError);
                if (nRet == -1)
                {
                    string strErrorText = "从文件中获取 " + strMonitorName + " 每日启动时间时发生错误: " + strError;
                    this.AppendResultText(strErrorText + "\r\n");
                    this.App.WriteErrorLog(strErrorText);
                    return;
                }

                string strStartTimeDef = "";
                //      bRet    是否到了每日启动时间
                bool   bRet           = false;
                string strOldLastTime = strLastTime;

                // return:
                //      -2  strLastTime 格式错误
                //      -1  一般错误
                //      0   没有找到startTime配置参数
                //      1   找到了startTime配置参数
                nRet = IsNowAfterPerDayStart(
                    strMonitorName,
                    ref strLastTime,
                    out bRet,
                    out strStartTimeDef,
                    out strError);
                if (nRet == -1 || nRet == -2)
                {
                    string strErrorText = "获取 " + strMonitorName + " 每日启动时间时发生错误: " + strError;
                    this.AppendResultText(strErrorText + "\r\n");
                    this.App.WriteErrorLog(strErrorText);
                    if (nRet == -2)
                    {
                        // 删除断点文件,避免下次继续报错
                        WriteLastTime(strMonitorName, "");
                    }
                    return;
                }

                // 如果nRet == 0,表示没有配置相关参数,则兼容原来的习惯,每次都作
                if (nRet == 0)
                {
                }
                else if (nRet == 1)
                {
                    if (bRet == false)
                    {
                        if (this.ManualStart == true)
                        {
                            this.AppendResultText("已试探启动任务 '" + this.Name + "',但因没有到每日启动时间 " + strStartTimeDef + " 而未能启动。(上次任务处理结束时间为 " + DateTimeUtil.LocalTime(strLastTime) + ")\r\n");
                        }

                        // 2014/3/31
                        if (string.IsNullOrEmpty(strOldLastTime) == true &&
                            string.IsNullOrEmpty(strLastTime) == false)
                        {
                            this.AppendResultText("史上首次启动此任务。已把当前时间当作上次任务处理结束时间 " + DateTimeUtil.LocalTime(strLastTime) + " 写入了断点记忆文件\r\n");
                            WriteLastTime(strMonitorName, strLastTime);
                        }

                        return; // 还没有到每日时间
                    }

                    bPerDayStart = true;
                }

                this.App.WriteErrorLog((bPerDayStart == true ? "(定时)" : "(不定时)") + strMonitorName + " 启动。");
            }

            AppendResultText("开始新一轮循环");

            RmsChannel channel = this.RmsChannels.GetChannel(this.App.WsUrl);

            string strMessageDbName = this.App.MessageDbName;

            if (String.IsNullOrEmpty(strMessageDbName) == true)
            {
                AppendResultText("尚未配置消息库名(<message dbname='...' />)");
                this.Loop = false;
                return;
            }

            if (String.IsNullOrEmpty(this.App.MessageReserveTimeSpan) == true)
            {
                AppendResultText("尚未配置消息保留期限(<message reserveTimeSpan='...' />");
                this.Loop = false;
                return;
            }

            // 解析期限值
            string strPeriodUnit = "";
            long   lPeriodValue  = 0;

            nRet = LibraryApplication.ParsePeriodUnit(
                this.App.MessageReserveTimeSpan,
                out lPeriodValue,
                out strPeriodUnit,
                out strError);
            if (nRet == -1)
            {
                strError = "消息保留期限 值 '" + this.App.MessageReserveTimeSpan + "' 格式错误: " + strError;
                AppendResultText(strError);
                this.Loop = false;
                return;
            }

            AppendResultText("开始处理消息库 " + strMessageDbName + " 的循环");

            // string strID = "1";
            int nRecCount = 0;

            for (; ; nRecCount++)
            {
                // 系统挂起的时候,不运行本线程
                // 2008/2/4
                if (this.App.ContainsHangup("LogRecover") == true)
                {
                    break;
                }
                // 2012/2/4
                if (this.App.PauseBatchTask == true)
                {
                    break;
                }

                if (this.Stopped == true)
                {
                    break;
                }

                string strStyle = "";
                strStyle = "data,content,timestamp,outputpath";

                if (bFirst == true)
                {
                    strStyle += "";
                }
                else
                {
                    strStyle += ",next";
                }

                string strPath = strMessageDbName + "/" + strID;

                string strXmlBody        = "";
                string strMetaData       = "";
                string strOutputPath     = "";
                byte[] baOutputTimeStamp = null;

                //
                SetProgressText((nRecCount + 1).ToString() + " " + strPath);

                // 获得资源
                // return:
                //		-1	出错。具体出错原因在this.ErrorCode中。this.ErrorInfo中有出错信息。
                //		0	成功
                long lRet = channel.GetRes(strPath,
                                           strStyle,
                                           out strXmlBody,
                                           out strMetaData,
                                           out baOutputTimeStamp,
                                           out strOutputPath,
                                           out strError);
                if (lRet == -1)
                {
                    if (channel.ErrorCode == ChannelErrorCode.NotFound)
                    {
                        if (bFirst == true)
                        {
                            // 第一条没有找到, 但是要强制循环进行
                            bFirst = false;
                            goto CONTINUE;
                        }
                        else
                        {
                            if (bFirst == true)
                            {
                                strError = "数据库 " + strMessageDbName + " 记录 " + strID + " 不存在。处理结束。";
                            }
                            else
                            {
                                strError = "数据库 " + strMessageDbName + " 记录 " + strID + " 是最末一条记录。处理结束。";
                            }
                            break;
                        }
                    }
                    else if (channel.ErrorCode == ChannelErrorCode.EmptyRecord)
                    {
                        bFirst = false;
                        // 把id解析出来
                        strID = ResPath.GetRecordId(strOutputPath);
                        goto CONTINUE;
                    }

                    goto ERROR1;
                }

                bFirst = false;

                // 把id解析出来
                strID = ResPath.GetRecordId(strOutputPath);

                try
                {
                    // 处理
                    nRet = DoOneRecord(
                        lPeriodValue,
                        strPeriodUnit,
                        strOutputPath,
                        strXmlBody,
                        baOutputTimeStamp,
                        out strError);
                }
                catch (Exception ex)
                {
                    strError = "DoOneRecord exception: " + ExceptionUtil.GetDebugText(ex);
                    this.AppendResultText(strError + "\r\n");
                    this.SetProgressText(strError);
                    nRet = -1;
                }
                if (nRet == -1)
                {
                    AppendResultText("DoOneRecord() error : " + strError + "。\r\n");
                }


CONTINUE:
                continue;
            } // end of for

            // 正常结束,复位断点
            this.App.RemoveBatchTaskBreakPointFile(this.Name);
            this.StartInfo.Start = "";

            AppendResultText("针对消息库 " + strMessageDbName + " 的循环结束。共处理 " + nRecCount.ToString() + " 条记录。\r\n");

            {
                Debug.Assert(this.App != null, "");

                // 写入文件,记忆已经做过的当日时间
                string strLastTime = DateTimeUtil.Rfc1123DateTimeStringEx(this.App.Clock.UtcNow.ToLocalTime());  // 2007/12/17 changed // DateTime.UtcNow // 2012/5/27
                WriteLastTime(strMonitorName,
                              strLastTime);
                string strErrorText = (bPerDayStart == true ? "(定时)" : "(不定时)") + strMonitorName + "结束。共处理记录 " + nRecCount.ToString() + " 个。";
                this.App.WriteErrorLog(strErrorText);
            }

            return;

ERROR1:
            // 记忆断点
            this.StartInfo.Start = MemoBreakPoint(
                strID //strRecordID,
                );


            this.Loop       = true; // 便于稍后继续重新循环?
            startinfo.Param = MakeMessageMonitorParam(
                bLoop);


            AppendResultText("MessageMonitor thread error : " + strError + "\r\n");
            this.App.WriteErrorLog("MessageMonitor thread error : " + strError + "\r\n");
            return;
        }
Example #2
0
        // 针对读者记录中的 borrow 元素中 overflow (尚未超期)的,重新计算是否超额。如果不超额的,修改为正常的借期
        // parameters:
        //      now 当前时间。本地时间格式。这是用来判断是否超期的依据
        // return.Value:
        //      -1  出错
        //      0   成功
        //      1   有警告信息,在 strError 中返回
        internal AdjustOverflowResult AdjustOverflow(
            XmlDocument readerdom,
            DateTime now,
            StringBuilder debugInfo)
        {
            List <ItemModifyInfo> modifies = new List <ItemModifyInfo>();

            int nRet = BuildBorrowItemInfo(readerdom,
                                           now,
                                           out List <BorrowItemInfo> items,
                                           out string strError);

            if (nRet == -1)
            {
                return new AdjustOverflowResult
                       {
                           Value     = -1,
                           ErrorInfo = strError,
                           Modifies  = modifies
                       }
            }
            ;

            // 没有任何在借事项
            if (items.Count == 0)
            {
                return new AdjustOverflowResult
                       {
                           Value    = 0,
                           Modifies = modifies
                       }
            }
            ;

            int overflow_count = BorrowItemInfo.CountOverflow(items);

            // 没有超额事项可供调整
            if (overflow_count == 0)
            {
                return new AdjustOverflowResult
                       {
                           Value    = 0,
                           Modifies = modifies
                       }
            }
            ;

            // 获得总的最大可借数
            // return:
            //      -1  出错
            //      其他  最大可借册数
            int totalMax = GetTotalMax(
                readerdom,
                out strError);

            if (totalMax == -1)
            {
                return new AdjustOverflowResult
                       {
                           Value     = -1,
                           ErrorInfo = strError,
                           Modifies  = modifies
                       }
            }
            ;

            List <string> warnings = new List <string>();

            var groups = BorrowItemInfo.GroupByBookType(items);

            // 对每种图书类型,尝试修正到本类型的最大许可外借数
            foreach (var group in groups)
            {
                string bookType = group[0].BookType;

                // 获得特定图书类型的最大可借数
                // return:
                //      -1  出错
                //      其他  此类型图书的最大可借册数
                int typeMax = GetTypeMax(
                    readerdom,
                    bookType,
                    out strError);
                if (typeMax == -1)
                {
                    warnings.Add(strError);
                    continue;   // 放弃这一类型的处理,继续处理其他类型
                }

                while (true)
                {
                    // 统计数组中,正常借阅(非超额)的数量
                    int count = BorrowItemInfo.CountNormal(group);
                    if (count < typeMax)
                    {
                        // 尝试从中改掉一个 overflow
                        // return:
                        //      true 成功改掉一个
                        //      false   没能改掉。(原因可能是因为没有可以改动状态的 overflow 元素了)
                        var item = BorrowItemInfo.DecOverflow(group);
                        if (item == null)
                        {
                            break;
                        }

                        // 检查总册数是否超额。如果超额,刚才的改动需要 undo
                        int totalCount = BorrowItemInfo.CountNormal(items);
                        if (totalCount > totalMax)
                        {
                            item.ModifyAction = null;   // Undo
                            break;
                        }
                    }
                    else
                    {
                        break;
                    }
                }
            }

            // 开始修改 borrow 元素
            foreach (var item in items)
            {
                if (item.ModifyAction != "removeOverflow")
                {
                    continue;
                }

                string strOldBorrowInfo = item.Element.OuterXml;

                // 获得一册书的借阅参数
                nRet = GetBorrowParam(
                    readerdom,
                    item.BookType,
                    item.BorrowDate,
                    out string borrowPeriod,
                    out string denyPeriod,
                    out string returningDate,
                    out strError);
                if (nRet == -1)
                {
                    warnings.Add(strError);
                    continue;
                }

                item.Element.SetAttribute("borrowPeriod",
                                          borrowPeriod);

                if (string.IsNullOrEmpty(denyPeriod) == false)
                {
                    item.Element.SetAttribute("denyPeriod",
                                              denyPeriod);
                }
                else
                {
                    item.Element.RemoveAttribute("denyPeriod");
                }

                item.Element.SetAttribute("returningDate",
                                          returningDate);

                // 删除 overflow 属性
                item.Element.RemoveAttribute("overflow");

                modifies.Add(new ItemModifyInfo
                {
                    LibraryCode   = DomUtil.GetElementText(readerdom.DocumentElement, "libraryCode"),
                    PatronBarcode = DomUtil.GetElementText(readerdom.DocumentElement, "barcode"),
                    BorrowID      = item.Element.GetAttribute("borrowID"),
                    ItemBarcode   = item.Barcode,
                    BorrowDate    = item.Element.GetAttribute("borrowDate"),
                    BorrowPeriod  = borrowPeriod,
                    DenyPeriod    = denyPeriod,
                    ReturningDate = returningDate,
                    OldBorrowInfo = strOldBorrowInfo,
                });
            }

            /*
             * // 修改涉及到的册记录
             * if (modifies.Count > 0 && sessioninfo != null)
             * {
             *  foreach (var info in modifies)
             *  {
             *      nRet = ModifyItemRecord(
             * sessioninfo,
             * info,
             * out strError);
             *      if (nRet == -1)
             *      {
             *          warnings.Add($"修改册记录 {info.ItemBarcode} 过程中出错: {strError}");
             *          debugInfo?.Append($"{warnings[warnings.Count - 1]}");
             *      }
             *  }
             * }
             */

            if (warnings.Count > 0)
            {
                strError = StringUtil.MakePathList(warnings, "; ");
                return(new AdjustOverflowResult
                {
                    Value = 1,
                    ErrorInfo = strError,
                    Modifies = modifies
                });
            }

            return(new AdjustOverflowResult
            {
                Value = 0,
                Modifies = modifies
            });
        }

#if NO
        // 针对读者记录中的 borrow 元素中 overflow (尚未超期)的,重新计算是否超额。如果不超额的,修改为正常的借期
        // return:
        //      -1  出错
        //      0   成功
        //      1   有警告信息,在 strError 中返回
        int AdjustOverflow(
            SessionInfo sessioninfo,
            XmlDocument readerdom,
            StringBuilder debugInfo,
            out string strError)
        {
            strError = "";
            int nRet = 0;

            debugInfo.AppendLine($"用于调整的读者记录: {DomUtil.GetIndentXml(readerdom)}");

            List <string>         warnings = new List <string>();
            List <ItemModifyInfo> items    = new List <ItemModifyInfo>();

            string libraryCode = DomUtil.GetElementText(readerdom.DocumentElement, "libraryCode");
            string readerType  = DomUtil.GetElementText(readerdom.DocumentElement, "readerType");

            // List<XmlElement> overflows = new List<XmlElement>();

            debugInfo?.AppendLine($"libraryCode='{libraryCode}'");
            debugInfo?.AppendLine($"readerType='{readerType}'");

            var nodes = readerdom.DocumentElement.SelectNodes("borrows/borrow");

            foreach (XmlElement borrow in nodes)
            {
                debugInfo?.AppendLine($"=== 对 borrow 元素进行处理: {borrow.OuterXml}");
                if (borrow.HasAttribute("overflow") == false)
                {
                    debugInfo?.AppendLine("没有 overflow 属性,跳过处理");
                    continue;
                }

                string no = borrow.GetAttribute("no");
                if (string.IsNullOrEmpty(no) == false)
                {
                    if (Int32.TryParse(no, out int value) == true)
                    {
                        if (value > 0)
                        {
                            debugInfo?.AppendLine("续借的情况跳过处理");
                            continue;   // 续借的情况不考虑
                        }
                    }
                    else
                    {
                        warnings.Add($"续借次数 '{no}' 格式错误");
                        debugInfo?.Append($"{warnings[warnings.Count - 1]}");
                        continue;
                    }
                }

                string itemBarcode = borrow.GetAttribute("barcode");
                if (string.IsNullOrEmpty(itemBarcode))
                {
                    itemBarcode = "@refid:" + borrow.GetAttribute("refID");
                }

                debugInfo?.AppendLine($"条码号='{itemBarcode}'");

                try
                {
                    // 获得借阅开始时间
                    string borrowDate = borrow.GetAttribute("borrowDate");

                    debugInfo?.AppendLine($"borrowDate='{borrowDate}'");

                    DateTime borrowTime = DateTimeUtil.FromRfc1123DateTimeString(borrowDate).ToLocalTime();

                    // 看看是否已经超期。已经超期的不处理
                    {
                        string returningDate = borrow.GetAttribute("returningDate");

                        debugInfo?.AppendLine($"returningDate='{returningDate}'");

                        DateTime returningTime = DateTimeUtil.FromRfc1123DateTimeString(returningDate).ToLocalTime();

                        string period = borrow.GetAttribute("borrowPeriod");

                        debugInfo?.AppendLine($"borrowPeriod='{period}'");

                        nRet = LibraryApplication.ParsePeriodUnit(period,
                                                                  out long lPeriodValue,
                                                                  out string strPeriodUnit,
                                                                  out strError);
                        if (nRet == -1)
                        {
                            debugInfo?.AppendLine($"ParsePeriodUnit('{period}') 出错:{strError}。只好把时间单位当作 day 来处理");
                            strPeriodUnit = "day";
                            // continue;
                        }

                        DateTime now = DateTime.Now;
                        // 正规化时间
                        nRet = DateTimeUtil.RoundTime(strPeriodUnit,
                                                      ref now,
                                                      out strError);
                        if (nRet == -1)
                        {
                            warnings.Add($"正规化时间出错(1)。strPeriodUnit={strPeriodUnit}");
                            debugInfo?.Append($"{warnings[warnings.Count - 1]}");
                            continue;
                        }

                        nRet = DateTimeUtil.RoundTime(strPeriodUnit,
                                                      ref returningTime,
                                                      out strError);
                        if (nRet == -1)
                        {
                            warnings.Add($"正规化时间出错(2)。strPeriodUnit={strPeriodUnit}");
                            debugInfo?.Append($"{warnings[warnings.Count - 1]}");
                            continue;
                        }

                        if (returningTime < now)
                        {
                            debugInfo?.AppendLine($"已经超期,跳过处理 (returningTime={returningTime.ToString()}, now={now.ToString()})");
                            continue;
                        }
                    }

                    string bookType = borrow.GetAttribute("type");

                    debugInfo?.AppendLine($"bookType='{bookType}'");

                    // 假设要首次借阅这一册,是否会超额?
                    {
                        // 从读者信息中,找出该读者以前已经借阅过的同类图书的册数
                        int nThisTypeCount = readerdom.DocumentElement.SelectNodes("borrows/borrow[@type='" + bookType + "']").Count;

                        nRet = this.GetLoanParam(
                            //null,
                            libraryCode,
                            readerType,
                            bookType,
                            "可借册数",
                            out string strParamValue,
                            out MatchResult _,
                            out strError);
                        if (nRet == -1)
                        {
                            warnings.Add($"获得 馆代码 '{ libraryCode }' 中 读者类型 '{ readerType }' 针对图书类型 '{ bookType }' 的 可借册数 参数时发生错误: {strError}");
                            debugInfo?.Append($"{warnings[warnings.Count - 1]}");
                            continue;
                        }
                        if (nRet < 4)
                        {
                            warnings.Add($"馆代码 '{ libraryCode}' 中 读者类型 '{ readerType }' 针对图书类型 '{ bookType }' 的 可借册数 参数无法获得: {strError}");
                            debugInfo?.Append($"{warnings[warnings.Count - 1]}");
                            continue;
                        }

                        if (Int32.TryParse(strParamValue, out int thisTypeMax) == false)
                        {
                            warnings.Add($"馆代码 '{ libraryCode}' 中 读者类型 '{ readerType }' 针对图书类型 '{ bookType }' 的 可借册数 参数 '{strParamValue}' 格式错误");
                            debugInfo?.Append($"{warnings[warnings.Count - 1]}");
                            continue;
                        }

                        // 依然超额了。不修改
                        if (nThisTypeCount > thisTypeMax)
                        {
                            debugInfo?.AppendLine($"特定类型的图书超额了,跳过处理。nThisTypeCount={nThisTypeCount}, thisTypeMax={thisTypeMax}, bookType={bookType}, readerType={readerType}");
                            continue;
                        }

                        // 看 可借总册数
                        nRet = this.GetLoanParam(
//null,
                            libraryCode,
                            readerType,
                            "",
                            "可借总册数",
                            out strParamValue,
                            out MatchResult _,
                            out strError);
                        if (nRet == -1)
                        {
                            warnings.Add($"获得 馆代码 '{ libraryCode }' 中 读者类型 '{ readerType }' 的 可借总册数 参数时发生错误: {strError}");
                            debugInfo?.Append($"{warnings[warnings.Count - 1]}");
                            continue;
                        }
                        if (nRet < 3)
                        {
                            warnings.Add($"馆代码 '{ libraryCode}' 中 读者类型 '{ readerType }' 的 可借总册数 参数无法获得: {strError}");
                            debugInfo?.Append($"{warnings[warnings.Count - 1]}");
                            continue;
                        }
                        if (Int32.TryParse(strParamValue, out int max) == false)
                        {
                            warnings.Add($"馆代码 '{ libraryCode}' 中 读者类型 '{ readerType }' 的 可借总册数 参数 '{strParamValue}' 格式错误");
                            debugInfo?.Append($"{warnings[warnings.Count - 1]}");
                            continue;
                        }

                        // 从读者信息中,找出该读者已经借阅过的册数
                        int count = readerdom.DocumentElement.SelectNodes("borrows/borrow").Count;
                        // 依然超额了。不修改
                        if (count > max)
                        {
                            debugInfo?.AppendLine($"全部图书超额了,跳过处理。count={count}, max={max}, readerType={readerType}");
                            continue;
                        }
                    }


                    // return:
                    //      reader和book类型均匹配 算4分
                    //      只有reader类型匹配,算3分
                    //      只有book类型匹配,算2分
                    //      reader和book类型都不匹配,算1分
                    nRet = this.GetLoanParam(
                        libraryCode,
                        readerType,
                        bookType,
                        "借期",
                        out string strBorrowPeriodList,
                        out MatchResult matchresult,
                        out strError);
                    if (nRet == -1)
                    {
                        warnings.Add($"获得 馆代码 '{ libraryCode }' 中 读者类型 '{ readerType }' 针对图书类型 '{ bookType }' 的 借期 参数时发生错误: {strError}");
                        debugInfo?.Append($"{warnings[warnings.Count - 1]}");
                        continue;
                    }
                    if (nRet < 4)  // nRet == 0
                    {
                        warnings.Add($"馆代码 '{ libraryCode}' 中 读者类型 '{ readerType }' 针对图书类型 '{ bookType }' 的 借期 参数无法获得: {strError}");
                        debugInfo?.Append($"{warnings[warnings.Count - 1]}");
                        continue;
                    }

                    string[] aPeriod = strBorrowPeriodList.Split(new char[] { ',' });
                    if (aPeriod.Length == 0)
                    {
                        warnings.Add($"'{strBorrowPeriodList}' Split error");
                        debugInfo?.Append($"{warnings[warnings.Count - 1]}");
                        continue;
                    }

                    string borrowPeriod = aPeriod[0];
                    if (string.IsNullOrEmpty(borrowPeriod))
                    {
                        warnings.Add($"期限字符串 '{strBorrowPeriodList}' 中第一部分 '{borrowPeriod}' 为空");
                        debugInfo?.Append($"{warnings[warnings.Count - 1]}");
                        continue;
                    }

                    nRet = ParseBorrowPeriod(borrowPeriod,
                                             out string strThisBorrowPeriod,
                                             out string strThisDenyPeriod,
                                             out strError);
                    if (nRet == -1)
                    {
                        warnings.Add($"ParseBorrowPeroid() '{borrowPeriod}' error");
                        debugInfo?.Append($"{warnings[warnings.Count - 1]}");
                        continue;
                    }


                    // 计算应还书时间
                    nRet = ComputeReturningDay(
                        borrowTime,
                        strThisBorrowPeriod,
                        out DateTime this_return_time,
                        out strError);
                    if (nRet == -1)
                    {
                        warnings.Add($"ComputeReturningDay() error. borrowTime='{borrowTime}', strThisBorrowPeriod='{strThisBorrowPeriod}'");
                        debugInfo?.Append($"{warnings[warnings.Count - 1]}");
                        continue;
                    }

                    borrow.SetAttribute("borrowPeriod",
                                        strThisBorrowPeriod);
                    // 2016/6/7
                    if (string.IsNullOrEmpty(strThisDenyPeriod) == false)
                    {
                        borrow.SetAttribute("denyPeriod",
                                            strThisDenyPeriod);
                    }
                    else
                    {
                        borrow.RemoveAttribute("denyPeriod");
                    }

                    string strReturningDate = DateTimeUtil.Rfc1123DateTimeStringEx(this_return_time.ToLocalTime());
                    borrow.SetAttribute("returningDate",
                                        strReturningDate);

                    // 删除 overflow 属性
                    borrow.RemoveAttribute("overflow");

                    items.Add(new ItemModifyInfo
                    {
                        ItemBarcode   = itemBarcode,
                        BorrowPeriod  = strThisBorrowPeriod,
                        DenyPeriod    = strThisDenyPeriod,
                        ReturningDate = strReturningDate
                    });
                }
                catch (Exception ex)
                {
                    warnings.Add($"册记录 {itemBarcode} 处理过程出现异常: {ex.Message}");
                    debugInfo?.Append($"{warnings[warnings.Count - 1]}");
                }
            }

            // 修改涉及到的册记录
            if (items.Count > 0)
            {
                foreach (var info in items)
                {
                    nRet = ModifyItemRecord(
                        sessioninfo,
                        info,
                        out strError);
                    if (nRet == -1)
                    {
                        warnings.Add($"修改册记录 {info.ItemBarcode} 过程中出错: {strError}");
                        debugInfo?.Append($"{warnings[warnings.Count - 1]}");
                    }
                }
            }


            if (warnings.Count > 0)
            {
                strError = StringUtil.MakePathList(warnings, "; ");
                return(1);
            }

            return(0);
        }
Example #3
0
        // 判断是否超过保留期限
        // return:
        //      -1  error
        //      0   没有超过
        //      1   已经超过
        int CheckeOutOfReservation(
            Calendar calendar,
            XmlDocument queue_rec_dom,
            out string strError)
        {
            strError = "";

            string strState = DomUtil.GetElementText(queue_rec_dom.DocumentElement,
    "state");

            // 对通知完成后的记录, 循环中不必处理
            if (StringUtil.IsInList("outof", strState) == true)
                return 0;

            string strNotifyDate = DomUtil.GetElementText(queue_rec_dom.DocumentElement,
                "notifyDate");

            /*
            string strItemBarcode = DomUtil.GetElementText(queue_rec_dom.DocumentElement,
                "itemBarcode");
            string strReaderBarcode = DomUtil.GetElementText(queue_rec_dom.DocumentElement,
                "readerBarcode");
             * */


            // 解析期限值
            string strPeriodUnit = "";
            long lPeriodValue = 0;

            int nRet = LibraryApplication.ParsePeriodUnit(
                this.App.ArrivedReserveTimeSpan,
                out lPeriodValue,
                out strPeriodUnit,
                out strError);
            if (nRet == -1)
            {
                strError = "预约保留期限 值 '" + this.App.ArrivedReserveTimeSpan + "' 格式错误: " + strError;
                return -1;
            }

            //
            DateTime notifydate;

            try
            {
                notifydate = DateTimeUtil.FromRfc1123DateTimeString(strNotifyDate);
            }
            catch
            {
                strError = "通知日期值 '" + strNotifyDate + "' 格式错误";
                return -1;
            }


            DateTime timeEnd = DateTime.MinValue;

            nRet = LibraryApplication.GetOverTime(
                calendar,
                notifydate,
                lPeriodValue,
                strPeriodUnit,
                out timeEnd,
                out strError);
            if (nRet == -1)
            {
                strError = "计算保留期过程发生错误: " + strError;
                return -1;
            }

            DateTime now = this.App.Clock.UtcNow;  //  DateTime.UtcNow;

            // 正规化时间
            nRet = DateTimeUtil.RoundTime(strPeriodUnit,
                ref now,
                out strError);
            if (nRet == -1)
                return -1;

            TimeSpan delta = now - timeEnd;

            long lDelta = 0;

            nRet = LibraryApplication.ParseTimeSpan(
                delta,
                strPeriodUnit,
                out lDelta,
                out strError);
            if (nRet == -1)
                return -1;

            if (lDelta > 0)
                return 1;

            return 0;
        }
Example #4
0
        // parameters:
        //      now 当前时间。本地时间格式。这是用来判断是否超期的依据
        static bool IsOverdue(XmlElement borrow,
                              DateTime now,
                              out List <string> warnings)
        {
            warnings = new List <string>();
            StringBuilder debugInfo = null;
            // 看看是否已经超期。已经超期的不处理
            string returningDate = borrow.GetAttribute("returningDate");

            // 2020/9/14
            // 较旧的 dp2library 版本中没有 returningDate 属性,这种情况意味着所借图书的借阅时间很早很早了,可以简单当作已经超期来处理
            // 注:也可以考虑这里尝试用 borrowDate 加上 borrowPeriod 来计算出应还时间,只是比较麻烦一点
            if (string.IsNullOrEmpty(returningDate) == true)
            {
                return(true);
            }

            debugInfo?.AppendLine($"returningDate='{returningDate}'");

            DateTime returningTime = DateTimeUtil.FromRfc1123DateTimeString(returningDate).ToLocalTime();

            string period = borrow.GetAttribute("borrowPeriod");

            debugInfo?.AppendLine($"borrowPeriod='{period}'");

            int nRet = LibraryApplication.ParsePeriodUnit(period,
                                                          out long lPeriodValue,
                                                          out string strPeriodUnit,
                                                          out string strError);

            if (nRet == -1)
            {
                debugInfo?.AppendLine($"ParsePeriodUnit('{period}') 出错:{strError}。只好把时间单位当作 day 来处理");
                strPeriodUnit = "day";
                // continue;
            }

            // DateTime now = DateTime.Now;
            // 正规化时间
            nRet = DateTimeUtil.RoundTime(strPeriodUnit,
                                          ref now,
                                          out strError);
            if (nRet == -1)
            {
                warnings.Add($"正规化时间出错(1)。strPeriodUnit={strPeriodUnit}");
                debugInfo?.Append($"{warnings[warnings.Count - 1]}");
                return(false);
            }

            nRet = DateTimeUtil.RoundTime(strPeriodUnit,
                                          ref returningTime,
                                          out strError);
            if (nRet == -1)
            {
                warnings.Add($"正规化时间出错(2)。strPeriodUnit={strPeriodUnit}");
                debugInfo?.Append($"{warnings[warnings.Count - 1]}");
                return(false);
            }

            if (returningTime < now)
            {
                debugInfo?.AppendLine($"已经超期,跳过处理 (returningTime={returningTime.ToString()}, now={now.ToString()})");
                return(true);
            }

            return(false);
        }