浏览代码

新增调度服务
修复配置目录Configs小写问题,导致linux发布后启动失败
修改返回类型

zhontai 2 年之前
父节点
当前提交
c33e0eff24
共有 35 个文件被更改,包括 990 次插入696 次删除
  1. 6 4
      src/hosts/ZhonTai.Host/Configs/appconfig.json
  2. 1 6
      src/platform/ZhonTai.Admin/Core/Auth/ClaimAttributes.cs
  3. 0 34
      src/platform/ZhonTai.Admin/Core/Auth/UserIdentiyServer.cs
  4. 5 0
      src/platform/ZhonTai.Admin/Core/Configs/AppConfig.cs
  5. 5 0
      src/platform/ZhonTai.Admin/Core/Consts/AdminConsts.cs
  6. 7 5
      src/platform/ZhonTai.Admin/Core/Dto/IResultOutput.cs
  7. 5 8
      src/platform/ZhonTai.Admin/Core/Dto/ResultOutput.cs
  8. 3 12
      src/platform/ZhonTai.Admin/Core/HostApp.cs
  9. 8 34
      src/platform/ZhonTai.Admin/Domain/Employee/EmployeeEntity.cs
  10. 2 1
      src/platform/ZhonTai.Admin/HttpApi/AreaController.cs
  11. 2 1
      src/platform/ZhonTai.Admin/Services/Api/ApiService.cs
  12. 244 245
      src/platform/ZhonTai.Admin/Services/Auth/AuthService.cs
  13. 2 1
      src/platform/ZhonTai.Admin/Services/Cache/CacheService.cs
  14. 2 1
      src/platform/ZhonTai.Admin/Services/Dictionary/DictionaryService.cs
  15. 2 1
      src/platform/ZhonTai.Admin/Services/DictionaryType/DictionaryTypeService.cs
  16. 2 1
      src/platform/ZhonTai.Admin/Services/Document/DocumentService.cs
  17. 4 7
      src/platform/ZhonTai.Admin/Services/Employee/EmployeeService.cs
  18. 0 1
      src/platform/ZhonTai.Admin/Services/Employee/IEmployeeService.cs
  19. 2 2
      src/platform/ZhonTai.Admin/Services/Employee/_MapConfig.cs
  20. 2 1
      src/platform/ZhonTai.Admin/Services/LoginLog/LoginLogService.cs
  21. 2 1
      src/platform/ZhonTai.Admin/Services/OprationLog/OprationLogService.cs
  22. 1 1
      src/platform/ZhonTai.Admin/Services/Permission/PermissionService.cs
  23. 2 1
      src/platform/ZhonTai.Admin/Services/Role/RoleService.cs
  24. 28 0
      src/platform/ZhonTai.Admin/Services/TaskScheduler/Dto/TaskSchedulerAddInput.cs
  25. 7 0
      src/platform/ZhonTai.Admin/Services/TaskScheduler/Dto/TaskSchedulerGetOutput.cs
  26. 10 0
      src/platform/ZhonTai.Admin/Services/TaskScheduler/Dto/TaskSchedulerGetPageDto.cs
  27. 37 0
      src/platform/ZhonTai.Admin/Services/TaskScheduler/Dto/TaskSchedulerListOutput.cs
  28. 18 0
      src/platform/ZhonTai.Admin/Services/TaskScheduler/Dto/TaskSchedulerUpdateInput.cs
  29. 25 0
      src/platform/ZhonTai.Admin/Services/TaskScheduler/ITaskSchedulerService.cs
  30. 132 0
      src/platform/ZhonTai.Admin/Services/TaskScheduler/TaskSchedulerService.cs
  31. 2 1
      src/platform/ZhonTai.Admin/Services/Tenant/TenantService.cs
  32. 256 257
      src/platform/ZhonTai.Admin/Services/User/UserService.cs
  33. 3 4
      src/platform/ZhonTai.Admin/Services/View/ViewService.cs
  34. 162 65
      src/platform/ZhonTai.Admin/ZhonTai.Admin.xml
  35. 1 1
      src/platform/ZhonTai.Common/Helpers/ConfigHelper.cs

+ 6 - 4
src/hosts/ZhonTai.Host/Configs/appconfig.json

@@ -8,7 +8,7 @@
   //程序集名称
   "assemblyNames": [ "ZhonTai.Admin" ],
   //租户
-  "Tenant": true,
+  "tenant": true,
   //Swagger文档
   "swagger": {
     //启用
@@ -35,9 +35,9 @@
     }
   },
   //MiniProfiler性能分析器
-  "MiniProfiler": false,
+  "miniProfiler": false,
   //统一认证授权服务器
-  "IdentityServer": {
+  "identityServer": {
     //启用
     "enable": false,
     //地址,开发认证地址前往appconfig.Development.json修改
@@ -61,5 +61,7 @@
     "enable": true,
     //字体列表
     "fonts": [ "Times New Roman", "Verdana", "Arial", "Gungsuh", "Impact" ]
-  }
+  },
+  //默认密码
+  "defaultPassword": "111111"
 }

+ 1 - 6
src/platform/ZhonTai.Admin/Core/Auth/ClaimAttributes.cs

@@ -8,12 +8,7 @@
         /// <summary>
         /// 用户Id
         /// </summary>
-        public const string UserId = "id";
-
-        /// <summary>
-        /// 认证授权用户Id
-        /// </summary>
-        public const string IdentityServerUserId = "sub";
+        public const string UserId = "sub";
 
         /// <summary>
         /// 用户名

+ 0 - 34
src/platform/ZhonTai.Admin/Core/Auth/UserIdentiyServer.cs

@@ -1,34 +0,0 @@
-using Microsoft.AspNetCore.Http;
-using ZhonTai.Common.Extensions;
-
-namespace ZhonTai.Admin.Core.Auth
-{
-    /// <summary>
-    /// 用户信息
-    /// </summary>
-    public class UserIdentiyServer : User
-    {
-        private readonly IHttpContextAccessor _accessor;
-
-        public UserIdentiyServer(IHttpContextAccessor accessor) : base(accessor)
-        {
-            _accessor = accessor;
-        }
-
-        /// <summary>
-        /// 用户Id
-        /// </summary>
-        public override long Id
-        {
-            get
-            {
-                var id = _accessor?.HttpContext?.User?.FindFirst(ClaimAttributes.IdentityServerUserId);
-                if (id != null && id.Value.NotNull())
-                {
-                    return id.Value.ToLong();
-                }
-                return 0;
-            }
-        }
-    }
-}

+ 5 - 0
src/platform/ZhonTai.Admin/Core/Configs/AppConfig.cs

@@ -68,6 +68,11 @@ namespace ZhonTai.Admin.Core.Configs
         /// 验证码配置
         /// </summary>
         public VarifyCodeConfig VarifyCode { get; set; } = new VarifyCodeConfig();
+
+        /// <summary>
+        /// 默认密码
+        /// </summary>
+        public string DefaultPassword { get; set; } = "111111";
     }
 
     /// <summary>

+ 5 - 0
src/platform/ZhonTai.Admin/Core/Consts/AdminConsts.cs

