Exemplo n.º 1
0
        public bool ClearPhotoCache(string photo_path)
        {
            if (string.IsNullOrEmpty(photo_path))
            {
                return(false);
            }

            /*
             * string cacheDir = Path.Combine(WpfClientInfo.UserDir, "photo");
             * string fileName = Path.Combine(cacheDir, GetPath(photo_path));
             */
            string fileName = GetCachePhotoPath(photo_path);

            try
            {
                SetPhoto((Stream)null);
                if (File.Exists(fileName))
                {
                    File.Delete(fileName);
                    return(true);
                }
                return(false);
            }
            catch (Exception ex)
            {
                WpfClientInfo.WriteErrorLog($"清除照片缓存文件 '{fileName}' 时出现异常: {ExceptionUtil.GetDebugText(ex)}");
                return(false);
            }
        }
Exemplo n.º 2
0
        // 开始监控一个门
        public void BeginMonitor(DoorItem door)
        {
            lock (_syncRoot)
            {
                // 检查以前这个门是否已经有监控消息
                var message = _messages.Find((m) =>
                {
                    if (m.Door == door)
                    {
                        return(true);
                    }
                    return(false);
                });

                if (message != null)
                {
                    App.CurrentApp.Speak("补做遗留提交");
                    WpfClientInfo.WriteInfoLog($"对门 {message.Door.Name} 补做一次 submit (1)");

                    _func_submit?.Invoke(message.Door, false);
                    message.StartTime      = DateTime.Now; // 重新开始
                    message.HeartbeatTicks = RfidManager.LockHeartbeat;
                }
                else
                {
                    message = new MonitorMessage
                    {
                        Door           = door,
                        StartTime      = DateTime.Now,
                        HeartbeatTicks = RfidManager.LockHeartbeat
                    };
                    _messages.Add(message);
                }
            }
        }
Exemplo n.º 3
0
        // 处理一次监控任务
        public void ProcessTimeout()
        {
            lock (_syncRoot)
            {
                List <MonitorMessage> delete_messages = new List <MonitorMessage>();
                foreach (var message in _messages)
                {
                    // if (DateTime.Now - message.StartTime > TimeoutLength)
                    if (RfidManager.LockHeartbeat - message.HeartbeatTicks >= 2)
                    {
                        App.CurrentApp.Speak("超时补做提交");
                        WpfClientInfo.WriteInfoLog($"超时情况下,对门 {message.Door.Name} 补做一次 submit");

                        _func_submit?.Invoke(message.Door, true);
                        delete_messages.Add(message);

                        message.Door.Waiting--;
                    }
                }

                foreach (var message in delete_messages)
                {
                    _messages.Remove(message);
                }
            }
        }
Exemplo n.º 4
0
        // 新版本的事件
#pragma warning disable VSTHRD100 // 避免使用 Async Void 方法
        private async void CurrentApp_NewTagChanged(object sender, NewTagChangedEventArgs e)
#pragma warning restore VSTHRD100 // 避免使用 Async Void 方法
        {
            try
            {
                // throw new Exception("testing");

                var channel = (BaseChannel <IRfid>)sender;
                // TODO: 对离开的 tag 变化为灰色颜色

                bool speaked = false;
                // 2020/10/10
                // TODO: 发出什么响声表示?
                // 把以前遗留的出错 entity 尝试重新 GetTagInfo()
                foreach (var entity in InventoryData.ErrorEntities)
                {
                    FillEntity(channel, entity, (e1) =>
                    {
                        // 说过一次便不再说
                        if (speaked == true)
                        {
                            return(false);
                        }
                        speaked = SpeakLocation(e1);
                        return(speaked);
                    });
                }

                // 筛选出需要 GetTagInfo() 的那些标签
                await FilterTags(channel, e.AddTags);

#if NO
                SoundMaker.InitialSequence(e.AddTags.Count);

                foreach (var tag in e.AddTags)
                {
                    SoundMaker.NextSound();
                    ProcessTag(channel, tag);
                }

                SoundMaker.StopCurrent();
#endif

                /*
                 * foreach (var tag in e.UpdateTags)
                 * {
                 *  ProcessTag(channel, tag);
                 * }
                 */

                App.SetError("NewTagChanged", null);
            }
            catch (Exception ex)
            {
                App.SetError("NewTagChanged", $"CurrentApp_NewTagChanged() 捕获异常: {ex.Message}");
                WpfClientInfo.WriteErrorLog($"CurrentApp_NewTagChanged() 捕获异常: {ExceptionUtil.GetDebugText(ex)}");
            }
        }
Exemplo n.º 5
0
        protected override void OnExit(ExitEventArgs e)
        {
            this._channelPool.BeforeLogin -= new DigitalPlatform.LibraryClient.BeforeLoginEventHandle(Channel_BeforeLogin);
            this._channelPool.AfterLogin  -= new AfterLoginEventHandle(Channel_AfterLogin);
            this._channelPool.Close();

            WpfClientInfo.Finish();
            base.OnExit(e);
        }
Exemplo n.º 6
0
        private void PageInventory_Loaded(object sender, RoutedEventArgs e)
        {
            App.NewTagChanged        += CurrentApp_NewTagChanged;
            App.IsPageInventoryActive = true;

            _ = Task.Run(() =>
            {
                CancellationTokenSource cancel = new CancellationTokenSource();

                ProgressWindow progress = null;
                App.Invoke(new Action(() =>
                {
                    progress                       = new ProgressWindow();
                    progress.TitleText             = "dp2SSL -- 盘点";
                    progress.MessageText           = "正在获取 UID 对照信息,请稍候 ...";
                    progress.Owner                 = Application.Current.MainWindow;
                    progress.WindowStartupLocation = WindowStartupLocation.CenterOwner;
                    progress.Closed               += (s, e1) =>
                    {
                        cancel.Cancel();
                    };
                    progress.okButton.Visibility = Visibility.Collapsed;
                    // progress.okButton.Content = "停止";
                    App.SetSize(progress, "middle");
                    progress.BackColor = "green";
                    progress.Show();
                }));

                try
                {
                    Hashtable uid_table = new Hashtable();
                    var result          = InventoryData.DownloadUidTable(
                        null,
                        uid_table,
                        (text) =>
                    {
                        App.Invoke(new Action(() =>
                        {
                            progress.MessageText = text;
                        }));
                    },
                        cancel.Token);
                    InventoryData.SetUidTable(uid_table);
                }
                catch (Exception ex)
                {
                    WpfClientInfo.WriteErrorLog($"准备册记录过程出现异常: {ExceptionUtil.GetDebugText(ex)}");
                }
                finally
                {
                    App.Invoke(new Action(() =>
                    {
                        progress.Close();
                    }));
                }
            });
        }
Exemplo n.º 7
0
 private void openKeyboard_Click(object sender, RoutedEventArgs e)
 {
     try
     {
         Process.Start("osk");
     }
     catch (Exception ex)
     {
         WpfClientInfo.WriteErrorLog($"打开触摸键盘时出现异常: {ExceptionUtil.GetDebugText(ex)}");
     }
 }
Exemplo n.º 8
0
        public static async Task <NormalResult> RenewAsync(string patronBarcode,
                                                           string itemBarcode)
        {
            try
            {
                using (var releaser = await _channelLimit.EnterAsync())
                {
                    SipChannel channel = await GetChannelAsync();

                    try
                    {
                        var result = await channel.RenewAsync(patronBarcode, itemBarcode);

                        if (result.Value == -1)
                        {
                            return new NormalResult
                                   {
                                       Value     = -1,
                                       ErrorInfo = result.ErrorInfo,
                                       ErrorCode = result.ErrorCode
                                   }
                        }
                        ;
                        if (result.Value == 0)
                        {
                            return new NormalResult
                                   {
                                       Value     = -1,
                                       ErrorInfo = result.ErrorInfo,
                                       ErrorCode = result.ErrorCode
                                   }
                        }
                        ;
                        return(new NormalResult());
                    }
                    finally
                    {
                        ReturnChannel(channel);
                    }
                }
            }
            catch (Exception ex)
            {
                WpfClientInfo.WriteErrorLog($"RenewAsync() 出现异常: {ExceptionUtil.GetDebugText(ex)}");

                return(new GetEntityDataResult
                {
                    Value = -1,
                    ErrorInfo = $"RenewAsync() 出现异常: {ex.Message}",
                    ErrorCode = ex.GetType().ToString()
                });
            }
        }
