diff --git a/Yi.Framework/Yi.Framework.ApiMicroservice/Controllers/AccountController.cs b/Yi.Framework/Yi.Framework.ApiMicroservice/Controllers/AccountController.cs index a029f36a..b2ca8438 100644 --- a/Yi.Framework/Yi.Framework.ApiMicroservice/Controllers/AccountController.cs +++ b/Yi.Framework/Yi.Framework.ApiMicroservice/Controllers/AccountController.cs @@ -152,5 +152,6 @@ namespace Yi.Framework.ApiMicroservice.Controllers return Result.Success(msg); } + } } \ No newline at end of file diff --git a/Yi.Framework/Yi.Framework.ApiMicroservice/Controllers/JobController.cs b/Yi.Framework/Yi.Framework.ApiMicroservice/Controllers/JobController.cs new file mode 100644 index 00000000..3221d34a --- /dev/null +++ b/Yi.Framework/Yi.Framework.ApiMicroservice/Controllers/JobController.cs @@ -0,0 +1,70 @@ +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Yi.Framework.Common; +using Yi.Framework.Common.Helper; +using Yi.Framework.Common.Models; +using Yi.Framework.Core; +using Yi.Framework.DTOModel; +using Yi.Framework.Interface; +using Yi.Framework.Model.Models; + +namespace Yi.Framework.ApiMicroservice.Controllers +{ + [ApiController] + [Route("api/[controller]/[action]")] + public class JobController : Controller + { + private readonly ILogger _logger; + private QuartzInvoker _quartzInvoker; + public JobController(ILogger logger,QuartzInvoker quartzInvoker) + { + _logger = logger; + _quartzInvoker = quartzInvoker; + } + + [HttpPost] + public async Task startJob() + { + await _quartzInvoker.start("*/1 * * * * ? ", new Quartz.JobKey("test", "my"), "VisitJob"); + return Result.Success(); + } + + [HttpGet] + public async Task getRunJobList() + { + return Result.Success().SetData(await _quartzInvoker.getRunJobList()); + } + + [HttpGet] + public Result getJobClass() + { + return Result.Success().SetData(_quartzInvoker.getJobClassList()); + } + + [HttpPut] + public async Task stopJob() + { + await _quartzInvoker.Stop(new Quartz.JobKey("test", "my")); + return Result.Success(); + } + + [HttpDelete] + public async Task DeleteJob() + { + await _quartzInvoker.Delete(new Quartz.JobKey("test", "my")); + return Result.Success(); + } + + [HttpPut] + public async Task ResumeJob() + { + await _quartzInvoker.Resume(new Quartz.JobKey("test", "my")); + return Result.Success(); + } + } +} \ No newline at end of file diff --git a/Yi.Framework/Yi.Framework.ApiMicroservice/Startup.cs b/Yi.Framework/Yi.Framework.ApiMicroservice/Startup.cs index 2283df4d..6f28e2ef 100644 --- a/Yi.Framework/Yi.Framework.ApiMicroservice/Startup.cs +++ b/Yi.Framework/Yi.Framework.ApiMicroservice/Startup.cs @@ -27,6 +27,11 @@ namespace Yi.Framework.ApiMicroservice #endregion services.AddIocService(Configuration); + #region + //Quartz + #endregion + services.AddQuartzService(); + #region //+ #endregion diff --git a/Yi.Framework/Yi.Framework.ApiMicroservice/SwaggerDoc.xml b/Yi.Framework/Yi.Framework.ApiMicroservice/SwaggerDoc.xml index cad3e2be..33305d1d 100644 --- a/Yi.Framework/Yi.Framework.ApiMicroservice/SwaggerDoc.xml +++ b/Yi.Framework/Yi.Framework.ApiMicroservice/SwaggerDoc.xml @@ -39,6 +39,12 @@ + + + 这个是要递归的,但是要过滤掉删除的,所以,可以写一个通用过滤掉删除的方法 + + + 更 @@ -53,9 +59,10 @@ - + 增 + 现在,top菜单只允许为一个 @@ -63,16 +70,11 @@ 给一个菜单设置一个接口,Id1为菜单id,Id2为接口id + 用于给菜单设置接口 - - - 得到该用户有哪些菜单,关联mould - - - 给一个菜单添加子节点(注意:添加,不是覆盖) @@ -80,9 +82,10 @@ - + 获取用户的目录菜单,不包含接口 + 用于账户信息页面,显示这个用户有哪些菜单,需要并列 @@ -128,13 +131,28 @@ + + + 根据用户id得到该用户有哪些角色 + 用于显示用户详情中的角色说明 + + + 给角色设置菜单,多个角色与多个菜单,让每一个角色都设置,ids1为角色,ids2为菜单 + 用于设置角色 + + + 用于给角色设置菜单的时候,点击一个角色,显示这个角色拥有的并列的菜单 + + + + 查 @@ -162,36 +180,34 @@ - - - 通过上下文对象获取user(注意,_user下只有userId),返回值为该用户下所有的menu,(注意子类递归)并且需要关联mould - - - 给多个用户设置多个角色,ids有用户id与 角色列表ids,多对多,ids1用户,ids2为角色 + 用户设置给用户设置角色 - - - 根据http上下文的用户得到该用户有哪些角色 - - - - - - 根据用户id得到该用户有哪些角色 - - - - + 根据http上下文的用户得到该用户信息,关联角色 + 用于显示账号信息页中的用户信息和角色信息 + + + 得到登录用户的递归菜单,放到导航栏 + 用户放到导航栏中 + + + + + + 得到请求模型 + + + + diff --git a/Yi.Framework/Yi.Framework.ApiMicroservice/Yi.Framework.ApiMicroservice.csproj b/Yi.Framework/Yi.Framework.ApiMicroservice/Yi.Framework.ApiMicroservice.csproj index d84cd1dc..b4833ceb 100644 --- a/Yi.Framework/Yi.Framework.ApiMicroservice/Yi.Framework.ApiMicroservice.csproj +++ b/Yi.Framework/Yi.Framework.ApiMicroservice/Yi.Framework.ApiMicroservice.csproj @@ -14,7 +14,6 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - diff --git a/Yi.Framework/Yi.Framework.ApiMicroservice/appsettings.json b/Yi.Framework/Yi.Framework.ApiMicroservice/appsettings.json index fbc284ac..159ff0ad 100644 --- a/Yi.Framework/Yi.Framework.ApiMicroservice/appsettings.json +++ b/Yi.Framework/Yi.Framework.ApiMicroservice/appsettings.json @@ -1,5 +1,4 @@ { - "urls": "http://*:19000", "Logging": { "LogLevel": { "Default": "Information", diff --git a/Yi.Framework/Yi.Framework.Common/Helper/AssemblyHelper.cs b/Yi.Framework/Yi.Framework.Common/Helper/AssemblyHelper.cs new file mode 100644 index 00000000..895900db --- /dev/null +++ b/Yi.Framework/Yi.Framework.Common/Helper/AssemblyHelper.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; + +namespace Yi.Framework.Common.Helper +{ + public class AssemblyHelper + { + public static List GetClass(string assemblyFile, string className = null, string spaceName=null) + { + Assembly assembly = Assembly.Load(assemblyFile); + return assembly.GetTypes().Where(m => m.IsClass + && m.Name==null?true:m.Name==className + ).ToList(); + } + + } +} diff --git a/Yi.Framework/Yi.Framework.Core/TaskJob/visitJob.cs b/Yi.Framework/Yi.Framework.Common/Models/VisitModel.cs similarity index 53% rename from Yi.Framework/Yi.Framework.Core/TaskJob/visitJob.cs rename to Yi.Framework/Yi.Framework.Common/Models/VisitModel.cs index 58b39434..03ed48f5 100644 --- a/Yi.Framework/Yi.Framework.Core/TaskJob/visitJob.cs +++ b/Yi.Framework/Yi.Framework.Common/Models/VisitModel.cs @@ -4,9 +4,10 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace Yi.Framework.Core.TaskJob +namespace Yi.Framework.Common.Models { - class VisitJob + public class visitModel { + public static int visitNum { get; set; } = 0; } } diff --git a/Yi.Framework/Yi.Framework.Core/Quartz/MyQuartzFactory.cs b/Yi.Framework/Yi.Framework.Core/Quartz/MyQuartzFactory.cs new file mode 100644 index 00000000..098989f7 --- /dev/null +++ b/Yi.Framework/Yi.Framework.Core/Quartz/MyQuartzFactory.cs @@ -0,0 +1,32 @@ +using Microsoft.Extensions.DependencyInjection; +using Quartz; +using Quartz.Spi; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Yi.Framework.Core.Quartz +{ + public class MyQuartzFactory : IJobFactory + { + private readonly IServiceProvider _serviceProvider; + + public MyQuartzFactory(IServiceProvider serviceProvider) + { + _serviceProvider = serviceProvider; + } + + public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler) + { + return _serviceProvider.GetRequiredService(bundle.JobDetail.JobType) as IJob; + } + + public void ReturnJob(IJob job) + { + var disposable = job as IDisposable; + disposable?.Dispose(); + } + } +} diff --git a/Yi.Framework/Yi.Framework.Core/Quartz/QuartzInvoker.cs b/Yi.Framework/Yi.Framework.Core/Quartz/QuartzInvoker.cs new file mode 100644 index 00000000..e846a290 --- /dev/null +++ b/Yi.Framework/Yi.Framework.Core/Quartz/QuartzInvoker.cs @@ -0,0 +1,144 @@ +using Microsoft.Extensions.Logging; +using Quartz; +using Quartz.Impl.Matchers; +using Quartz.Spi; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Yi.Framework.Common.Helper; +using Yi.Framework.Job; + +namespace Yi.Framework.Core +{ + public class QuartzInvoker + { + private readonly ISchedulerFactory _schedulerFactory; + private IScheduler _scheduler; + private ILogger _logger; + private IJobFactory _jobFactory; + public QuartzInvoker(ISchedulerFactory schedulerFactory, ILogger logger, IJobFactory jobFactory) + { + _schedulerFactory = schedulerFactory; + _logger = logger; + _jobFactory = jobFactory; + } + + /// + /// 开始任务 + /// + /// + /// + /// + /// + /// + /// + public async Task start(string cron, JobKey jobKey, string jobClass, long second = 0) + { + var myClass = AssemblyHelper.GetClass("Yi.Framework.Job", jobClass).FirstOrDefault(); + + _scheduler = await _schedulerFactory.GetScheduler(); + _scheduler.JobFactory = _jobFactory; + //开启调度器 + await _scheduler.Start(); + //创建一个触发器 + var trigger = TriggerBuilder.Create() + .StartAt(DateTimeOffset.Now.AddSeconds(second)) + .WithCronSchedule(cron) + .Build(); + //创建任务 + var jobDetail = JobBuilder.Create(myClass) + .WithIdentity(jobKey.Name, jobKey.Group) + .Build(); + //将触发器和任务器绑定到调度器中 + await _scheduler.ScheduleJob(jobDetail, trigger); + + _logger.LogWarning($"开始任务:{jobKey.Name},组别:{jobKey.Group}"); + } + + /// + /// 暂停任务 + /// + /// + /// + public async Task Stop(JobKey jobKey) + { + var _scheduler = await _schedulerFactory.GetScheduler(); + //LogUtil.Debug($"暂停任务{jobKey.Group},{jobKey.Name}"); + await _scheduler.PauseJob(jobKey); + _logger.LogWarning($"暂停任务:{jobKey.Name},组别:{jobKey.Group}"); + } + + + public async Task Delete(JobKey jobKey) + { + var _scheduler = await _schedulerFactory.GetScheduler(); + //LogUtil.Debug($"暂停任务{jobKey.Group},{jobKey.Name}"); + await _scheduler.DeleteJob(jobKey); + _logger.LogWarning($"删除任务:{jobKey.Name},组别:{jobKey.Group}"); + } + + public async Task Resume(JobKey jobKey) + { + var _scheduler = await _schedulerFactory.GetScheduler(); + //LogUtil.Debug($"恢复任务{jobKey.Group},{jobKey.Name}"); + await _scheduler.ResumeJob(jobKey); + _logger.LogWarning($"恢复任务:{jobKey.Name},组别:{jobKey.Group}"); + } + + + /// + /// 得到可运行的job列表 + /// + /// + public List getJobClassList() + { + var myClassList = AssemblyHelper.GetClass("Yi.Framework.Job"); + List data = new List(); + myClassList.ForEach(k => data.Add(k.Name)); + return data; + } + + /// + /// 得到现在正在运行的任务列表 + /// + /// + public async Task> getRunJobList() + { + _scheduler = await _schedulerFactory.GetScheduler(); + var groups = await _scheduler.GetJobGroupNames(); + var data = new List(); + foreach (var groupName in groups) + { + foreach (var jobKey in await _scheduler.GetJobKeys(GroupMatcher.GroupEquals(groupName))) + { + string jobName = jobKey.Name; + string jobGroup = jobKey.Group; + data.Add(jobKey); + var triggers = await _scheduler.GetTriggersOfJob(jobKey); + foreach (ITrigger trigger in triggers) + { + ///下一次的执行时间 + var utcTime =trigger.GetNextFireTimeUtc(); + string str = utcTime.ToString(); + //TimeZone.CurrentTimeZone.ToLocalTime(Convert.ToDateTime(str)); + + + } + } + } + + return data; + } + } + + + + public class JobKeyModel + { + public JobKey jobKey { get; set; } + public DateTime? nextTime { get; set; } + } +} + diff --git a/Yi.Framework/Yi.Framework.Core/Yi.Framework.Core.csproj b/Yi.Framework/Yi.Framework.Core/Yi.Framework.Core.csproj index 2049f607..d359fcfb 100644 --- a/Yi.Framework/Yi.Framework.Core/Yi.Framework.Core.csproj +++ b/Yi.Framework/Yi.Framework.Core/Yi.Framework.Core.csproj @@ -17,6 +17,7 @@ + diff --git a/Yi.Framework/Yi.Framework.Interface/T4Iservice.cs b/Yi.Framework/Yi.Framework.Interface/T4Iservice.cs index e3393b89..bf91c56d 100644 --- a/Yi.Framework/Yi.Framework.Interface/T4Iservice.cs +++ b/Yi.Framework/Yi.Framework.Interface/T4Iservice.cs @@ -31,4 +31,10 @@ namespace Yi.Framework.Interface Task DelListByUpdateAsync(List _ids); Task> GetAllEntitiesTrueAsync(); } + + public partial interface IVisitService:IBaseService + { + Task DelListByUpdateAsync(List _ids); + Task> GetAllEntitiesTrueAsync(); + } } diff --git a/Yi.Framework/Yi.Framework.Model/DataContext.cs b/Yi.Framework/Yi.Framework.Model/DataContext.cs index 12166072..40cd5730 100644 --- a/Yi.Framework/Yi.Framework.Model/DataContext.cs +++ b/Yi.Framework/Yi.Framework.Model/DataContext.cs @@ -16,7 +16,7 @@ namespace Yi.Framework.Model public partial class DataContext : DbContext { //private readonly IOptionsMonitor _optionsMonitor; - private string _connStr; + public static string _connStr; public static string DbSelect = DbConst.Mysql; //public DataContext(IOptionsMonitor optionsMonitor) //{ diff --git a/Yi.Framework/Yi.Framework.Model/Migrations/20211030074708_yi-3.Designer.cs b/Yi.Framework/Yi.Framework.Model/Migrations/20211030074708_yi-3.Designer.cs new file mode 100644 index 00000000..47b070c2 --- /dev/null +++ b/Yi.Framework/Yi.Framework.Model/Migrations/20211030074708_yi-3.Designer.cs @@ -0,0 +1,199 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Yi.Framework.Model; + +namespace Yi.Framework.Model.Migrations +{ + [DbContext(typeof(DataContext))] + [Migration("20211030074708_yi-3")] + partial class yi3 + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("Relational:MaxIdentifierLength", 64) + .HasAnnotation("ProductVersion", "5.0.11"); + + modelBuilder.Entity("Yi.Framework.Model.Models.menu", b => + { + b.Property("id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("icon") + .HasColumnType("longtext"); + + b.Property("is_delete") + .HasColumnType("int"); + + b.Property("is_show") + .HasColumnType("int"); + + b.Property("is_top") + .HasColumnType("int"); + + b.Property("menu_name") + .HasColumnType("longtext"); + + b.Property("menuid") + .HasColumnType("int"); + + b.Property("mouldid") + .HasColumnType("int"); + + b.Property("roleid") + .HasColumnType("int"); + + b.Property("router") + .HasColumnType("longtext"); + + b.Property("sort") + .HasColumnType("int"); + + b.HasKey("id"); + + b.HasIndex("menuid"); + + b.HasIndex("mouldid"); + + b.HasIndex("roleid"); + + b.ToTable("menu"); + }); + + modelBuilder.Entity("Yi.Framework.Model.Models.mould", b => + { + b.Property("id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("is_delete") + .HasColumnType("int"); + + b.Property("mould_name") + .HasColumnType("longtext"); + + b.Property("url") + .HasColumnType("longtext"); + + b.HasKey("id"); + + b.ToTable("mould"); + }); + + modelBuilder.Entity("Yi.Framework.Model.Models.role", b => + { + b.Property("id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("introduce") + .HasColumnType("longtext"); + + b.Property("is_delete") + .HasColumnType("int"); + + b.Property("role_name") + .HasColumnType("longtext"); + + b.Property("userid") + .HasColumnType("int"); + + b.HasKey("id"); + + b.HasIndex("userid"); + + b.ToTable("role"); + }); + + modelBuilder.Entity("Yi.Framework.Model.Models.user", b => + { + b.Property("id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("address") + .HasColumnType("longtext"); + + b.Property("age") + .HasColumnType("int"); + + b.Property("email") + .HasColumnType("longtext"); + + b.Property("icon") + .HasColumnType("longtext"); + + b.Property("introduction") + .HasColumnType("longtext"); + + b.Property("ip") + .HasColumnType("longtext"); + + b.Property("is_delete") + .HasColumnType("int"); + + b.Property("nick") + .HasColumnType("longtext"); + + b.Property("password") + .HasColumnType("longtext"); + + b.Property("phone") + .HasColumnType("int"); + + b.Property("username") + .HasColumnType("longtext"); + + b.HasKey("id"); + + b.ToTable("user"); + }); + + modelBuilder.Entity("Yi.Framework.Model.Models.menu", b => + { + b.HasOne("Yi.Framework.Model.Models.menu", null) + .WithMany("children") + .HasForeignKey("menuid"); + + b.HasOne("Yi.Framework.Model.Models.mould", "mould") + .WithMany() + .HasForeignKey("mouldid"); + + b.HasOne("Yi.Framework.Model.Models.role", null) + .WithMany("menus") + .HasForeignKey("roleid"); + + b.Navigation("mould"); + }); + + modelBuilder.Entity("Yi.Framework.Model.Models.role", b => + { + b.HasOne("Yi.Framework.Model.Models.user", null) + .WithMany("roles") + .HasForeignKey("userid"); + }); + + modelBuilder.Entity("Yi.Framework.Model.Models.menu", b => + { + b.Navigation("children"); + }); + + modelBuilder.Entity("Yi.Framework.Model.Models.role", b => + { + b.Navigation("menus"); + }); + + modelBuilder.Entity("Yi.Framework.Model.Models.user", b => + { + b.Navigation("roles"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Yi.Framework/Yi.Framework.Model/Migrations/20211030074708_yi-3.cs b/Yi.Framework/Yi.Framework.Model/Migrations/20211030074708_yi-3.cs new file mode 100644 index 00000000..5df34fdc --- /dev/null +++ b/Yi.Framework/Yi.Framework.Model/Migrations/20211030074708_yi-3.cs @@ -0,0 +1,17 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Yi.Framework.Model.Migrations +{ + public partial class yi3 : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + + } + } +} diff --git a/Yi.Framework/Yi.Framework.Model/Migrations/20211030074922_yi-5.Designer.cs b/Yi.Framework/Yi.Framework.Model/Migrations/20211030074922_yi-5.Designer.cs new file mode 100644 index 00000000..5d247544 --- /dev/null +++ b/Yi.Framework/Yi.Framework.Model/Migrations/20211030074922_yi-5.Designer.cs @@ -0,0 +1,219 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Yi.Framework.Model; + +namespace Yi.Framework.Model.Migrations +{ + [DbContext(typeof(DataContext))] + [Migration("20211030074922_yi-5")] + partial class yi5 + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("Relational:MaxIdentifierLength", 64) + .HasAnnotation("ProductVersion", "5.0.11"); + + modelBuilder.Entity("Yi.Framework.Model.Models.menu", b => + { + b.Property("id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("icon") + .HasColumnType("longtext"); + + b.Property("is_delete") + .HasColumnType("int"); + + b.Property("is_show") + .HasColumnType("int"); + + b.Property("is_top") + .HasColumnType("int"); + + b.Property("menu_name") + .HasColumnType("longtext"); + + b.Property("menuid") + .HasColumnType("int"); + + b.Property("mouldid") + .HasColumnType("int"); + + b.Property("roleid") + .HasColumnType("int"); + + b.Property("router") + .HasColumnType("longtext"); + + b.Property("sort") + .HasColumnType("int"); + + b.HasKey("id"); + + b.HasIndex("menuid"); + + b.HasIndex("mouldid"); + + b.HasIndex("roleid"); + + b.ToTable("menu"); + }); + + modelBuilder.Entity("Yi.Framework.Model.Models.mould", b => + { + b.Property("id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("is_delete") + .HasColumnType("int"); + + b.Property("mould_name") + .HasColumnType("longtext"); + + b.Property("url") + .HasColumnType("longtext"); + + b.HasKey("id"); + + b.ToTable("mould"); + }); + + modelBuilder.Entity("Yi.Framework.Model.Models.role", b => + { + b.Property("id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("introduce") + .HasColumnType("longtext"); + + b.Property("is_delete") + .HasColumnType("int"); + + b.Property("role_name") + .HasColumnType("longtext"); + + b.Property("userid") + .HasColumnType("int"); + + b.HasKey("id"); + + b.HasIndex("userid"); + + b.ToTable("role"); + }); + + modelBuilder.Entity("Yi.Framework.Model.Models.user", b => + { + b.Property("id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("address") + .HasColumnType("longtext"); + + b.Property("age") + .HasColumnType("int"); + + b.Property("email") + .HasColumnType("longtext"); + + b.Property("icon") + .HasColumnType("longtext"); + + b.Property("introduction") + .HasColumnType("longtext"); + + b.Property("ip") + .HasColumnType("longtext"); + + b.Property("is_delete") + .HasColumnType("int"); + + b.Property("nick") + .HasColumnType("longtext"); + + b.Property("password") + .HasColumnType("longtext"); + + b.Property("phone") + .HasColumnType("int"); + + b.Property("username") + .HasColumnType("longtext"); + + b.HasKey("id"); + + b.ToTable("user"); + }); + + modelBuilder.Entity("Yi.Framework.Model.Models.visit", b => + { + b.Property("id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("is_delete") + .HasColumnType("int"); + + b.Property("num") + .HasColumnType("int"); + + b.Property("time") + .HasColumnType("datetime(6)"); + + b.HasKey("id"); + + b.ToTable("visit"); + }); + + modelBuilder.Entity("Yi.Framework.Model.Models.menu", b => + { + b.HasOne("Yi.Framework.Model.Models.menu", null) + .WithMany("children") + .HasForeignKey("menuid"); + + b.HasOne("Yi.Framework.Model.Models.mould", "mould") + .WithMany() + .HasForeignKey("mouldid"); + + b.HasOne("Yi.Framework.Model.Models.role", null) + .WithMany("menus") + .HasForeignKey("roleid"); + + b.Navigation("mould"); + }); + + modelBuilder.Entity("Yi.Framework.Model.Models.role", b => + { + b.HasOne("Yi.Framework.Model.Models.user", null) + .WithMany("roles") + .HasForeignKey("userid"); + }); + + modelBuilder.Entity("Yi.Framework.Model.Models.menu", b => + { + b.Navigation("children"); + }); + + modelBuilder.Entity("Yi.Framework.Model.Models.role", b => + { + b.Navigation("menus"); + }); + + modelBuilder.Entity("Yi.Framework.Model.Models.user", b => + { + b.Navigation("roles"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Yi.Framework/Yi.Framework.Model/Migrations/20211030074922_yi-5.cs b/Yi.Framework/Yi.Framework.Model/Migrations/20211030074922_yi-5.cs new file mode 100644 index 00000000..1d627b06 --- /dev/null +++ b/Yi.Framework/Yi.Framework.Model/Migrations/20211030074922_yi-5.cs @@ -0,0 +1,34 @@ +using System; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Yi.Framework.Model.Migrations +{ + public partial class yi5 : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "visit", + columns: table => new + { + id = table.Column(type: "int", nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + time = table.Column(type: "datetime(6)", nullable: false), + num = table.Column(type: "int", nullable: false), + is_delete = table.Column(type: "int", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_visit", x => x.id); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "visit"); + } + } +} diff --git a/Yi.Framework/Yi.Framework.Model/Migrations/DataContextModelSnapshot.cs b/Yi.Framework/Yi.Framework.Model/Migrations/DataContextModelSnapshot.cs index aade8592..42c7f861 100644 --- a/Yi.Framework/Yi.Framework.Model/Migrations/DataContextModelSnapshot.cs +++ b/Yi.Framework/Yi.Framework.Model/Migrations/DataContextModelSnapshot.cs @@ -153,6 +153,26 @@ namespace Yi.Framework.Model.Migrations b.ToTable("user"); }); + modelBuilder.Entity("Yi.Framework.Model.Models.visit", b => + { + b.Property("id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("is_delete") + .HasColumnType("int"); + + b.Property("num") + .HasColumnType("int"); + + b.Property("time") + .HasColumnType("datetime(6)"); + + b.HasKey("id"); + + b.ToTable("visit"); + }); + modelBuilder.Entity("Yi.Framework.Model.Models.menu", b => { b.HasOne("Yi.Framework.Model.Models.menu", null) diff --git a/Yi.Framework/Yi.Framework.Model/Models/visit.cs b/Yi.Framework/Yi.Framework.Model/Models/visit.cs new file mode 100644 index 00000000..845b753c --- /dev/null +++ b/Yi.Framework/Yi.Framework.Model/Models/visit.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Yi.Framework.Model.Models +{ + public class visit:baseModel + { + public DateTime time { get; set; } + public int num { get; set; } + } +} diff --git a/Yi.Framework/Yi.Framework.Model/T4DataContext.cs b/Yi.Framework/Yi.Framework.Model/T4DataContext.cs index 4c6778cb..071e4b24 100644 --- a/Yi.Framework/Yi.Framework.Model/T4DataContext.cs +++ b/Yi.Framework/Yi.Framework.Model/T4DataContext.cs @@ -12,6 +12,7 @@ namespace Yi.Framework.Model public DbSet mould { get; set; } public DbSet role { get; set; } public DbSet user { get; set; } + public DbSet visit { get; set; } } } diff --git a/Yi.Framework/Yi.Framework.Service/T4Service.cs b/Yi.Framework/Yi.Framework.Service/T4Service.cs index e0e80aa5..1b59d0eb 100644 --- a/Yi.Framework/Yi.Framework.Service/T4Service.cs +++ b/Yi.Framework/Yi.Framework.Service/T4Service.cs @@ -82,4 +82,22 @@ namespace Yi.Framework.Service } } + + public partial class VisitService:BaseService,IVisitService + { + public VisitService(IDbContextFactory DbFactory):base(DbFactory){ } + + public async Task DelListByUpdateAsync(List _ids) + { + var visitList = await GetEntitiesAsync(u=>_ids.Contains(u.id)); + visitList.ToList().ForEach(u => u.is_delete = (short)Common.Enum.DelFlagEnum.Deleted); + return await UpdateListAsync(visitList); + } + + public async Task> GetAllEntitiesTrueAsync() + { + return await GetEntitiesAsync(u=> u.is_delete == (short)Common.Enum.DelFlagEnum.Normal); + } + + } } diff --git a/Yi.Framework/Yi.Framework.Task/HttpJob.cs b/Yi.Framework/Yi.Framework.Task/HttpJob.cs new file mode 100644 index 00000000..a7763bf6 --- /dev/null +++ b/Yi.Framework/Yi.Framework.Task/HttpJob.cs @@ -0,0 +1,27 @@ +using Microsoft.Extensions.Logging; +using Quartz; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Yi.Framework.Job +{ + public class HttpJob : IJob + { + private ILogger _logger; + public HttpJob(ILogger logger) + { + _logger = logger; + } + + public Task Execute(IJobExecutionContext context) + { + return Task.Run(() => + { + + }); + } + } +} diff --git a/Yi.Framework/Yi.Framework.Task/VisitJob.cs b/Yi.Framework/Yi.Framework.Task/VisitJob.cs new file mode 100644 index 00000000..8c73e23e --- /dev/null +++ b/Yi.Framework/Yi.Framework.Task/VisitJob.cs @@ -0,0 +1,45 @@ + +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Logging; +using Quartz; +using System; +using System.IO; +using System.Text; +using System.Threading.Tasks; +using Yi.Framework.Common.Models; +using Yi.Framework.Model.ModelFactory; +using Yi.Framework.Model.Models; + +namespace Yi.Framework.Job +{ + public class VisitJob : IJob + { + private ILogger _logger; + private DbContext _DBWrite; + public VisitJob(ILogger logger, IDbContextFactory DbFactory) + { + _logger = logger; + _DBWrite = DbFactory.ConnWriteOrRead(Common.Enum.WriteAndReadEnum.Write); + } + + /// + /// 应该将拜访清零,并且写入数据库中的拜访表中 + /// + /// + /// + public Task Execute(IJobExecutionContext context) + { + return Task.Run(() => + { + + _DBWrite.Set().Add(new visit() { num = visitModel.visitNum, time = DateTime.Now }); + _DBWrite.SaveChanges(); + _logger.LogWarning("定时任务开始调度:" + nameof(VisitJob) + ":" + DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss") + $":访问总数为:{visitModel.visitNum}"); + visitModel.visitNum = 0; + } + + ); + } + } +} + diff --git a/Yi.Framework/Yi.Framework.Task/Yi.Framework.Job.csproj b/Yi.Framework/Yi.Framework.Task/Yi.Framework.Job.csproj new file mode 100644 index 00000000..7b71cf06 --- /dev/null +++ b/Yi.Framework/Yi.Framework.Task/Yi.Framework.Job.csproj @@ -0,0 +1,16 @@ + + + + net5.0 + + + + + + + + + + + + diff --git a/Yi.Framework/Yi.Framework.WebCore/MiddlewareExtend/CorsExtension.cs b/Yi.Framework/Yi.Framework.WebCore/MiddlewareExtend/CorsExtension.cs index d82443e4..cdfd12fe 100644 --- a/Yi.Framework/Yi.Framework.WebCore/MiddlewareExtend/CorsExtension.cs +++ b/Yi.Framework/Yi.Framework.WebCore/MiddlewareExtend/CorsExtension.cs @@ -15,7 +15,6 @@ namespace Yi.Framework.WebCore.MiddlewareExtend if (Appsettings.appBool("Cors_Enabled")) { - services.AddCors(options => options.AddPolicy("CorsPolicy",//解决跨域问题 builder => { diff --git a/Yi.Framework/Yi.Framework.WebCore/MiddlewareExtend/DbExtend.cs b/Yi.Framework/Yi.Framework.WebCore/MiddlewareExtend/DbExtend.cs index 53458505..afc20ff6 100644 --- a/Yi.Framework/Yi.Framework.WebCore/MiddlewareExtend/DbExtend.cs +++ b/Yi.Framework/Yi.Framework.WebCore/MiddlewareExtend/DbExtend.cs @@ -16,6 +16,7 @@ namespace Yi.Framework.WebCore.MiddlewareExtend { DbContextFactory.MutiDB_Enabled = Appsettings.appBool("MutiDB_Enabled"); DataContext.DbSelect = Appsettings.app("DbSelect"); + DataContext._connStr = Appsettings.app("DbConn", "WriteUrl"); services.Configure(Appsettings.appConfiguration("DbConn")); return services; } diff --git a/Yi.Framework/Yi.Framework.WebCore/MiddlewareExtend/QuartzExtensions.cs b/Yi.Framework/Yi.Framework.WebCore/MiddlewareExtend/QuartzExtensions.cs new file mode 100644 index 00000000..4dca1fd7 --- /dev/null +++ b/Yi.Framework/Yi.Framework.WebCore/MiddlewareExtend/QuartzExtensions.cs @@ -0,0 +1,34 @@ +using Autofac.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection; +using Quartz; +using Quartz.Impl; +using Quartz.Spi; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Yi.Framework.Core; +using Yi.Framework.Core.Quartz; + +namespace Yi.Framework.WebCore.MiddlewareExtend +{ + /// + /// 启动定时器服务,后台服务 + /// + public static class QuartzExtensions + { + /// + /// 使用定时器 + /// + /// + /// + public static IServiceCollection AddQuartzService(this IServiceCollection services) + { + services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(); + return services; + } + } + +} diff --git a/Yi.Framework/Yi.Framework.WebCore/Utility/CustomAutofacModule.cs b/Yi.Framework/Yi.Framework.WebCore/Utility/CustomAutofacModule.cs index 7db7d8f2..49e6c303 100644 --- a/Yi.Framework/Yi.Framework.WebCore/Utility/CustomAutofacModule.cs +++ b/Yi.Framework/Yi.Framework.WebCore/Utility/CustomAutofacModule.cs @@ -10,6 +10,7 @@ using System.IO; using System.Linq; using System.Reflection; using System.Threading.Tasks; +using Yi.Framework.Job; using Yi.Framework.Model.ModelFactory; using Yi.Framework.WebCore.Utility; using Module = Autofac.Module; @@ -18,26 +19,44 @@ namespace Yi.Framework.WebCore.Utility { public class CustomAutofacModule : Module { - protected override void Load(ContainerBuilder containerBuilder) + private Assembly GetDll(string ass) { - - containerBuilder.RegisterType().As().InstancePerDependency().EnableInterfaceInterceptors(); - var basePath = AppContext.BaseDirectory; - var servicesDllFile = Path.Combine(basePath, "Yi.Framework.Service.dll"); + var servicesDllFile = Path.Combine(basePath, ass); if (!(File.Exists(servicesDllFile))) { var msg = "service.dll 丢失,请编译后重新生成。"; throw new Exception(msg); } - var assemblysServices = Assembly.LoadFrom(servicesDllFile); + return Assembly.LoadFrom(servicesDllFile); ; + } + + protected override void Load(ContainerBuilder containerBuilder) + { + + containerBuilder.RegisterType().As().InstancePerDependency().EnableInterfaceInterceptors(); + + + + + +///反射注入服务层及接口层 + var assemblysServices = GetDll( "Yi.Framework.Service.dll"); containerBuilder.RegisterAssemblyTypes(assemblysServices) .AsImplementedInterfaces() .InstancePerDependency() .EnableInterfaceInterceptors(); - + +///反射注册任务调度层 + var assemblysJob = GetDll("Yi.Framework.Job.dll"); + containerBuilder.RegisterAssemblyTypes(assemblysJob) + .InstancePerDependency(); + + containerBuilder.Register(c => new CustomAutofacAop());//AOP注册 + + //containerBuilder.RegisterType().As().EnableInterfaceInterceptors();开启Aop //将数据库对象注入 diff --git a/Yi.Framework/Yi.Framework.WebCore/Yi.Framework.WebCore.csproj b/Yi.Framework/Yi.Framework.WebCore/Yi.Framework.WebCore.csproj index ce702729..a8cf0338 100644 --- a/Yi.Framework/Yi.Framework.WebCore/Yi.Framework.WebCore.csproj +++ b/Yi.Framework/Yi.Framework.WebCore/Yi.Framework.WebCore.csproj @@ -15,6 +15,7 @@ + diff --git a/Yi.Framework/Yi.Framework.sln b/Yi.Framework/Yi.Framework.sln index 01222fad..5858f43d 100644 --- a/Yi.Framework/Yi.Framework.sln +++ b/Yi.Framework/Yi.Framework.sln @@ -29,17 +29,19 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Framework.WebCore", "Yi. EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Framework.ApiMicroservice", "Yi.Framework.ApiMicroservice\Yi.Framework.ApiMicroservice.csproj", "{A95157D2-907F-411E-BA1D-A17F48C54A0E}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Yi.Framework.OcelotGateway", "Yi.Framework.OcelotGateway\Yi.Framework.OcelotGateway.csproj", "{671E38D8-ECAF-484B-A2AE-63DDC469C315}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Framework.OcelotGateway", "Yi.Framework.OcelotGateway\Yi.Framework.OcelotGateway.csproj", "{671E38D8-ECAF-484B-A2AE-63DDC469C315}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Yi.Framework.AuthenticationCenter", "Yi.Framework.AuthenticationCenter\Yi.Framework.AuthenticationCenter.csproj", "{694C0EC0-ED32-4E5D-8EA1-FB82E1303EAB}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Framework.AuthenticationCenter", "Yi.Framework.AuthenticationCenter\Yi.Framework.AuthenticationCenter.csproj", "{694C0EC0-ED32-4E5D-8EA1-FB82E1303EAB}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Yi.Framework.StaticPageProcessor", "Yi.Framework.StaticPageProcessor\Yi.Framework.StaticPageProcessor.csproj", "{D2BC3EBE-7F08-476E-9BB5-58A6F27AB31A}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Framework.StaticPageProcessor", "Yi.Framework.StaticPageProcessor\Yi.Framework.StaticPageProcessor.csproj", "{D2BC3EBE-7F08-476E-9BB5-58A6F27AB31A}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Yi.Framework.ElasticSearchProcessor", "Yi.Framework.ElasticSearchProcessor\Yi.Framework.ElasticSearchProcessor.csproj", "{EEF89893-A6A9-4C02-818C-D116C8EAE0EF}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Framework.ElasticSearchProcessor", "Yi.Framework.ElasticSearchProcessor\Yi.Framework.ElasticSearchProcessor.csproj", "{EEF89893-A6A9-4C02-818C-D116C8EAE0EF}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Yi.Framework.MSUnitTest", "Yi.Framework.MSUnitTest\Yi.Framework.MSUnitTest.csproj", "{531255B3-9669-4BC1-B4E5-A0C6E0540F0D}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Framework.MSUnitTest", "Yi.Framework.MSUnitTest\Yi.Framework.MSUnitTest.csproj", "{531255B3-9669-4BC1-B4E5-A0C6E0540F0D}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Yi.Framework.PageDetail", "Yi.Framework.PageDetail\Yi.Framework.PageDetail.csproj", "{637501E2-A32E-485C-8680-ED863D1793C2}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Framework.PageDetail", "Yi.Framework.PageDetail\Yi.Framework.PageDetail.csproj", "{637501E2-A32E-485C-8680-ED863D1793C2}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Yi.Framework.Job", "Yi.Framework.Task\Yi.Framework.Job.csproj", "{F1C990DD-32C3-4F02-83B0-6E52B18B0B17}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -103,6 +105,10 @@ Global {637501E2-A32E-485C-8680-ED863D1793C2}.Debug|Any CPU.Build.0 = Debug|Any CPU {637501E2-A32E-485C-8680-ED863D1793C2}.Release|Any CPU.ActiveCfg = Release|Any CPU {637501E2-A32E-485C-8680-ED863D1793C2}.Release|Any CPU.Build.0 = Release|Any CPU + {F1C990DD-32C3-4F02-83B0-6E52B18B0B17}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F1C990DD-32C3-4F02-83B0-6E52B18B0B17}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F1C990DD-32C3-4F02-83B0-6E52B18B0B17}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F1C990DD-32C3-4F02-83B0-6E52B18B0B17}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -122,6 +128,7 @@ Global {EEF89893-A6A9-4C02-818C-D116C8EAE0EF} = {D6B44435-EAFA-4D55-90D0-3AF80485FB83} {531255B3-9669-4BC1-B4E5-A0C6E0540F0D} = {C90E38FB-69EA-4997-8B3A-2C71EFA65B2B} {637501E2-A32E-485C-8680-ED863D1793C2} = {026D2797-07D1-4BA5-8070-50CDE0258C59} + {F1C990DD-32C3-4F02-83B0-6E52B18B0B17} = {9ABAF6B1-6C02-498A-90A2-ABC1140CF89A} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {1ED77A6E-377F-4EEF-A3D0-D65C94657DAF}