@@ -2,6 +2,11 @@
 {
     public static partial class AdminConsts
     {
+        /// <summary>
+        /// 默认域
+        /// </summary>
+        public const string AreaName = "admin";
+
         /// <summary>
         /// 默认租户
         /// </summary>

+ 7 - 5
src/platform/ZhonTai.Admin/Core/Dto/IResultOutput.cs

@@ -1,6 +1,4 @@
-using System.Text.Json.Serialization;
-
-namespace ZhonTai.Admin.Core.Dto
+namespace ZhonTai.Admin.Core.Dto
 {
     /// <summary>
     /// 结果输出接口
@@ -10,13 +8,17 @@ namespace ZhonTai.Admin.Core.Dto
         /// <summary>
         /// 是否成功
         /// </summary>
-        [JsonIgnore]
         bool Success { get; }
 
         /// <summary>
         /// 消息
         /// </summary>
-        public string Msg { get; }
+        string Msg { get; }
+
+        /// <summary>
+        /// 编码
+        /// </summary>
+        string Code { get; set; }
     }
 
     /// <summary>

+ 5 - 8
src/platform/ZhonTai.Admin/Core/Dto/ResultOutput.cs

@@ -1,6 +1,4 @@
-using Newtonsoft.Json;
-
-namespace ZhonTai.Admin.Core.Dto
+namespace ZhonTai.Admin.Core.Dto
 {
     /// <summary>
     /// 结果输出
@@ -10,13 +8,12 @@ namespace ZhonTai.Admin.Core.Dto
         /// <summary>
         /// 是否成功标记
         /// </summary>
-        [JsonIgnore]
         public bool Success { get; private set; }
 
         /// <summary>
-        /// 状态
+        /// 
         /// </summary>
-        public int Code => Success ? 1 : 0;
+        public string Code { get; set; }
 
         /// <summary>
         /// 消息
@@ -48,7 +45,7 @@ namespace ZhonTai.Admin.Core.Dto
         /// <param name="msg">消息</param>
         /// <param name="data">数据</param>
         /// <returns></returns>
-        public ResultOutput<T> NotOk(string msg = null, T data = default(T))
+        public ResultOutput<T> NotOk(string msg = null, T data = default)
         {
             Success = false;
             Msg = msg;
@@ -89,7 +86,7 @@ namespace ZhonTai.Admin.Core.Dto
         /// <param name="msg">消息</param>
         /// <param name="data">数据</param>
         /// <returns></returns>
-        public static IResultOutput NotOk<T>(string msg = null, T data = default(T))
+        public static IResultOutput NotOk<T>(string msg = null, T data = default)
         {
             return new ResultOutput<T>().NotOk(msg, data);
         }

+ 3 - 12
src/platform/ZhonTai.Admin/Core/HostApp.cs

@@ -72,10 +72,10 @@ namespace ZhonTai.Admin.Core
             //添加配置
             builder.Host.ConfigureAppConfiguration((context, builder) =>
             {
-                builder.AddJsonFile("./configs/ratelimitconfig.json", optional: true, reloadOnChange: true);
+                builder.AddJsonFile("./Configs/ratelimitconfig.json", optional: true, reloadOnChange: true);
                 if (context.HostingEnvironment.EnvironmentName.NotNull())
                 {
-                    builder.AddJsonFile($"./configs/ratelimitconfig.{context.HostingEnvironment.EnvironmentName}.json", optional: true, reloadOnChange: true);
+                    builder.AddJsonFile($"./Configs/ratelimitconfig.{context.HostingEnvironment.EnvironmentName}.json", optional: true, reloadOnChange: true);
                 }
                 builder.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
                 if (context.HostingEnvironment.EnvironmentName.NotNull())
@@ -165,16 +165,7 @@ namespace ZhonTai.Admin.Core
 
             //用户信息
             services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
-            if (appConfig.IdentityServer.Enable)
-            {
-                //is4
-                services.TryAddSingleton<IUser, UserIdentiyServer>();
-            }
-            else
-            {
-                //jwt
-                services.TryAddSingleton<IUser, User>();
-            }
+            services.TryAddSingleton<IUser, User>();
 
             //添加数据库
             services.AddDbAsync(env, _hostAppOptions).Wait();

+ 8 - 34
src/platform/ZhonTai.Admin/Domain/Employee/EmployeeEntity.cs

@@ -3,7 +3,6 @@ using FreeSql.DataAnnotations;
 using System;
 using System.Collections.Generic;
 using ZhonTai.Admin.Domain.Organization;
-using ZhonTai.Admin.Domain.Position;
 
 namespace ZhonTai.Admin.Domain.Employee
 {
@@ -11,7 +10,7 @@ namespace ZhonTai.Admin.Domain.Employee
     /// 员工
     /// </summary>
 	[Table(Name = "ad_employee")]
-    [Index("idx_{tablename}_01", nameof(Code) + "," + nameof(TenantId), true)]
+    [Index("idx_{tablename}_01", nameof(JobNumber) + "," + nameof(TenantId), true)]
     public partial class EmployeeEntity : EntityFull, ITenant
     {
         /// <summary>
@@ -25,18 +24,6 @@ namespace ZhonTai.Admin.Domain.Employee
         /// </summary>
         public long? UserId { get; set; }
 
-        /// <summary>
-        /// 姓名
-        /// </summary>
-        [Column(StringLength = 20)]
-        public string Name { get; set; }
-
-        /// <summary>
-        /// 昵称
-        /// </summary>
-        [Column(StringLength = 20)]
-        public string NickName { get; set; }
-
         /// <summary>
         /// 性别
         /// </summary>
@@ -46,33 +33,20 @@ namespace ZhonTai.Admin.Domain.Employee
         /// 工号
         /// </summary>
         [Column(StringLength = 20)]
-        public string Code { get; set; }
+        public string JobNumber { get; set; }
 
         /// <summary>
         /// 主属部门Id
         /// </summary>
-        public long OrganizationId { get; set; }
+        public long MainOrgId { get; set; }
 
-        public OrganizationEntity Organization { get; set; }
-
-        /// <summary>
-        /// 职位Id
-        /// </summary>
-        public long PositionId { get; set; }
-
-        public PositionEntity Position { get; set; }
-
-        /// <summary>
-        /// 手机号
-        /// </summary>
-        [Column(StringLength = 20)]
-        public string Phone { get; set; }
+        public OrganizationEntity MainOrg { get; set; }
 
         /// <summary>
-        /// 邮箱
+        /// 职位
         /// </summary>
-        [Column(StringLength = 250)]
-        public string Email { get; set; }
+        [Column(OldName = "PositionId")]
+        public string Position { get; set; }
 
         /// <summary>
         /// 入职时间
@@ -80,6 +54,6 @@ namespace ZhonTai.Admin.Domain.Employee
         public DateTime? EntryTime { get; set; }
 
         [Navigate(ManyToMany = typeof(EmployeeOrganizationEntity))]
-        public ICollection<OrganizationEntity> Organizations { get; set; }
+        public ICollection<OrganizationEntity> Orgs { get; set; }
     }
 }

+ 2 - 1
src/platform/ZhonTai.Admin/HttpApi/AreaController.cs

@@ -1,12 +1,13 @@
 using Microsoft.AspNetCore.Mvc;
 using ZhonTai.Admin.Core;
+using ZhonTai.Admin.Core.Consts;
 
 namespace ZhonTai.Admin.HttpApi
 {
     /// <summary>
     /// 域控制器
     /// </summary>
-    [Area("Admin")]
+    [Area(AdminConsts.AreaName)]
     public abstract class AreaController : BaseController
     {
     }

+ 2 - 1
src/platform/ZhonTai.Admin/Services/Api/ApiService.cs

@@ -9,13 +9,14 @@ using ZhonTai.Admin.Services.Api.Dto;
 using ZhonTai.Admin.Domain.Api.Dto;
 using ZhonTai.DynamicApi;
 using ZhonTai.DynamicApi.Attributes;
+using ZhonTai.Admin.Core.Consts;
 
 namespace ZhonTai.Admin.Services.Api
 {
     /// <summary>
     /// 接口服务
     /// </summary>
-    [DynamicApi(Area = "admin")]
+    [DynamicApi(Area = AdminConsts.AreaName)]
     public class ApiService : BaseService, IApiService, IDynamicApi
     {
         private readonly IApiRepository _apiRepository;

+ 244 - 245
src/platform/ZhonTai.Admin/Services/Auth/AuthService.cs

@@ -31,304 +31,303 @@ using System.Text;
 using Microsoft.IdentityModel.Tokens;
 using Microsoft.IdentityModel.JsonWebTokens;
 
-namespace ZhonTai.Admin.Services.Auth
+namespace ZhonTai.Admin.Services.Auth;
+
+/// <summary>
+/// 认证授权服务
+/// </summary>
+[DynamicApi(Area = AdminConsts.AreaName)]
+public class AuthService : BaseService, IAuthService, IDynamicApi
 {
+    private readonly AppConfig _appConfig;
+    private readonly JwtConfig _jwtConfig;
+    private readonly IPermissionRepository _permissionRepository;
+    private readonly IUserRepository _userRepository;
+    private readonly ITenantRepository _tenantRepository;
+    private readonly ICaptchaTool _captchaTool;
+
+    public AuthService(
+        AppConfig appConfig,
+        JwtConfig jwtConfig,
+        IUserRepository userRepository,
+        IPermissionRepository permissionRepository,
+        ITenantRepository tenantRepository,
+        ICaptchaTool captchaTool
+    )
+    {
+        _appConfig = appConfig;
+        _jwtConfig = jwtConfig;
+        _userRepository = userRepository;
+        _permissionRepository = permissionRepository;
+        _tenantRepository = tenantRepository;
+        _captchaTool = captchaTool;
+    }
+
     /// <summary>
-    /// 认证授权服务
+    /// 获得token
     /// </summary>
-    [DynamicApi(Area = "admin")]
-    public class AuthService : BaseService, IAuthService, IDynamicApi
+    /// <param name="user">用户信息</param>
+    /// <returns></returns>
+    private string GetToken(AuthLoginOutput user)
     {
-        private readonly AppConfig _appConfig;
-        private readonly JwtConfig _jwtConfig;
-        private readonly IPermissionRepository _permissionRepository;
-        private readonly IUserRepository _userRepository;
-        private readonly ITenantRepository _tenantRepository;
-        private readonly ICaptchaTool _captchaTool;
-
-        public AuthService(
-            AppConfig appConfig,
-            JwtConfig jwtConfig,
-            IUserRepository userRepository,
-            IPermissionRepository permissionRepository,
-            ITenantRepository tenantRepository,
-            ICaptchaTool captchaTool
-        )
+        if (user == null)
         {
-            _appConfig = appConfig;
-            _jwtConfig = jwtConfig;
-            _userRepository = userRepository;
-            _permissionRepository = permissionRepository;
-            _tenantRepository = tenantRepository;
-            _captchaTool = captchaTool;
+            return string.Empty;
         }
 
-        /// <summary>
-        /// 获得token
-        /// </summary>
-        /// <param name="user">用户信息</param>
-        /// <returns></returns>
-        private string GetToken(AuthLoginOutput user)
+        var token = LazyGetRequiredService<IUserToken>().Create(new[]
         {
-            if (user == null)
-            {
-                return string.Empty;
-            }
+            new Claim(ClaimAttributes.UserId, user.Id.ToString()),
+            new Claim(ClaimAttributes.UserName, user.UserName),
+            new Claim(ClaimAttributes.UserNickName, user.NickName),
+            new Claim(ClaimAttributes.TenantId, user.TenantId.ToString()),
+            new Claim(ClaimAttributes.TenantType, user.TenantType.ToString()),
+            new Claim(ClaimAttributes.DataIsolationType, user.DataIsolationType.ToString())
+        });
+
+        return token;
+    }
 
-            var token = LazyGetRequiredService<IUserToken>().Create(new[]
-            {
-                new Claim(ClaimAttributes.UserId, user.Id.ToString()),
-                new Claim(ClaimAttributes.UserName, user.UserName),
-                new Claim(ClaimAttributes.UserNickName, user.NickName),
-                new Claim(ClaimAttributes.TenantId, user.TenantId.ToString()),
-                new Claim(ClaimAttributes.TenantType, user.TenantType.ToString()),
-                new Claim(ClaimAttributes.DataIsolationType, user.DataIsolationType.ToString())
-            });
-
-            return token;
-        }
+    /// <summary>
+    /// 查询密钥
+    /// </summary>
+    /// <returns></returns>
+    [HttpGet]
+    [AllowAnonymous]
+    [NoOprationLog]
+    public async Task<IResultOutput> GetPasswordEncryptKeyAsync()
+    {
+        //写入Redis
+        var guid = Guid.NewGuid().ToString("N");
+        var key = string.Format(CacheKeys.PassWordEncryptKey, guid);
+        var encyptKey = StringHelper.GenerateRandom(8);
+        await Cache.SetAsync(key, encyptKey, TimeSpan.FromMinutes(5));
+        var data = new { key = guid, encyptKey };
+
+        return ResultOutput.Ok(data);
+    }
 
-        /// <summary>
-        /// 查询密钥
-        /// </summary>
-        /// <returns></returns>
-        [HttpGet]
-        [AllowAnonymous]
-        [NoOprationLog]
-        public async Task<IResultOutput> GetPasswordEncryptKeyAsync()
+    /// <summary>
+    /// 查询用户信息
+    /// </summary>
+    /// <returns></returns>
+    [Login]
+    public async Task<IResultOutput> GetUserInfoAsync()
+    {
+        if (!(User?.Id > 0))
         {
-            //写入Redis
-            var guid = Guid.NewGuid().ToString("N");
-            var key = string.Format(CacheKeys.PassWordEncryptKey, guid);
-            var encyptKey = StringHelper.GenerateRandom(8);
-            await Cache.SetAsync(key, encyptKey, TimeSpan.FromMinutes(5));
-            var data = new { key = guid, encyptKey };
-
-            return ResultOutput.Ok(data);
+            return ResultOutput.NotOk("未登录!");
         }
 
-        /// <summary>
-        /// 查询用户信息
-        /// </summary>
-        /// <returns></returns>
-        [Login]
-        public async Task<IResultOutput> GetUserInfoAsync()
+        var authUserInfoOutput = new AuthUserInfoOutput
         {
-            if (!(User?.Id > 0))
-            {
-                return ResultOutput.NotOk("未登录!");
-            }
-
-            var authUserInfoOutput = new AuthUserInfoOutput
-            {
-                //用户信息
-                User = await _userRepository.GetAsync<AuthUserProfileDto>(User.Id),
-
-                //用户菜单
-                Menus = await _permissionRepository.Select
-                .Where(a => new[] { PermissionTypeEnum.Group, PermissionTypeEnum.Menu }.Contains(a.Type))
-                .Where(a =>
-                    _permissionRepository.Orm.Select<RolePermissionEntity>()
-                    .InnerJoin<UserRoleEntity>((b, c) => b.RoleId == c.RoleId && c.UserId == User.Id)
-                    .Where(b => b.PermissionId == a.Id)
-                    .Any()
-                )
-                .OrderBy(a => a.ParentId)
-                .OrderBy(a => a.Sort)
-                .ToListAsync(a => new AuthUserMenuDto { ViewPath = a.View.Path }),
-
-                //用户权限点
-                Permissions = await _permissionRepository.Select
-                .Where(a => a.Type == PermissionTypeEnum.Dot)
-                .Where(a =>
-                    _permissionRepository.Orm.Select<RolePermissionEntity>()
-                    .InnerJoin<UserRoleEntity>((b, c) => b.RoleId == c.RoleId && c.UserId == User.Id)
-                    .Where(b => b.PermissionId == a.Id)
-                    .Any()
-                )
-                .ToListAsync(a => a.Code)
-            };
-
-            return ResultOutput.Ok(authUserInfoOutput);
-        }
+            //用户信息
+            User = await _userRepository.GetAsync<AuthUserProfileDto>(User.Id),
+
+            //用户菜单
+            Menus = await _permissionRepository.Select
+            .Where(a => new[] { PermissionTypeEnum.Group, PermissionTypeEnum.Menu }.Contains(a.Type))
+            .Where(a =>
+                _permissionRepository.Orm.Select<RolePermissionEntity>()
+                .InnerJoin<UserRoleEntity>((b, c) => b.RoleId == c.RoleId && c.UserId == User.Id)
+                .Where(b => b.PermissionId == a.Id)
+                .Any()
+            )
+            .OrderBy(a => a.ParentId)
+            .OrderBy(a => a.Sort)
+            .ToListAsync(a => new AuthUserMenuDto { ViewPath = a.View.Path }),
+
+            //用户权限点
+            Permissions = await _permissionRepository.Select
+            .Where(a => a.Type == PermissionTypeEnum.Dot)
+            .Where(a =>
+                _permissionRepository.Orm.Select<RolePermissionEntity>()
+                .InnerJoin<UserRoleEntity>((b, c) => b.RoleId == c.RoleId && c.UserId == User.Id)
+                .Where(b => b.PermissionId == a.Id)
+                .Any()
+            )
+            .ToListAsync(a => a.Code)
+        };
+
+        return ResultOutput.Ok(authUserInfoOutput);
+    }
 
-        /// <summary>
-        /// 登录
-        /// </summary>
-        /// <param name="input"></param>
-        /// <returns></returns>
-        [HttpPost]
-        [AllowAnonymous]
-        [NoOprationLog]
-        public async Task<IResultOutput> LoginAsync(AuthLoginInput input)
-        {
-            var sw = new Stopwatch();
-            sw.Start();
+    /// <summary>
+    /// 登录
+    /// </summary>
+    /// <param name="input"></param>
+    /// <returns></returns>
+    [HttpPost]
+    [AllowAnonymous]
+    [NoOprationLog]
+    public async Task<IResultOutput> LoginAsync(AuthLoginInput input)
+    {
+        var sw = new Stopwatch();
+        sw.Start();
 
-            #region 验证码校验
+        #region 验证码校验
 
-            if (_appConfig.VarifyCode.Enable)
+        if (_appConfig.VarifyCode.Enable)
+        {
+            input.Captcha.DeleteCache = true;
+            input.Captcha.CaptchaKey = CacheKeys.CaptchaKey;
+            var isOk = await _captchaTool.CheckAsync(input.Captcha);
+            if (!isOk)
             {
-                input.Captcha.DeleteCache = true;
-                input.Captcha.CaptchaKey = CacheKeys.CaptchaKey;
-                var isOk = await _captchaTool.CheckAsync(input.Captcha);
-                if (!isOk)
-                {
-                    return ResultOutput.NotOk("安全验证不通过,请重新登录!");
-                }
+                return ResultOutput.NotOk("安全验证不通过,请重新登录!");
             }
+        }
 
-            #endregion 验证码校验
+        #endregion 验证码校验
 
-            UserEntity user = null;
+        UserEntity user = null;
 
-            user = await _userRepository.Select.DisableGlobalFilter("Tenant").Where(a => a.UserName == input.UserName).ToOneAsync();
+        user = await _userRepository.Select.DisableGlobalFilter("Tenant").Where(a => a.UserName == input.UserName).ToOneAsync();
 
-            if (!(user?.Id > 0))
-            {
-                return ResultOutput.NotOk("账号输入有误!", 3);
-            }
+        if (!(user?.Id > 0))
+        {
+            return ResultOutput.NotOk("账号输入有误!", 3);
+        }
 
-            #region 解密
+        #region 解密
 
-            if (input.PasswordKey.NotNull())
+        if (input.PasswordKey.NotNull())
+        {
+            var passwordEncryptKey = string.Format(CacheKeys.PassWordEncryptKey, input.PasswordKey);
+            var existsPasswordKey = await Cache.ExistsAsync(passwordEncryptKey);
+            if (existsPasswordKey)
             {
-                var passwordEncryptKey = string.Format(CacheKeys.PassWordEncryptKey, input.PasswordKey);
-                var existsPasswordKey = await Cache.ExistsAsync(passwordEncryptKey);
-                if (existsPasswordKey)
-                {
-                    var secretKey = await Cache.GetAsync(passwordEncryptKey);
-                    if (secretKey.IsNull())
-                    {
-                        return ResultOutput.NotOk("解密失败!", 1);
-                    }
-                    input.Password = DesEncrypt.Decrypt(input.Password, secretKey);
-                    await Cache.DelAsync(passwordEncryptKey);
-                }
-                else
+                var secretKey = await Cache.GetAsync(passwordEncryptKey);
+                if (secretKey.IsNull())
                 {
                     return ResultOutput.NotOk("解密失败!", 1);
                 }
+                input.Password = DesEncrypt.Decrypt(input.Password, secretKey);
+                await Cache.DelAsync(passwordEncryptKey);
             }
-
-            #endregion 解密
-
-            var password = MD5Encrypt.Encrypt32(input.Password);
-            if (user.Password != password)
+            else
             {
-                return ResultOutput.NotOk("密码输入有误!", 4);
+                return ResultOutput.NotOk("解密失败!", 1);
             }
+        }
 
-            var authLoginOutput = Mapper.Map<AuthLoginOutput>(user);
+        #endregion 解密
 
-            if (_appConfig.Tenant)
-            {
-                var tenant = await _tenantRepository.Select.DisableGlobalFilter("Tenant").WhereDynamic(user.TenantId).ToOneAsync(a => new { a.TenantType, a.DataIsolationType });
-                authLoginOutput.TenantType = tenant.TenantType;
-                authLoginOutput.DataIsolationType = tenant.DataIsolationType;
-            }
+        var password = MD5Encrypt.Encrypt32(input.Password);
+        if (user.Password != password)
+        {
+            return ResultOutput.NotOk("密码输入有误!", 4);
+        }
 
-            string token = GetToken(authLoginOutput);
+        var authLoginOutput = Mapper.Map<AuthLoginOutput>(user);
 
-            sw.Stop();
+        if (_appConfig.Tenant)
+        {
+            var tenant = await _tenantRepository.Select.DisableGlobalFilter("Tenant").WhereDynamic(user.TenantId).ToOneAsync(a => new { a.TenantType, a.DataIsolationType });
+            authLoginOutput.TenantType = tenant.TenantType;
+            authLoginOutput.DataIsolationType = tenant.DataIsolationType;
+        }
 
-            #region 添加登录日志
+        string token = GetToken(authLoginOutput);
 
-            var loginLogAddInput = new LoginLogAddInput
-            {
-                CreatedUserName = input.UserName,
-                ElapsedMilliseconds = sw.ElapsedMilliseconds,
-                Status = true,
-                CreatedUserId = authLoginOutput.Id,
-                NickName = authLoginOutput.NickName,
-                TenantId = authLoginOutput.TenantId
-            };
+        sw.Stop();
 
-            await LazyGetRequiredService<ILoginLogService>().AddAsync(loginLogAddInput);
+        #region 添加登录日志
 
-            #endregion 添加登录日志
+        var loginLogAddInput = new LoginLogAddInput
+        {
+            CreatedUserName = input.UserName,
+            ElapsedMilliseconds = sw.ElapsedMilliseconds,
+            Status = true,
+            CreatedUserId = authLoginOutput.Id,
+            NickName = authLoginOutput.NickName,
+            TenantId = authLoginOutput.TenantId
+        };
 
-            return ResultOutput.Ok(new { token });
-        }
+        await LazyGetRequiredService<ILoginLogService>().AddAsync(loginLogAddInput);
 
-        /// <summary>
-        /// 刷新Token
-        /// 以旧换新
-        /// </summary>
-        /// <param name="token"></param>
-        /// <returns></returns>
-        [HttpGet]
-        [AllowAnonymous]
-        public async Task<IResultOutput> Refresh([BindRequired] string token)
-        {
-            var jwtSecurityToken = LazyGetRequiredService<IUserToken>().Decode(token);
-            var userClaims = jwtSecurityToken?.Claims?.ToArray();
-            if (userClaims == null || userClaims.Length == 0)
-            {
-                return ResultOutput.NotOk();
-            }
+        #endregion 添加登录日志
 
-            var refreshExpires = userClaims.FirstOrDefault(a => a.Type == ClaimAttributes.RefreshExpires)?.Value;
-            if (refreshExpires.IsNull())
-            {
-                return ResultOutput.NotOk();
-            }
+        return ResultOutput.Ok(new { token });
+    }
 
-            if (refreshExpires.ToLong() <= DateTime.Now.ToTimestamp())
-            {
-                return ResultOutput.NotOk("登录信息已过期");
-            }
+    /// <summary>
+    /// 刷新Token
+    /// 以旧换新
+    /// </summary>
+    /// <param name="token"></param>
+    /// <returns></returns>
+    [HttpGet]
+    [AllowAnonymous]
+    public async Task<IResultOutput> Refresh([BindRequired] string token)
+    {
+        var jwtSecurityToken = LazyGetRequiredService<IUserToken>().Decode(token);
+        var userClaims = jwtSecurityToken?.Claims?.ToArray();
+        if (userClaims == null || userClaims.Length == 0)
+        {
+            return ResultOutput.NotOk();
+        }
 
-            var userId = userClaims.FirstOrDefault(a => a.Type == ClaimAttributes.UserId)?.Value;
-            if (userId.IsNull())
-            {
-                return ResultOutput.NotOk("登录信息已失效");
-            }
+        var refreshExpires = userClaims.FirstOrDefault(a => a.Type == ClaimAttributes.RefreshExpires)?.Value;
+        if (refreshExpires.IsNull())
+        {
+            return ResultOutput.NotOk();
+        }
 
-            //验签
-            var securityKey = _jwtConfig.SecurityKey;
-            var signingCredentials = new SigningCredentials(new SymmetricSecurityKey(Encoding.ASCII.GetBytes(securityKey)), SecurityAlgorithms.HmacSha256);
-            var input = jwtSecurityToken.RawHeader + "." + jwtSecurityToken.RawPayload;
-            if (jwtSecurityToken.RawSignature != JwtTokenUtilities.CreateEncodedSignature(input, signingCredentials))
-            {
-                return ResultOutput.NotOk("验签失败");
-            }
+        if (refreshExpires.ToLong() <= DateTime.Now.ToTimestamp())
+        {
+            return ResultOutput.NotOk("登录信息已过期");
+        }
 
-            var output = await LazyGetRequiredService<IUserService>().GetLoginUserAsync(userId.ToLong());
-            string newToken = GetToken(output?.Data);
-            return ResultOutput.Ok(new { token = newToken });
+        var userId = userClaims.FirstOrDefault(a => a.Type == ClaimAttributes.UserId)?.Value;
+        if (userId.IsNull())
+        {
+            return ResultOutput.NotOk("登录信息已失效");
         }
 
-        /// <summary>
-        /// 获取验证数据
-        /// </summary>
-        /// <returns></returns>
-        [HttpGet]
-        [AllowAnonymous]
-        [NoOprationLog]
-        [EnableCors(AdminConsts.AllowAnyPolicyName)]
-        public async Task<IResultOutput> GetCaptcha()
+        //验签
+        var securityKey = _jwtConfig.SecurityKey;
+        var signingCredentials = new SigningCredentials(new SymmetricSecurityKey(Encoding.ASCII.GetBytes(securityKey)), SecurityAlgorithms.HmacSha256);
+        var input = jwtSecurityToken.RawHeader + "." + jwtSecurityToken.RawPayload;
+        if (jwtSecurityToken.RawSignature != JwtTokenUtilities.CreateEncodedSignature(input, signingCredentials))
         {
-            using (MiniProfiler.Current.Step("获取滑块验证"))
-            {
-                var data = await _captchaTool.GetAsync(CacheKeys.CaptchaKey);
-                return ResultOutput.Ok(data);
-            }
+            return ResultOutput.NotOk("验签失败");
         }
 
-        /// <summary>
-        /// 检查验证数据
-        /// </summary>
-        /// <returns></returns>
-        [HttpGet]
-        [AllowAnonymous]
-        [NoOprationLog]
-        [EnableCors(AdminConsts.AllowAnyPolicyName)]
-        public async Task<IResultOutput> CheckCaptcha([FromQuery] CaptchaInput input)
+        var output = await LazyGetRequiredService<IUserService>().GetLoginUserAsync(userId.ToLong());
+        string newToken = GetToken(output?.Data);
+        return ResultOutput.Ok(new { token = newToken });
+    }
+
+    /// <summary>
+    /// 获取验证数据
+    /// </summary>
+    /// <returns></returns>
+    [HttpGet]
+    [AllowAnonymous]
+    [NoOprationLog]
+    [EnableCors(AdminConsts.AllowAnyPolicyName)]
+    public async Task<IResultOutput> GetCaptcha()
+    {
+        using (MiniProfiler.Current.Step("获取滑块验证"))
         {
-            input.CaptchaKey = CacheKeys.CaptchaKey;
-            var result = await _captchaTool.CheckAsync(input);
-            return ResultOutput.Result(result);
+            var data = await _captchaTool.GetAsync(CacheKeys.CaptchaKey);
+            return ResultOutput.Ok(data);
         }
     }
+
+    /// <summary>
+    /// 检查验证数据
+    /// </summary>
+    /// <returns></returns>
+    [HttpGet]
+    [AllowAnonymous]
+    [NoOprationLog]
+    [EnableCors(AdminConsts.AllowAnyPolicyName)]
+    public async Task<IResultOutput> CheckCaptcha([FromQuery] CaptchaInput input)
+    {
+        input.CaptchaKey = CacheKeys.CaptchaKey;
+        var result = await _captchaTool.CheckAsync(input);
+        return ResultOutput.Result(result);
+    }
 }

+ 2 - 1
src/platform/ZhonTai.Admin/Services/Cache/CacheService.cs

@@ -11,13 +11,14 @@ using ZhonTai.Admin.Core.Configs;
 using ZhonTai.Admin.Core.Dto;
 using ZhonTai.DynamicApi;
 using ZhonTai.DynamicApi.Attributes;
+using ZhonTai.Admin.Core.Consts;
 
 namespace ZhonTai.Admin.Services.Cache
 {
     /// <summary>
     /// 缓存服务
     /// </summary>
-    [DynamicApi(Area = "admin")]
+    [DynamicApi(Area = AdminConsts.AreaName)]
     public class CacheService : BaseService, ICacheService, IDynamicApi
     {
         public CacheService()

+ 2 - 1
src/platform/ZhonTai.Admin/Services/Dictionary/DictionaryService.cs

@@ -6,13 +6,14 @@ using ZhonTai.Admin.Domain.Dictionary.Dto;
 using ZhonTai.DynamicApi;
 using ZhonTai.DynamicApi.Attributes;
 using Microsoft.AspNetCore.Mvc;
+using ZhonTai.Admin.Core.Consts;
 
 namespace ZhonTai.Admin.Services.Dictionary
 {
     /// <summary>
     /// 数据字典服务
     /// </summary>
-    [DynamicApi(Area = "admin")]
+    [DynamicApi(Area = AdminConsts.AreaName)]
     public class DictionaryService : BaseService, IDictionaryService, IDynamicApi
     {
         private readonly IDictionaryRepository _dictionaryRepository;

+ 2 - 1
src/platform/ZhonTai.Admin/Services/DictionaryType/DictionaryTypeService.cs

@@ -9,13 +9,14 @@ using ZhonTai.Admin.Domain.DictionaryType.Dto;
 using ZhonTai.DynamicApi;
 using ZhonTai.DynamicApi.Attributes;
 using Microsoft.AspNetCore.Mvc;
+using ZhonTai.Admin.Core.Consts;
 
 namespace ZhonTai.Admin.Services.DictionaryType
 {
     /// <summary>
     /// 字典类型服务
     /// </summary>
-    [DynamicApi(Area = "admin")]
+    [DynamicApi(Area = AdminConsts.AreaName)]
     public class DictionaryTypeService : BaseService, IDictionaryTypeService, IDynamicApi
     {
         private readonly IDictionaryTypeRepository _DictionaryTypeRepository;

+ 2 - 1
src/platform/ZhonTai.Admin/Services/Document/DocumentService.cs

@@ -11,13 +11,14 @@ using ZhonTai.Admin.Services.Document.Dto;
 using ZhonTai.DynamicApi;
 using ZhonTai.DynamicApi.Attributes;
 using ZhonTai.Admin.Core.Helpers;
+using ZhonTai.Admin.Core.Consts;
 
 namespace ZhonTai.Admin.Services.Document
 {
     /// <summary>
     /// 文档服务
     /// </summary>
-    [DynamicApi(Area = "admin")]
+    [DynamicApi(Area = AdminConsts.AreaName)]
     public class DocumentService : BaseService, IDocumentService, IDynamicApi
     {
         private readonly IDocumentRepository _documentRepository;

+ 4 - 7
src/platform/ZhonTai.Admin/Services/Employee/EmployeeService.cs

@@ -5,7 +5,6 @@ using ZhonTai.Admin.Core.Dto;
 using ZhonTai.Admin.Domain;
 using ZhonTai.Admin.Services.Employee.Input;
 using ZhonTai.Admin.Services.Employee.Output;
-using ZhonTai.Admin.Services;
 using ZhonTai.Admin.Core.Repositories;
 using ZhonTai.Admin.Domain.Employee;
 using ZhonTai.Admin.Domain.Organization;
@@ -40,11 +39,10 @@ namespace ZhonTai.Admin.Services.Employee
 
             var dto = await _employeeRepository.Select
             .WhereDynamic(id)
-            .IncludeMany(a => a.Organizations.Select(b => new OrganizationEntity { Id = b.Id }))
+            .IncludeMany(a => a.Orgs.Select(b => new OrganizationEntity { Id = b.Id }))
             .ToOneAsync(a => new EmployeeGetOutput
             {
-                OrganizationName = a.Organization.Name,
-                PositionName = a.Position.Name
+                OrganizationName = a.MainOrg.Name
             });
 
             return res.Ok(dto);
@@ -61,12 +59,11 @@ namespace ZhonTai.Admin.Services.Employee
             .WhereDynamicFilter(input.DynamicFilter)
             .Count(out var total)
             .OrderByDescending(true, a => a.Id)
-            .IncludeMany(a => a.Organizations.Select(b => new OrganizationEntity { Name = b.Name }))
+            .IncludeMany(a => a.Orgs.Select(b => new OrganizationEntity { Name = b.Name }))
             .Page(input.CurrentPage, input.PageSize)
             .ToListAsync(a => new EmployeeListOutput 
             { 
-                OrganizationName = a.Organization.Name, 
-                PositionName = a.Position.Name
+                OrganizationName = a.MainOrg.Name
             });
 
             var data = new PageOutput<EmployeeListOutput>()

+ 0 - 1
src/platform/ZhonTai.Admin/Services/Employee/IEmployeeService.cs

@@ -2,7 +2,6 @@
 using ZhonTai.Admin.Core.Dto;
 using ZhonTai.Admin.Services.Employee.Input;
 using ZhonTai.Admin.Services.Employee.Output;
-using ZhonTai.Admin.Domain.Employee;
 
 namespace ZhonTai.Admin.Services.Employee
 {

+ 2 - 2
src/platform/ZhonTai.Admin/Services/Employee/_MapConfig.cs

@@ -14,11 +14,11 @@ namespace ZhonTai.Admin.Services.Employee
         {
             config
             .NewConfig<EmployeeEntity, EmployeeGetOutput>()
-            .Map(dest => dest.OrganizationIds, src => src.Organizations.Select(a => a.Id));
+            .Map(dest => dest.OrganizationIds, src => src.Orgs.Select(a => a.Id));
 
             config
             .NewConfig<EmployeeEntity, EmployeeListOutput>()
-            .Map(dest => dest.OrganizationNames, src => src.Organizations.Select(a => a.Name));
+            .Map(dest => dest.OrganizationNames, src => src.Orgs.Select(a => a.Name));
         }
     }
 }

+ 2 - 1
src/platform/ZhonTai.Admin/Services/LoginLog/LoginLogService.cs

@@ -8,13 +8,14 @@ using ZhonTai.Admin.Domain;
 using ZhonTai.DynamicApi;
 using ZhonTai.DynamicApi.Attributes;
 using Microsoft.AspNetCore.Mvc;
+using ZhonTai.Admin.Core.Consts;
 
 namespace ZhonTai.Admin.Services.LoginLog
 {
     /// <summary>
     /// 登录日志服务
     /// </summary>
-    [DynamicApi(Area = "admin")]
+    [DynamicApi(Area = AdminConsts.AreaName)]
     public class LoginLogService : BaseService, ILoginLogService, IDynamicApi
     {
         private readonly IHttpContextAccessor _context;

+ 2 - 1
src/platform/ZhonTai.Admin/Services/OprationLog/OprationLogService.cs

@@ -8,13 +8,14 @@ using ZhonTai.Admin.Domain;
 using ZhonTai.DynamicApi;
 using ZhonTai.DynamicApi.Attributes;
 using Microsoft.AspNetCore.Mvc;
+using ZhonTai.Admin.Core.Consts;
 
 namespace ZhonTai.Admin.Services.OprationLog
 {
     /// <summary>
     /// 操作日志服务
     /// </summary>
-    [DynamicApi(Area = "admin")]
+    [DynamicApi(Area = AdminConsts.AreaName)]
     public class OprationLogService : BaseService, IOprationLogService, IDynamicApi
     {
         private readonly IHttpContextAccessor _context;

+ 1 - 1
src/platform/ZhonTai.Admin/Services/Permission/PermissionService.cs

@@ -27,7 +27,7 @@ namespace ZhonTai.Admin.Services.Permission
     /// <summary>
     /// 权限服务
     /// </summary>
-    [DynamicApi(Area = "admin")]
+    [DynamicApi(Area = AdminConsts.AreaName)]
     public class PermissionService : BaseService, IPermissionService, IDynamicApi
     {
         private readonly AppConfig _appConfig;

+ 2 - 1
src/platform/ZhonTai.Admin/Services/Role/RoleService.cs

@@ -9,13 +9,14 @@ using ZhonTai.Admin.Domain.Role.Dto;
 using ZhonTai.DynamicApi;
 using ZhonTai.DynamicApi.Attributes;
 using Microsoft.AspNetCore.Mvc;
+using ZhonTai.Admin.Core.Consts;
 
 namespace ZhonTai.Admin.Services.Role
 {
     /// <summary>
     /// 角色服务
     /// </summary>
-    [DynamicApi(Area = "admin")]
+    [DynamicApi(Area = AdminConsts.AreaName)]
     public class RoleService : BaseService, IRoleService, IDynamicApi
     {
         private readonly IRoleRepository _roleRepository;

+ 28 - 0
src/platform/ZhonTai.Admin/Services/TaskScheduler/Dto/TaskSchedulerAddInput.cs

@@ -0,0 +1,28 @@
+namespace ZhonTai.Admin.Services.TaskScheduler.Dto
+{
+    /// <summary>
+    /// 添加
+    /// </summary>
+    public class TaskSchedulerAddInput
+    {
+        /// <summary>
+        /// 名称
+        /// </summary>
+        public string Name { get; set; }
+
+        /// <summary>
+        /// 编码
+        /// </summary>
+        public string Code { get; set; }
+
+        /// <summary>
+        /// 说明
+        /// </summary>
+        public string Description { get; set; }
+
+        /// <summary>
+        /// 启用
+        /// </summary>
+		public bool Enabled { get; set; }
+    }
+}

+ 7 - 0
src/platform/ZhonTai.Admin/Services/TaskScheduler/Dto/TaskSchedulerGetOutput.cs

@@ -0,0 +1,7 @@
+
+namespace ZhonTai.Admin.Services.TaskScheduler.Dto
+{
+    public class TaskSchedulerGetOutput : TaskSchedulerUpdateInput
+    {
+    }
+}

+ 10 - 0
src/platform/ZhonTai.Admin/Services/TaskScheduler/Dto/TaskSchedulerGetPageDto.cs

@@ -0,0 +1,10 @@
+namespace ZhonTai.Admin.Domain.TaskScheduler.Dto
+{
+    public partial class TaskSchedulerGetPageDto
+    {
+        /// <summary>
+        /// 名称
+        /// </summary>
+        public string Name { get; set; }
+    }
+}

+ 37 - 0
src/platform/ZhonTai.Admin/Services/TaskScheduler/Dto/TaskSchedulerListOutput.cs

@@ -0,0 +1,37 @@
+using System;
+
+namespace ZhonTai.Admin.Services.TaskScheduler.Dto
+{
+    public class TaskSchedulerListOutput
+    {
+        /// <summary>
+        /// 主键
+        /// </summary>
+        public long Id { get; set; }
+
+        /// <summary>
+        /// 名称
+        /// </summary>
+        public string Name { get; set; }
+
+        /// <summary>
+        /// 编码
+        /// </summary>
+        public string Code { get; set; }
+
+        /// <summary>
+        /// 说明
+        /// </summary>
+        public string Description { get; set; }
+
+        /// <summary>
+        /// 启用
+        /// </summary>
+		public bool Enabled { get; set; }
+
+        /// <summary>
+        /// 创建时间
+        /// </summary>
+        public DateTime? CreatedTime { get; set; }
+    }
+}

+ 18 - 0
src/platform/ZhonTai.Admin/Services/TaskScheduler/Dto/TaskSchedulerUpdateInput.cs

@@ -0,0 +1,18 @@
+namespace ZhonTai.Admin.Services.TaskScheduler.Dto
+{
+    /// <summary>
+    /// 修改
+    /// </summary>
+    public partial class TaskSchedulerUpdateInput : TaskSchedulerAddInput
+    {
+        /// <summary>
+        /// 接口Id
+        /// </summary>
+        public long Id { get; set; }
+
+        /// <summary>
+        /// 版本
+        /// </summary>
+        public long Version { get; set; }
+    }
+}

+ 25 - 0
src/platform/ZhonTai.Admin/Services/TaskScheduler/ITaskSchedulerService.cs

@@ -0,0 +1,25 @@
+using System.Threading.Tasks;
+using ZhonTai.Admin.Core.Dto;
+using ZhonTai.Admin.Domain.TaskScheduler.Dto;
+using ZhonTai.Admin.Services.TaskScheduler.Dto;
+
+namespace ZhonTai.Admin.Services.TaskScheduler
+{
+    /// <summary>
+    /// 任务调度接口
+    /// </summary>
+    public interface ITaskSchedulerService
+    {
+        Task<IResultOutput> GetAsync(long id);
+
+        Task<IResultOutput> GetPageAsync(PageInput<TaskSchedulerGetPageDto> input);
+
+        Task<IResultOutput> AddAsync(TaskSchedulerAddInput input);
+
+        Task<IResultOutput> UpdateAsync(TaskSchedulerUpdateInput input);
+
+        Task<IResultOutput> DeleteAsync(string id);
+
+        Task<IResultOutput> BatchSoftDeleteAsync(string[] ids);
+    }
+}

+ 132 - 0
src/platform/ZhonTai.Admin/Services/TaskScheduler/TaskSchedulerService.cs

@@ -0,0 +1,132 @@
+using System.Linq;
+using System.Threading.Tasks;
+using ZhonTai.Admin.Core.Repositories;
+using ZhonTai.Admin.Core.Dto;
+using ZhonTai.Admin.Services.TaskScheduler.Dto;
+using ZhonTai.Admin.Domain.TaskScheduler.Dto;
+using ZhonTai.DynamicApi;
+using ZhonTai.DynamicApi.Attributes;
+using Microsoft.AspNetCore.Mvc;
+using ZhonTai.Admin.Core.Consts;
+using FreeScheduler;
+
+namespace ZhonTai.Admin.Services.TaskScheduler
+{
+    /// <summary>
+    /// 任务调度服务
+    /// </summary>
+    [DynamicApi(Area = AdminConsts.AreaName)]
+    public class TaskSchedulerService : BaseService, ITaskSchedulerService, IDynamicApi
+    {
+        private IRepositoryBase<TaskInfo> _taskInfoRepository => LazyGetRequiredService<IRepositoryBase<TaskInfo>>();
+        private IRepositoryBase<TaskLog> _taskLogRepository => LazyGetRequiredService<IRepositoryBase<TaskLog>>();
+
+        public TaskSchedulerService()
+        {
+
+        }
+
+        /// <summary>
+        /// 查询任务调度
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        public async Task<IResultOutput> GetAsync(long id)
+        {
+            var result = await _taskInfoRepository.GetAsync<TaskSchedulerGetOutput>(id);
+            return ResultOutput.Ok(result);
+        }
+
+        /// <summary>
+        /// 查询任务调度列表
+        /// </summary>
+        /// <param name="input"></param>
+        /// <returns></returns>
+        [HttpPost]
+        public async Task<IResultOutput> GetPageAsync(PageInput<TaskSchedulerGetPageDto> input)
+        {
+            var key = input.Filter?.Name;
+
+            var list = await _taskInfoRepository.Select
+            .WhereDynamicFilter(input.DynamicFilter)
+            .WhereIf(key.NotNull(), a => a.Topic.Contains(key))
+            .Count(out var total)
+            .OrderByDescending(true, c => c.Id)
+            .Page(input.CurrentPage, input.PageSize)
+            .ToListAsync<TaskSchedulerListOutput>();
+
+            var data = new PageOutput<TaskSchedulerListOutput>()
+            {
+                List = list,
+                Total = total
+            };
+
+            return ResultOutput.Ok(data);
+        }
+
+        /// <summary>
+        /// 新增
+        /// </summary>
+        /// <param name="input"></param>
+        /// <returns></returns>
+        public async Task<IResultOutput> AddAsync(TaskSchedulerAddInput input)
+        {
+            var entity = Mapper.Map<TaskInfo>(input);
+            await _taskInfoRepository.InsertAsync(entity);
+            return ResultOutput.Ok();
+        }
+
+        /// <summary>
+        /// 修改
+        /// </summary>
+        /// <param name="input"></param>
+        /// <returns></returns>
+        public async Task<IResultOutput> UpdateAsync(TaskSchedulerUpdateInput input)
+        {
+            if (!(input?.Id > 0))
+            {
+                return ResultOutput.NotOk();
+            }
+
+            var entity = await _taskInfoRepository.GetAsync(input.Id);
+            if (entity != null && entity.Id.NotNull())
+            {
+                return ResultOutput.NotOk("任务调度不存在!");
+            }
+
+            Mapper.Map(input, entity);
+            await _taskInfoRepository.UpdateAsync(entity);
+            return ResultOutput.Ok();
+        }
+
+        /// <summary>
+        /// 彻底删除
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        public async Task<IResultOutput> DeleteAsync(string id)
+        {
+            if (id.NotNull())
+            {
+                await _taskInfoRepository.DeleteAsync(m => m.Id == id);
+            }
+
+            return ResultOutput.Ok();
+        }
+
+        /// <summary>
+        /// 批量删除
+        /// </summary>
+        /// <param name="ids"></param>
+        /// <returns></returns>
+        public async Task<IResultOutput> BatchSoftDeleteAsync(string[] ids)
+        {
+            if(ids?.Length > 0)
+            {
+                await _taskInfoRepository.DeleteAsync(a => ids.Contains(a.Id));
+            }
+
+            return ResultOutput.Ok();
+        }
+    }
+}

+ 2 - 1
src/platform/ZhonTai.Admin/Services/Tenant/TenantService.cs

@@ -14,13 +14,14 @@ using ZhonTai.Admin.Domain.Tenant.Dto;
 using ZhonTai.DynamicApi;
 using ZhonTai.DynamicApi.Attributes;
 using Microsoft.AspNetCore.Mvc;
+using ZhonTai.Admin.Core.Consts;
 
 namespace ZhonTai.Admin.Services.Tenant
 {
     /// <summary>
     /// 租户服务
     /// </summary>
-    [DynamicApi(Area = "admin")]
+    [DynamicApi(Area = AdminConsts.AreaName)]
     public class TenantService : BaseService, ITenantService, IDynamicApi
     {
         private readonly ITenantRepository _tenantRepository;

+ 256 - 257
src/platform/ZhonTai.Admin/Services/User/UserService.cs

@@ -23,317 +23,316 @@ using Microsoft.Extensions.Options;
 using ZhonTai.Admin.Core.Helpers;
 using ZhonTai.Admin.Core.Consts;
 
-namespace ZhonTai.Admin.Services.User
+namespace ZhonTai.Admin.Services.User;
+
+/// <summary>
+/// 用户服务
+/// </summary>
+[DynamicApi(Area = AdminConsts.AreaName)]
+public class UserService : BaseService, IUserService, IDynamicApi
 {
+    private readonly AppConfig _appConfig;
+    private readonly IUserRepository _userRepository;
+    private readonly IRepositoryBase<UserRoleEntity> _userRoleRepository;
+    private readonly ITenantRepository _tenantRepository;
+    private readonly IApiRepository _apiRepository;
+
+    private IRoleRepository _roleRepository => LazyGetRequiredService<IRoleRepository>();
+
+    public UserService(
+        AppConfig appConfig,
+        IUserRepository userRepository,
+        IRepositoryBase<UserRoleEntity> userRoleRepository,
+        ITenantRepository tenantRepository,
+        IApiRepository apiRepository
+    )
+    {
+        _appConfig = appConfig;
+        _userRepository = userRepository;
+        _userRoleRepository = userRoleRepository;
+        _tenantRepository = tenantRepository;
+        _apiRepository = apiRepository;
+    }
+
     /// <summary>
-    /// 用户服务
+    /// 查询用户
     /// </summary>
-    [DynamicApi(Area = "admin")]
-    public class UserService : BaseService, IUserService, IDynamicApi
+    /// <param name="id"></param>
+    /// <returns></returns>
+    public async Task<IResultOutput> GetAsync(long id)
     {
-        private readonly AppConfig _appConfig;
-        private readonly IUserRepository _userRepository;
-        private readonly IRepositoryBase<UserRoleEntity> _userRoleRepository;
-        private readonly ITenantRepository _tenantRepository;
-        private readonly IApiRepository _apiRepository;
-
-        private IRoleRepository _roleRepository => LazyGetRequiredService<IRoleRepository>();
-
-        public UserService(
-            AppConfig appConfig,
-            IUserRepository userRepository,
-            IRepositoryBase<UserRoleEntity> userRoleRepository,
-            ITenantRepository tenantRepository,
-            IApiRepository apiRepository
-        )
-        {
-            _appConfig = appConfig;
-            _userRepository = userRepository;
-            _userRoleRepository = userRoleRepository;
-            _tenantRepository = tenantRepository;
-            _apiRepository = apiRepository;
-        }
-
-        /// <summary>
-        /// 查询用户
-        /// </summary>
-        /// <param name="id"></param>
-        /// <returns></returns>
-        public async Task<IResultOutput> GetAsync(long id)
-        {
-            var entity = await _userRepository.Select
-            .WhereDynamic(id)
-            .IncludeMany(a => a.Roles.Select(b => new RoleEntity { Id = b.Id }))
-            .ToOneAsync();
+        var entity = await _userRepository.Select
+        .WhereDynamic(id)
+        .IncludeMany(a => a.Roles.Select(b => new RoleEntity { Id = b.Id }))
+        .ToOneAsync();
 
-            var roles = await _roleRepository.Select.ToListAsync(a => new { a.Id, a.Name });
+        var roles = await _roleRepository.Select.ToListAsync(a => new { a.Id, a.Name });
 
-            return ResultOutput.Ok(new { Form = Mapper.Map<UserGetOutput>(entity), Select = new { roles } });
-        }
+        return ResultOutput.Ok(new { Form = Mapper.Map<UserGetOutput>(entity), Select = new { roles } });
+    }
 
-        /// <summary>
-        /// 查询分页
-        /// </summary>
-        /// <param name="input"></param>
-        /// <returns></returns>
-        [HttpPost]
-        public async Task<IResultOutput> GetPageAsync(PageInput input)
+    /// <summary>
+    /// 查询分页
+    /// </summary>
+    /// <param name="input"></param>
+    /// <returns></returns>
+    [HttpPost]
+    public async Task<IResultOutput> GetPageAsync(PageInput input)
+    {
+        var list = await _userRepository.Select
+        .WhereDynamicFilter(input.DynamicFilter)
+        .Count(out var total)
+        .OrderByDescending(true, a => a.Id)
+        .IncludeMany(a => a.Roles.Select(b => new RoleEntity { Name = b.Name }))
+        .Page(input.CurrentPage, input.PageSize)
+        .ToListAsync();
+
+        var data = new PageOutput<UserListOutput>()
         {
-            var list = await _userRepository.Select
-            .WhereDynamicFilter(input.DynamicFilter)
-            .Count(out var total)
-            .OrderByDescending(true, a => a.Id)
-            .IncludeMany(a => a.Roles.Select(b => new RoleEntity { Name = b.Name }))
-            .Page(input.CurrentPage, input.PageSize)
-            .ToListAsync();
-
-            var data = new PageOutput<UserListOutput>()
-            {
-                List = Mapper.Map<List<UserListOutput>>(list),
-                Total = total
-            };
+            List = Mapper.Map<List<UserListOutput>>(list),
+            Total = total
+        };
 
-            return ResultOutput.Ok(data);
-        }
+        return ResultOutput.Ok(data);
+    }
 
-        /// <summary>
-        /// 查询登录用户信息
-        /// </summary>
-        /// <param name="id"></param>
-        /// <returns></returns>
-        public async Task<ResultOutput<AuthLoginOutput>> GetLoginUserAsync(long id)
+    /// <summary>
+    /// 查询登录用户信息
+    /// </summary>
+    /// <param name="id"></param>
+    /// <returns></returns>
+    public async Task<ResultOutput<AuthLoginOutput>> GetLoginUserAsync(long id)
+    {
+        var output = new ResultOutput<AuthLoginOutput>();
+        var entityDto = await _userRepository.Select.DisableGlobalFilter("Tenant").WhereDynamic(id).ToOneAsync<AuthLoginOutput>();
+        if (_appConfig.Tenant && entityDto?.TenantId.Value > 0)
         {
-            var output = new ResultOutput<AuthLoginOutput>();
-            var entityDto = await _userRepository.Select.DisableGlobalFilter("Tenant").WhereDynamic(id).ToOneAsync<AuthLoginOutput>();
-            if (_appConfig.Tenant && entityDto?.TenantId.Value > 0)
+            var tenant = await _tenantRepository.Select.DisableGlobalFilter("Tenant").WhereDynamic(entityDto.TenantId).ToOneAsync(a => new { a.TenantType, a.DataIsolationType });
+            if (null != tenant)
             {
-                var tenant = await _tenantRepository.Select.DisableGlobalFilter("Tenant").WhereDynamic(entityDto.TenantId).ToOneAsync(a => new { a.TenantType, a.DataIsolationType });
-                if (null != tenant)
-                {
-                    entityDto.TenantType = tenant.TenantType;
-                    entityDto.DataIsolationType = tenant.DataIsolationType;
-                }
+                entityDto.TenantType = tenant.TenantType;
+                entityDto.DataIsolationType = tenant.DataIsolationType;
             }
-            return output.Ok(entityDto);
         }
+        return output.Ok(entityDto);
+    }
 
-        /// <summary>
-        /// 查询下拉数据
-        /// </summary>
-        /// <returns></returns>
-        public async Task<IResultOutput> GetSelectAsync()
-        {
-            var roles = await _roleRepository.Select.ToListAsync(a => new { a.Id, a.Name });
+    /// <summary>
+    /// 查询下拉数据
+    /// </summary>
+    /// <returns></returns>
+    public async Task<IResultOutput> GetSelectAsync()
+    {
+        var roles = await _roleRepository.Select.ToListAsync(a => new { a.Id, a.Name });
 
-            return ResultOutput.Ok(new { Select = new { roles } });
-        }
+        return ResultOutput.Ok(new { Select = new { roles } });
+    }
 
-        /// <summary>
-        /// 查询用户基本信息
-        /// </summary>
-        /// <returns></returns>
-        public async Task<IResultOutput> GetBasicAsync()
+    /// <summary>
+    /// 查询用户基本信息
+    /// </summary>
+    /// <returns></returns>
+    public async Task<IResultOutput> GetBasicAsync()
+    {
+        if (!(User?.Id > 0))
         {
-            if (!(User?.Id > 0))
-            {
-                return ResultOutput.NotOk("未登录!");
-            }
-
-            var data = await _userRepository.GetAsync<UserUpdateBasicInput>(User.Id);
-            return ResultOutput.Ok(data);
+            return ResultOutput.NotOk("未登录!");
         }
 
-        /// <summary>
-        /// 查询用户权限信息
-        /// </summary>
-        /// <returns></returns>
-        public async Task<IList<UserPermissionsOutput>> GetPermissionsAsync()
+        var data = await _userRepository.GetAsync<UserUpdateBasicInput>(User.Id);
+        return ResultOutput.Ok(data);
+    }
+
+    /// <summary>
+    /// 查询用户权限信息
+    /// </summary>
+    /// <returns></returns>
+    public async Task<IList<UserPermissionsOutput>> GetPermissionsAsync()
+    {
+        var key = string.Format(CacheKeys.UserPermissions, User.Id);
+        var result = await Cache.GetOrSetAsync(key, async () =>
         {
-            var key = string.Format(CacheKeys.UserPermissions, User.Id);
-            var result = await Cache.GetOrSetAsync(key, async () =>
-            {
-                return await _apiRepository
-                .Where(a => _userRoleRepository.Orm.Select<UserRoleEntity, RolePermissionEntity, PermissionApiEntity>()
-                .InnerJoin((b, c, d) => b.RoleId == c.RoleId && b.UserId == User.Id)
-                .InnerJoin((b, c, d) => c.PermissionId == d.PermissionId)
-                .Where((b, c, d) => d.ApiId == a.Id).Any())
-                .ToListAsync<UserPermissionsOutput>();
-            });
-            return result;
-        }
+            return await _apiRepository
+            .Where(a => _userRoleRepository.Orm.Select<UserRoleEntity, RolePermissionEntity, PermissionApiEntity>()
+            .InnerJoin((b, c, d) => b.RoleId == c.RoleId && b.UserId == User.Id)
+            .InnerJoin((b, c, d) => c.PermissionId == d.PermissionId)
+            .Where((b, c, d) => d.ApiId == a.Id).Any())
+            .ToListAsync<UserPermissionsOutput>();
+        });
+        return result;
+    }
 
-        /// <summary>
-        /// 新增用户
-        /// </summary>
-        /// <param name="input"></param>
-        /// <returns></returns>
-        [Transaction]
-        public async Task<IResultOutput> AddAsync(UserAddInput input)
+    /// <summary>
+    /// 新增用户
+    /// </summary>
+    /// <param name="input"></param>
+    /// <returns></returns>
+    [Transaction]
+    public async Task<IResultOutput> AddAsync(UserAddInput input)
+    {
+        if (input.Password.IsNull())
         {
-            if (input.Password.IsNull())
-            {
-                input.Password = "111111";
-            }
+            input.Password = _appConfig.DefaultPassword;
+        }
 
-            input.Password = MD5Encrypt.Encrypt32(input.Password);
+        input.Password = MD5Encrypt.Encrypt32(input.Password);
 
-            var entity = Mapper.Map<UserEntity>(input);
-            var user = await _userRepository.InsertAsync(entity);
+        var entity = Mapper.Map<UserEntity>(input);
+        var user = await _userRepository.InsertAsync(entity);
 
-            if (!(user?.Id > 0))
-            {
-                return ResultOutput.NotOk();
-            }
+        if (!(user?.Id > 0))
+        {
+            return ResultOutput.NotOk();
+        }
 
-            if (input.RoleIds != null && input.RoleIds.Any())
-            {
-                var roles = input.RoleIds.Select(a => new UserRoleEntity { UserId = user.Id, RoleId = a });
-                await _userRoleRepository.InsertAsync(roles);
-            }
+        if (input.RoleIds != null && input.RoleIds.Any())
+        {
+            var roles = input.RoleIds.Select(a => new UserRoleEntity { UserId = user.Id, RoleId = a });
+            await _userRoleRepository.InsertAsync(roles);
+        }
 
-            return ResultOutput.Ok();
+        return ResultOutput.Ok();
+    }
+
+    /// <summary>
+    /// 修改用户
+    /// </summary>
+    /// <param name="input"></param>
+    /// <returns></returns>
+    [Transaction]
+    public async Task<IResultOutput> UpdateAsync(UserUpdateInput input)
+    {
+        if (!(input?.Id > 0))
+        {
+            return ResultOutput.NotOk();
         }
 
-        /// <summary>
-        /// 修改用户
-        /// </summary>
-        /// <param name="input"></param>
-        /// <returns></returns>
-        [Transaction]
-        public async Task<IResultOutput> UpdateAsync(UserUpdateInput input)
+        var user = await _userRepository.GetAsync(input.Id);
+        if (!(user?.Id > 0))
         {
-            if (!(input?.Id > 0))
-            {
-                return ResultOutput.NotOk();
-            }
+            return ResultOutput.NotOk("用户不存在!");
+        }
 
-            var user = await _userRepository.GetAsync(input.Id);
-            if (!(user?.Id > 0))
-            {
-                return ResultOutput.NotOk("用户不存在!");
-            }
+        Mapper.Map(input, user);
+        await _userRepository.UpdateAsync(user);
 
-            Mapper.Map(input, user);
-            await _userRepository.UpdateAsync(user);
+        await _userRoleRepository.DeleteAsync(a => a.UserId == user.Id);
 
-            await _userRoleRepository.DeleteAsync(a => a.UserId == user.Id);
+        if (input.RoleIds != null && input.RoleIds.Any())
+        {
+            var roles = input.RoleIds.Select(a => new UserRoleEntity { UserId = user.Id, RoleId = a });
+            await _userRoleRepository.InsertAsync(roles);
+        }
 
-            if (input.RoleIds != null && input.RoleIds.Any())
-            {
-                var roles = input.RoleIds.Select(a => new UserRoleEntity { UserId = user.Id, RoleId = a });
-                await _userRoleRepository.InsertAsync(roles);
-            }
+        return ResultOutput.Ok();
+    }
 
-            return ResultOutput.Ok();
-        }
+    /// <summary>
+    /// 更新用户基本信息
+    /// </summary>
+    /// <param name="input"></param>
+    /// <returns></returns>
+    public async Task<IResultOutput> UpdateBasicAsync(UserUpdateBasicInput input)
+    {
+        var entity = await _userRepository.GetAsync(input.Id);
+        entity = Mapper.Map(input, entity);
+        var result = (await _userRepository.UpdateAsync(entity)) > 0;
 
-        /// <summary>
-        /// 更新用户基本信息
-        /// </summary>
-        /// <param name="input"></param>
-        /// <returns></returns>
-        public async Task<IResultOutput> UpdateBasicAsync(UserUpdateBasicInput input)
-        {
-            var entity = await _userRepository.GetAsync(input.Id);
-            entity = Mapper.Map(input, entity);
-            var result = (await _userRepository.UpdateAsync(entity)) > 0;
+        //清除用户缓存
+        await Cache.DelAsync(string.Format(CacheKeys.UserInfo, input.Id));
 
-            //清除用户缓存
-            await Cache.DelAsync(string.Format(CacheKeys.UserInfo, input.Id));
+        return ResultOutput.Result(result);
+    }
 
-            return ResultOutput.Result(result);
+    /// <summary>
+    /// 修改用户密码
+    /// </summary>
+    /// <param name="input"></param>
+    /// <returns></returns>
+    public async Task<IResultOutput> ChangePasswordAsync(UserChangePasswordInput input)
+    {
+        if (input.ConfirmPassword != input.NewPassword)
+        {
+            return ResultOutput.NotOk("新密码和确认密码不一致!");
         }
 
-        /// <summary>
-        /// 修改用户密码
-        /// </summary>
-        /// <param name="input"></param>
-        /// <returns></returns>
-        public async Task<IResultOutput> ChangePasswordAsync(UserChangePasswordInput input)
+        var entity = await _userRepository.GetAsync(input.Id);
+        var oldPassword = MD5Encrypt.Encrypt32(input.OldPassword);
+        if (oldPassword != entity.Password)
         {
-            if (input.ConfirmPassword != input.NewPassword)
-            {
-                return ResultOutput.NotOk("新密码和确认密码不一致!");
-            }
-
-            var entity = await _userRepository.GetAsync(input.Id);
-            var oldPassword = MD5Encrypt.Encrypt32(input.OldPassword);
-            if (oldPassword != entity.Password)
-            {
-                return ResultOutput.NotOk("旧密码不正确!");
-            }
+            return ResultOutput.NotOk("旧密码不正确!");
+        }
 
-            input.Password = MD5Encrypt.Encrypt32(input.NewPassword);
+        input.Password = MD5Encrypt.Encrypt32(input.NewPassword);
 
-            entity = Mapper.Map(input, entity);
-            var result = (await _userRepository.UpdateAsync(entity)) > 0;
+        entity = Mapper.Map(input, entity);
+        var result = (await _userRepository.UpdateAsync(entity)) > 0;
 
-            return ResultOutput.Result(result);
-        }
+        return ResultOutput.Result(result);
+    }
 
-        /// <summary>
-        /// 彻底删除用户
-        /// </summary>
-        /// <param name="id"></param>
-        /// <returns></returns>
-        public async Task<IResultOutput> DeleteAsync(long id)
+    /// <summary>
+    /// 彻底删除用户
+    /// </summary>
+    /// <param name="id"></param>
+    /// <returns></returns>
+    public async Task<IResultOutput> DeleteAsync(long id)
+    {
+        var result = false;
+        if (id > 0)
         {
-            var result = false;
-            if (id > 0)
-            {
-                result = (await _userRepository.DeleteAsync(m => m.Id == id)) > 0;
-            }
-
-            return ResultOutput.Result(result);
+            result = (await _userRepository.DeleteAsync(m => m.Id == id)) > 0;
         }
 
-        /// <summary>
-        /// 删除用户
-        /// </summary>
-        /// <param name="id"></param>
-        /// <returns></returns>
-        [Transaction]
-        public async Task<IResultOutput> SoftDeleteAsync(long id)
-        {
-            var result = await _userRepository.SoftDeleteAsync(id);
-            await _userRoleRepository.DeleteAsync(a => a.UserId == id);
+        return ResultOutput.Result(result);
+    }
 
-            return ResultOutput.Result(result);
-        }
+    /// <summary>
+    /// 删除用户
+    /// </summary>
+    /// <param name="id"></param>
+    /// <returns></returns>
+    [Transaction]
+    public async Task<IResultOutput> SoftDeleteAsync(long id)
+    {
+        var result = await _userRepository.SoftDeleteAsync(id);
+        await _userRoleRepository.DeleteAsync(a => a.UserId == id);
 
-        /// <summary>
-        /// 批量删除用户
-        /// </summary>
-        /// <param name="ids"></param>
-        /// <returns></returns>
-        [Transaction]
-        public async Task<IResultOutput> BatchSoftDeleteAsync(long[] ids)
-        {
-            var result = await _userRepository.SoftDeleteAsync(ids);
-            await _userRoleRepository.DeleteAsync(a => ids.Contains(a.UserId));
+        return ResultOutput.Result(result);
+    }
 
-            return ResultOutput.Result(result);
-        }
+    /// <summary>
+    /// 批量删除用户
+    /// </summary>
+    /// <param name="ids"></param>
+    /// <returns></returns>
+    [Transaction]
+    public async Task<IResultOutput> BatchSoftDeleteAsync(long[] ids)
+    {
+        var result = await _userRepository.SoftDeleteAsync(ids);
+        await _userRoleRepository.DeleteAsync(a => ids.Contains(a.UserId));
 
-        /// <summary>
-        /// 上传头像
-        /// </summary>
-        /// <param name="file"></param>
-        /// <returns></returns>
-        [HttpPost]
-        [Login]
-        public async Task<IResultOutput> AvatarUpload([FromForm] IFormFile file)
-        {
-            var uploadConfig = LazyGetRequiredService<IOptionsMonitor<UploadConfig>>().CurrentValue;
-            var uploadHelper = LazyGetRequiredService<UploadHelper>();
-            var config = uploadConfig.Avatar;
-            var res = await uploadHelper.UploadAsync(file, config, new { User.Id });
-            if (res.Success)
-            {
-                return ResultOutput.Ok(res.Data.FileRelativePath);
-            }
+        return ResultOutput.Result(result);
+    }
 
-            return ResultOutput.NotOk(res.Msg ?? "上传失败!");
+    /// <summary>
+    /// 上传头像
+    /// </summary>
+    /// <param name="file"></param>
+    /// <returns></returns>
+    [HttpPost]
+    [Login]
+    public async Task<IResultOutput> AvatarUpload([FromForm] IFormFile file)
+    {
+        var uploadConfig = LazyGetRequiredService<IOptionsMonitor<UploadConfig>>().CurrentValue;
+        var uploadHelper = LazyGetRequiredService<UploadHelper>();
+        var config = uploadConfig.Avatar;
+        var res = await uploadHelper.UploadAsync(file, config, new { User.Id });
+        if (res.Success)
+        {
+            return ResultOutput.Ok(res.Data.FileRelativePath);
         }
+
+        return ResultOutput.NotOk(res.Msg ?? "上传失败!");
     }
 }

+ 3 - 4
src/platform/ZhonTai.Admin/Services/View/ViewService.cs

@@ -1,21 +1,20 @@
-using Microsoft.AspNetCore.Mvc;
-using System.Collections.Generic;
+using System.Collections.Generic;
 using System.Linq;
 using System.Threading.Tasks;
 using ZhonTai.Admin.Core.Attributes;
 using ZhonTai.Admin.Core.Dto;
 using ZhonTai.Admin.Domain.View;
-using ZhonTai.Admin.Domain.View.Dto;
 using ZhonTai.Admin.Services.View.Dto;
 using ZhonTai.DynamicApi;
 using ZhonTai.DynamicApi.Attributes;
+using ZhonTai.Admin.Core.Consts;
 
 namespace ZhonTai.Admin.Services.View
 {
     /// <summary>
     /// 视图服务
     /// </summary>
-    [DynamicApi(Area = "admin")]
+    [DynamicApi(Area = AdminConsts.AreaName)]
     public class ViewService : BaseService, IViewService, IDynamicApi
     {
         private readonly IViewRepository _viewRepository;

+ 162 - 65
src/platform/ZhonTai.Admin/ZhonTai.Admin.xml

@@ -59,11 +59,6 @@
             用户Id
             </summary>
         </member>
-        <member name="F:ZhonTai.Admin.Core.Auth.ClaimAttributes.IdentityServerUserId">
-            <summary>
-            认证授权用户Id
-            </summary>
-        </member>
         <member name="F:ZhonTai.Admin.Core.Auth.ClaimAttributes.UserName">
             <summary>
             用户名
@@ -195,16 +190,6 @@
             数据隔离
             </summary>
         </member>
-        <member name="T:ZhonTai.Admin.Core.Auth.UserIdentiyServer">
-            <summary>
-            用户信息
-            </summary>
-        </member>
-        <member name="P:ZhonTai.Admin.Core.Auth.UserIdentiyServer.Id">
-            <summary>
-            用户Id
-            </summary>
-        </member>
         <member name="T:ZhonTai.Admin.Core.BaseController">
             <summary>
             基础控制器
@@ -275,6 +260,11 @@
             验证码配置
             </summary>
         </member>
+        <member name="P:ZhonTai.Admin.Core.Configs.AppConfig.DefaultPassword">
+            <summary>
+            默认密码
+            </summary>
+        </member>
         <member name="T:ZhonTai.Admin.Core.Configs.SwaggerConfig">
             <summary>
             Swagger配置
@@ -570,6 +560,11 @@
             文件格式
             </summary>
         </member>
+        <member name="F:ZhonTai.Admin.Core.Consts.AdminConsts.AreaName">
+            <summary>
+            默认域
+            </summary>
+        </member>
         <member name="F:ZhonTai.Admin.Core.Consts.AdminConsts.TenantName">
             <summary>
             默认租户
@@ -809,6 +804,11 @@
             消息
             </summary>
         </member>
+        <member name="P:ZhonTai.Admin.Core.Dto.IResultOutput.Code">
+            <summary>
+            编码
+            </summary>
+        </member>
         <member name="T:ZhonTai.Admin.Core.Dto.IResultOutput`1">
             <summary>
             泛型结果输出接口
@@ -878,7 +878,7 @@
         </member>
         <member name="P:ZhonTai.Admin.Core.Dto.ResultOutput`1.Code">
             <summary>
-            状态
+            
             </summary>
         </member>
         <member name="P:ZhonTai.Admin.Core.Dto.ResultOutput`1.Msg">
@@ -1886,54 +1886,24 @@
             用户Id
             </summary>
         </member>
-        <member name="P:ZhonTai.Admin.Domain.Employee.EmployeeEntity.Name">
-            <summary>
-            姓名
-            </summary>
-        </member>
-        <member name="P:ZhonTai.Admin.Domain.Employee.EmployeeEntity.NickName">
-            <summary>
-            昵称
-            </summary>
-        </member>
         <member name="P:ZhonTai.Admin.Domain.Employee.EmployeeEntity.Sex">
             <summary>
             性别
             </summary>
         </member>
-        <member name="P:ZhonTai.Admin.Domain.Employee.EmployeeEntity.Code">
+        <member name="P:ZhonTai.Admin.Domain.Employee.EmployeeEntity.JobNumber">
             <summary>
             工号
             </summary>
         </member>
-        <member name="P:ZhonTai.Admin.Domain.Employee.EmployeeEntity.OrganizationId">
+        <member name="P:ZhonTai.Admin.Domain.Employee.EmployeeEntity.MainOrgId">
             <summary>
             主属部门Id
             </summary>
         </member>
-        <member name="P:ZhonTai.Admin.Domain.Employee.EmployeeEntity.PrimaryEmployeeId">
-            <summary>
-            主管Id
-            </summary>
-        </member>
-        <member name="P:ZhonTai.Admin.Domain.Employee.EmployeeEntity.PrimaryEmployee">
-            <summary>
-            主管
-            </summary>
-        </member>
-        <member name="P:ZhonTai.Admin.Domain.Employee.EmployeeEntity.PositionId">
+        <member name="P:ZhonTai.Admin.Domain.Employee.EmployeeEntity.Position">
             <summary>
-            职位Id
-            </summary>
-        </member>
-        <member name="P:ZhonTai.Admin.Domain.Employee.EmployeeEntity.Phone">
-            <summary>
-            手机号
-            </summary>
-        </member>
-        <member name="P:ZhonTai.Admin.Domain.Employee.EmployeeEntity.Email">
-            <summary>
-            邮箱
+            职位
             </summary>
         </member>
         <member name="P:ZhonTai.Admin.Domain.Employee.EmployeeEntity.EntryTime">
@@ -2156,16 +2126,6 @@
             </summary>
         </member>
-        <member name="P:ZhonTai.Admin.Domain.Organization.OrganizationEntity.PrimaryEmployeeId">
-            <summary>
-            主管Id
-            </summary>
-        </member>
-        <member name="P:ZhonTai.Admin.Domain.Organization.OrganizationEntity.PrimaryEmployee">
-            <summary>
-            主管
-            </summary>
-        </member>
         <member name="P:ZhonTai.Admin.Domain.Organization.OrganizationEntity.EmployeeCount">
             <summary>
             员工人数
@@ -2836,6 +2796,21 @@
             密码
             </summary>
         </member>
+        <member name="P:ZhonTai.Admin.Domain.User.UserEntity.Name">
+            <summary>
+            姓名
+            </summary>
+        </member>
+        <member name="P:ZhonTai.Admin.Domain.User.UserEntity.Mobile">
+            <summary>
+            手机号
+            </summary>
+        </member>
+        <member name="P:ZhonTai.Admin.Domain.User.UserEntity.Email">
+            <summary>
+            邮箱
+            </summary>
+        </member>
         <member name="P:ZhonTai.Admin.Domain.User.UserEntity.NickName">
             <summary>
             昵称
@@ -2851,11 +2826,6 @@
             状态
             </summary>
         </member>
-        <member name="P:ZhonTai.Admin.Domain.User.UserEntity.Remark">
-            <summary>
-            备注
-            </summary>
-        </member>
         <member name="P:ZhonTai.Admin.Domain.View.Dto.ViewDataOutput.TenantId">
             <summary>
             租户Id
@@ -2946,6 +2916,11 @@
             排序
             </summary>
         </member>
+        <member name="P:ZhonTai.Admin.Domain.TaskScheduler.Dto.TaskSchedulerGetPageDto.Name">
+            <summary>
+            名称
+            </summary>
+        </member>
         <member name="T:ZhonTai.Admin.HttpApi.AreaController">
             <summary>
             域控制器
@@ -5450,6 +5425,128 @@
             <param name="ids"></param>
             <returns></returns>
         </member>
+        <member name="T:ZhonTai.Admin.Services.TaskScheduler.Dto.TaskSchedulerAddInput">
+            <summary>
+            添加
+            </summary>
+        </member>
+        <member name="P:ZhonTai.Admin.Services.TaskScheduler.Dto.TaskSchedulerAddInput.Name">
+            <summary>
+            名称
+            </summary>
+        </member>
+        <member name="P:ZhonTai.Admin.Services.TaskScheduler.Dto.TaskSchedulerAddInput.Code">
+            <summary>
+            编码
+            </summary>
+        </member>
+        <member name="P:ZhonTai.Admin.Services.TaskScheduler.Dto.TaskSchedulerAddInput.Description">
+            <summary>
+            说明
+            </summary>
+        </member>
+        <member name="P:ZhonTai.Admin.Services.TaskScheduler.Dto.TaskSchedulerAddInput.Enabled">
+            <summary>
+            启用
+            </summary>
+        </member>
+        <member name="P:ZhonTai.Admin.Services.TaskScheduler.Dto.TaskSchedulerListOutput.Id">
+            <summary>
+            主键
+            </summary>
+        </member>
+        <member name="P:ZhonTai.Admin.Services.TaskScheduler.Dto.TaskSchedulerListOutput.Name">
+            <summary>
+            名称
+            </summary>
+        </member>
+        <member name="P:ZhonTai.Admin.Services.TaskScheduler.Dto.TaskSchedulerListOutput.Code">
+            <summary>
+            编码
+            </summary>
+        </member>
+        <member name="P:ZhonTai.Admin.Services.TaskScheduler.Dto.TaskSchedulerListOutput.Description">
+            <summary>
+            说明
+            </summary>
+        </member>
+        <member name="P:ZhonTai.Admin.Services.TaskScheduler.Dto.TaskSchedulerListOutput.Enabled">
+            <summary>
+            启用
+            </summary>
+        </member>
+        <member name="P:ZhonTai.Admin.Services.TaskScheduler.Dto.TaskSchedulerListOutput.CreatedTime">
+            <summary>
+            创建时间
+            </summary>
+        </member>
+        <member name="T:ZhonTai.Admin.Services.TaskScheduler.Dto.TaskSchedulerUpdateInput">
+            <summary>
+            修改
+            </summary>
+        </member>
+        <member name="P:ZhonTai.Admin.Services.TaskScheduler.Dto.TaskSchedulerUpdateInput.Id">
+            <summary>
+            接口Id
+            </summary>
+        </member>
+        <member name="P:ZhonTai.Admin.Services.TaskScheduler.Dto.TaskSchedulerUpdateInput.Version">
+            <summary>
+            版本
+            </summary>
+        </member>
+        <member name="T:ZhonTai.Admin.Services.TaskScheduler.ITaskSchedulerService">
+            <summary>
+            任务调度接口
+            </summary>
+        </member>
+        <member name="T:ZhonTai.Admin.Services.TaskScheduler.TaskSchedulerService">
+            <summary>
+            任务调度服务
+            </summary>
+        </member>
+        <member name="M:ZhonTai.Admin.Services.TaskScheduler.TaskSchedulerService.GetAsync(System.Int64)">
+            <summary>
+            查询角色
+            </summary>
+            <param name="id"></param>
+            <returns></returns>
+        </member>
+        <member name="M:ZhonTai.Admin.Services.TaskScheduler.TaskSchedulerService.GetPageAsync(ZhonTai.Admin.Core.Dto.PageInput{ZhonTai.Admin.Domain.TaskScheduler.Dto.TaskSchedulerGetPageDto})">
+            <summary>
+            查询角色列表
+            </summary>
+            <param name="input"></param>
+            <returns></returns>
+        </member>
+        <member name="M:ZhonTai.Admin.Services.TaskScheduler.TaskSchedulerService.AddAsync(ZhonTai.Admin.Services.TaskScheduler.Dto.TaskSchedulerAddInput)">
+            <summary>
+            新增
+            </summary>
+            <param name="input"></param>
+            <returns></returns>
+        </member>
+        <member name="M:ZhonTai.Admin.Services.TaskScheduler.TaskSchedulerService.UpdateAsync(ZhonTai.Admin.Services.TaskScheduler.Dto.TaskSchedulerUpdateInput)">
+            <summary>
+            修改
+            </summary>
+            <param name="input"></param>
+            <returns></returns>
+        </member>
+        <member name="M:ZhonTai.Admin.Services.TaskScheduler.TaskSchedulerService.DeleteAsync(System.String)">
+            <summary>
+            彻底删除
+            </summary>
+            <param name="id"></param>
+            <returns></returns>
+        </member>
+        <member name="M:ZhonTai.Admin.Services.TaskScheduler.TaskSchedulerService.BatchSoftDeleteAsync(System.String[])">
+            <summary>
+            批量删除
+            </summary>
+            <param name="ids"></param>
+            <returns></returns>
+        </member>
         <member name="T:ZhonTai.Admin.Services.Tenant.Dto.TenantAddInput">
             <summary>
             添加

+ 1 - 1
src/platform/ZhonTai.Common/Helpers/ConfigHelper.cs

@@ -30,7 +30,7 @@ namespace ZhonTai.Common.Helpers
         /// <returns></returns>
         public static IConfiguration Load(string fileName, string environmentName = "", bool optional = true, bool reloadOnChange = false)
         {
-            var filePath = Path.Combine(AppContext.BaseDirectory, "configs");
+            var filePath = Path.Combine(AppContext.BaseDirectory, "Configs");
             if (!Directory.Exists(filePath))
                 return null;