Exemplo n.º 9
0
        // 把 Actions 追加保存到本地数据库
        // 当本函数执行完以后,ActionInfo 对象的 ID 有了值,和数据库记录的 ID 对应
        public static async Task SaveActionsToDatabaseAsync(List <ActionInfo> actions)
        {
            try
            {
                using (var releaser = await _databaseLimit.EnterAsync())
                {
                    using (var context = new RequestContext())
                    {
                        context.Database.EnsureCreated();

                        var requests = FromActions(actions);
                        foreach (var request in requests)
                        {
                            // 注:这样一个一个保存可以保持 ID 的严格从小到大。因为这些事项之间是有严格顺序关系的(借和还顺序不能颠倒)
                            await context.Requests.AddRangeAsync(request);

                            int nCount = await context.SaveChangesAsync();

                            // 2020/4/27
                            // 如果是还书动作,需要更新它之前的全部同 PII 的借书动作的 LinkID 字段
                            if (request.Action == "return" || request.Action == "inventory")
                            {
                                var borrowRequests = context.Requests.
                                                     Where(o => o.PII == request.PII && o.Action == "borrow" && o.LinkID == null)
                                                     .ToList();
                                foreach (var item in borrowRequests)
                                {
                                    item.LinkID = request.ID.ToString();
                                    context.Requests.Update(item);
                                    await context.SaveChangesAsync();
                                }
                            }
                        }

                        Debug.Assert(requests.Count == actions.Count, "");
                        // 刷新 ActionInfo 对象的 ID
                        for (int i = 0; i < requests.Count; i++)
                        {
                            actions[i].ID = requests[i].ID;
                        }

                        WpfClientInfo.WriteInfoLog($"Actions 保存到本地数据库成功。内容如下:\r\n{ActionInfo.ToString(actions)}");
                    }
                }
            }
            catch (Exception ex)
            {
                WpfClientInfo.WriteErrorLog($"SaveActionsToDatabase() 出现异常: {ExceptionUtil.GetDebugText(ex)}");
                throw ex;
            }
        }
Exemplo n.º 10
0
        // sync/commerror/normalerror/空
        // 同步成功/通讯出错/一般出错/从未同步过

        // 从外部存储中装载尚未同步的 Actions
        // 注意:这些 Actions 应该先按照 PII 排序分组以后,一组一组进行处理
        public static async Task <List <ActionInfo> > LoadRetryActionsFromDatabaseAsync()
        {
            using (var releaser = await _databaseLimit.EnterAsync())
            {
                using (var context = new RequestContext())
                {
                    context.Database.EnsureCreated();
                    var items = context.Requests.Where(o => o.State != "sync" && o.State != "dontsync")
                                .OrderBy(o => o.ID).ToList();
                    var actions = FromRequests(items);
                    WpfClientInfo.WriteInfoLog($"从本地数据库装载 Actions 成功。内容如下:\r\n{ActionInfo.ToString(actions)}");
                    return(actions);
                }
            }
        }
Exemplo n.º 11
0
        // 启动盘点后台任务
        public static void StartInventoryTask()
        {
            if (_inventoryTask != null)
            {
                return;
            }

            CancellationToken token = App.CancelToken;

            token.Register(() =>
            {
                _eventInventory.Set();
            });

            _inventoryTask = Task.Factory.StartNew(async() =>
            {
                WpfClientInfo.WriteInfoLog("盘点后台线程开始");
                try
                {
                    while (token.IsCancellationRequested == false)
                    {
                        // await Task.Delay(TimeSpan.FromSeconds(10));
                        _eventInventory.WaitOne(_inventoryIdleLength);

                        token.ThrowIfCancellationRequested();

                        //
                        await ProcessingAsync();
                    }
                    _inventoryTask = null;
                }
                catch (OperationCanceledException)
                {
                }
                catch (Exception ex)
                {
                    WpfClientInfo.WriteErrorLog($"盘点后台线程出现异常: {ExceptionUtil.GetDebugText(ex)}");
                    App.SetError("inventory_worker", $"盘点后台线程出现异常: {ex.Message}");
                }
                finally
                {
                    WpfClientInfo.WriteInfoLog("盘点后台线程结束");
                }
            },
                                                   token,
                                                   TaskCreationOptions.LongRunning,
                                                   TaskScheduler.Default);
        }
Exemplo n.º 12
0
        // result.Value
        //      0   没有找到记录。没有发生更新
        //      1   成功更新
        public static async Task <NormalResult> UpdateEntityXmlAsync(string pii,
                                                                     string item_xml,
                                                                     byte[] timestamp)
        {
            try
            {
                using (BiblioCacheContext context = new BiblioCacheContext())
                {
                    if (_cacheDbCreated == false)
                    {
                        context.Database.EnsureCreated();
                        _cacheDbCreated = true;
                    }

                    // 先尝试从本地实体库中获得原记录
                    var entity_record = context.Entities.Where(o => o.PII == pii).FirstOrDefault();
                    if (entity_record == null)
                    {
                        return new NormalResult {
                                   Value = 0
                        }
                    }
                    ;

                    entity_record.Xml       = item_xml;
                    entity_record.Timestamp = timestamp;

                    // 保存到本地数据库
                    context.Entities.Update(entity_record);
                    await context.SaveChangesAsync();

                    return(new NormalResult {
                        Value = 1
                    });
                }
            }
            catch (Exception ex)
            {
                WpfClientInfo.WriteErrorLog($"UpdateEntityXmlAsync() 出现异常: {ExceptionUtil.GetDebugText(ex)}");

                return(new NormalResult
                {
                    Value = -1,
                    ErrorInfo = $"UpdateEntityXmlAsync() 出现异常: {ex.Message}"
                });
            }
        }
Exemplo n.º 13
0
        public static void Start(
            List <ProcessInfo> process_infos,
            delegate_writeLog writeLog,
            CancellationToken token)
        {
            TimeSpan wait_time = TimeSpan.FromSeconds(30);

            Task.Run(() =>
            {
                while (token.IsCancellationRequested == false)
                {
                    // 延时
                    try
                    {
                        Task.Delay(// TimeSpan.FromMilliseconds(1000),
                            wait_time,
                            token).Wait();
                    }
                    catch
                    {
                        return;
                    }

                    foreach (ProcessInfo info in process_infos)
                    {
                        if (token.IsCancellationRequested)
                        {
                            return;
                        }

                        if (WpfClientInfo.HasModuleStarted(info.MutexName) == true)
                        {
                            continue;
                        }

                        // TODO: 写入日志
                        writeLog?.Invoke(info, "进程被重新启动");

                        // 启动
                        WpfClientInfo.StartModule(info.ShortcutPath, "minimize");
                    }
                }
            });
        }
Exemplo n.º 14
0
        protected override void OnStartup(StartupEventArgs e)
        {
            if (DetectVirus.Detect360() || DetectVirus.DetectGuanjia())
            {
                MessageBox.Show("dp2SSL 被木马软件干扰,无法启动");
                System.Windows.Application.Current.Shutdown();
                return;
            }

            WpfClientInfo.TypeOfProgram = typeof(App);
            if (StringUtil.IsDevelopMode() == false)
            {
                WpfClientInfo.PrepareCatchException();
            }

            WpfClientInfo.Initial("dp2SSL");
            base.OnStartup(e);

            this._channelPool.BeforeLogin += new DigitalPlatform.LibraryClient.BeforeLoginEventHandle(Channel_BeforeLogin);
            this._channelPool.AfterLogin  += new AfterLoginEventHandle(Channel_AfterLogin);

            // 后台自动检查更新
            Task.Run(() =>
            {
                NormalResult result = WpfClientInfo.InstallUpdateSync();
                if (result.Value == -1)
                {
                    OutputHistory("自动更新出错: " + result.ErrorInfo, 2);
                }
                else if (result.Value == 1)
                {
                    OutputHistory(result.ErrorInfo, 1);
                }
                else if (string.IsNullOrEmpty(result.ErrorInfo) == false)
                {
                    OutputHistory(result.ErrorInfo, 0);
                }
            });
        }
Exemplo n.º 15
0
        // 2020/8/26
        // 把本地动作库中符合指定 borrowID 的状态修改为 “dontsync”
        internal static async Task ChangeDatabaseBorrowStateAsync(string borrowID)
        {
            using (var releaser = await _databaseLimit.EnterAsync())
            {
                using (var context = new RequestContext())
                {
                    var         items   = context.Requests.Where(o => o.Action == "borrow" && o.LinkID == null && string.IsNullOrEmpty(o.ActionString) == false).ToList();
                    RequestItem request = null;
                    foreach (var item in items)
                    {
                        try
                        {
                            var borrow_info = JsonConvert.DeserializeObject <BorrowInfo>(item.ActionString);
                            if (borrow_info.BorrowID == borrowID)
                            {
                                request = item;
                                break;
                            }
                        }
                        catch (Exception ex)
                        {
                            WpfClientInfo.WriteErrorLog($"解析 borrow_info 字符串 '{item.ActionString}' 时出现异常: {ExceptionUtil.GetDebugText(ex)}");
                        }
                    }

                    if (request != null)
                    {
                        // request.State = "dontsync";

                        // 表示这个借书动作已经发生了还书
                        request.LinkID = $"borrowID={borrowID}";
                        context.SaveChanges();
                    }
                }
            }
        }
