[UI.Client]

修正RecipeEditor视图无法加载Routine编辑表格的问题。
新增类型RecipeType,用于区分当前RecipeData对象的类型。
RecipeFormatBuilder对象中构建Recipe表格格式时,判断Recipe类型,如果不是Process,则默认赋予所有列WR权限。
This commit is contained in:
SL 2023-08-22 16:48:45 +08:00
parent e7ad49b615
commit e516422e8e
13 changed files with 128 additions and 109 deletions

View File

@ -1,12 +0,0 @@
namespace MECF.Framework.UI.Client.CenterViews.Editors
{
public enum EditMode
{
None,
New,
ReName,
Edit,
Normal,
EditWhitelist
}
}

View File

@ -1,5 +1,4 @@
using System;
using System.Collections.ObjectModel;
using System.Collections.ObjectModel;
using MECF.Framework.Common.CommonData;
using MECF.Framework.UI.Client.CenterViews.Editors.Sequence;
@ -7,17 +6,6 @@ namespace MECF.Framework.UI.Client.CenterViews.Editors
{
public class ProcessTypeFileItem : NotifiableItem
{
/// <summary>
/// 工艺文件类型。
/// </summary>
[Flags]
public enum ProcessFileTypes
{
Process = 0x1 << 0,
Routine = 0x1 << 1,
Clean = 0x1 << 2
}
#region Variablers
private ObservableCollection<FileNode> _filterFileListByProcessType;
@ -32,16 +20,16 @@ namespace MECF.Framework.UI.Client.CenterViews.Editors
FilterFileListByProcessType = new ObservableCollection<FileNode>();
}
public ProcessTypeFileItem(ProcessFileTypes processType) : this()
public ProcessTypeFileItem(RecipeType type) : this()
{
ProcessType = processType.ToString();
ProcessType = type;
}
#endregion
#region Properties
public string ProcessType { get; set; }
public RecipeType ProcessType { get; set; }
public ObservableCollection<FileNode> FileListByProcessType { get; set; }
@ -72,11 +60,11 @@ namespace MECF.Framework.UI.Client.CenterViews.Editors
switch (fileTypes.ToLower())
{
case "process":
return GetProcessFilesPrefix(ProcessFileTypes.Process);
return GetProcessFilesPrefix(RecipeType.Process);
case "routine":
return GetProcessFilesPrefix(ProcessFileTypes.Routine);
return GetProcessFilesPrefix(RecipeType.Routine);
case "clean":
return GetProcessFilesPrefix(ProcessFileTypes.Clean);
return GetProcessFilesPrefix(RecipeType.Clean);
default:
return string.Empty;
}
@ -86,19 +74,19 @@ namespace MECF.Framework.UI.Client.CenterViews.Editors
/// <summary>
/// 根据指定的工艺文件类型获取工艺文件前缀。
/// </summary>
/// <param name="fileTypes"></param>
/// <param name="type"></param>
/// <returns></returns>
public static string GetProcessFilesPrefix(ProcessFileTypes fileTypes)
public static string GetProcessFilesPrefix(RecipeType type)
{
switch (fileTypes)
switch (type)
{
case ProcessFileTypes.Process:
case RecipeType.Process:
return "Sic\\Process";
case ProcessFileTypes.Routine:
case RecipeType.Routine:
return "Sic\\Routine";
case ProcessFileTypes.Clean:
case RecipeType.Clean:
return "Sic\\Clean";
default:

View File

@ -30,6 +30,7 @@ namespace MECF.Framework.UI.Client.CenterViews.Editors.Recipe
#region Variables
private readonly RoleManager _roleManager = new();
private readonly IRecipeGasFlowCalculator _recipeGasFlowCalculator;
private RecipeData _currentRecipe;
private bool _isLoading;
@ -290,7 +291,7 @@ namespace MECF.Framework.UI.Client.CenterViews.Editors.Recipe
public string CurrentChamberType => ChamberType[ChamberTypeIndexSelection];
public string CurrentProcessType => ProcessTypeFileList[ProcessTypeIndexSelection].ProcessType;
public RecipeType CurrentProcessType => ProcessTypeFileList[ProcessTypeIndexSelection].ProcessType;
public Visibility MultiChamberVisibility { get; set; }
@ -308,6 +309,8 @@ namespace MECF.Framework.UI.Client.CenterViews.Editors.Recipe
{
base.OnInitialize();
_roleManager.Initialize();
var chamberType = QueryDataClient.Instance.Service.GetConfig("System.Recipe.SupportedChamberType");
if (chamberType == null)
{
@ -323,9 +326,9 @@ namespace MECF.Framework.UI.Client.CenterViews.Editors.Recipe
var processType = "Process,Routine,Clean";
ProcessTypeFileList = new ObservableCollection<ProcessTypeFileItem>();
var recipeProcessType = ((string)processType).Split(',');
var recipeProcessType = Utils.GetRecipeTypeList();
for (var i = 0; i < recipeProcessType.Length; i++)
for (var i = 0; i < recipeProcessType.Count; i++)
{
var type = new ProcessTypeFileItem();
type.ProcessType = recipeProcessType[i];
@ -338,27 +341,19 @@ namespace MECF.Framework.UI.Client.CenterViews.Editors.Recipe
}
DicColunms = new Dictionary<string, List<EditorDataGridTemplateColumnBase>>();
UpdateRecipeFormat();
}
protected override void OnActivate()
{
//初始化RoleManager
var roleManager = new RoleManager();
roleManager.Initialize();
//得到当前登录的RoleItem
var role = roleManager.GetRoleByName(BaseApp.Instance.UserContext.RoleName);
CurrentRecipe.ReloadRolePermission(role);
UpdateView();
UpdateRecipeFormat();
// 根据角色权限设置判断是否显示按钮。
IsShowCellAccessPermEditButton = GetCapeModeButtonPerm();
NotifyOfPropertyChange(nameof(IsShowCellAccessPermEditButton));
UpdateView();
base.OnActivate();
}
@ -437,23 +432,31 @@ namespace MECF.Framework.UI.Client.CenterViews.Editors.Recipe
Chambers = new ObservableCollection<string>(new string[] { "PM1" });
}
_editMode = EditMode.None;
MultiChamberVisibility = Chambers.Count > 1 ? Visibility.Visible : Visibility.Collapsed;
SelectedChamber = Chambers[0];
#region Create RecipeData
CurrentRecipe = new RecipeData(_recipeGasFlowCalculator);
CurrentRecipe.BuildFormat($"{CurrentChamberType}\\{CurrentProcessType}", SelectedChamber, BaseApp.Instance.UserContext.RoleName);
CurrentRecipe.OnValidated += (sender, args) =>
var recipeData = new RecipeData(_recipeGasFlowCalculator, CurrentProcessType);
recipeData.BuildFormat($"{CurrentChamberType}\\{CurrentProcessType}", SelectedChamber, BaseApp.Instance.UserContext.RoleName);
recipeData.OnValidated += (sender, args) =>
{
ErrorsCount = CurrentRecipe.ValidationErrorCount;
ErrorsCount = recipeData.ValidationErrorCount;
};
CurrentRecipe.OnAccessibleWhitelistChanged += (sender, count) =>
recipeData.OnAccessibleWhitelistChanged += (sender, count) =>
{
AccessibleWhitelistCount = count;
};
_editMode = EditMode.None;
//得到当前登录的RoleItem
var role = _roleManager.GetRoleByName(BaseApp.Instance.UserContext.RoleName);
recipeData.ReloadRolePermission(role);
MultiChamberVisibility = Chambers.Count > 1 ? Visibility.Visible : Visibility.Collapsed;
CurrentRecipe = recipeData;
#endregion
}
@ -799,7 +802,7 @@ namespace MECF.Framework.UI.Client.CenterViews.Editors.Recipe
return;
}
var recipe = new RecipeData(_recipeGasFlowCalculator);
var recipe = new RecipeData(_recipeGasFlowCalculator, CurrentProcessType);
recipe.Name = recipeName;
recipe.PrefixPath = prefix;
recipe.Creator = BaseApp.Instance.UserContext.LoginName;
@ -810,10 +813,8 @@ namespace MECF.Framework.UI.Client.CenterViews.Editors.Recipe
if (!Save(recipe, true))
return;
var types = prefix.Split('\\');
ReloadRecipeFileList(types[0], types[1], recipeName, false);
ReloadRecipeFileList(CurrentChamberType, CurrentProcessType, recipeName, false);
}
@ -861,7 +862,7 @@ namespace MECF.Framework.UI.Client.CenterViews.Editors.Recipe
return;
}
var recipe = new RecipeData(_recipeGasFlowCalculator);
var recipe = new RecipeData(_recipeGasFlowCalculator, CurrentProcessType);
recipe.Name = recipeName;
recipe.PrefixPath = CurrentChamberType + "\\" + CurrentProcessType;
recipe.Creator = BaseApp.Instance.UserContext.LoginName;
@ -877,7 +878,7 @@ namespace MECF.Framework.UI.Client.CenterViews.Editors.Recipe
ReloadRecipeFileList(CurrentChamberType, CurrentProcessType, recipeName, false);
}
private void ReloadRecipeFileList(string chamberType, string processType, string selectedFile,
private void ReloadRecipeFileList(string chamberType, RecipeType processType, string selectedFile,
bool selectionIsFolder)
{
var item = ProcessTypeFileList.FirstOrDefault(x => x.ProcessType == processType);
@ -1208,14 +1209,14 @@ namespace MECF.Framework.UI.Client.CenterViews.Editors.Recipe
Multiselect = true
};
var prefix = ProcessTypeFileItem.GetProcessFilesPrefix(ProcessTypeFileItem.ProcessFileTypes.Process);
var prefix = ProcessTypeFileItem.GetProcessFilesPrefix(RecipeType.Process);
if (openFileDialog.ShowDialog() != true)
return;
#region
var dialog = new RecipeSelectDialogViewModel(true, true, ProcessTypeFileItem.ProcessFileTypes.Process)
var dialog = new RecipeSelectDialogViewModel(true, true, RecipeType.Process)
{
DisplayName = "Select Folder to Import ..."
};
@ -1272,7 +1273,7 @@ namespace MECF.Framework.UI.Client.CenterViews.Editors.Recipe
}
// 刷新Recipe列表
ReloadRecipeFileList("Sic", "Process", "", false);
ReloadRecipeFileList("Sic", RecipeType.Process, "", false);
}

