示例#1
0
 public void PushContent(MessageDocument doc)
 {
     _contents.Add(new DisplayContent
     {
         Document = doc
     });
     // 变化按钮文字
     RefreshButtonText();
 }
示例#2
0
        private void Message_MouseDown(object sender, MouseButtonEventArgs e)
        {
            if (e.ChangedButton == MouseButton.Right)
            {
                Clipboard.SetDataObject(this.message.Text, true);
            }
            if (e.ChangedButton == MouseButton.Left)
            {
                // 测试功能
                MessageDocument doc = new MessageDocument();
                DateTime        now = DateTime.Now;
                doc.Add(new Operator {
                    PatronName = "姓名"
                }, now, "borrow", "succeed", "", "", new Entity {
                    Title = "书名1"
                });
                doc.Add(new Operator {
                    PatronName = "姓名"
                }, now, "borrow", "succeed", "", "", new Entity {
                    Title = "书名2"
                });
                doc.Add(new Operator {
                    PatronName = "姓名"
                }, now, "return", "warning", "这是警告信息", "", new Entity {
                    Title = "书名3"
                });
                doc.Add(new Operator {
                    PatronName = "姓名"
                }, now, "return", "error", "还书出错", "errorCode", new Entity {
                    Title = "书名4"
                });

                ProgressWindow progress = null;

                App.Invoke(new Action(() =>
                {
                    progress = new ProgressWindow();
                    // progress.MessageText = "正在处理,请稍候 ...";
                    progress.MessageDocument = doc.BuildDocument(
                        MessageDocument.BaseFontSize,
                        "",
                        out string speak);
                    progress.Owner = Application.Current.MainWindow;
                    progress.WindowStartupLocation = WindowStartupLocation.CenterOwner;
                    //progress.Closed += Progress_Closed;
                    App.SetSize(progress, "wide");

                    //progress.Width = Math.Min(700, this.ActualWidth);
                    //progress.Height = Math.Min(500, this.ActualHeight);
                    progress.Show();
                    //AddLayer();
                }));
            }
        }
示例#3
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);
        }
示例#4
0
        public Paragraph BuildParagraph(int index,
                                        double baseFontSize,
                                        string style)
        {
            bool display_transfer = StringUtil.IsInList("transfer", style);

            if (Operation == "transfer" && display_transfer == false)
            {
                return(null);
            }

            var p = new Paragraph();

            p.FontFamily = new FontFamily("微软雅黑");
            p.FontSize   = baseFontSize;
            // p.FontStyle = FontStyles.Italic;
            p.TextAlignment = TextAlignment.Left;
            p.Foreground    = Brushes.Gray;
            // p.LineHeight = 18;
            p.TextIndent = -20;
            p.Margin     = new Thickness(10, 0, 0, 8); // 10,0,0,8
            p.Tag        = this;                       // 记忆下来后面隐藏事项的时候可以用到

            // 序号
            p.Inlines.Add(new Run($"{(index + 1).ToString()}) "));

            Brush back = Brushes.Transparent;

            // 成功和失败状态
            if (ResultType == "error")
            {
                back = Brushes.DarkRed;
                p.Inlines.Add(new Run
                {
                    Text       = " 失败 ",
                    Background = back,
                    Foreground = Brushes.White
                });
            }
            else if (ResultType == "warning")
            {
                back = Brushes.DarkGoldenrod;
                p.Inlines.Add(new Run
                {
                    Text       = " 警告 ",
                    Background = back,
                    Foreground = Brushes.White
                });
            }
            else if (ResultType == "information")
            {
                back = Brushes.Gray;
                p.Inlines.Add(new Run
                {
                    Text       = " 信息 ",
                    Background = back,
                    Foreground = Brushes.White
                });
            }
            else
            {
                back = Brushes.DarkGreen;
                p.Inlines.Add(new Run
                {
                    Text       = " 成功 ",
                    Background = back,
                    Foreground = Brushes.White
                });
            }

            // 操作名称
            p.Inlines.Add(new Run
            {
                Text       = GetOperationCaption(Operation) + " ",
                Foreground = Brushes.White
            });

            // 转移方向
            if (Operation == "transfer" && string.IsNullOrEmpty(Direction) == false)
            {
                p.Inlines.Add(new Run
                {
                    Text       = GetOperationCaption(Direction) + " ",
                    Foreground = Brushes.White
                });
            }

            // 书目摘要
            if (Entity != null && string.IsNullOrEmpty(Entity.Title) == false)
            {
                Run run = new Run(MessageDocument.ShortTitle(Entity.Title));

                /*
                 * run.FontSize = 14;
                 * run.FontStyle = FontStyles.Normal;
                 * run.Background = Brushes.DarkRed;
                 * run.Foreground = Brushes.White;
                 */

                p.Inlines.Add(run);
            }

            // 错误码和错误信息
            if (string.IsNullOrEmpty(ErrorInfo) == false)
            {
                p.Inlines.Add(new Run
                {
                    Text       = "\r\n" + ErrorInfo,
                    Background = back,
                    Foreground = Brushes.White
                });
            }

            return(p);
        }
