/// <summary> /// 检查 XNCF 模块是否可用(推荐) /// </summary> /// <param name="xncfRegister"></param> /// <returns></returns> public async Task <bool> CheckXncfValiable(IXncfRegister xncfRegister) { //检查内存中是否存在 return(xncfRegister != null && IsRegistered(xncfRegister) ? await CheckOpenStateAsync(xncfRegister.Name).ConfigureAwait(false) : false); }
internal void Build(IApplicationBuilder app, IXncfRegister register) { var threadRegister = register as IXncfThread; if (threadRegister == null) { return; } var i = 0; //遍历单个 XNCF 内所有线程配置 foreach (var threadInfo in _threadInfoList) { if (threadInfo.Task == null) { continue; } try { i++; //定义线程 Thread thread = new Thread(async() => { SenparcTrace.SendCustomLog("启动线程", $"{register.Name}-{threadInfo.Name}"); await Task.Delay(TimeSpan.FromSeconds(i)); while (true) { try { await threadInfo.Task.Invoke(app, threadInfo); // 建议开发者自己在内部做好线程内的异常处理 } catch (Exception ex) { if (threadInfo.ExceptionHandler != null) { await threadInfo.ExceptionHandler.Invoke(ex); } else { SenparcTrace.BaseExceptionLog(ex); } } finally { //进行延迟 await Task.Delay(threadInfo.IntervalTime); } } }); thread.Name = $"{register.Uid}-{threadInfo.Name ?? Guid.NewGuid().ToString()}"; thread.Start();//启动 Register.ThreadCollection[threadInfo] = thread; } catch (Exception ex) { SenparcTrace.BaseExceptionLog(ex); } } }
public async Task <IActionResult> OnPostAsync() { var adminUserInfo = _accountInfoService.Init(out string userName, out string password);//初始化管理员信息 if (adminUserInfo == null) { return(new StatusCodeResult(404)); //base.Response.StatusCode = 404; //return; } else { Step = 1; _systemConfigService.Init();//初始化系统信息 _sysMenuService.Init(); IXncfRegister systemRegister = Senparc.Ncf.XncfBase.Register.RegisterList.First(z => z.GetType() == typeof(Senparc.Areas.Admin.Register)); await _xncfModuleService.InstallMenuAsync(systemRegister, Ncf.Core.Enums.InstallOrUpdate.Install);//安装菜单 AdminUserName = userName; AdminPassword = password;//这里不可以使用 adminUserInfo.Password,因为此参数已经是加密信息 return(Page()); } }
/// <summary> /// 安装模块之后,安装菜单 /// </summary> /// <param name="register"></param> /// <returns></returns> public async Task InstallMenuAsync(IXncfRegister register, InstallOrUpdate installOrUpdate) { var topMenu = await _sysMenuService.Value.GetObjectAsync(z => z.MenuName == "扩展模块").ConfigureAwait(false); var currentMenu = await _sysMenuService.Value.GetObjectAsync(z => z.ParentId == topMenu.Id && z.MenuName == register.MenuName).ConfigureAwait(false); SysMenuDto menuDto; if (installOrUpdate == InstallOrUpdate.Update && currentMenu != null) { //更新菜单 menuDto = _sysMenuService.Value.Mapper.Map <SysMenuDto>(currentMenu); menuDto.MenuName = register.MenuName; //更新菜单名称 menuDto.Icon = register.Icon; //更新菜单图标 } else { //新建菜单 var icon = register.Icon.IsNullOrEmpty() ? "fa fa-bars" : register.Icon; var order = 20; switch (register.Uid) { case SiteConfig.SYSTEM_XNCF_MODULE_SERVICE_UID: order = 160; break; case SiteConfig.SYSTEM_XNCF_MODULE_AREAS_ADMIN_UID: order = 150; break; default: break; } menuDto = new SysMenuDto(true, null, register.MenuName, topMenu.Id, $"/Admin/XncfModule/Start/?uid={register.Uid}", icon, order, true, null); } var sysMemu = await _sysMenuService.Value.CreateOrUpdateAsync(menuDto).ConfigureAwait(false); if (installOrUpdate == InstallOrUpdate.Install) { //更新菜单信息 SysPermissionDto sysPermissionDto = new SysPermissionDto() { IsMenu = true, ResourceCode = sysMemu.ResourceCode, RoleId = "1", RoleCode = "administrator", PermissionId = sysMemu.Id }; SenparcEntities db = _serviceProvider.GetService <SenparcEntities>(); db.SysPermission.Add(new SysPermission(sysPermissionDto)); await db.SaveChangesAsync(); var updateMenuDto = new UpdateMenuId_XncfModuleDto(register.Uid, sysMemu.Id); await base.UpdateMenuIdAsync(updateMenuDto).ConfigureAwait(false); } }
/// <summary> /// 获取显示的版本号信息(如果有新版本,则显示格式:[旧版本号] -> [新版本号] /// </summary> /// <param name="xncfModules"></param> /// <param name="xncfRegister"></param> /// <returns></returns> public string GetVersionDisplayName(List <XncfModule> xncfModules, IXncfRegister xncfRegister) { var installedXncf = xncfModules.FirstOrDefault(z => z.Uid == xncfRegister.Uid); if (installedXncf == null || installedXncf.Version == xncfRegister.Version) { return(xncfRegister.Version); } return($"{installedXncf.Version} -> {xncfRegister.Version}"); }
/// <summary> /// 获取 Admin 后台左侧菜单结构 /// </summary> /// <param name="sysMenuTreeItems"></param> /// <returns></returns> private async Task <IEnumerable <SysMenuTreeItemDto> > GetSysMenuTreesMainRecursiveAsync(IEnumerable <SysMenuDto> sysMenuTreeItems) { bool hideModuleManager = FullSystemConfig.HideModuleManager == true;//是否处于发布状态,需要隐藏部分菜单 List <SysMenuTreeItemDto> sysMenuTrees = new List <SysMenuTreeItemDto>(); List <SysMenuDto> dest = new List <SysMenuDto>(); int index = 60000; XncfRegisterManager xncfRegisterManager = new XncfRegisterManager(_serviceProvider); //遍历菜单设置项目,查找和 XNCF 模块有关的菜单节点 foreach (var item in sysMenuTreeItems) { //定位 XNCF 模块 IXncfRegister xncfRegister = XncfRegisterList .FirstOrDefault(z => !string.IsNullOrEmpty(item.Url) && item.Url.Contains($"uid={z.Uid}", StringComparison.OrdinalIgnoreCase)); //TODO:判断Xncf条件还可以更细 var isStoredXncf = !string.IsNullOrEmpty(item.Url) && item.Url.Contains("uid=", StringComparison.OrdinalIgnoreCase); //在数据库里面注册为模块 var xncfMissing = isStoredXncf && xncfRegister == null; //程序集未加载 if (xncfRegister != null && xncfRegister is Senparc.Ncf.Core.Areas.IAreaRegister xncfAreapage && xncfAreapage.AareaPageMenuItems.Count() > 0) { if (hideModuleManager) { item.ParentId = null; item.Id = (index++).ToString(); } else { dest.Add(new SysMenuDto() { MenuName = "设置/执行", Url = item.Url, Id = (index++).ToString(), ParentId = item.Id, Icon = "fa fa-play" }); } dest.AddRange(xncfAreapage.AareaPageMenuItems.Select(_ => new SysMenuDto() { MenuName = _.Name, Url = _.Url, Icon = _.Icon, Id = string.IsNullOrEmpty(_.Id) ? (index++).ToString() : _.Id, ParentId = string.IsNullOrEmpty(_.ParentId) ? item.Id : _.ParentId })); item.Url = string.Empty; }
public async Task <IActionResult> OnPostAsync() { var adminUserInfo = _accountInfoService.Init(out string userName, out string password);//初始化管理员信息 if (adminUserInfo == null) { return(new StatusCodeResult(404)); } else { Step = 1; //添加初始化多租户信息 if (SiteConfig.SenparcCoreSetting.EnableMultiTenant) { var httpContext = _httpContextAccessor.Value.HttpContext; try { //var tenantInfo = await _tenantInfoService.CreateInitTenantInfoAsync(httpContext); CreatedRequestTenantInfo = await _tenantInfoService.SetScopedRequestTenantInfoAsync(httpContext); TenantInfoDto = _tenantInfoService.Mapper.Map <TenantInfoDto>(await _tenantInfoService.GetObjectAsync(z => z.Id == CreatedRequestTenantInfo.Id)); } catch (Exception) { } finally { } } _systemConfigService.Init();//初始化系统信息 _sysMenuService.Init(); IXncfRegister systemRegister = XncfRegisterManager.RegisterList.First(z => z.GetType() == typeof(Senparc.Areas.Admin.Register)); await _xncfModuleService.InstallMenuAsync(systemRegister, Ncf.Core.Enums.InstallOrUpdate.Install);//安装菜单 AdminUserName = userName; AdminPassword = password;//这里不可以使用 adminUserInfo.Password,因为此参数已经是加密信息 return(Page()); } }
public XncfPageException(IXncfRegister xncfRegister, string message, Exception inner, bool logged = false) : base(message, inner, logged) { XncfRegister = xncfRegister; }
/// <summary> /// handler=Detail /// </summary> /// <param name="uid"></param> /// <returns></returns> public async Task <IActionResult> OnGetDetailAsync(string uid) { bool mustUpdate = false; if (uid.IsNullOrEmpty()) { throw new Exception("模块编号未提供!"); } Ncf.Core.Models.DataBaseModel.XncfModule xncfModule = await _xncfModuleService.GetObjectAsync(z => z.Uid == uid).ConfigureAwait(false); if (xncfModule == null) { throw new Exception("模块未添加!"); } IEnumerable <string> xncfModuleUpdateLog = new List <string>(); if (!xncfModule.UpdateLog.IsNullOrEmpty()) { xncfModuleUpdateLog = xncfModule.UpdateLog .Split(new[] { "\r", "\n" }, StringSplitOptions.RemoveEmptyEntries) .ToList(); } IXncfRegister xncfRegister = XncfRegisterManager.RegisterList.FirstOrDefault(z => z.Uid == uid); if (xncfRegister == null) { throw new Exception($"模块丢失或未加载({XncfRegisterManager.RegisterList.Count})!"); } IDictionary <IXncfFunction, List <FunctionParameterInfo> > functionParameterInfoCollection = new Dictionary <IXncfFunction, List <FunctionParameterInfo> >(); try { foreach (var functionType in xncfRegister.Functions) { var function = _serviceProvider.GetService(functionType) as FunctionBase;//如:Senparc.Xncf.ChangeNamespace.Functions.ChangeNamespace functionParameterInfoCollection[function] = await function.GetFunctionParameterInfoAsync(_serviceProvider, true); } } catch (Exception) { SenparcTrace.SendCustomLog("模块读取失败", @$ "模块:{XncfModule.Name} / {XncfModule.MenuName} / {XncfModule.Uid} 请尝试更新此模块后刷新页面!"); mustUpdate = true; } IEnumerable <KeyValuePair <ThreadInfo, Thread> > registeredThreadInfo = xncfRegister.RegisteredThreadInfo; return(Ok(new { mustUpdate, xncfModule, xncfModuleUpdateLog, xncfRegister = new { AreaHomeUrl = xncfRegister.GetAreaHomeUrl(), xncfRegister.MenuName, xncfRegister.Icon, xncfRegister.Version, xncfRegister.Uid, areaPageMenuItems = (xncfRegister as Ncf.Core.Areas.IAreaRegister)?.AareaPageMenuItems ?? new List <Ncf.Core.Areas.AreaPageMenuItem>(), Interfaces = xncfRegister.GetType().GetInterfaces().Select(_ => _.Name), FunctionCount = xncfRegister.Functions.Count, registeredThreadInfo = xncfRegister.RegisteredThreadInfo.Select(_ => new { Key = new { _.Key.Name, _.Key.StoryHtml }, Value = new { _.Value.IsAlive, IsBackground = _.Value.IsAlive ? new bool?(_.Value.IsBackground) : null, ThreadState = _.Value.IsAlive ? new ThreadState?(_.Value.ThreadState) : null, ThreadStateStr = _.Value.IsAlive ? _.Value.ThreadState.ToString() : null } }) }, functionParameterInfoCollection = functionParameterInfoCollection .Select(_ => new { Key = new { _.Key.Name, _.Key.Description }, _.Value }), registeredThreadInfo = registeredThreadInfo.Select(_ => new { Key = new { _.Key.Name, _.Key.StoryHtml }, Value = new { _.Value.IsAlive, IsBackground = _.Value.IsAlive ? new bool?(_.Value.IsBackground) : null, ThreadState = _.Value.IsAlive ? new ThreadState?(_.Value.ThreadState) : null, ThreadStateStr = _.Value.IsAlive ? _.Value.ThreadState.ToString() : null } }) })); }
/// <summary> /// 判断指定名称的模块是否已注册(推荐) /// </summary> /// <param name="xncfRegister">XncfRegister</param> /// <returns></returns> public static bool IsRegistered(IXncfRegister xncfRegister) => RegisterList.Exists(z => z.Uid == xncfRegister.Uid);