Exemplo n.º 16
0
        public static bool ClearPhotoCacheFile(string photo_path)
        {
            if (string.IsNullOrEmpty(photo_path))
            {
                return(false);
            }

            string fileName = GetCachePhotoPath(photo_path);

            try
            {
                if (File.Exists(fileName))
                {
                    File.Delete(fileName);
                    return(true);
                }
                return(false);
            }
            catch (Exception ex)
            {
                WpfClientInfo.WriteErrorLog($"删除照片缓存文件 '{fileName}' 时出现异常: {ExceptionUtil.GetDebugText(ex)}");
                return(false);
            }
        }
Exemplo n.º 17
0
        // 将指定门的暂存的信息保存为 Action。但并不立即提交
        public async static Task SaveDoorActions(DoorItem door, bool clearOperator)
        {
            var result = await ShelfData.SaveActions((entity) =>
            {
                var results = DoorItem.FindDoors(ShelfData.Doors, entity.ReaderName, entity.Antenna);
                // TODO: 如果遇到 results.Count > 1 是否抛出异常?
                if (results.Count > 1)
                {
                    WpfClientInfo.WriteErrorLog($"读卡器名 '{entity.ReaderName}' 天线编号 {entity.Antenna} 匹配上 {results.Count} 个门");
                    throw new Exception($"读卡器名 '{entity.ReaderName}' 天线编号 {entity.Antenna} 匹配上 {results.Count} 个门。请检查 shelf.xml 并修正配置此错误,确保只匹配一个门");
                }

                if (results.IndexOf(door) != -1)
                {
                    return(door.Operator);
                    // return GetOperator(entity);
                }
                return(null);
            });

            if (result.Value == -1)
            {
                SetGlobalError("save_actions", $"SaveDoorActions() 出错: {result.ErrorInfo}");
                PageShelf.TrySetMessage(null, $"SaveDoorActions() 出错: {result.ErrorInfo}。这是一个严重错误,请管理员及时介入处理");
            }
            else
            {
                SetGlobalError("save_actions", null);
            }

            // 2019/12/21
            if (clearOperator == true && door.State == "close")
            {
                door.Operator = null; // 清掉门上的操作者名字
            }
        }
Exemplo n.º 18
0
        // 启动同步任务。此任务长期在后台运行
        public static void StartSyncTask()
        {
            if (_syncTask != null)
            {
                return;
            }

            CancellationToken token = _cancel.Token;

            token.Register(() =>
            {
                _eventSync.Set();
            });

            // 启动重试专用线程
            _syncTask = Task.Factory.StartNew(async() =>
            {
                WpfClientInfo.WriteInfoLog("重试专用线程开始");
                try
                {
                    while (token.IsCancellationRequested == false)
                    {
                        // TODO: 无论是整体退出,还是需要激活,都需要能中断 Delay
                        // Task.Delay(TimeSpan.FromSeconds(10)).Wait(token);
                        _eventSync.WaitOne(_syncIdleLength);
                        token.ThrowIfCancellationRequested();

#if REMOVED
                        // 顺便检查和确保连接到消息服务器
                        App.CurrentApp.EnsureConnectMessageServer().Wait(token);
#endif

#if REMOVED
                        // 顺便关闭天线射频
                        if (_tagAdded)
                        {
                            _ = Task.Run(async() =>
                            {
                                try
                                {
                                    await SelectAntennaAsync();
                                }
                                catch
                                {
                                    // TODO: 写入错误日志
                                }
                            });
                            _tagAdded = false;
                        }
#endif

                        if (PauseSubmit)
                        {
                            continue;
                        }

                        // 2020/6/21
                        if (ShelfData.LibraryNetworkCondition != "OK")
                        {
                            continue;
                        }

                        // TODO: 从本地数据库中装载需要同步的那些 Actions
                        List <ActionInfo> actions = await LoadRetryActionsFromDatabaseAsync();
                        if (actions.Count == 0)
                        {
                            continue;
                        }

                        // RefreshRetryInfo() ???

                        // 一般来说,只要 SubmitWindow 开着,就要显示请求情况结果。
                        // 特殊地,如果 SubmitWindow 没有开着,但本次至少有一个成功的请求结果了,那就专门打开 SubmitWindow 显示信息

                        int succeedCount = 0; // 同步成功的事项数量
                        int newCount     = 0; // 首次进行同步的事项数量

                        // 排序和分组。按照分组提交给 dp2library 服务器
                        // TODO: 但进度显示不应该太细碎?应该按照总的进度来显示
                        var groups = GroupActions(actions);

                        // List<MessageItem> messages = new List<MessageItem>();

                        // 准备对话框
                        // SubmitWindow progress = PageMenu.PageShelf?.OpenProgressWindow();
                        SubmitWindow progress = PageMenu.PageShelf?.ProgressWindow;

                        int start = 0;  // 当前 group 开始的偏移
                        int total = actions.Count;
                        foreach (var group in groups)
                        {
                            int current_count = group.Count;    // 当前 group 包含的动作数量

                            var result = await SubmitCheckInOutAsync(
                                (min, max, value, text) =>
                            {
                                // 2020/4/2
                                // 修正三个值
                                if (max != -1)
                                {
                                    max = total;
                                }
                                //if (min != -1)
                                //    min += start;
                                if (value != -1)
                                {
                                    value += start;
                                }

                                if (progress != null)
                                {
                                    App.Invoke(new Action(() =>
                                    {
                                        if (min == -1 && max == -1 && value == -1 &&
                                            groups.IndexOf(group) == groups.Count - 1)  // 只有最后一次才隐藏进度条
                                        {
                                            progress.ProgressBar.Visibility = Visibility.Collapsed;
                                        }
                                        else
                                        {
                                            progress.ProgressBar.Visibility = Visibility.Visible;
                                        }

                                        if (text != null)
                                        {
                                            progress.TitleText = text;  // + " " + (progress.Tag as string);
                                        }
                                        if (min != -1)
                                        {
                                            progress.ProgressBar.Minimum = min;
                                        }
                                        if (max != -1)
                                        {
                                            progress.ProgressBar.Maximum = max;
                                        }
                                        if (value != -1)
                                        {
                                            progress.ProgressBar.Value = value;
                                        }
                                    }));
                                }
                            },
                                group,
                                "auto_stop");

                            // TODO: 把 group 中报错的信息写入本地数据库的对应事项中

                            /*
                             * // 把已经处理成功的 Action 对应在本地数据库中的事项的状态修改
                             * List<ActionInfo> processed = new List<ActionInfo>();
                             * if (result.RetryActions != null)
                             * {
                             *  foreach (var action in group)
                             *  {
                             *      if (result.RetryActions.IndexOf(action) == -1)
                             *      {
                             *          ChangeDatabaseActionState(action.ID, "sync");
                             *          processed.Add(action);
                             *      }
                             *  }
                             * }
                             */
                            if (result.ProcessedActions != null)
                            {
                                // result.ProcessedActions.ForEach(o => { if (o.SyncCount == 0) newCount++; });

                                foreach (var action in result.ProcessedActions)
                                {
                                    if (action.State == "sync")
                                    {
                                        succeedCount++;
                                    }
                                    if (action.SyncCount == 1)
                                    {
                                        newCount++;
                                    }
                                    // sync/commerror/normalerror/空
                                    // 同步成功/通讯出错/一般出错/从未同步过
                                    await ChangeDatabaseActionStateAsync(action.ID, action);
                                }

                                // TODO: 通知消息正文是否也告知一下同一个 PII 后面有多少个动作被跳过处理?
                                MessageNotifyOverflow(result.ProcessedActions);
                            }

                            if (progress != null && progress.IsVisible)
                            {
                                // 根据全部和已处理集合得到未处理(被跳过的)集合
                                var skipped = GetSkippedActions(group, result.ProcessedActions);
                                foreach (var action in skipped)
                                {
                                    action.State         = "_";
                                    action.SyncErrorCode = "skipped";
                                    // action.SyncErrorInfo = "暂时跳过同步";
                                }

                                List <ActionInfo> display = new List <ActionInfo>(result.ProcessedActions);
                                display.AddRange(skipped);
                                // Thread.Sleep(3000);
                                // 刷新显示
                                App.Invoke(new Action(() =>
                                {
                                    progress?.Refresh(display);
                                }));
                            }

                            /*
                             * if (result.MessageDocument != null)
                             *  messages.AddRange(result.MessageDocument.Items);
                             */
                            start += current_count;
                        }

                        // TODO: 更新每个事项的 RetryCount。如果超过 10 次,要把 State 更新为 fail

                        // 将 submit 情况写入日志备查
                        // WpfClientInfo.WriteInfoLog($"重试提交请求:\r\n{ActionInfo.ToString(actions)}\r\n返回结果:{result.ToString()}");



#if REMOVED
                        // 如果本轮有成功的请求,并且进度窗口没有打开,则补充打开进度窗口
                        if ((progress == null || progress.IsVisible == false) &&
                            succeedCount > 0)
                        {
                            progress = PageMenu.PageShelf?.OpenProgressWindow();
                        }

                        // 把执行结果显示到对话框内
                        // 全部事项都重试失败的时候不需要显示
                        if (progress != null && progress.IsVisible &&
                            (succeedCount > 0 || newCount > 0))
                        {
                            Application.Current.Dispatcher.Invoke(new Action(() =>
                            {
                                MessageDocument doc = new MessageDocument();
                                doc.AddRange(messages);
                                progress?.PushContent(doc);
                            }));

                            // 显示出来
                            Application.Current.Dispatcher.Invoke(new Action(() =>
                            {
                                progress?.ShowContent();
                            }));
                        }
#endif
                    }
                    _syncTask = null;
                }
                catch (OperationCanceledException)
                {
                }
                catch (Exception ex)
                {
                    WpfClientInfo.WriteErrorLog($"重试专用线程出现异常: {ExceptionUtil.GetDebugText(ex)}");
                    App.SetError("sync", $"重试专用线程出现异常: {ex.Message}");
                }
                finally
                {
                    WpfClientInfo.WriteInfoLog("重试专用线程结束");
                }
            },
                                              token,
                                              TaskCreationOptions.LongRunning,
                                              TaskScheduler.Default);
        }