View File

@ -13,7 +13,7 @@ namespace MECF.Framework.UI.Client.CenterViews.Editors.Recipe
#region Variables
private readonly ProcessFileTypes _fileTypes;
private readonly RecipeType _fileTypes;
private readonly bool _isFolderOnly;
private readonly bool _isShowRootNode;
private FileNode _currentFileNode;
@ -24,14 +24,14 @@ namespace MECF.Framework.UI.Client.CenterViews.Editors.Recipe
public RecipeSelectDialogViewModel()
{
_fileTypes = ProcessFileTypes.Process | ProcessFileTypes.Routine | ProcessFileTypes.Clean;
_fileTypes = RecipeType.Process | RecipeType.Routine | RecipeType.Clean;
_isFolderOnly = false;
_isShowRootNode = false;
BuildFileTree(_isShowRootNode, _isFolderOnly, _fileTypes);
}
public RecipeSelectDialogViewModel(bool isShowRootNode, bool isFolderOnly, ProcessFileTypes fileType)
public RecipeSelectDialogViewModel(bool isShowRootNode, bool isFolderOnly, RecipeType fileType)
{
_fileTypes = fileType;
_isFolderOnly = isFolderOnly;
@ -56,40 +56,35 @@ namespace MECF.Framework.UI.Client.CenterViews.Editors.Recipe
#region Private Methods
private void BuildFileTree(bool isShowRootNode, bool isFolderOnly, ProcessFileTypes fileType)
private void BuildFileTree(bool isShowRootNode, bool isFolderOnly, RecipeType fileType)
{
var recipeProvider = new RecipeProvider();
var processType = QueryDataClient.Instance.Service.GetConfig("System.Recipe.SupportedProcessType").ToString();
if (string.IsNullOrEmpty(processType))
var scProcessType = QueryDataClient.Instance.Service.GetConfig("System.Recipe.SupportedProcessType").ToString();
var supportedRecipeType = new List<RecipeType>(new[] { RecipeType.Process, RecipeType.Routine });
if (!string.IsNullOrEmpty(scProcessType))
{
processType = $"{ProcessFileTypes.Process.ToString()}, {ProcessFileTypes.Routine.ToString()}";
}
else
{
// 根据参数过滤掉不需要加载的文件类型。
var newProcessFileType = new List<string>();
if (fileType.HasFlag(ProcessFileTypes.Process) && processType.Contains(ProcessFileTypes.Process.ToString()))
newProcessFileType.Add(ProcessFileTypes.Process.ToString());
supportedRecipeType.Clear();
if (fileType.HasFlag(ProcessFileTypes.Routine) && processType.Contains(ProcessFileTypes.Routine.ToString()))
newProcessFileType.Add(ProcessFileTypes.Routine.ToString());
if (fileType.HasFlag(RecipeType.Process) && scProcessType.Contains(RecipeType.Process.ToString()))
supportedRecipeType.Add(RecipeType.Process);
if (fileType.HasFlag(ProcessFileTypes.Clean) && processType.Contains(ProcessFileTypes.Clean.ToString()))
newProcessFileType.Add(ProcessFileTypes.Clean.ToString());
if (fileType.HasFlag(RecipeType.Routine) && scProcessType.Contains(RecipeType.Routine.ToString()))
supportedRecipeType.Add(RecipeType.Routine);
processType = string.Join(",", newProcessFileType);
if (fileType.HasFlag(RecipeType.Clean) && scProcessType.Contains(RecipeType.Clean.ToString()))
supportedRecipeType.Add(RecipeType.Clean);
}
var processTypeFileList = new List<ProcessTypeFileItem>();
var recipeProcessType = ((string)processType).Split(',');
for (var i = 0; i < recipeProcessType.Length; i++)
for (var i = 0; i < supportedRecipeType.Count; i++)
{
var type = new ProcessTypeFileItem
{
ProcessType = recipeProcessType[i]
ProcessType = supportedRecipeType[i]
};
var prefix = $"Sic\\{recipeProcessType[i]}";
var prefix = $"Sic\\{supportedRecipeType[i]}";
var recipes = recipeProvider.GetXmlRecipeList(prefix);
type.FileListByProcessType = RecipeSequenceTreeBuilder.BuildFileNode(prefix, "", false, recipes, isFolderOnly, isShowRootNode)[0].Files;
processTypeFileList.Add(type);

View File

@ -139,7 +139,7 @@ namespace MECF.Framework.UI.Client.CenterViews.Editors.RecipeConfig
VatVisibility = _columnBuilder.VatConfig.Count > 0 ? Visibility.Visible : Visibility.Hidden;
FineTuningVisibility = _columnBuilder.FineTuningConfig.Count > 0 ? Visibility.Visible : Visibility.Hidden;
this.CurrentRecipe = new RecipeData(null);
this.CurrentRecipe = new RecipeData(null, RecipeType.Process);
CurrentRecipe.RecipeChamberType = _columnBuilder.RecipeChamberType;
CurrentRecipe.RecipeVersion = _columnBuilder.RecipeVersion;

View File

@ -756,7 +756,7 @@ namespace MECF.Framework.UI.Client.CenterViews.Editors.Sequence
public void SelectRecipe(PathFileParam param)
{
var dialog = new RecipeSelectDialogViewModel(false, false, ProcessTypeFileItem.ProcessFileTypes.Process);
var dialog = new RecipeSelectDialogViewModel(false, false, RecipeType.Process);
dialog.DisplayName = "Select Recipe";
var parameters = param.Parent;
PositionParam posParam = null;

View File

@ -0,0 +1,31 @@
using System;
using System.Collections.Generic;
namespace MECF.Framework.UI.Client.CenterViews.Editors
{
public enum EditMode
{
None,
New,
ReName,
Edit,
Normal,
EditWhitelist
}
[Flags]
public enum RecipeType
{
Process = 0x1 << 0,
Routine = 0x1 << 1,
Clean = 0x1 << 2
}
public static class Utils
{
public static List<RecipeType> GetRecipeTypeList()
{
return new List<RecipeType>(new[] { RecipeType.Process, RecipeType.Routine, RecipeType.Clean });
}
}
}

View File

@ -280,7 +280,7 @@ namespace MECF.Framework.UI.Client.CenterViews.Modules.PM
//
public RecipeData CurrentRecipe { get; set; } = new RecipeData(null);
public RecipeData CurrentRecipe { get; set; } = new RecipeData(null, RecipeType.Process );
public List<EditorDataGridTemplateColumnBase> Columns { get; set; } = new List<EditorDataGridTemplateColumnBase>();
private RecipeFormatBuilder _columnBuilder = new RecipeFormatBuilder();
@ -490,7 +490,7 @@ namespace MECF.Framework.UI.Client.CenterViews.Modules.PM
public void SelectRecipe()
{
var dialog = new RecipeSelectDialogViewModel(false, false, ProcessTypeFileItem.ProcessFileTypes.Process);
var dialog = new RecipeSelectDialogViewModel(false, false, RecipeType.Process);
dialog.DisplayName = "Select Recipe";
var wm = new WindowManager();
@ -660,7 +660,7 @@ namespace MECF.Framework.UI.Client.CenterViews.Modules.PM
public void UpdateRecipeFormat()
{
CurrentRecipe = new RecipeData(_recipeGasFlowCalculator);
CurrentRecipe = new RecipeData(_recipeGasFlowCalculator, RecipeType.Process);
CurrentRecipe.BuildFormat($"Sic\\Process", SystemName, BaseApp.Instance.UserContext.RoleName);
}

View File

@ -406,7 +406,7 @@
</Compile>
<Compile Include="CenterViews\DataLogs\WaferHistory\WaferHistoryViewModel.cs" />
<Compile Include="CenterViews\DataLogs\WaferHistory\YAxisLabelProvider.cs" />
<Compile Include="CenterViews\Editors\EditMode.cs" />
<Compile Include="CenterViews\Editors\Utils.cs" />
<Compile Include="CenterViews\Editors\FolderOrFileTemplateSelector.cs" />
<Compile Include="CenterViews\Editors\InputFileNameDialogView.xaml.cs">
<DependentUpon>InputFileNameDialogView.xaml</DependentUpon>

View File

@ -70,8 +70,12 @@ namespace MECF.Framework.UI.Client.RecipeEditorLib.DGExtension
// 创建DataGrid列
dg.ClearColumns();
foreach (var col in recipe.Columns)
dg.AddColumn(col);
if (recipe.Columns != null)
{
foreach (var col in recipe.Columns)
dg.AddColumn(col);
}
}
else
dg.dgCustom.ItemsSource = null;

View File

@ -16,6 +16,7 @@ using Aitex.Core.RT.Log;
using Caliburn.Micro.Core;
using MECF.Framework.Common.DataCenter;
using MECF.Framework.UI.Client.CenterViews.Configs.Roles;
using MECF.Framework.UI.Client.CenterViews.Editors;
using MECF.Framework.UI.Client.CenterViews.Editors.Recipe;
using MECF.Framework.UI.Client.ClientBase;
using MECF.Framework.UI.Client.RecipeEditorLib.DGExtension.CustomColumn;
@ -72,9 +73,10 @@ namespace MECF.Framework.UI.Client.RecipeEditorLib.RecipeModel
/// <param name="gasFlowCalculator">
/// 配方步骤气体流量计算器,请参考:<see cref="IRecipeGasFlowCalculator"/>。
/// </param>
/// <param name="formatBuilder">配方表格格式创建器。</param>
public RecipeData(IRecipeGasFlowCalculator gasFlowCalculator)
/// <param name="type">Recipe类型</param>
public RecipeData(IRecipeGasFlowCalculator gasFlowCalculator, RecipeType type)
{
RecipeType = type;
_formatBuilder = new RecipeFormatBuilder();
ValidationErrorInfo = new ObservableRangeCollection<RecipeStepValidationInfo>();
@ -123,6 +125,8 @@ namespace MECF.Framework.UI.Client.RecipeEditorLib.RecipeModel
#region Properties
public RecipeType RecipeType { get; }
public bool IsChanged
{
get
@ -667,7 +671,7 @@ namespace MECF.Framework.UI.Client.RecipeEditorLib.RecipeModel
public void BuildFormat(string path, string chamber, string roleName)
{
Columns = _formatBuilder.Build(path, chamber, true, roleName);
Columns = _formatBuilder.Build(path, chamber, true, roleName, RecipeType);
}
public void Clear()
@ -1804,8 +1808,10 @@ namespace MECF.Framework.UI.Client.RecipeEditorLib.RecipeModel
/// <param name="role"></param>
public void ReloadRolePermission(RoleItem role)
{
_formatBuilder.ReloadColumnsPermission(role);
if (RecipeType != RecipeType.Process)
return;
_formatBuilder.ReloadColumnsPermission(role);
var mp = new MenuPermission();
mp.ParsePermission(role.Role.MenuPermission);

View File

@ -7,6 +7,7 @@ using System.Xml;
using Aitex.Core.RT.Log;
using MECF.Framework.UI.Client.CenterViews.Configs.Roles;
using MECF.Framework.UI.Client.CenterViews.Configs.SystemConfig;
using MECF.Framework.UI.Client.CenterViews.Editors;
using MECF.Framework.UI.Client.ClientBase;
using MECF.Framework.UI.Client.RecipeEditorLib.DGExtension.CustomColumn;
using MECF.Framework.UI.Client.RecipeEditorLib.RecipeModel.Params;
@ -380,7 +381,7 @@ namespace MECF.Framework.UI.Client.RecipeEditorLib.RecipeModel
/// <param name="defaultCellEnable"></param>
/// <param name="roleName"></param>
/// <returns></returns>
public List<EditorDataGridTemplateColumnBase> Build(string path, string module = "PM1", bool defaultCellEnable = true, string roleName = "管理员")
public List<EditorDataGridTemplateColumnBase> Build(string path, string module = "PM1", bool defaultCellEnable = true, string roleName = "管理员", RecipeType recipeType = RecipeType.Process)
{
//XML文档读取格式由 $"PM.{module}.RecipeConfig 改为 $"RecipeConfig RecipeConfig参数放在Sic层级下和PM同级别
var str = _recipeProvider.GetRecipeFormatXml(path);
@ -770,7 +771,7 @@ namespace MECF.Framework.UI.Client.RecipeEditorLib.RecipeModel
// Header属性指向列对象使用HeaderTemplate模板渲染Header
col.Header = col;
// 单元格是否可编辑?
var isCellEditable = step.Attributes["IsColumnEditable"]?.Value;
if (string.IsNullOrEmpty(isCellEditable) == false && isCellEditable.ToLower() == "false")
@ -779,10 +780,14 @@ namespace MECF.Framework.UI.Client.RecipeEditorLib.RecipeModel
col.IsReadOnly = true;
col.StringCellEditingTemplate = "";
}
// 默认情况下当前Col具有访问权限
col.Permission = MenuPermissionEnum.MP_READ_WRITE;
// 设置列访问权限
SetPermission(col, menuPermission);
// 如果当前Recipe类型为Process则根据配置设置访问权限
if (recipeType == RecipeType.Process)
SetPermission(col, menuPermission);
colExpander.ChildColumns.Add(col); // 将本列追加到Expander中
columns.Add(col);
}

View File

@ -1,4 +1,5 @@
using System;
using System.Collections;
using System.Linq;
namespace Sicentury.Core.Extensions