public ServiceWizardViewModel(PanaceaServices core, TaskCompletionSource <bool> source) { _core = core; _source = source; SelectedItems = new ObservableCollection <Service>(); RemoveServiceCommand = new RelayCommand(args => { SelectedItems.Remove(args as Service); if (!SelectedItems.Any()) { CartBoxIsOpen = false; } }); SwitchToServicesCommand = new RelayCommand(args => { if (SelectedIndex == 0) { SelectedIndex = 1; } else { SelectedIndex = 0; } }); BuyServiceCommand = new RelayCommand(arg => { SelectedItems.Clear(); TabsSelectedIndex = 0; }); CompleteCommand = new RelayCommand(arg => { source.TrySetResult(true); }); ToggleCartBoxCommand = new RelayCommand(arg => { CartBoxIsOpen = !CartBoxIsOpen; }); CheckoutCommand = new RelayCommand(async args => { if (Packages != null && Packages.Any(p => p.IsChecked) || Services != null && Services.Any(s => s.IsChecked)) { CartBoxIsOpen = false; if (core.UserService.User.Id == null) { if (core.TryGetUserAccountManager(out IUserAccountManager account)) { _waitingForAnotherTask = true; if (await account.RequestLoginAsync("In order to continue, you need to sign in with your user account")) { _waitingForAnotherTask = false; TabsSelectedIndex = 1; CreateWebBrowser(); BuyService(); } } //todo TabsSelectedIndex = 1; } else { var pop = new UserConfirmationViewModel(_core.UserService.User); if (_core.TryGetUiManager(out IUiManager ui)) { var res = await ui.ShowPopup(pop); if (res == UserConfirmationResult.Confirm) { TabsSelectedIndex = 1; CreateWebBrowser(); BuyService(); //CheckUserService(() => //{ // }); } else if (res == UserConfirmationResult.NotMe) { if (!(_core.TryGetUserAccountManager(out IUserAccountManager user) && await user.LogoutAsync())) { await _core.UserService.LogoutAsync(); //todo (true) } CheckoutCommand.Execute(null); } else { CartBoxIsOpen = true; } } } } else { if (core.TryGetUiManager(out IUiManager ui)) { await ui.ShowPopup(new NoServiceSelectedPopupViewModel()); } } }); SelectCommand = new RelayCommand(args => { var package = args as Service; if (package == null) { return; } CancelButtonVisibility = Visibility.Collapsed; CancelButtonServicesVisibility = Visibility.Visible; if (package is Package) { CancelButtonVisibility = Visibility.Visible; CancelButtonServicesVisibility = Visibility.Collapsed; SelectedItems.Clear(); Packages.ForEach(lp => lp.IsChecked = false); Services.ForEach(lp => lp.IsChecked = false); package.IsChecked = true; } else if (SelectedItems.Any(i => i is Package)) { SelectedItems.Clear(); Packages.ForEach(lp => lp.IsChecked = false); Services.ForEach(lp => lp.IsChecked = false); package.IsChecked = true; } if (SelectedItems.Contains(package)) { SelectedItems.Remove(package); package.IsChecked = false; CartBoxIsOpen = SelectedItems.Count > 0; HasSelectedPerDay = SelectedItems.All(i => i.IsPricePerDay); UpdateSum(); TotalPanelVisibility = SelectedItems.Any(i => i.IsPricePerDay) || SelectedItems.Count > 1 ? Visibility.Visible : Visibility.Collapsed; return; } if ((package.IsPricePerDay && SelectedItems.Any(s => !s.IsPricePerDay)) || (!package.IsPricePerDay && SelectedItems.Any(s => s.IsPricePerDay))) { /*todo * var warning = new ChangeServiceTypeWarning(); * warning.Continue += (oo, ee) => * { * window.ThemeManager.HidePopup(warning); * SelectedItems.Clear(); * packages.ForEach(lp => lp.IsChecked = false); * services.ForEach(lp => lp.IsChecked = false); * package.IsChecked = true; * SelectedItems.Add(package); * CartBox.IsOpen = SelectedItems.Count > 0; * HasSelectedPerDay = SelectedItems.All(i => i.IsPricePerDay); * UpdateSum(); * TotalPanel.Visibility = SelectedItems.Any(i => i.IsPricePerDay) || SelectedItems.Count > 1 * ? Visibility.Visible * : Visibility.Collapsed; * }; * * warning.Cancel += (oo, ee) => * { * window.ThemeManager.HidePopup(warning); * package.IsChecked = false; * CartBox.IsOpen = SelectedItems.Count > 0; * }; * CartBoxIsOpen = false; * * window.ThemeManager.ShowPopup(warning).Closed += (oo, ee) => * { * package.IsChecked = false; * }; */ } else { SelectedItems.Add(package); CartBoxIsOpen = SelectedItems.Count > 0; HasSelectedPerDay = SelectedItems.All(i => i.IsPricePerDay); UpdateSum(); TotalPanelVisibility = SelectedItems.Any(i => i.IsPricePerDay) || SelectedItems.Count > 1 ? Visibility.Visible : Visibility.Collapsed; } }); }
/// <summary> /// 下载更新信息 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void UpdateMetaDownloadInternal(object sender, DoWorkEventArgs e) { try { // 下载更新信息 OnUpdateMetaDownloading(); var localFile = Context.UpdateMetaFilePath; if (File.Exists(localFile)) { Trace.TraceInformation("正在读取本地升级信息文件 [" + localFile + "]"); Context.UpdateMetaTextContent = File.ReadAllText(localFile, Encoding.UTF8); } else { //下载信息时不直接下载到文件中.这样不会导致始终创建文件夹 Exception ex = null; byte[] data = null; var url = Context.UpdateMetaFileUrl; var client = Context.CreateWebClient(); client.DownloadProgressChanged += (x, y) => (sender as BackgroundWorker).ReportProgress(Utility.GetPercentProgress(y.BytesReceived, y.TotalBytesToReceive)); //远程下载。为了支持进度显示,这里必须使用异步下载 using (var wHandler = new AutoResetEvent(false)) { client.DownloadDataCompleted += (x, y) => { ex = y.Error; if (ex == null) { data = y.Result; } wHandler.Set(); }; Trace.TraceInformation("正在从 " + url + " 下载升级信息"); client.DownloadDataAsync(new Uri(url)); //等待下载完成 wHandler.WaitOne(); } if (ex != null) { throw ex; } Trace.TraceInformation("服务器返回数据----->" + (data == null ? "<null>" : data.Length.ToString() + "字节")); if (data != null && data.Length > 0x10) { //不是<xml标记,则执行解压缩 if (BitConverter.ToInt32(data, 0) != 0x6D783F3C && BitConverter.ToInt32(data, 0) != 0x3CBFBBEF) { Trace.TraceInformation("正在执行解压缩"); data = data.Decompress(); } Context.UpdateMetaTextContent = Encoding.UTF8.GetString(data); } //是否返回了正确的结果? if (string.IsNullOrEmpty(Context.UpdateMetaTextContent)) { throw new ApplicationException("服务器返回了不正确的更新结果"); } } // 下载升级信息完成事件 OnUpdateMetaDownloadFinished(); if ((Context.UpdateMeta = SerializeHelper.XmlDeserialize <UpdateMeta>(Context.UpdateMetaTextContent)) == null) { throw new ApplicationException("未能成功加载升级信息"); } Trace.TraceInformation("服务器版本:{0}", Context.UpdateMeta.AppVersion); Trace.TraceInformation("当前版本:{0}", Context.CurrentVersion); //设置必须的属性 if (Context.UpdateMeta.MustUpdate) { Context.AutoKillProcesses = true; Trace.TraceInformation("已设置自动关闭进程。"); Context.AutoEndProcessesWithinAppDir = true; Trace.TraceInformation("已设置自动关闭同目录进程。"); Context.ForceUpdate = true; Trace.TraceInformation("已设置强制升级。"); } //判断升级 if (!string.IsNullOrEmpty(Context.UpdateMeta.RequiredMinVersion) && Context.CurrentVersion < new Version(Context.UpdateMeta.RequiredMinVersion)) { Context.CurrentVersionTooLow = true; Trace.TraceWarning("当前应用程序版本过低,无法升级。要求最低版本:{0},当前版本:{1}。", Context.UpdateMeta.RequiredMinVersion, Context.CurrentVersion); } else { Context.HasUpdate = new Version(Context.UpdateMeta.AppVersion) > Context.CurrentVersion; Trace.TraceInformation("已找到升级:" + Context.HasUpdate); } if (Context.HasUpdate) { //判断要升级的包 if (Packages == null || Packages.Count == 0) { var pkgList = Context.UpdatePackageListPath; Trace.TraceInformation("外部升级包列表:{0}", pkgList); if (File.Exists(pkgList)) { Trace.TraceInformation("外部升级包列表:已加载成功"); Packages = SerializeHelper.XmlDeserialize <List <Package> >(File.ReadAllText(pkgList, Encoding.UTF8)); Packages.ForEach(s => s.Context = Context); } else { Trace.TraceInformation("外部升级包列表:当前不存在,正在生成升级清单"); GatheringDownloadPackages(sender, e); } var preserveFileList = Context.PreserveFileListPath; Trace.TraceInformation("外部文件保留列表:{0}", preserveFileList); if (File.Exists(preserveFileList)) { Trace.TraceInformation("外部文件保留列表:已加载成功"); var list = SerializeHelper.XmlDeserialize <List <string> >(File.ReadAllText(preserveFileList, Encoding.UTF8)); list.ForEach(s => FileInstaller.PreservedFiles.Add(s, null)); } else { Trace.TraceInformation("外部升级包列表:当前不存在,等待重新生成"); } } //如果没有要升级的包?虽然很奇怪,但依然当作不需要升级 if (Packages.Count == 0) { Context.HasUpdate = false; Trace.TraceWarning("警告:虽然版本出现差别,但是并没有可升级的文件。将会当作无升级对待。"); } } } catch (Exception ex) { Context.IsInUpdating = false; Context.Exception = ex; Trace.TraceWarning("检测更新信息失败:" + ex.Message, ex.ToString()); OnError(); OnCheckUpdateComplete(); } }