Exemplo n.º 19
0
        private void PageInventory_Loaded(object sender, RoutedEventArgs e)
        {
            App.NewTagChanged        += CurrentApp_NewTagChanged;
            App.IsPageInventoryActive = true;

            RefreshActionModeMenu();

            _ = Task.Run(() =>
            {
                // 获得馆藏地列表
                GetLocationListResult get_result = LibraryChannelUtil.GetLocationList();
                if (get_result.Value == -1)
                {
                    App.SetError("inventory", $"获得馆藏地列表时出错: {get_result.ErrorInfo}");
                }

                string batchNo = "inventory_" + DateTime.Now.ToShortDateString();

                bool slow_mode     = false;
                bool dialog_result = false;
                // “开始盘点”对话框
                App.Invoke(new Action(() =>
                {
                    App.PauseBarcodeScan();
                    try
                    {
                        BeginInventoryWindow dialog = new BeginInventoryWindow();
                        dialog.TitleText            = $"开始盘点";
                        // dialog.Text = $"如何处理以上放入 {door_names} 的 {collection.Count} 册图书?";
                        dialog.Owner = App.CurrentApp.MainWindow;
                        // dialog.BatchNo = batchNo;
                        dialog.WindowStartupLocation = WindowStartupLocation.CenterOwner;
                        App.SetSize(dialog, "tall");
                        dialog.location.ItemsSource = get_result.List;  // result.List;
                        dialog.BatchNo    = batchNo;
                        dialog.ActionMode = ActionMode;
                        dialog.ShowDialog();
                        if (dialog.DialogResult == false)
                        {
                            dialog_result = false;
                        }
                        else
                        {
                            dialog_result = true;

                            {
                                _actionMode = dialog.ActionMode;
                                RefreshActionModeMenu();
                            }

                            CurrentLocation = dialog.Location;
                            CurrentBatchNo  = dialog.BatchNo;
                            slow_mode       = dialog.SlowMode;
                        }
                    }
                    finally
                    {
                        App.ContinueBarcodeScan();
                    }
                }));

                ClearList();

                if (dialog_result == true && slow_mode == false)
                {
                    CancellationTokenSource cancel = new CancellationTokenSource();

                    ProgressWindow progress = null;
                    App.Invoke(new Action(() =>
                    {
                        progress                       = new ProgressWindow();
                        progress.TitleText             = "dp2SSL -- 盘点";
                        progress.MessageText           = "正在获取 UID 对照信息,请稍候 ...";
                        progress.Owner                 = Application.Current.MainWindow;
                        progress.WindowStartupLocation = WindowStartupLocation.CenterOwner;
                        progress.Closed               += (s, e1) =>
                        {
                            cancel.Cancel();
                        };
                        progress.okButton.Visibility = Visibility.Collapsed;
                        // progress.okButton.Content = "停止";
                        App.SetSize(progress, "middle");
                        progress.BackColor = "green";
                        progress.Show();
                    }));

                    try
                    {
                        Hashtable uid_table = new Hashtable();
                        var result          = InventoryData.DownloadUidTable(
                            null,
                            uid_table,
                            (text) =>
                        {
                            App.Invoke(new Action(() =>
                            {
                                progress.MessageText = text;
                            }));
                        },
                            cancel.Token);
                        InventoryData.SetUidTable(uid_table);
                    }
                    catch (Exception ex)
                    {
                        WpfClientInfo.WriteErrorLog($"准备册记录过程出现异常: {ExceptionUtil.GetDebugText(ex)}");
                    }
                    finally
                    {
                        App.Invoke(new Action(() =>
                        {
                            progress.Close();
                        }));
                    }
                }
            });
        }
Exemplo n.º 20
0
        // 启动一般监控任务
        public static void StartMonitorTask()
        {
            if (_monitorTask != null)
            {
                return;
            }

            PerdayTask.StartPerdayTask();

            CancellationToken token = _cancel.Token;

            // bool download_complete = false;

            token.Register(() =>
            {
                _eventMonitor.Set();
            });

            _monitorTask = Task.Factory.StartNew(async() =>
            {
                WpfClientInfo.WriteInfoLog("书柜监控专用线程开始");
                try
                {
                    while (token.IsCancellationRequested == false)
                    {
                        // await Task.Delay(TimeSpan.FromSeconds(10));
                        _eventMonitor.WaitOne(_monitorIdleLength);

                        token.ThrowIfCancellationRequested();

                        // ***
                        // 关闭天线射频
                        if (_tagAdded)
                        {
                            _ = Task.Run(async() =>
                            {
                                try
                                {
                                    await SelectAntennaAsync();
                                }
                                catch (Exception ex)
                                {
                                    WpfClientInfo.WriteErrorLog($"关闭天线射频 SelectAntennaAsync() 时出现异常: {ExceptionUtil.GetDebugText(ex)}");
                                }
                            });
                            _tagAdded = false;
                        }

                        if (DateTime.Now - _lastDetectTime > _detectPeriod)
                        {
                            DetectLibraryNetwork();

                            _lastDetectTime = DateTime.Now;
                        }

                        // 提醒关门
                        WarningCloseDoor();

                        // 下载或同步读者信息
                        string startDate = LoadStartDate();
                        if (/*download_complete == false || */
                            string.IsNullOrEmpty(startDate) &&
                            _replicatePatronError == 0)
                        {
                            // 如果 Config 中没有记载断点位置,说明以前从来没有首次同步过。需要进行一次首次同步
                            if (string.IsNullOrEmpty(startDate))
                            {
                                // SaveStartDate("");

                                var repl_result = await PatronReplication.DownloadAllPatronRecordAsync(
                                    (text) =>
                                {
                                    WpfClientInfo.WriteInfoLog(text);
                                    PageShelf.TrySetMessage(null, text);
                                },
                                    token);
                                if (repl_result.Value == -1)
                                {
                                    // TODO: 判断通讯出错的错误码。如果是通讯出错,则稍后需要重试下载
                                    _replicatePatronError++;
                                }
                                else
                                {
                                    SaveStartDate(repl_result.StartDate);
                                }

                                // 立刻允许接着做一次零星同步
                                ActivateMonitor();
                            }
                            // download_complete = true;
                        }
                        else
                        {
                            // 进行零星同步
                            if (DateTime.Now - _lastReplicateTime > _replicatePeriod)
                            {
                                // string startDate = LoadStartDate();

                                // testing
                                // startDate = "20200507:0-";

                                if (string.IsNullOrEmpty(startDate) == false)
                                {
                                    string endDate = DateTimeUtil.DateTimeToString8(DateTime.Now);

                                    // parameters:
                                    //      strLastDate   处理中断或者结束时返回最后处理过的日期
                                    //      last_index  处理或中断返回时最后处理过的位置。以后继续处理的时候可以从这个偏移开始
                                    // return:
                                    //      -1  出错
                                    //      0   中断
                                    //      1   完成
                                    ReplicationResult repl_result = await PatronReplication.DoReplication(
                                        startDate,
                                        endDate,
                                        LogType.OperLog,
                                        token);
                                    if (repl_result.Value == -1)
                                    {
                                        WpfClientInfo.WriteErrorLog($"同步出错: {repl_result.ErrorInfo}");
                                    }
                                    else if (repl_result.Value == 1)
                                    {
                                        string lastDate = repl_result.LastDate + ":" + repl_result.LastIndex + "-";    // 注意 - 符号不能少。少了意思就会变成每次只获取一条日志记录了
                                        SaveStartDate(lastDate);
                                    }

                                    _lastReplicateTime = DateTime.Now;
                                }
                            }
                        }
                    }
                    _monitorTask = null;
                }
                catch (OperationCanceledException)
                {
                }
                catch (Exception ex)
                {
                    WpfClientInfo.WriteErrorLog($"书柜监控专用线程出现异常: {ExceptionUtil.GetDebugText(ex)}");
                    App.SetError("shelf_monitor", $"书柜监控专用线程出现异常: {ex.Message}");
                }
                finally
                {
                    WpfClientInfo.WriteInfoLog("书柜监控专用线程结束");
                }
            },
                                                 token,
                                                 TaskCreationOptions.LongRunning,
                                                 TaskScheduler.Default);
        }
