using JNPF.Common.Extension; using Tnb.Vengine.DataAccess; namespace Tnb.Vengine.Domain { public class VmQueryParser { private readonly IDataAccess _dataAccess; private readonly Vmodel _root; private List _outputs; private Dictionary _selectProps = new Dictionary(); private Dictionary _navModels = new Dictionary(); public VmQueryParser(IDataAccess dataAccess, Vmodel rootModel, string output) { _dataAccess = dataAccess; _root = rootModel; ParseOutputStr(output); } /// /// 按模型组织要输出的属性 /// private void ParseOutputStr(string output) { _outputs = output.Split(',').Distinct().ToList(); _selectProps.Add(Vmodel.MAIN_ALIES, new VmSelect() { navModel = _root }); foreach (var outStr in _outputs) { if (string.IsNullOrWhiteSpace(outStr)) continue; var codes = outStr.Split('.'); if (codes.Length == 1) { _selectProps[Vmodel.MAIN_ALIES].propCodes.Add(outStr); continue; } var vmPath = ""; for (int i = 0; i < codes.Length - 1; i++) { vmPath = i == 0 ? codes[i] : vmPath + "." + codes[i]; if (!_selectProps.ContainsKey(vmPath)) { _selectProps.Add(vmPath, new VmSelect(vmPath, i + 2)); } if (i == codes.Length - 2) { _selectProps[vmPath].propCodes.Add(codes[i + 1]); } } } } private async Task LoadNavModel() { var keys = _selectProps.Keys.Where(a => a != Vmodel.MAIN_ALIES).OrderBy(a => a).ToList(); foreach (var selVm in _selectProps.Values) { if (_navModels.ContainsKey(selVm.path)) { continue; } } var navProps = _root.navProps.Where(a => _selectProps.Values.Any(b => b.path.StartsWith(a.code + "."))).ToList(); await LoadVmodelNavigateAsync(navProps); } private async Task LoadVmodelNavigateAsync(List navProps) { var db = _dataAccess.GetSqlSugar(); var vmids = navProps.Select(a => a.vmid).Distinct().ToList(); var navs = await db.Queryable().Where(a => vmids.Contains(a.id)).ToDictionaryAsync(a => a.id, a => a); foreach (var navProp in navProps) { navProp.naviModel = (Vmodel)navs.GetOrDefault(navProp.vmid); navProp.naviModel.navProps.Where(a => _selectProps.Values.Any(b => b.path.StartsWith(a.code + "."))).ToList(); } } } internal class VmSelect { public Vmodel? navModel { get; set; } public string path { get; set; } = Vmodel.MAIN_ALIES; public int level { get; set; } = 1; public eNavigateType navType { get; set; } = eNavigateType.None; public List navPaths { get; set; } = new List(); public List propCodes { get; set; } = new List(); public List fieldCodes { get; set; } = new List(); public VmSelect() { } public VmSelect(string vmPath, int vmLevel) { path = vmPath; level = vmLevel; } } internal class NavigateVmodel { public Vmodel? navModel { get; set; } public string navPath { get; set; } } }