示例#5
0
        public static Paragraph BuildParagraph(
            ActionInfo action,
            int index,
            double baseFontSize,
            string style)
        {
            // 是否显示 transfer (in) 条目。注意,即便 false, 也要显示 transfer (out) 条目的
            bool display_transfer = StringUtil.IsInList("transfer", style);

            if (action.Action.StartsWith("transfer") && action.TransferDirection == "in" &&
                display_transfer == false)
            {
                return(null);
            }

            var p = new Paragraph();

            p.FontFamily = new FontFamily("微软雅黑");
            p.FontSize   = baseFontSize;
            // p.FontStyle = FontStyles.Italic;
            p.TextAlignment = TextAlignment.Left;
            p.Foreground    = Brushes.Gray;
            // p.LineHeight = 18;
            p.TextIndent = -20;
            p.Margin     = new Thickness(10, 0, 0, 8); // 10,0,0,8
            p.Tag        = new ParagraphInfo {
                Action = action, Index = index
            };                                                              // 记忆下来后面刷新事项的时候可以用到

            // 序号
            p.Inlines.Add(new Run($"{(index + 1).ToString()}) "));

            Brush back = Brushes.Transparent;

            // 状态
            {
                // 等待动画
                if (string.IsNullOrEmpty(action.State))
                {
                    var image = new FontAwesome.WPF.ImageAwesome();
                    image.Icon         = FontAwesome.WPF.FontAwesomeIcon.Spinner;
                    image.Spin         = true;
                    image.SpinDuration = 5;
                    image.Height       = baseFontSize * 2.0;
                    image.Foreground   = Brushes.DarkGray;
                    var container = new InlineUIContainer(image);
                    container.Name = "image_id";
                    p.Inlines.Add(container);
                }
                else if (action.SyncErrorCode == "overflow")
                {
                    back = Brushes.DarkRed;
                    p.Inlines.Add(new Run
                    {
                        Text       = " 超额 ",
                        Background = back,
                        Foreground = Brushes.White
                    });
                }
                else if (action.State == "sync")
                {
                    back = Brushes.DarkGreen;
                    p.Inlines.Add(new Run
                    {
                        Text       = " 成功 ",
                        Background = back,
                        Foreground = Brushes.White
                    });
                }
                else if (action.SyncErrorCode == "skipped")
                {
                    back = Brushes.DeepSkyBlue;
                    p.Inlines.Add(new Run
                    {
                        Text       = $" 暂时跳过同步 ",
                        Background = back,
                        Foreground = Brushes.White
                    });
                }
                else if (action.State == "commerror" || action.State == "normalerror")
                {
                    if (ShelfData.LibraryNetworkCondition == "Bad")
                    {
                        back = Brushes.DeepSkyBlue;
                    }
                    else
                    {
                        back = Brushes.DarkRed;
                    }
                    p.Inlines.Add(new Run
                    {
                        Text       = $" 同步失败({action.State}) ",
                        Background = back,
                        Foreground = Brushes.White
                    });
                }
                else if (action.State == "dontsync")
                {
                    back = Brushes.DarkBlue;
                    p.Inlines.Add(new Run
                    {
                        Text       = $" 不再同步 ",
                        Background = back,
                        Foreground = Brushes.White
                    });
                }
                else
                {
                    back = Brushes.DarkRed;
                    p.Inlines.Add(new Run
                    {
                        Text       = $" {action.State} ",
                        Background = back,
                        Foreground = Brushes.White
                    });
                }
            }

            // 转移方向
            if (action.Action.StartsWith("transfer")
                /*&& string.IsNullOrEmpty(action.TransferDirection) == false*/)
            {
                p.Inlines.Add(new Run
                {
                    Text       = GetTransferDirCaption(action.TransferDirection, action.Location) + " ",
                    Foreground = Brushes.White
                });
            }
            else
            {
                // 操作名称
                p.Inlines.Add(new Run
                {
                    Text       = GetOperationCaption(action.Action) + " ",
                    Foreground = Brushes.White
                });
            }

            string title = "";

            if (action.Entity != null)
            {
                title = MessageDocument.ShortTitle(action.Entity.Title);
                // 2020/5/6
                // 尝试从本地缓存中获取书目摘要
                if (string.IsNullOrEmpty(title))
                {
                    title = LibraryChannelUtil.GetBiblioSummaryFromLocal(action.Entity.GetOiPii(true));
                }
                if (string.IsNullOrEmpty(title))
                {
                    title = ShelfData.GetPiiString(action.Entity);
                }
                else
                {
                    // 2020/7/22
                    title = $"[{ShelfData.GetPiiString(action.Entity)}] {title}";
                }
            }
            else
            {
                title = "(action.Entity 为空)";
            }

            // 书目摘要
            if (string.IsNullOrEmpty(title) == false)
            {
                Run run = new Run(title);

                /*
                 * run.FontSize = 14;
                 * run.FontStyle = FontStyles.Normal;
                 * run.Background = Brushes.DarkRed;
                 * run.Foreground = Brushes.White;
                 */

                p.Inlines.Add(run);
            }

            // 对于上架/下架来说,还要补充显示一些细节信息:location 去向;和 currentLocation 去向
            if (action.Action.StartsWith("transfer"))
            {
                List <string> details = new List <string>();
                if (string.IsNullOrEmpty(action.Location) == false)
                {
                    details.Add($"调拨到:{action.Location}");
                }
                if (string.IsNullOrEmpty(action.CurrentShelfNo) == false)
                {
                    details.Add($"新架位:{action.CurrentShelfNo}");
                }
                p.Inlines.Add(new Run
                {
                    Text       = " " + StringUtil.MakePathList(details, " ") + " ",
                    Foreground = Brushes.Green
                });
            }

            // 错误码和错误信息
            if (string.IsNullOrEmpty(action.SyncErrorInfo) == false &&
                (action.State != "sync" || action.SyncErrorCode == "overflow"))
            {
                p.Inlines.Add(new Run
                {
                    Text       = "\r\n" + action.SyncErrorInfo,
                    Background = back,
                    Foreground = Brushes.White
                });
            }

            return(p);
        }