Exemplo n.º 21
0
 public static void WriteInfoLog(string text)
 {
     WpfClientInfo.WriteInfoLog(text);
 }
Exemplo n.º 22
0
        // 启动一般监控任务
        public static void StartMonitorTask()
        {
            if (_monitorTask != null)
            {
                return;
            }

            CancellationToken token = _cancel.Token;
            bool download_complete  = false;

            token.Register(() =>
            {
                _eventMonitor.Set();
            });

            _monitorTask = Task.Factory.StartNew(async() =>
            {
                WpfClientInfo.WriteInfoLog("监控专用线程开始");
                try
                {
                    while (token.IsCancellationRequested == false)
                    {
                        // await Task.Delay(TimeSpan.FromSeconds(10));
                        _eventMonitor.WaitOne(_monitorIdleLength);

                        token.ThrowIfCancellationRequested();

                        // ***
                        // 关闭天线射频
                        if (_tagAdded)
                        {
                            _ = Task.Run(async() =>
                            {
                                try
                                {
                                    await SelectAntennaAsync();
                                }
                                catch (Exception ex)
                                {
                                    WpfClientInfo.WriteErrorLog($"关闭天线射频 SelectAntennaAsync() 时出现异常: {ExceptionUtil.GetDebugText(ex)}");
                                }
                            });
                            _tagAdded = false;
                        }

                        if (DateTime.Now - _lastDetectTime > _detectPeriod)
                        {
                            DetectLibraryNetwork();

                            _lastDetectTime = DateTime.Now;
                        }

                        // 提醒关门
                        WarningCloseDoor();

                        // 下载或同步读者信息
                        string startDate = LoadStartDate();
                        if (/*download_complete == false || */
                            string.IsNullOrEmpty(startDate))
                        {
                            // 如果 Config 中没有记载断点位置,说明以前从来没有首次同步过。需要进行一次首次同步
                            if (string.IsNullOrEmpty(startDate))
                            {
                                // SaveStartDate("");

                                var repl_result = await PatronReplication.DownloadAllPatronRecordAsync(token);
                                if (repl_result.Value == -1)
                                {
                                    // TODO: 判断通讯出错的错误码。如果是通讯出错,则稍后需要重试下载
                                }
                                else
                                {
                                    SaveStartDate(repl_result.StartDate);
                                }

                                // 立刻允许接着做一次零星同步
                                ActivateMonitor();
                            }
                            // download_complete = true;
                        }
                        else
                        {
                            // 进行零星同步
                            if (DateTime.Now - _lastReplicateTime > _replicatePeriod)
                            {
                                // string startDate = LoadStartDate();

                                // testing
                                // startDate = "20200507:0-";

                                if (string.IsNullOrEmpty(startDate) == false)
                                {
                                    string endDate = DateTimeUtil.DateTimeToString8(DateTime.Now);

                                    // parameters:
                                    //      strLastDate   处理中断或者结束时返回最后处理过的日期
                                    //      last_index  处理或中断返回时最后处理过的位置。以后继续处理的时候可以从这个偏移开始
                                    // return:
                                    //      -1  出错
                                    //      0   中断
                                    //      1   完成
                                    ReplicationResult repl_result = PatronReplication.DoReplication(
                                        startDate,
                                        endDate,
                                        LogType.OperLog,
                                        token);
                                    if (repl_result.Value == -1)
                                    {
                                        WpfClientInfo.WriteErrorLog($"同步出错: {repl_result.ErrorInfo}");
                                    }
                                    else if (repl_result.Value == 1)
                                    {
                                        string lastDate = repl_result.LastDate + ":" + repl_result.LastIndex + "-";    // 注意 - 符号不能少。少了意思就会变成每次只获取一条日志记录了
                                        SaveStartDate(lastDate);
                                    }

                                    _lastReplicateTime = DateTime.Now;
                                }
                            }
                        }

                        // 检查升级 dp2ssl
                        if (_updated == false
                            // && StringUtil.IsDevelopMode() == false
                            && ApplicationDeployment.IsNetworkDeployed == false &&
                            DateTime.Now - _lastUpdateTime > _updatePeriod)
                        {
                            WpfClientInfo.WriteInfoLog("开始自动检查升级");
                            // result.Value:
                            //      -1  出错
                            //      0   经过检查发现没有必要升级
                            //      1   成功
                            //      2   成功,但需要立即重新启动计算机才能让复制的文件生效
                            var update_result = await GreenInstaller.InstallFromWeb("http://dp2003.com/dp2ssl/v1_dev",
                                                                                    "c:\\dp2ssl",
                                                                                    "delayExtract,updateGreenSetupExe",
                                                                                    //true,
                                                                                    //true,
                                                                                    token,
                                                                                    null);
                            if (update_result.Value == -1)
                            {
                                WpfClientInfo.WriteErrorLog($"自动检查升级出错: {update_result.ErrorInfo}");
                            }
                            else
                            {
                                WpfClientInfo.WriteInfoLog($"结束自动检查升级 update_result:{update_result.ToString()}");
                            }

                            if (update_result.Value == 1 || update_result.Value == 2)
                            {
                                App.TriggerUpdated("重启可使用新版本");
                                _updated = true;
                                PageShelf.TrySetMessage(null, "dp2SSL 升级文件已经下载成功,下次重启时可自动升级到新版本");
                            }
                            _lastUpdateTime = DateTime.Now;
                        }
                    }
                    _monitorTask = null;
                }
                catch (OperationCanceledException)
                {
                }
                catch (Exception ex)
                {
                    WpfClientInfo.WriteErrorLog($"监控专用线程出现异常: {ExceptionUtil.GetDebugText(ex)}");
                    App.SetError("monitor", $"监控专用线程出现异常: {ex.Message}");
                }
                finally
                {
                    WpfClientInfo.WriteInfoLog("监控专用线程结束");
                }
            },
                                                 token,
                                                 TaskCreationOptions.LongRunning,
                                                 TaskScheduler.Default);
        }
Exemplo n.º 23
0
        // 从 _entityList 中取出一批事项进行处理。由于是复制出来处理的,所以整个处理过程中(除了取出和最后删除的瞬间)不用对 _entityList 加锁
        // 对每一个事项,要进行如下处理:
        //  1) 获得册记录和书目摘要
        //  2) 尝试请求还书
        //  3) 请求设置 UID
        //  4) 修改 currentLocation 和 location
        static async Task ProcessingAsync()
        {
            var list = CopyList();

            foreach (var state in list)
            {
                // state.State = "???";
                try
                {
                    if (state.NewState == "open")
                    {
                        continue;
                    }

                    Debug.Assert(state.NewState == "close");

                    List <ActionInfo> actions = null;

                    try
                    {
                        DateTime start = DateTime.Now;

                        var result = await ShelfData.RefreshInventoryAsync(state.Door);

                        WpfClientInfo.WriteInfoLog($"针对门 {state.Door.Name} 执行 RefreshInventoryAsync() 耗时 {(DateTime.Now - start).TotalSeconds.ToString()}");

                        start = DateTime.Now;

                        // 2020/4/21 把这两句移动到 try 范围内
                        await SaveDoorActions(state.Door, true);

                        WpfClientInfo.WriteInfoLog($"针对门 {state.Door.Name} 执行 SaveDoorActions() 耗时 {(DateTime.Now - start).TotalSeconds.ToString()}");

                        start = DateTime.Now;

                        actions = ShelfData.PullActions();
                        WpfClientInfo.WriteInfoLog($"针对门 {state.Door.Name} 执行 PullActions() 耗时 {(DateTime.Now - start).TotalSeconds.ToString()}");
                    }
                    finally
                    {
                        state.Door.DecWaiting();
                        //WpfClientInfo.WriteInfoLog($"--decWaiting() door '{e.Door.Name}' state changed");
                    }


                    // 注: 调用完成后门控件上的 +- 数字才会消失
                    var task = PageMenu.PageShelf.DoRequestAsync(actions, "");

                    App.SetError("processing", null);
                }
                catch (Exception ex)
                {
                    WpfClientInfo.WriteErrorLog($"ProcessingAsync() 出现异常: {ExceptionUtil.GetDebugText(ex)}");
                    App.SetError("processing", $"ProcessingAsync() 出现异常: {ex.Message}");
                }
                finally
                {
                    // state.State = "";
                }
            }

            // 把处理过的 entity 从 list 中移走
            RemoveList(list);

            // 2020/11/21
            // 如果发现队列里面又有新的对象,则立即激活任务
            if (GetListCount() > 0)
            {
                ActivateTask();
            }
        }
Exemplo n.º 24
0
        // 启动一般监控任务
        public static void StartMonitorTask()
        {
            if (_monitorTask != null)
            {
                return;
            }

            CancellationToken token = App.CancelToken;

            token.Register(() =>
            {
                _eventMonitor.Set();
            });

            _monitorTask = Task.Factory.StartNew(async() =>
            {
                WpfClientInfo.WriteInfoLog("SIP 监控专用线程开始");
                try
                {
                    while (token.IsCancellationRequested == false)
                    {
                        // await Task.Delay(TimeSpan.FromSeconds(10));
                        _eventMonitor.WaitOne(_monitorIdleLength);

                        token.ThrowIfCancellationRequested();

                        if (DateTime.Now - _lastDetectTime > _detectPeriod)
                        {
                            var detect_result = await DetectSipNetworkAsync();
                            _lastDetectTime   = DateTime.Now;

                            // testing
                            //detect_result.Value = -1;
                            //detect_result.ErrorInfo = "测试文字";

                            if (detect_result.Value != 1)
                            {
                                App.OpenErrorWindow(detect_result.ErrorInfo);
                            }
                            else
                            {
                                App.CloseErrorWindow();
                            }
                        }
                    }
                    _monitorTask = null;
                }
                catch (OperationCanceledException)
                {
                }
                catch (Exception ex)
                {
                    WpfClientInfo.WriteErrorLog($"SIP 监控专用线程出现异常: {ExceptionUtil.GetDebugText(ex)}");
                    App.SetError("monitor", $"SIP 监控专用线程出现异常: {ex.Message}");
                }
                finally
                {
                    WpfClientInfo.WriteInfoLog("SIP 监控专用线程结束");
                }
            },
                                                 token,
                                                 TaskCreationOptions.LongRunning,
                                                 TaskScheduler.Default);
        }
Exemplo n.º 25
0
        static async Task <NormalResult> DetectSipNetworkAsync()
        {
            /*
             * // testing
             * return new NormalResult { Value = 1 };
             */
            try
            {
                using (var releaser = await _channelLimit.EnterAsync())
                {
                    SipChannel channel = await GetChannelAsync();

                    try
                    {
                        // -1出错,0不在线,1正常
                        var result = await channel.ScStatusAsync();

                        if (result.Value == -1)
                        {
                            return new NormalResult
                                   {
                                       Value     = -1,
                                       ErrorInfo = result.ErrorInfo,
                                       ErrorCode = result.ErrorCode
                                   }
                        }
                        ;
                        if (result.Value == 0)
                        {
                            return new NormalResult
                                   {
                                       Value     = 0,
                                       ErrorInfo = result.ErrorInfo,
                                       ErrorCode = result.ErrorCode
                                   }
                        }
                        ;
                        return(new NormalResult
                        {
                            Value = result.Value,
                            ErrorInfo = result.ErrorInfo,
                            ErrorCode = result.ErrorCode
                        });
                    }
                    finally
                    {
                        ReturnChannel(channel);
                    }
                }
            }
            catch (Exception ex)
            {
                WpfClientInfo.WriteErrorLog($"DetectSipNetworkAsync() 出现异常: {ExceptionUtil.GetDebugText(ex)}");

                return(new GetEntityDataResult
                {
                    Value = -1,
                    ErrorInfo = $"DetectSipNetworkAsync() 出现异常: {ex.Message}",
                    ErrorCode = ex.GetType().ToString()
                });
            }
        }
Exemplo n.º 26
0
        // return.Value:
        //      -1  出错
        //      0   读者记录没有找到
        //      1   成功
        public static async Task <GetReaderInfoResult> GetReaderInfoAsync(string pii)
        {
            try
            {
                using (var releaser = await _channelLimit.EnterAsync())
                {
                    SipChannel channel = await GetChannelAsync();

                    try
                    {
                        List <NormalResult> errors = new List <NormalResult>();

                        int nRedoCount = 0;
REDO_GETITEMINFO:
                        var get_result = await _channel.GetPatronInfoAsync(pii);

                        if (get_result.Value == -1)
                        {
                            return new GetReaderInfoResult
                                   {
                                       Value     = -1,
                                       ErrorInfo = get_result.ErrorInfo,
                                       ErrorCode = get_result.ErrorCode
                                   }
                        }
                        ;

                        /*
                         * else if (get_result.Result.CirculationStatus_2 == "01")
                         * {
                         *  errors.Add(new NormalResult
                         *  {
                         *      Value = -1,
                         *      ErrorInfo = get_result.Result.AF_ScreenMessage_o,
                         *      ErrorCode = get_result.Result.CirculationStatus_2
                         *  });
                         * }
                         * else if (get_result.Result.CirculationStatus_2 == "13")
                         * {
                         *  errors.Add(new NormalResult
                         *  {
                         *      Value = -1,
                         *      ErrorInfo = get_result.Result.AF_ScreenMessage_o,
                         *      ErrorCode = "itemNotFound"
                         *  });
                         * }
                         */
                        else
                        {
                            XmlDocument readerdom = new XmlDocument();

                            readerdom.LoadXml("<root />");

                            // 证状态
                            string state = "***";
                            if (get_result.Result.BL_ValidPatron_o == "Y")
                            {
                                state = "";
                            }
                            DomUtil.SetElementText(readerdom.DocumentElement,
                                                   "state",
                                                   state);

                            // 读者证条码号
                            DomUtil.SetElementText(readerdom.DocumentElement,
                                                   "barcode",
                                                   get_result.Result.AA_PatronIdentifier_r);

                            // 姓名
                            DomUtil.SetElementText(readerdom.DocumentElement,
                                                   "name",
                                                   get_result.Result.AE_PersonalName_r);

                            // 可借册数
                            Patron.SetParamValue(readerdom.DocumentElement, "当前还可借", get_result.Result.BZ_HoldItemsLimit_o);
                            Patron.SetParamValue(readerdom.DocumentElement, "可借总册数", get_result.Result.CB_ChargedItemsLimit_o);

                            // 在借册
                            var root  = readerdom.DocumentElement.AppendChild(readerdom.CreateElement("borrows")) as XmlElement;
                            var items = get_result.Result.AU_ChargedItems_o;
                            if (items != null)
                            {
                                foreach (var item in items)
                                {
                                    if (item.Value == null)
                                    {
                                        continue;
                                    }
                                    var borrow = root.AppendChild(readerdom.CreateElement("borrow")) as XmlElement;
                                    borrow.SetAttribute("barcode", item.Value);
                                }
                            }

                            return(new GetReaderInfoResult
                            {
                                Value = 1,
                                ReaderXml = readerdom.OuterXml,
                                RecPath = "",
                                Timestamp = null
                            });
                        }
                    }
                    finally
                    {
                        ReturnChannel(channel);
                    }
                }
            }
            catch (Exception ex)
            {
                WpfClientInfo.WriteErrorLog($"GetEntGetReaderInfoAsyncityDataAsync() 出现异常: {ExceptionUtil.GetDebugText(ex)}");

                return(new GetReaderInfoResult
                {
                    Value = -1,
                    ErrorInfo = $"GetReaderInfoAsync() 出现异常: {ex.Message}",
                    ErrorCode = ex.GetType().ToString()
                });
            }
        }
Exemplo n.º 27
0
        // 从本地数据库获得册记录信息和书目摘要信息
        // .Value
        //      0   没有找到
        //      1   找到一种
        //      2   两种都找到了
        public static GetEntityDataResult LocalGetEntityData(string pii)
        {
            try
            {
                using (BiblioCacheContext context = new BiblioCacheContext())
                {
                    if (_cacheDbCreated == false)
                    {
                        context.Database.EnsureCreated();
                        _cacheDbCreated = true;
                    }

                    GetEntityDataResult result = null;

                    // ***
                    // 第一步:获取册记录

                    // 从本地实体库中获得记录
                    var entity_record = context.Entities.Where(o => o.PII == pii).FirstOrDefault();
                    // EntityItem entity_record = null;   // testing

                    if (entity_record != null)
                    {
                        result = new GetEntityDataResult
                        {
                            Value       = 1,
                            ItemXml     = entity_record.Xml,
                            ItemRecPath = entity_record.RecPath,
                            Title       = "",
                        }
                    }
                    ;

                    // ***
                    /// 第二步:获取书目摘要

                    // 从本地书目库中获取书目摘要

                    var item = context.BiblioSummaries.Where(o => o.PII == pii).FirstOrDefault();
                    if (item != null &&
                        string.IsNullOrEmpty(item.BiblioSummary) == false)
                    {
                        if (result == null)
                        {
                            result = new GetEntityDataResult();
                        }

                        result.Title = item.BiblioSummary;
                        result.Value++;
                    }

                    if (result == null)
                    {
                        return new GetEntityDataResult {
                                   Value = 0
                        }
                    }
                    ;

                    return(result);
                }
            }
            catch (Exception ex)
            {
                WpfClientInfo.WriteErrorLog($"LocalGetEntityDataAsync() 出现异常: {ExceptionUtil.GetDebugText(ex)}");

                return(new GetEntityDataResult
                {
                    Value = -1,
                    ErrorInfo = $"LocalGetEntityDataAsync() 出现异常: {ex.Message}",
                    ErrorCode = ex.GetType().ToString()
                });
            }
        }
Exemplo n.º 28
0
        // 获得册记录信息和书目摘要信息
        // parameters:
        //      style   风格。network 表示只从网络获取册记录;否则优先从本地获取,本地没有再从网络获取册记录。无论如何,书目摘要都是尽量从本地获取
        // .Value
        //      0   没有找到
        //      1   找到
        public static async Task <GetEntityDataResult> GetEntityDataAsync(string pii,
                                                                          string style)
        {
            bool network = StringUtil.IsInList("network", style);

            try
            {
                using (var releaser = await _channelLimit.EnterAsync())
                    using (BiblioCacheContext context = new BiblioCacheContext())
                    {
                        if (_cacheDbCreated == false)
                        {
                            context.Database.EnsureCreated();
                            _cacheDbCreated = true;
                        }

                        LibraryChannel channel     = App.CurrentApp.GetChannel();
                        TimeSpan       old_timeout = channel.Timeout;
                        channel.Timeout = TimeSpan.FromSeconds(10);
                        try
                        {
                            GetEntityDataResult result = null;
                            List <NormalResult> errors = new List <NormalResult>();

                            EntityItem entity_record = null;

                            // ***
                            // 第一步:获取册记录

                            if (network == false)
                            {
                                // 先尝试从本地实体库中获得记录
                                entity_record = context.Entities.Where(o => o.PII == pii).FirstOrDefault();
                                // EntityItem entity_record = null;   // testing
                            }

                            if (entity_record != null)
                            {
                                result = new GetEntityDataResult
                                {
                                    Value       = 1,
                                    ItemXml     = entity_record.Xml,
                                    ItemRecPath = entity_record.RecPath,
                                    Title       = "",
                                }
                            }
                            ;
                            else
                            {
                                // 再尝试从 dp2library 服务器获取
                                // TODO: ItemXml 和 BiblioSummary 可以考虑在本地缓存一段时间
                                int nRedoCount = 0;
REDO_GETITEMINFO:
                                long lRet = channel.GetItemInfo(null,
                                                                "item",
                                                                pii,
                                                                "",
                                                                "xml",
                                                                out string item_xml,
                                                                out string item_recpath,
                                                                out byte[] timestamp,
                                                                "",
                                                                out _,
                                                                out _,
                                                                out string strError);
                                if (lRet == -1)
                                {
                                    if ((channel.ErrorCode == ErrorCode.RequestError ||
                                         channel.ErrorCode == ErrorCode.RequestTimeOut) &&
                                        nRedoCount < 2)
                                    {
                                        nRedoCount++;
                                        goto REDO_GETITEMINFO;
                                    }
                                    // TODO: 这里不着急返回,还需要尝试获得书目摘要
                                    errors.Add(new NormalResult
                                    {
                                        Value     = -1,
                                        ErrorInfo = strError,
                                        ErrorCode = channel.ErrorCode.ToString()
                                    });

                                    /*
                                     * return new GetEntityDataResult
                                     * {
                                     *  Value = -1,
                                     *  ErrorInfo = strError,
                                     *  ErrorCode = channel.ErrorCode.ToString()
                                     * };
                                     */
                                }
                                else
                                {
                                    result = new GetEntityDataResult
                                    {
                                        Value       = 1,
                                        ItemXml     = item_xml,
                                        ItemRecPath = item_recpath,
                                        Title       = "",
                                    };

                                    // 保存到本地数据库
                                    await AddOrUpdateAsync(context, new EntityItem
                                    {
                                        PII       = pii,
                                        Xml       = item_xml,
                                        RecPath   = item_recpath,
                                        Timestamp = timestamp,
                                    });

#if NO
                                    context.Entities.Add(new EntityItem
                                    {
                                        PII       = pii,
                                        Xml       = item_xml,
                                        RecPath   = item_recpath,
                                        Timestamp = timestamp,
                                    });
                                    try
                                    {
                                        await context.SaveChangesAsync();
                                    }
                                    catch (Exception ex)
                                    {
                                        SqliteException sqlite_exception = ex.InnerException as SqliteException;
                                        if (sqlite_exception != null && sqlite_exception.SqliteErrorCode == 19)
                                        {
                                            // PII 发生重复了
                                        }
                                        else
                                        {
                                            throw ex;
                                        }
                                    }
#endif
                                }
                            }

                            // ***
                            /// 第二步:获取书目摘要

                            // 先尝试从本地书目库中获取书目摘要

                            var item = context.BiblioSummaries.Where(o => o.PII == pii).FirstOrDefault();
                            if (item != null &&
                                string.IsNullOrEmpty(item.BiblioSummary) == false)
                            {
                                if (result == null)
                                {
                                    result = new GetEntityDataResult();
                                }

                                result.Title = item.BiblioSummary;
                            }
                            else
                            {
                                // 从 dp2library 服务器获取书目摘要
                                int nRedoCount = 0;
REDO_GETBIBLIOSUMMARY:
                                long lRet = channel.GetBiblioSummary(
                                    null,
                                    pii,
                                    "", // strConfirmItemRecPath,
                                    null,
                                    out _,
                                    out string strSummary,
                                    out string strError);
                                if (lRet == -1)
                                {
                                    if ((channel.ErrorCode == ErrorCode.RequestError ||
                                         channel.ErrorCode == ErrorCode.RequestTimeOut) &&
                                        nRedoCount < 2)
                                    {
                                        nRedoCount++;
                                        goto REDO_GETBIBLIOSUMMARY;
                                    }

                                    errors.Add(new NormalResult
                                    {
                                        Value     = -1,
                                        ErrorInfo = strError,
                                        ErrorCode = channel.ErrorCode.ToString()
                                    });

                                    /*
                                     * return new GetEntityDataResult
                                     * {
                                     *  Value = -1,
                                     *  ErrorInfo = strError,
                                     *  ErrorCode = channel.ErrorCode.ToString(),
                                     * };
                                     */
                                }
                                else
                                {
                                    strSummary = strSummary?.Replace(". -- ", "\r\n"); // .Replace("/", "\r\n");

                                    if (result == null)
                                    {
                                        result = new GetEntityDataResult();
                                    }

                                    result.Title = strSummary;

                                    // 存入数据库备用
                                    if (lRet == 1 && string.IsNullOrEmpty(strSummary) == false)
                                    {
                                        try
                                        {
                                            var exist_item = context.BiblioSummaries.Where(o => o.PII == pii).FirstOrDefault();

                                            if (exist_item != null)
                                            {
                                                if (exist_item.BiblioSummary != strSummary)
                                                {
                                                    exist_item.BiblioSummary = strSummary;
                                                    context.BiblioSummaries.Update(exist_item);
                                                }
                                            }
                                            else
                                            {
                                                context.BiblioSummaries.Add(new BiblioSummaryItem
                                                {
                                                    PII           = pii,
                                                    BiblioSummary = strSummary
                                                });
                                            }
                                            await context.SaveChangesAsync();
                                        }
                                        catch (Exception ex)
                                        {
                                            WpfClientInfo.WriteErrorLog($"GetEntityDataAsync() 中保存 summary 时(PII 为 '{pii}')出现异常:{ExceptionUtil.GetDebugText(ex)}");
                                        }
                                    }
                                }

                                /*
                                 * return new GetEntityDataResult
                                 * {
                                 *  Value = (int)lRet,
                                 *  ItemXml = item_xml,
                                 *  ItemRecPath = item_recpath,
                                 *  Title = strSummary,
                                 *  ErrorInfo = strError,
                                 *  ErrorCode = channel.ErrorCode.ToString()
                                 * };
                                 */
                            }

                            // 完全成功
                            if (result != null && errors.Count == 0)
                            {
                                return(result);
                            }
                            if (result == null)
                            {
                                return new GetEntityDataResult
                                       {
                                           Value     = errors[0].Value,
                                           ErrorInfo = errors[0].ErrorInfo,
                                           ErrorCode = errors[0].ErrorCode
                                       }
                            }
                            ;
                            result.ErrorInfo = errors[0].ErrorInfo;
                            result.ErrorCode = errors[0].ErrorCode;
                            return(result);
                        }
                        finally
                        {
                            channel.Timeout = old_timeout;
                            App.CurrentApp.ReturnChannel(channel);
                        }
                    }
            }
            catch (Exception ex)
            {
                WpfClientInfo.WriteErrorLog($"GetEntityDataAsync() 出现异常: {ExceptionUtil.GetDebugText(ex)}");

                return(new GetEntityDataResult
                {
                    Value = -1,
                    ErrorInfo = $"GetEntityDataAsync() 出现异常: {ex.Message}",
                    ErrorCode = ex.GetType().ToString()
                });
            }
        }
Exemplo n.º 29
0
        public void LoadPhoto(string photo_path)
        {
            if (string.IsNullOrEmpty(photo_path))
            {
                App.Invoke(new Action(() =>
                {
                    this.SetPhoto(null);
                }));
                return;
            }

            // TODO: 照片可以缓存到本地。每次只需要获取 timestamp 即可。如果 timestamp 和缓存的不一致再重新获取一次

            Stream stream = null;

            try
            {
                // 先尝试从缓存获取
                string cacheDir = Path.Combine(WpfClientInfo.UserDir, "photo");
                PathUtil.CreateDirIfNeed(cacheDir);
                string fileName = Path.Combine(cacheDir, GetPath(photo_path));
                if (File.Exists(fileName))
                {
                    try
                    {
                        stream = File.OpenRead(fileName);
                    }
                    catch (Exception ex)
                    {
                        WpfClientInfo.WriteErrorLog($"从读者照片本地缓存文件 {fileName} 读取内容时出现异常:{ExceptionUtil.GetDebugText(ex)}");
                        stream = null;
                    }
                }

                if (stream == null)
                {
                    stream = new MemoryStream();
                    var      channel     = App.CurrentApp.GetChannel();
                    TimeSpan old_timeout = channel.Timeout;
                    channel.Timeout = TimeSpan.FromSeconds(30);
                    try
                    {
                        long lRet = channel.GetRes(
                            null,
                            photo_path,
                            stream,
                            "data,content", // strGetStyle,
                            null,           // byte [] input_timestamp,
                            out string strMetaData,
                            out byte[] baOutputTimeStamp,
                            out string strOutputPath,
                            out string strError);
                        if (lRet == -1)
                        {
                            // SetGlobalError("patron", $"获取读者照片时出错: {strError}");
                            // return;
                            throw new Exception($"获取读者照片(path='{photo_path}')时出错: {strError}");
                        }

                        // 顺便存储到本地
                        {
                            bool suceed = false;
                            stream.Seek(0, SeekOrigin.Begin);
                            try
                            {
                                using (var file = File.OpenWrite(fileName))
                                {
                                    StreamUtil.DumpStream(stream, file);
                                }

                                suceed = true;
                            }
                            catch (Exception ex)
                            {
                                WpfClientInfo.WriteErrorLog($"读者照片写入本地缓存文件 {fileName} 时出现异常:{ExceptionUtil.GetDebugText(ex)}");
                            }
                            finally
                            {
                                if (suceed == false)
                                {
                                    File.Delete(fileName);
                                }
                            }
                        }

                        stream.Seek(0, SeekOrigin.Begin);
                    }
                    finally
                    {
                        channel.Timeout = old_timeout;
                        App.CurrentApp.ReturnChannel(channel);
                    }
                }

                App.Invoke(new Action(() =>
                {
                    this.SetPhoto(stream);
                }));
                stream = null;
            }
            finally
            {
                if (stream != null)
                {
                    stream.Dispose();
                }
            }
        }
Exemplo n.º 30
0
        // 获得册记录信息和书目摘要信息
        // parameters:
        //      style   风格。network 表示只从网络获取册记录;否则优先从本地获取,本地没有再从网络获取册记录。无论如何,书目摘要都是尽量从本地获取
        // .Value
        //      0   没有找到
        //      1   找到
        public static async Task <GetEntityDataResult> GetEntityDataAsync(string pii,
                                                                          string style)
        {
            bool network = StringUtil.IsInList("network", style);

            try
            {
                using (var releaser = await _channelLimit.EnterAsync())
                {
                    SipChannel channel = await GetChannelAsync();

                    try
                    {
                        GetEntityDataResult result = null;
                        List <NormalResult> errors = new List <NormalResult>();

                        EntityItem entity_record = null;

                        // ***
                        // 第一步:获取册记录

                        {
                            // 再尝试从 dp2library 服务器获取
                            // TODO: ItemXml 和 BiblioSummary 可以考虑在本地缓存一段时间
                            int nRedoCount = 0;
REDO_GETITEMINFO:
                            var get_result = await _channel.GetItemInfoAsync("", pii);

                            if (get_result.Value == -1)
                            {
                                errors.Add(new NormalResult
                                {
                                    Value     = -1,
                                    ErrorInfo = get_result.ErrorInfo,
                                    ErrorCode = get_result.ErrorCode
                                });
                            }
                            else if (get_result.Result.CirculationStatus_2 == "01")
                            {
                                errors.Add(new NormalResult
                                {
                                    Value     = -1,
                                    ErrorInfo = get_result.Result.AF_ScreenMessage_o,
                                    ErrorCode = get_result.Result.CirculationStatus_2
                                });
                            }
                            else if (get_result.Result.CirculationStatus_2 == "13")
                            {
                                errors.Add(new NormalResult
                                {
                                    Value     = -1,
                                    ErrorInfo = get_result.Result.AF_ScreenMessage_o,
                                    ErrorCode = "itemNotFound"
                                });
                            }
                            else
                            {
                                XmlDocument itemdom = new XmlDocument();
                                itemdom.LoadXml("<root />");

                                string state = "";
                                if (get_result.Result.CirculationStatus_2 == "12")
                                {
                                    state = "丢失";
                                }

                                DomUtil.SetElementText(itemdom.DocumentElement, "state", state);

                                DomUtil.SetElementText(itemdom.DocumentElement,
                                                       "barcode",
                                                       get_result.Result.AB_ItemIdentifier_r);
                                DomUtil.SetElementText(itemdom.DocumentElement,
                                                       "location",
                                                       get_result.Result.AQ_PermanentLocation_o);
                                DomUtil.SetElementText(itemdom.DocumentElement,
                                                       "currentLocation",
                                                       get_result.Result.AP_CurrentLocation_o);

                                DomUtil.SetElementText(itemdom.DocumentElement,
                                                       "accessNo",
                                                       get_result.Result.CH_ItemProperties_o);

                                // 借书时间
                                {
                                    string borrowDateString = get_result.Result.CM_HoldPickupDate_18;
                                    if (string.IsNullOrEmpty(borrowDateString) == false)
                                    {
                                        if (DateTime.TryParseExact(borrowDateString,
                                                                   "yyyyMMdd    HHmmss",
                                                                   CultureInfo.InvariantCulture,
                                                                   DateTimeStyles.None,
                                                                   out DateTime borrowDate))
                                        {
                                            DomUtil.SetElementText(itemdom.DocumentElement,
                                                                   "borrowDate",
                                                                   DateTimeUtil.Rfc1123DateTimeStringEx(borrowDate));

                                            DomUtil.SetElementText(itemdom.DocumentElement,
                                                                   "borrower",
                                                                   "***");
                                        }
                                        else
                                        {
                                            // 报错,时间字符串格式错误,无法解析
                                        }
                                    }
                                }

                                // 应还书时间
                                {
                                    string returnningDateString = get_result.Result.AH_DueDate_o;
                                    if (string.IsNullOrEmpty(returnningDateString) == false)
                                    {
                                        if (DateTime.TryParseExact(returnningDateString,
                                                                   DateFormat,
                                                                   CultureInfo.InvariantCulture,
                                                                   DateTimeStyles.None,
                                                                   out DateTime returningDate))
                                        {
                                            DomUtil.SetElementText(itemdom.DocumentElement,
                                                                   "returningDate",
                                                                   DateTimeUtil.Rfc1123DateTimeStringEx(returningDate));
                                        }
                                        else
                                        {
                                            // 报错,时间字符串格式错误,无法解析
                                        }
                                    }
                                }

                                result = new GetEntityDataResult
                                {
                                    Value       = 1,
                                    ItemXml     = itemdom.OuterXml,
                                    ItemRecPath = get_result.Result.AB_ItemIdentifier_r,
                                    Title       = get_result.Result.AJ_TitleIdentifier_r,
                                };

                                /*
                                 * // 保存到本地数据库
                                 * await AddOrUpdateAsync(context, new EntityItem
                                 * {
                                 *  PII = pii,
                                 *  Xml = item_xml,
                                 *  RecPath = item_recpath,
                                 *  Timestamp = timestamp,
                                 * });
                                 */
                            }
                        }

                        // ***
                        /// 第二步:获取书目摘要

                        // 完全成功
                        if (result != null && errors.Count == 0)
                        {
                            return(result);
                        }
                        if (result == null)
                        {
                            return new GetEntityDataResult
                                   {
                                       Value     = errors[0].Value,
                                       ErrorInfo = errors[0].ErrorInfo,
                                       ErrorCode = errors[0].ErrorCode
                                   }
                        }
                        ;
                        result.ErrorInfo = errors[0].ErrorInfo;
                        result.ErrorCode = errors[0].ErrorCode;
                        return(result);
                    }
                    finally
                    {
                        ReturnChannel(channel);
                    }
                }
            }
            catch (Exception ex)
            {
                WpfClientInfo.WriteErrorLog($"GetEntityDataAsync() 出现异常: {ExceptionUtil.GetDebugText(ex)}");

                return(new GetEntityDataResult
                {
                    Value = -1,
                    ErrorInfo = $"GetEntityDataAsync() 出现异常: {ex.Message}",
                    ErrorCode = ex.GetType().ToString()
                });
            }
        }