diff --git a/CC.Yi.API/CC.Yi.API.csproj b/CC.Yi.API/CC.Yi.API.csproj index 4e2559a2..3fc6c3d1 100644 --- a/CC.Yi.API/CC.Yi.API.csproj +++ b/CC.Yi.API/CC.Yi.API.csproj @@ -1,10 +1,13 @@ - + net5.0 + + + all runtime; build; native; contentfiles; analyzers; buildtransitive @@ -15,8 +18,34 @@ + + + + Always + + + + + + + + + + True + True + T4Startup.tt + + + + + + TextTemplatingFileGenerator + T4Startup.cs + + + diff --git a/CC.Yi.API/Controllers/StudentController.cs b/CC.Yi.API/Controllers/StudentController.cs index 5411f596..cdacfe7e 100644 --- a/CC.Yi.API/Controllers/StudentController.cs +++ b/CC.Yi.API/Controllers/StudentController.cs @@ -1,9 +1,22 @@ -using CC.Yi.IBLL; +using CC.Yi.Common; +using CC.Yi.Common.Cache; +using CC.Yi.Common.Jwt; +using CC.Yi.IBLL; +using CC.Yi.Model; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Caching.Distributed; using Microsoft.Extensions.Logging; +using Microsoft.IdentityModel.Tokens; +using ServiceStack.Redis; using System; using System.Collections.Generic; +using System.IdentityModel.Tokens.Jwt; using System.Linq; +using System.Security.Claims; +using System.Text; using System.Threading.Tasks; namespace CC.Yi.API.Controllers @@ -12,19 +25,138 @@ namespace CC.Yi.API.Controllers [Route("[controller]/[action]")] public class StudentController : ControllerBase { - private readonly ILogger _logger; + private readonly ILogger _logger;//处理日志相关文件 + + //private UserManager _userManager;//处理用户相关逻辑:添加密码,修改密码,添加删除角色等等 + //private SignInManager _signInManager;//处理注册登录的相关逻辑 + private IstudentBll _studentBll; public StudentController(ILogger logger, IstudentBll studentBll) { - _studentBll = studentBll; _logger = logger; + _logger.LogInformation("现在你进入了StudentController控制器"); + _studentBll = studentBll; + } + #region + //关于身份认证配置使用: + //在需要身份认证的控制器上打上 [Authorize] 特性标签 + #endregion + //[HttpGet] + //public async Task IdentityTest() + //{ + // //用户登入 + // var data = await _signInManager.PasswordSignInAsync("账号", "密码", false, false); //"是否记住密码","是否登入失败锁定用户" + // //用户登出 + // await _signInManager.SignOutAsync(); + // //创建用户 + // var data2 = await _userManager.CreateAsync(new result_user { UserName="账户",Email="邮箱"},"密码"); + // //获取用户 + // var data3 = _userManager.Users;//这里可以使用Linq表达式Select + // return Ok(); + //} + + [HttpGet] + public Result GetReids() + { + var data = CacheHelper.CacheWriter.GetCache("key01"); + return Result.Success(data); + } + #region + //下面,权限验证 + #endregion + + //发送令牌 + [HttpGet] + public Result Login(string role) + { + string userName = "admin"; + var claims = new[] + { + new Claim(JwtRegisteredClaimNames.Nbf,$"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}") , + new Claim (JwtRegisteredClaimNames.Exp,$"{new DateTimeOffset(DateTime.Now.AddMinutes(30)).ToUnixTimeSeconds()}"), + new Claim(ClaimTypes.Name, userName), + new Claim(ClaimTypes.Role,role) + + }; + var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(JwtConst.SecurityKey)); + var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256); + + var token = new JwtSecurityToken( + issuer: JwtConst.Domain, + audience: JwtConst.Domain, + claims: claims, + expires: DateTime.Now.AddMinutes(30), + signingCredentials: creds); + + var tokenData = new JwtSecurityTokenHandler().WriteToken(token); + return Result.Success("欢迎你!管理员!").SetData(new { token = tokenData }); } [HttpGet] - public IActionResult Test() + [Authorize(Policy = "myadmin")]//基于策略的验证 + public Result MyAdmin() { - var data = _studentBll.GetAllEntities().ToList(); - return Content(Common.JsonFactory.JsonToString(data)); + return Result.Success("欢迎你!管理员!"); + } + + [HttpGet] + [Authorize(Roles = "user")]//基于角色的验证 + public Result MyUser() + { + return Result.Success("欢迎你!游客!"); + } + + #region + //下面,经典的 增删改查 即为简易--Yi意框架 + //注意:请确保你的数据库中存在合理的数据 + #endregion + [HttpGet] + public async Task GetTest()//查 + { + _logger.LogInformation("调用查方法"); + var data =await _studentBll.GetAllEntities().ToListAsync(); + return Result.Success().SetData(data); + } + [HttpGet] + public Result AddTest()//增 + { + _logger.LogInformation("调用增方法"); + List students = new List() { new student { name = "学生a" }, new student { name = "学生d" } }; + if (_studentBll.Add(students)) + { + return Result.Success(); + } + else + { + return Result.Error(); + } + } + [HttpGet] + public Result RemoveTest()//删 + { + _logger.LogInformation("调用删方法"); + if (_studentBll.Delete(u => u.name == "学生a")) + { + return Result.Success(); + } + else + { + return Result.Error(); + } + } + [HttpGet] + public Result UpdateTest()//改 + { + _logger.LogInformation("调用改方法"); + if (_studentBll.Update(new student { id = 2, name = "学生a" }, "name")) + { + return Result.Success(); + } + else + { + return Result.Error(); + } + } } } diff --git a/CC.Yi.API/Extension/SwaggerExtension.cs b/CC.Yi.API/Extension/SwaggerExtension.cs new file mode 100644 index 00000000..6db50f61 --- /dev/null +++ b/CC.Yi.API/Extension/SwaggerExtension.cs @@ -0,0 +1,76 @@ +using Microsoft.AspNetCore.Builder; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.OpenApi.Models; +using System; +using System.IO; + +namespace CC.Yi.API.Extension +{ + /// + /// Swagger文档扩展方法 + /// + public static class SwaggerExtension + { + public static IServiceCollection AddSwaggerService(this IServiceCollection services) + { + var apiInfo = new OpenApiInfo + { + Title = "Yi意框架-API接口", + Version = "v1", + Contact = new OpenApiContact { Name = "橙子", Email = "454313500@qq.com", Url = new System.Uri("https://jiftcc.com") } + }; + #region 注册Swagger服务 + services.AddSwaggerGen(c => + { + c.SwaggerDoc("v1", apiInfo); + + //添加注释服务 + //为 Swagger JSON and UI设置xml文档注释路径 + //获取应用程序所在目录(绝对路径,不受工作目录影响,建议采用此方法获取路径使用windwos&Linux) + var basePath = Path.GetDirectoryName(typeof(Program).Assembly.Location); + var apiXmlPath = Path.Combine(basePath, @"ApiDoc.xml");//控制器层注释 + var entityXmlPath = Path.Combine(basePath, @"Model\ModelDoc.xml");//实体注释 + //c.IncludeXmlComments(apiXmlPath, true);//true表示显示控制器注释 + //c.IncludeXmlComments(entityXmlPath); + + //添加控制器注释 + //c.DocumentFilter(); + + //添加header验证信息 + //c.OperationFilter(); + //var security = new Dictionary> { { "Bearer", new string[] { } }, }; + + c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme() + { + Description = "文本框里输入从服务器获取的Token。格式为:Bearer + 空格+token",//JWT授权(数据将在请求头中进行传输) 参数结构: \"Authorization: Bearer {token}\" + Name = "Authorization",////jwt默认的参数名称 + In = ParameterLocation.Header,////jwt默认存放Authorization信息的位置(请求头中) + Type = SecuritySchemeType.ApiKey, + }); + c.AddSecurityRequirement(new OpenApiSecurityRequirement + { + { new OpenApiSecurityScheme + { + Reference = new OpenApiReference() + { + Id = "Bearer", + Type = ReferenceType.SecurityScheme + } + }, Array.Empty() } + }); + }); + #endregion + + return services; + } + + public static void UseSwaggerService(this IApplicationBuilder app) + { + //在 Startup.Configure 方法中,启用中间件为生成的 JSON 文档和 Swagger UI 提供服务: + // Enable middleware to serve generated Swagger as a JSON endpoint. + app.UseSwagger(); + app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "JwtTest v1")); + } + + } +} diff --git a/CC.Yi.API/Filter/DbContextFilter.cs b/CC.Yi.API/Filter/DbContextFilter.cs new file mode 100644 index 00000000..fc1bc2d1 --- /dev/null +++ b/CC.Yi.API/Filter/DbContextFilter.cs @@ -0,0 +1,21 @@ +using CC.Yi.DAL; +using CC.Yi.Model; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Filters; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace CC.Yi.API.Filter +{ + public class DbContextFilter : ActionFilterAttribute + { + public override void OnActionExecuting(ActionExecutingContext filterContext) + { + + base.OnActionExecuting(filterContext); + + } + } +} diff --git a/CC.Yi.API/Migrations/20210319112041_yi1.Designer.cs b/CC.Yi.API/Migrations/20210413063257_y1.Designer.cs similarity index 56% rename from CC.Yi.API/Migrations/20210319112041_yi1.Designer.cs rename to CC.Yi.API/Migrations/20210413063257_y1.Designer.cs index fa669c28..e6c4a383 100644 --- a/CC.Yi.API/Migrations/20210319112041_yi1.Designer.cs +++ b/CC.Yi.API/Migrations/20210413063257_y1.Designer.cs @@ -2,33 +2,29 @@ using CC.Yi.Model; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; namespace CC.Yi.API.Migrations { [DbContext(typeof(DataContext))] - [Migration("20210319112041_yi1")] - partial class yi1 + [Migration("20210413063257_y1")] + partial class y1 { protected override void BuildTargetModel(ModelBuilder modelBuilder) { #pragma warning disable 612, 618 modelBuilder - .HasAnnotation("Relational:MaxIdentifierLength", 128) - .HasAnnotation("ProductVersion", "5.0.4") - .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + .HasAnnotation("ProductVersion", "5.0.5"); modelBuilder.Entity("CC.Yi.Model.student", b => { b.Property("id") .ValueGeneratedOnAdd() - .HasColumnType("int") - .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + .HasColumnType("INTEGER"); - b.Property("name") - .HasColumnType("int"); + b.Property("name") + .HasColumnType("TEXT"); b.HasKey("id"); diff --git a/CC.Yi.API/Migrations/20210319112041_yi1.cs b/CC.Yi.API/Migrations/20210413063257_y1.cs similarity index 71% rename from CC.Yi.API/Migrations/20210319112041_yi1.cs rename to CC.Yi.API/Migrations/20210413063257_y1.cs index 03299091..532822d9 100644 --- a/CC.Yi.API/Migrations/20210319112041_yi1.cs +++ b/CC.Yi.API/Migrations/20210413063257_y1.cs @@ -2,7 +2,7 @@ namespace CC.Yi.API.Migrations { - public partial class yi1 : Migration + public partial class y1 : Migration { protected override void Up(MigrationBuilder migrationBuilder) { @@ -10,9 +10,9 @@ namespace CC.Yi.API.Migrations name: "student", columns: table => new { - id = table.Column(type: "int", nullable: false) - .Annotation("SqlServer:Identity", "1, 1"), - name = table.Column(type: "int", nullable: false) + id = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + name = table.Column(type: "TEXT", nullable: true) }, constraints: table => { diff --git a/CC.Yi.API/Migrations/DataContextModelSnapshot.cs b/CC.Yi.API/Migrations/DataContextModelSnapshot.cs index d2ae13a7..d49b625c 100644 --- a/CC.Yi.API/Migrations/DataContextModelSnapshot.cs +++ b/CC.Yi.API/Migrations/DataContextModelSnapshot.cs @@ -2,7 +2,6 @@ using CC.Yi.Model; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; namespace CC.Yi.API.Migrations @@ -14,19 +13,16 @@ namespace CC.Yi.API.Migrations { #pragma warning disable 612, 618 modelBuilder - .HasAnnotation("Relational:MaxIdentifierLength", 128) - .HasAnnotation("ProductVersion", "5.0.4") - .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + .HasAnnotation("ProductVersion", "5.0.5"); modelBuilder.Entity("CC.Yi.Model.student", b => { b.Property("id") .ValueGeneratedOnAdd() - .HasColumnType("int") - .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + .HasColumnType("INTEGER"); - b.Property("name") - .HasColumnType("int"); + b.Property("name") + .HasColumnType("TEXT"); b.HasKey("id"); diff --git a/CC.Yi.API/Program.cs b/CC.Yi.API/Program.cs index 5457af7a..188d6514 100644 --- a/CC.Yi.API/Program.cs +++ b/CC.Yi.API/Program.cs @@ -1,7 +1,11 @@ +using Autofac.Extensions.DependencyInjection; +using CC.Yi.DAL; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; +using NLog.Web; using System; using System.Collections.Generic; using System.Linq; @@ -13,14 +17,49 @@ namespace CC.Yi.API { public static void Main(string[] args) { - CreateHostBuilder(args).Build().Run(); + + + var logger = NLog.Web.NLogBuilder.ConfigureNLog("nlog.config").GetCurrentClassLogger(); + try + { + logger.Debug("Yiܡ"); + var host = CreateHostBuilder(args).Build(); + //var scope = host.Services.CreateScope(); + //var services = scope.ServiceProvider; + //var context = services.GetRequiredService();//ȡ + //DbContentFactory.Initialize(context);//þ̬෽ע + host.Run(); + logger.Info("Yiɹ"); + } + catch (Exception exception) + { + //NLog: catch setup errors + logger.Error(exception, "Stopped program because of exception"); + throw; + } + finally + { + // Ensure to flush and stop internal timers/threads before application-exit (Avoid segmentation fault on Linux) + NLog.LogManager.Shutdown(); + } + + + + } public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureWebHostDefaults(webBuilder => { - webBuilder.UseStartup(); - }); + + webBuilder.UseUrls("http://*:19000").UseStartup(); + }).UseServiceProviderFactory(new AutofacServiceProviderFactory()) + .ConfigureLogging(logging => + { + // logging.ClearProviders(); // п̨ + logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace); + }).UseNLog();//nlog־ + } } diff --git a/CC.Yi.API/Startup.cs b/CC.Yi.API/Startup.cs index fe9446c4..eb7e6c23 100644 --- a/CC.Yi.API/Startup.cs +++ b/CC.Yi.API/Startup.cs @@ -1,22 +1,30 @@ - +using Autofac; +using Autofac.Extras.DynamicProxy; +using CC.Yi.API.Extension; using CC.Yi.BLL; +using CC.Yi.Common.Castle; +using CC.Yi.Common.Jwt; using CC.Yi.DAL; using CC.Yi.IBLL; using CC.Yi.IDAL; using CC.Yi.Model; +using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.HttpsPolicy; +using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; +using Microsoft.IdentityModel.Tokens; using Microsoft.OpenApi.Models; using System; using System.Collections.Generic; using System.Linq; +using System.Text; using System.Threading.Tasks; namespace CC.Yi.API @@ -33,20 +41,80 @@ namespace CC.Yi.API // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { - - services.AddControllers(); - services.AddSwaggerGen(c => + services.AddAuthorization(options => { - c.SwaggerDoc("v1", new OpenApiInfo { Title = "CC.Yi.API", Version = "v1" }); + //ûڲԵ֤ + options.AddPolicy("myadmin", policy => + policy.RequireRole("admin")); }); - string connection = Configuration["ConnectionStringBySQL"]; + + + services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) + .AddJwtBearer(options => { + options.TokenValidationParameters = new TokenValidationParameters + { + ValidateIssuer = true,//Ƿ֤Issuer + ValidateAudience = true,//Ƿ֤Audience + ValidateLifetime = true,//Ƿ֤ʧЧʱ + ClockSkew = TimeSpan.FromSeconds(30), + ValidateIssuerSigningKey = true,//Ƿ֤SecurityKey + ValidAudience = JwtConst.Domain,//Audience + ValidIssuer = JwtConst.Domain,//Issuerǰǩjwtһ + IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(JwtConst.SecurityKey))//õSecurityKey + }; + }); + services.AddControllers(); + services.AddSwaggerService(); + services.AddSession(); + + //ù + Action filters = new Action(r => { + //r.Filters.Add(typeof(DbContextFilter)); + }); + services.AddMvc(filters); + string connection1 = Configuration["ConnectionStringBySQL"]; string connection2 = Configuration["ConnectionStringByMySQL"]; + string connection3 = Configuration["ConnectionStringBySQLite"]; services.AddDbContext(options => { - options.UseSqlServer(connection, b => b.MigrationsAssembly("CC.Yi.API"));//ݿ + options.UseSqlite(connection3, b => b.MigrationsAssembly("CC.Yi.API"));//ݿ }); - services.AddScoped(typeof(IBaseDal<>), typeof(BaseDal<>)); - services.AddScoped(typeof(IstudentBll), typeof(studentBll)); + + + //עתAutofac + //services.AddScoped(typeof(IBaseDal<>), typeof(BaseDal<>)); + //services.AddScoped(typeof(IstudentBll), typeof(studentBll)); + + + + //Identity֤ + //services.AddIdentity(options => + // { + // options.Password.RequiredLength = 6;//̳ + // options.Password.RequireDigit = false;// + // options.Password.RequireLowercase = false;//Сдĸ + // options.Password.RequireNonAlphanumeric = false;//ַ + // options.Password.RequireUppercase = false;//дĸ + // //options.User.RequireUniqueEmail = false;//עǷԲظ + // //options.User.AllowedUserNameCharacters="abcd"//ַֻ + //}).AddEntityFrameworkStores().AddDefaultTokenProviders(); + services.AddCors(options => options.AddPolicy("CorsPolicy",// + builder => + { + builder.AllowAnyMethod() + .SetIsOriginAllowed(_ => true) + .AllowAnyHeader() + .AllowCredentials(); + })); + } + + //ʼʹú + private void InitData(IServiceProvider serviceProvider) + { + //var serviceScope = serviceProvider.GetRequiredService().CreateScope(); + + //var context = serviceScope.ServiceProvider.GetService(); + //DbContentFactory.Initialize(context);//þ̬෽ע } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. @@ -55,20 +123,22 @@ namespace CC.Yi.API if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); - app.UseSwagger(); - app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "CC.Yi.API v1")); + app.UseSwaggerService(); } + + app.UseCors("CorsPolicy"); app.UseHttpsRedirection(); - + app.UseSession(); app.UseRouting(); - + app.UseAuthentication(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); + InitData(app.ApplicationServices); } } } diff --git a/CC.Yi.API/T4Startup.cs b/CC.Yi.API/T4Startup.cs new file mode 100644 index 00000000..75e8a6fd --- /dev/null +++ b/CC.Yi.API/T4Startup.cs @@ -0,0 +1,23 @@ +using Autofac; +using Autofac.Extras.DynamicProxy; +using CC.Yi.BLL; +using CC.Yi.Common.Castle; +using CC.Yi.DAL; +using CC.Yi.IBLL; +using CC.Yi.IDAL; +using System; + + +namespace CC.Yi.API +{ + public partial class Startup + { + //动态 面向AOP思想的依赖注入 Autofac + public void ConfigureContainer(ContainerBuilder builder) + { + builder.RegisterType(typeof(CustomAutofacAop)); + builder.RegisterGeneric(typeof(BaseDal<>)).As(typeof(IBaseDal<>)); + builder.RegisterType().As().EnableInterfaceInterceptors();//表示注入前后要执行Castle,AOP + } + } +} \ No newline at end of file diff --git a/CC.Yi.DALFactory/T4DbSession.tt b/CC.Yi.API/T4Startup.tt similarity index 54% rename from CC.Yi.DALFactory/T4DbSession.tt rename to CC.Yi.API/T4Startup.tt index 541800d5..166ebfc5 100644 --- a/CC.Yi.DALFactory/T4DbSession.tt +++ b/CC.Yi.API/T4Startup.tt @@ -13,24 +13,28 @@ sr.Close(); string[] ModelData= txt.Split(','); #> +using Autofac; +using Autofac.Extras.DynamicProxy; +using CC.Yi.BLL; +using CC.Yi.Common.Castle; using CC.Yi.DAL; +using CC.Yi.IBLL; using CC.Yi.IDAL; using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -namespace CC.Yi.DALFactory + +namespace CC.Yi.API { - public partial class DbSession : IDbSession + public partial class Startup { -<# foreach(string k in ModelData){ - #> - public I<#=k #>Dal <#=k #>Dal + //动态 面向AOP思想的依赖注入 Autofac + public void ConfigureContainer(ContainerBuilder builder) { - get { return StaticDalFactory.Get<#=k #>Dal(); } - } - + builder.RegisterType(typeof(CustomAutofacAop)); + builder.RegisterGeneric(typeof(BaseDal<>)).As(typeof(IBaseDal<>)); +<# foreach(string k in ModelData){#> + builder.RegisterType<<#=k #>Bll>().AsBll>().EnableInterfaceInterceptors();//表示注入前后要执行Castle,AOP <# } #> + } } } \ No newline at end of file diff --git a/CC.Yi.API/YIDB.db b/CC.Yi.API/YIDB.db new file mode 100644 index 00000000..5aff9324 Binary files /dev/null and b/CC.Yi.API/YIDB.db differ diff --git a/CC.Yi.API/appsettings.json b/CC.Yi.API/appsettings.json index 8fcd04df..23b05466 100644 --- a/CC.Yi.API/appsettings.json +++ b/CC.Yi.API/appsettings.json @@ -7,6 +7,8 @@ } }, "AllowedHosts": "*", - "ConnectionStringBySQL": "server=.;Database=cctest;UId=sa;PWD=Qz52013142020.", - "ConnectionStringByMySQL": "Data Source=49.235.212.122;Database=GraduationProject;User ID=root;Password=Qz52013142020.;pooling=true;port=3306;sslmode=none;CharSet=utf8;" + + "ConnectionStringBySQL": "server=.;Database=YIDB;UId=sa;PWD=52013142020.", + "ConnectionStringByMySQL": "Data Source=.;Database=YIDB;User ID=root;Password=52013142020.;pooling=true;port=3306;sslmode=none;CharSet=utf8;", + "ConnectionStringBySQLite": "Filename=YIDB.db" } diff --git a/CC.Yi.API/nlog.config b/CC.Yi.API/nlog.config new file mode 100644 index 00000000..ff359770 --- /dev/null +++ b/CC.Yi.API/nlog.config @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/CC.Yi.BLL/BaseBll.cs b/CC.Yi.BLL/BaseBll.cs index 5e7a1a4f..9a5c02b6 100644 --- a/CC.Yi.BLL/BaseBll.cs +++ b/CC.Yi.BLL/BaseBll.cs @@ -1,6 +1,7 @@ -using CC.Yi.DALFactory; -using CC.Yi.IBLL; +using CC.Yi.IBLL; using CC.Yi.IDAL; +using CC.Yi.Model; +using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; using System.Linq; @@ -11,10 +12,13 @@ namespace CC.Yi.BLL public class BaseBll : IBaseBll where T : class, new() { public IBaseDal CurrentDal; - public BaseBll(IBaseDal cd) + public DbContext DbSession; + public BaseBll(IBaseDal cd, DataContext _Db) { CurrentDal = cd; + DbSession = _Db; } + public IQueryable GetAllEntities() { return CurrentDal.GetAllEntities(); @@ -49,37 +53,53 @@ namespace CC.Yi.BLL return entity; } + public bool Add(IEnumerable entities) + { + CurrentDal.AddRange(entities); + return DbSession.SaveChanges() > 0; + } + public bool Update(T entity) { CurrentDal.Update(entity); return DbSession.SaveChanges() > 0; } + public bool Update(T entity, params string[] propertyNames) + { + CurrentDal.Update(entity,propertyNames); + return DbSession.SaveChanges() > 0; + } + public bool Delete(T entity) { CurrentDal.Delete(entity); return DbSession.SaveChanges() > 0; } - public IDbSession DbSession - { - get - { - return DbSessionFactory.GetCurrentDbSession(); - } - } public bool Delete(int id) { CurrentDal.Detete(id); return DbSession.SaveChanges() > 0; } - public int DeleteList(List ids) + public bool Delete(IEnumerable ids) { foreach (var id in ids) { CurrentDal.Detete(id); } - return DbSession.SaveChanges();//这里把SaveChanges方法提到了循环体外,自然就与数据库交互一次 + return DbSession.SaveChanges()>0; + } + public bool Delete(Expression> where) + { + IQueryable entities = CurrentDal.GetEntities(where); + if (entities != null) + { + CurrentDal.DeteteRange(entities); + + return DbSession.SaveChanges()>0; + } + return false; } } diff --git a/CC.Yi.BLL/CC.Yi.BLL.csproj b/CC.Yi.BLL/CC.Yi.BLL.csproj index ce6c0299..6a379c1e 100644 --- a/CC.Yi.BLL/CC.Yi.BLL.csproj +++ b/CC.Yi.BLL/CC.Yi.BLL.csproj @@ -5,7 +5,6 @@ - diff --git a/CC.Yi.BLL/T4BLL.cs b/CC.Yi.BLL/T4BLL.cs index da68edd2..a74dc943 100644 --- a/CC.Yi.BLL/T4BLL.cs +++ b/CC.Yi.BLL/T4BLL.cs @@ -6,14 +6,16 @@ using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; namespace CC.Yi.BLL { public partial class studentBll : BaseBll, IstudentBll { - public studentBll(IBaseDal cd):base(cd) + public studentBll(IBaseDal cd,DataContext _Db):base(cd,_Db) { CurrentDal = cd; + DbSession = _Db; } } } \ No newline at end of file diff --git a/CC.Yi.BLL/T4BLL.tt b/CC.Yi.BLL/T4BLL.tt index dcda0135..21a5d42d 100644 --- a/CC.Yi.BLL/T4BLL.tt +++ b/CC.Yi.BLL/T4BLL.tt @@ -21,6 +21,7 @@ using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; namespace CC.Yi.BLL { @@ -28,9 +29,10 @@ namespace CC.Yi.BLL #> public partial class <#=k #>Bll : BaseBll<<#=k #>>, I<#=k #>Bll { - public <#=k #>Bll(IBaseDal<<#=k #>> cd):base(cd) + public <#=k #>Bll(IBaseDal<<#=k #>> cd,DataContext _Db):base(cd,_Db) { CurrentDal = cd; + DbSession = _Db; } } <# } #> diff --git a/CC.Yi.Common/CC.Yi.Common.csproj b/CC.Yi.Common/CC.Yi.Common.csproj index a20524d3..520a2f8c 100644 --- a/CC.Yi.Common/CC.Yi.Common.csproj +++ b/CC.Yi.Common/CC.Yi.Common.csproj @@ -1,11 +1,16 @@ - + netcoreapp3.1 + + + + + diff --git a/CC.Yi.Common/Cache/CacheHelper.cs b/CC.Yi.Common/Cache/CacheHelper.cs new file mode 100644 index 00000000..e77f8fbc --- /dev/null +++ b/CC.Yi.Common/Cache/CacheHelper.cs @@ -0,0 +1,51 @@ +using Autofac; +using Microsoft.AspNetCore.Http; +using System; +using System.Collections.Generic; +using System.Text; + +namespace CC.Yi.Common.Cache +{ + public class CacheHelper + { + public static ICacheWriter CacheWriter { get; set; } + static CacheHelper() + { + CacheHelper.CacheWriter = new RedisCache(); + } + + + + + public bool AddCache(string key, T value, DateTime expDate) + { + return CacheWriter.AddCache(key,value,expDate); + } + + public bool AddCache(string key, T value) + { + return CacheWriter.AddCache(key, value); + } + + public bool RemoveCache(string key) + { + return CacheWriter.RemoveCache(key); + } + + public T GetCache(string key) + { + return CacheWriter.GetCache(key); + } + + public bool SetCache(string key, T value, DateTime expDate) + { + return CacheWriter.SetCache(key,value,expDate); + } + + public bool SetCache(string key, T value) + { + return CacheWriter.SetCache(key, value); + } + + } +} diff --git a/CC.Yi.Common/Cache/ICacheWriter.cs b/CC.Yi.Common/Cache/ICacheWriter.cs new file mode 100644 index 00000000..712f6857 --- /dev/null +++ b/CC.Yi.Common/Cache/ICacheWriter.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CC.Yi.Common.Cache +{ + public interface ICacheWriter + { + bool AddCache(string key, T value, DateTime expDate); + bool AddCache(string key, T value); + bool RemoveCache(string key); + T GetCache(string key); + bool SetCache(string key, T value, DateTime expDate); + bool SetCache(string key, T value); + } +} diff --git a/CC.Yi.Common/Cache/RedisCache.cs b/CC.Yi.Common/Cache/RedisCache.cs new file mode 100644 index 00000000..a1273002 --- /dev/null +++ b/CC.Yi.Common/Cache/RedisCache.cs @@ -0,0 +1,46 @@ +using ServiceStack.Redis; +using System; +using System.Collections.Generic; +using System.Text; + +namespace CC.Yi.Common.Cache +{ + public class RedisCache : ICacheWriter + { + private RedisClient client; + public RedisCache() + { + client = new RedisClient("127.0.0.1", 6379, "52013142020."); + } + + public bool AddCache(string key, T value, DateTime expDate) + { + return client.Add(key, value, expDate); + } + + public bool AddCache(string key, T value) + { + return client.Add(key, value); + } + + public bool RemoveCache(string key) + { + return client.Remove(key); + } + + public T GetCache(string key) + { + return client.Get(key); + } + + public bool SetCache(string key,T value, DateTime expDate) + { + return client.Set(key, value, expDate); + } + + public bool SetCache(string key, T value) + { + return client.Set(key, value); + } + } +} diff --git a/CC.Yi.Common/Castle/CustomAutofacAop.cs b/CC.Yi.Common/Castle/CustomAutofacAop.cs new file mode 100644 index 00000000..526d39ef --- /dev/null +++ b/CC.Yi.Common/Castle/CustomAutofacAop.cs @@ -0,0 +1,23 @@ +using Castle.DynamicProxy; +using System; +using System.Collections.Generic; +using System.Text; + +namespace CC.Yi.Common.Castle +{ + public class CustomAutofacAop : IInterceptor + { + public void Intercept(IInvocation invocation) + { + { + + //这里写执行方法前 + } + invocation.Proceed();//执行具体的实例 + { + + //这里写执行方法后 + } + } + } +} diff --git a/CC.Yi.Common/HttpHelper.cs b/CC.Yi.Common/HttpHelper.cs new file mode 100644 index 00000000..6bfdfb18 --- /dev/null +++ b/CC.Yi.Common/HttpHelper.cs @@ -0,0 +1,76 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading.Tasks; + +namespace CC.Yi.Common +{ + public static class HttpHelper + { + public static string HttpGet(string Url, string postDataStr="") + { + HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url + (postDataStr == "" ? "" : "?") + postDataStr); + request.Method = "GET"; + request.ContentType = "text/html;charset=UTF-8"; + + HttpWebResponse response = (HttpWebResponse)request.GetResponse(); + Stream myResponseStream = response.GetResponseStream(); + StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.GetEncoding("utf-8")); + string retString = myStreamReader.ReadToEnd(); + myStreamReader.Close(); + myResponseStream.Close(); + + return retString; + } + + public static bool HttpIOGet(string Url, string file, string postDataStr="") + { + HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url + (postDataStr == "" ? "" : "?") + postDataStr); + request.Method = "GET"; + request.ContentType = "text/html;charset=UTF-8"; + + HttpWebResponse response = (HttpWebResponse)request.GetResponse(); + Stream myResponseStream = response.GetResponseStream(); + FileStream writer = new FileStream(file, FileMode.OpenOrCreate, FileAccess.Write); + byte[] buffer = new byte[1024]; + int c; + while ((c = myResponseStream.Read(buffer, 0, buffer.Length)) > 0) + { + writer.Write(buffer, 0, c); + } + writer.Close(); + myResponseStream.Close(); + + return true; + } + + public static string HttpPost(string Url, string postDataStr="") + { + CookieContainer cookie = new CookieContainer(); + HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url); + request.Method = "POST"; + request.ContentType = "application/x-www-form-urlencoded"; + request.ContentLength = Encoding.UTF8.GetByteCount(postDataStr); + request.CookieContainer = cookie; + Stream myRequestStream = request.GetRequestStream(); + StreamWriter myStreamWriter = new StreamWriter(myRequestStream, Encoding.GetEncoding("gb2312")); + myStreamWriter.Write(postDataStr); + myStreamWriter.Close(); + + HttpWebResponse response = (HttpWebResponse)request.GetResponse(); + + response.Cookies = cookie.GetCookies(response.ResponseUri); + Stream myResponseStream = response.GetResponseStream(); + StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.GetEncoding("utf-8")); + string retString = myStreamReader.ReadToEnd(); + myStreamReader.Close(); + myResponseStream.Close(); + + return retString; + } + } +} diff --git a/CC.Yi.Common/JsonFactory.cs b/CC.Yi.Common/JsonFactory.cs deleted file mode 100644 index f51b56c4..00000000 --- a/CC.Yi.Common/JsonFactory.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; - -namespace CC.Yi.Common -{ - public static class JsonFactory - { - public static string JsonToString(object q) - { - return Newtonsoft.Json.JsonConvert.SerializeObject(q); - } - } -} diff --git a/CC.Yi.Common/JsonHelper.cs b/CC.Yi.Common/JsonHelper.cs new file mode 100644 index 00000000..ea9b4c2d --- /dev/null +++ b/CC.Yi.Common/JsonHelper.cs @@ -0,0 +1,24 @@ +using System; + +namespace CC.Yi.Common +{ + public static class JsonHelper + { + public static string JsonToString(object data = null, int code = 200, bool flag = true, string message = "成功") + { + return Newtonsoft.Json.JsonConvert.SerializeObject(new { code = code, flag = flag, message = message, data = data }); + } + public static string JsonToString2(object data = null, int code = 200, bool flag = true, string message = "成功", int count = 0) + { + return Newtonsoft.Json.JsonConvert.SerializeObject(new { code = code, flag = flag, message = message, count = count, data = data }); + } + public static string ToString(object data) + { + return Newtonsoft.Json.JsonConvert.SerializeObject(data); + } + public static T ToJson(string data) + { + return Newtonsoft.Json.JsonConvert.DeserializeObject(data); + } + } +} diff --git a/CC.Yi.Common/Jwt/JwtConst.cs b/CC.Yi.Common/Jwt/JwtConst.cs new file mode 100644 index 00000000..1e7713ff --- /dev/null +++ b/CC.Yi.Common/Jwt/JwtConst.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace CC.Yi.Common.Jwt +{ + public class JwtConst + { + public const string SecurityKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDI2a2EJ7m872v0afyoSDJT2o1+SitIeJSWtLJU8/Wz2m7gStexajkeD+Lka6DSTy8gt9UwfgVQo6uKjVLG5Ex7PiGOODVqAEghBuS7JzIYU5RvI543nNDAPfnJsas96mSA7L/mD7RTE2drj6hf3oZjJpMPZUQI/B1Qjb5H3K3PNwIDAQAB"; + public const string Domain = "http://localhost:5000"; + } +} diff --git a/CC.Yi.Common/Result.cs b/CC.Yi.Common/Result.cs new file mode 100644 index 00000000..400df0f8 --- /dev/null +++ b/CC.Yi.Common/Result.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; + +namespace CC.Yi.Common +{ + /// + /// 结果数据 + /// + public class Result + { + public bool status { get; set; } + public int code { get; set; } + public string msg { get; set; } + public object data { get; set; } + public static Result Instance(bool status, string msg) + { + return new Result() { status = status,code=500, msg = msg }; + } + public static Result Error(string msg="fail") + { + return new Result() { status = false, code = 500, msg = msg }; + } + public static Result Success(string msg= "succeed") + { + return new Result() { status = true, code = 200, msg = msg }; + } + public Result SetData(object obj) + { + this.data = obj; + return this; + } + public Result SetCode(int Code) + { + this.code = Code; + return this; + } + } +} \ No newline at end of file diff --git a/CC.Yi.Common/imageHelper.cs b/CC.Yi.Common/imageHelper.cs new file mode 100644 index 00000000..170aba9c --- /dev/null +++ b/CC.Yi.Common/imageHelper.cs @@ -0,0 +1,167 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using System.IO; +using System.IO.Compression; +using System.Drawing; + +namespace CC.Yi.Common +{ + public class SimilarPhoto + { + Image SourceImg; + public SimilarPhoto(string filePath) + { + SourceImg = Image.FromFile(filePath); + } + public SimilarPhoto(Stream stream) + { + SourceImg = Image.FromStream(stream); + } + public String GetHash() + { + Image image = ReduceSize(); + Byte[] grayValues = ReduceColor(image); + Byte average = CalcAverage(grayValues); + String reslut = ComputeBits(grayValues, average); + return reslut; + } + // Step 1 : Reduce size to 8*8 + private Image ReduceSize(int width = 8, int height = 8) + { + Image image = SourceImg.GetThumbnailImage(width, height, () => { return false; }, IntPtr.Zero); + return image; + } + // Step 2 : Reduce Color + private Byte[] ReduceColor(Image image) + { + Bitmap bitMap = new Bitmap(image); + Byte[] grayValues = new Byte[image.Width * image.Height]; + for (int x = 0; x < image.Width; x++) + for (int y = 0; y < image.Height; y++) + { + Color color = bitMap.GetPixel(x, y); + byte grayValue = (byte)((color.R * 30 + color.G * 59 + color.B * 11) / 100); + grayValues[x * image.Width + y] = grayValue; + } + return grayValues; + } + // Step 3 : Average the colors + private Byte CalcAverage(byte[] values) + { + int sum = 0; + for (int i = 0; i < values.Length; i++) + sum += (int)values[i]; + return Convert.ToByte(sum / values.Length); + } + // Step 4 : Compute the bits + private String ComputeBits(byte[] values, byte averageValue) + { + char[] result = new char[values.Length]; + for (int i = 0; i < values.Length; i++) + { + if (values[i] < averageValue) + result[i] = '0'; + else + result[i] = '1'; + } + SourceImg.Dispose(); + return new String(result); + } + // Compare hash + public static Int32 CalcSimilarDegree(string a, string b) + { + if (a.Length != b.Length) + throw new ArgumentException(); + int count = 0; + for (int i = 0; i < a.Length; i++) + { + if (a[i] != b[i]) + count++; + } + return count; + } + } + public static class imageHelper + { + public static int Compare(string filePath1, string filePath2) + { + SimilarPhoto photo1 = new SimilarPhoto(filePath1); + SimilarPhoto photo2 = new SimilarPhoto(filePath2); + return SimilarPhoto.CalcSimilarDegree(photo1.GetHash(), photo2.GetHash()); + } + public static bool ByStringToSave(string name, string iss) + { + iss = iss.Replace("data:image/png;base64,", "").Replace("data:image/jgp;base64,", "") + .Replace("data:image/jpg;base64,", "").Replace("data:image/jpeg;base64,", ""); + byte[] arr = Convert.FromBase64String(iss); + MemoryStream ms = new MemoryStream(arr); + Bitmap bmp = new Bitmap(ms); + string StudentWorkImages = "StudentWorkImages"; + + if (Directory.Exists(@"./wwwroot/" + StudentWorkImages) == false)//如果不存在就创建file文件夹 + { + Directory.CreateDirectory(@"./wwwroot/" + StudentWorkImages); + } + + + + bmp.Save(@"./wwwroot/" + StudentWorkImages + "/" + name + ".jpg", System.Drawing.Imaging.ImageFormat.Jpeg); + ms.Close(); + return true; + } + public static bool CreateZip() + { + string file_path = @"./wwwroot/StudentWorkImages.zip"; + string file_path2 = @"./wwwroot/StudentWorkImages/"; + if (File.Exists(file_path)) + { + File.Delete(file_path); + } + + ZipFile.CreateFromDirectory(file_path2, file_path); + return true; + } + public static bool DeleteAll() + { + string file_path = @"./wwwroot/StudentWorkImages/"; + if (Directory.Exists(file_path)) + { + DelectDir(file_path); + return true; + } + else + return false; + } + public static bool DeleteByString(string name) + { + File.Delete(@"./wwwroot/StudentWorkImages/" + name + ".jpg"); + return true; + } + public static void DelectDir(string srcPath) + { + try + { + DirectoryInfo dir = new DirectoryInfo(srcPath); + FileSystemInfo[] fileinfo = dir.GetFileSystemInfos(); //返回目录中所有文件和子目录 + foreach (FileSystemInfo i in fileinfo) + { + if (i is DirectoryInfo) //判断是否文件夹 + { + DirectoryInfo subdir = new DirectoryInfo(i.FullName); + subdir.Delete(true); //删除子目录和文件 + } + else + { + File.Delete(i.FullName); //删除指定文件 + } + } + } + catch (Exception e) + { + Console.Write(e.ToString()); + } + } + } +} diff --git a/CC.Yi.DAL/BaseDal.cs b/CC.Yi.DAL/BaseDal.cs index 70e00edd..a1f44266 100644 --- a/CC.Yi.DAL/BaseDal.cs +++ b/CC.Yi.DAL/BaseDal.cs @@ -1,7 +1,9 @@ using CC.Yi.IDAL; using CC.Yi.Model; using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.ChangeTracking; using System; +using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; @@ -9,7 +11,7 @@ namespace CC.Yi.DAL { public class BaseDal : IBaseDal where T : class, new() { - public DataContext Db; + public DbContext Db; public BaseDal(DataContext _Db) { Db = _Db; @@ -65,6 +67,11 @@ namespace CC.Yi.DAL //Db.SaveChanges(); return entity; } + public bool AddRange(IEnumerable entities) + { + Db.Set().AddRange(entities); + return true; + } public bool Update(T entity) { @@ -73,7 +80,16 @@ namespace CC.Yi.DAL //return Db.SaveChanges() > 0; return true; } - + public bool Update(T entity, params string[] propertyNames) + { + EntityEntry entry = Db.Entry(entity); + entry.State = EntityState.Unchanged; + foreach (var item in propertyNames) + { + entry.Property(item).IsModified = true; + } + return true; + } public bool Delete(T entity) { @@ -87,6 +103,12 @@ namespace CC.Yi.DAL Db.Set().Remove(entity);//由于这里先Find找到了实体,所以这里可以用Remove标记该实体要移除(删除)。如果不是先Find到实体就需要用System.Data.Entity.EntityState.Deleted return true; } + public bool DeteteRange(IEnumerable entity) + { + Db.Set().RemoveRange(entity); + return true; + } + } } diff --git a/CC.Yi.DAL/DbContentFactory.cs b/CC.Yi.DAL/DbContentFactory.cs deleted file mode 100644 index a89b3cb8..00000000 --- a/CC.Yi.DAL/DbContentFactory.cs +++ /dev/null @@ -1,50 +0,0 @@ -using CC.Yi.Model; -using Microsoft.EntityFrameworkCore; -using System.Collections.Concurrent; -using System.Threading; - - -namespace CC.Yi.DAL -{ - public class DbContentFactory - { - private static DataContext Webcontext; - - public DbContentFactory(DataContext webContext) - { - Webcontext = webContext; - } - - //public static void Initialize(DataContext webContext) - //{ - // Webcontext = webContext; - //} - public static DataContext GetCurrentDbContent() - { - ////return new DataModelContainer(); - ////一次请求共用一个上下文实例 - ////每一次http请求都会开启一个新的线程,保证在一个线程中,DbContext是唯一的 - ////CallContext:是线程内部唯一的数据槽(一块内存空间/容器),相当于一个键值对数据容器,通过key获取value了,需要引入System.Runtime.Remoting.Messaging;命名空间 - //DbContext db = CallContext.GetData("DbContext") as DbContext; - ////从 CallContext 中检索具有指定key“DbContext”的对象,并强转为DbContext - //if (db == null)//线程在数据槽里面没有此上下文 - //{ - // db = Webcontext; - // CallContext.SetData("DbContext", db);//放到数据槽中去,DbContext是key,db是value - //} - //return db; - return Webcontext; - } - - //private static class CallContext - //{ - // static ConcurrentDictionary> state = new ConcurrentDictionary>(); - - // public static void SetData(string name, object data) => - // state.GetOrAdd(name, _ => new AsyncLocal()).Value = data; - - // public static object GetData(string name) => - // state.TryGetValue(name, out AsyncLocal data) ? data.Value : null; - //} - } -} diff --git a/CC.Yi.DAL/T4DAL.cs b/CC.Yi.DAL/T4DAL.cs index e4656a91..7f13bb7a 100644 --- a/CC.Yi.DAL/T4DAL.cs +++ b/CC.Yi.DAL/T4DAL.cs @@ -3,13 +3,15 @@ using CC.Yi.Model; using System; using System.Collections.Generic; using System.Text; +using Microsoft.EntityFrameworkCore; namespace CC.Yi.DAL { public partial class studentDal : BaseDal, IstudentDal { - public studentDal(DataContext _Db) : base(_Db) + public studentDal(DataContext _Db):base(_Db) { + Db = _Db; } } } \ No newline at end of file diff --git a/CC.Yi.DAL/T4DAL.tt b/CC.Yi.DAL/T4DAL.tt index bd65067b..c5f32512 100644 --- a/CC.Yi.DAL/T4DAL.tt +++ b/CC.Yi.DAL/T4DAL.tt @@ -18,6 +18,7 @@ using CC.Yi.Model; using System; using System.Collections.Generic; using System.Text; +using Microsoft.EntityFrameworkCore; namespace CC.Yi.DAL { @@ -25,8 +26,9 @@ namespace CC.Yi.DAL #> public partial class <#=k #>Dal : BaseDal<<#=k #>>, I<#=k #>Dal { - public <#=k #>Dal(DataContext _Db) : base(_Db) + public <#=k #>Dal(DataContext _Db):base(_Db) { + Db = _Db; } } <# } #> diff --git a/CC.Yi.DALFactory/CC.Yi.DALFactory.csproj b/CC.Yi.DALFactory/CC.Yi.DALFactory.csproj deleted file mode 100644 index 7019acb0..00000000 --- a/CC.Yi.DALFactory/CC.Yi.DALFactory.csproj +++ /dev/null @@ -1,40 +0,0 @@ - - - - netcoreapp3.1 - - - - - - - - - - - - - - True - True - T4DbSession.tt - - - True - True - T4StaticDalFactory.tt - - - - - - TextTemplatingFileGenerator - T4DbSession.cs - - - TextTemplatingFileGenerator - T4StaticDalFactory.cs - - - - diff --git a/CC.Yi.DALFactory/DbSession.cs b/CC.Yi.DALFactory/DbSession.cs deleted file mode 100644 index 71b38475..00000000 --- a/CC.Yi.DALFactory/DbSession.cs +++ /dev/null @@ -1,21 +0,0 @@ -using CC.Yi.DAL; -using CC.Yi.IDAL; -using CC.Yi.Model; -using Microsoft.EntityFrameworkCore; -using System; - -namespace CC.Yi.DALFactory -{ - public partial class DbSession : IDbSession - { - public int SaveChanges() - { - return DbContentFactory.GetCurrentDbContent().SaveChanges(); - } - public DataContext GetDbContent() - { - return DbContentFactory.GetCurrentDbContent(); - } - - } -} diff --git a/CC.Yi.DALFactory/DbSessionFactory.cs b/CC.Yi.DALFactory/DbSessionFactory.cs deleted file mode 100644 index afa24d06..00000000 --- a/CC.Yi.DALFactory/DbSessionFactory.cs +++ /dev/null @@ -1,35 +0,0 @@ -using CC.Yi.IDAL; -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; - -namespace CC.Yi.DALFactory -{ - public class DbSessionFactory - { - public static IDbSession GetCurrentDbSession() - { - IDbSession db = CallContext.GetData("DbSession") as IDbSession; - if (db == null) - { - db = new DbSession(); - CallContext.SetData("DbSession", db); - } - return db; - } - - private static class CallContext - { - static ConcurrentDictionary> state = new ConcurrentDictionary>(); - - public static void SetData(string name, object data) => - state.GetOrAdd(name, _ => new AsyncLocal()).Value = data; - - public static object GetData(string name) => - state.TryGetValue(name, out AsyncLocal data) ? data.Value : null; - } - } -} diff --git a/CC.Yi.DALFactory/StaticDalFactory.cs b/CC.Yi.DALFactory/StaticDalFactory.cs deleted file mode 100644 index a91adf99..00000000 --- a/CC.Yi.DALFactory/StaticDalFactory.cs +++ /dev/null @@ -1,24 +0,0 @@ -using CC.Yi.DAL; -using CC.Yi.IDAL; -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Text; -using System.Threading; - -namespace CC.Yi.DALFactory -{ - public partial class StaticDalFactory - { - private static class CallContext - { - static ConcurrentDictionary> state = new ConcurrentDictionary>(); - - public static void SetData(string name, object data) => - state.GetOrAdd(name, _ => new AsyncLocal()).Value = data; - - public static object GetData(string name) => - state.TryGetValue(name, out AsyncLocal data) ? data.Value : null; - } - } -} diff --git a/CC.Yi.DALFactory/T4DbSession.cs b/CC.Yi.DALFactory/T4DbSession.cs deleted file mode 100644 index 6a94b709..00000000 --- a/CC.Yi.DALFactory/T4DbSession.cs +++ /dev/null @@ -1,18 +0,0 @@ -using CC.Yi.DAL; -using CC.Yi.IDAL; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; - -namespace CC.Yi.DALFactory -{ - public partial class DbSession : IDbSession - { - public IstudentDal studentDal - { - get { return StaticDalFactory.GetstudentDal(); } - } - - } -} \ No newline at end of file diff --git a/CC.Yi.DALFactory/T4StaticDalFactory.cs b/CC.Yi.DALFactory/T4StaticDalFactory.cs deleted file mode 100644 index 2733dbb1..00000000 --- a/CC.Yi.DALFactory/T4StaticDalFactory.cs +++ /dev/null @@ -1,25 +0,0 @@ -using CC.Yi.DAL; -using CC.Yi.IDAL; -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Text; -using System.Threading; - -namespace CC.Yi.DALFactory -{ - public partial class StaticDalFactory - { - public static IstudentDal GetstudentDal() - { - IstudentDal Data = CallContext.GetData("studentDal") as IstudentDal; - if (Data == null) - { - Data = new studentDal(DbSessionFactory.GetCurrentDbSession().GetDbContent()); - CallContext.SetData("studentDal", Data); - } - return Data; - } - - } -} \ No newline at end of file diff --git a/CC.Yi.DALFactory/T4StaticDalFactory.tt b/CC.Yi.DALFactory/T4StaticDalFactory.tt deleted file mode 100644 index 40388a29..00000000 --- a/CC.Yi.DALFactory/T4StaticDalFactory.tt +++ /dev/null @@ -1,43 +0,0 @@ -<#@ template debug="false" hostspecific="true" language="C#" #> -<#@ assembly name="System.Core" #> -<#@ import namespace="System.Linq" #> -<#@ import namespace="System.Text" #> -<#@ import namespace="System.Collections.Generic" #> -<#@ import namespace="System.IO" #> -<#@ output extension=".cs" #> -<# - string solutionsPath = Host.ResolveAssemblyReference("$(SolutionDir)");//获取解决方案路径 - string txt; - StreamReader sr = new StreamReader(solutionsPath+@"\T4Model\T4Model.txt"); - txt=sr.ReadToEnd(); - sr.Close(); - string[] ModelData= txt.Split(','); - #> -using CC.Yi.DAL; -using CC.Yi.IDAL; -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Text; -using System.Threading; - -namespace CC.Yi.DALFactory -{ - public partial class StaticDalFactory - { -<# foreach(string k in ModelData){ - #> - public static I<#=k #>Dal Get<#=k #>Dal() - { - I<#=k #>Dal Data = CallContext.GetData("<#=k #>Dal") as I<#=k #>Dal; - if (Data == null) - { - Data = new <#=k #>Dal(DbSessionFactory.GetCurrentDbSession().GetDbContent()); - CallContext.SetData("<#=k #>Dal", Data); - } - return Data; - } - -<# } #> - } -} \ No newline at end of file diff --git a/CC.Yi.IBLL/CC.Yi.IBLL.csproj b/CC.Yi.IBLL/CC.Yi.IBLL.csproj index 54b41008..778e1962 100644 --- a/CC.Yi.IBLL/CC.Yi.IBLL.csproj +++ b/CC.Yi.IBLL/CC.Yi.IBLL.csproj @@ -6,6 +6,7 @@ + diff --git a/CC.Yi.IBLL/IBaseBll.cs b/CC.Yi.IBLL/IBaseBll.cs index dae45507..9366bcbf 100644 --- a/CC.Yi.IBLL/IBaseBll.cs +++ b/CC.Yi.IBLL/IBaseBll.cs @@ -1,4 +1,5 @@ -using System; +using Autofac.Extras.DynamicProxy; +using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; @@ -11,6 +12,7 @@ namespace CC.Yi.IBLL //得到全部实体 #endregion IQueryable GetAllEntities(); + #region //通过表达式得到实体 #endregion @@ -36,11 +38,21 @@ namespace CC.Yi.IBLL #endregion T Add(T entity); + #region + //添加多个实体 + #endregion + bool Add(IEnumerable entities); + #region //更新实体 #endregion bool Update(T entity); + #region + //更新实体部分属性 + #endregion + bool Update(T entity, params string[] propertyNames); + #region //删除实体 #endregion @@ -54,6 +66,11 @@ namespace CC.Yi.IBLL #region //通过id列表删除多个实体 #endregion - int DeleteList(List ids); + bool Delete(IEnumerable ids); + + #region + //通过表达式删除实体 + #endregion + bool Delete(Expression> where); } } diff --git a/CC.Yi.IDAL/IBaseDal.cs b/CC.Yi.IDAL/IBaseDal.cs index a7b2d0cd..f4daf158 100644 --- a/CC.Yi.IDAL/IBaseDal.cs +++ b/CC.Yi.IDAL/IBaseDal.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; @@ -36,11 +37,20 @@ namespace CC.Yi.IDAL #endregion T Add(T entity); + #region + //添加多个实体 + #endregion + bool AddRange(IEnumerable entities); #region //更新单个实体 #endregion bool Update(T entity); + #region + //更新单个实体部分属性 + #endregion + bool Update(T entity, params string[] propertyNames); + #region //删除单个实体 #endregion @@ -50,5 +60,10 @@ namespace CC.Yi.IDAL //通过id删除实体 #endregion bool Detete(int id); + + #region + //删除多个实体 + #endregion + bool DeteteRange(IEnumerable entity); } } diff --git a/CC.Yi.IDAL/IDbSession.cs b/CC.Yi.IDAL/IDbSession.cs deleted file mode 100644 index 633da7f1..00000000 --- a/CC.Yi.IDAL/IDbSession.cs +++ /dev/null @@ -1,18 +0,0 @@ -using CC.Yi.Model; -using Microsoft.EntityFrameworkCore; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; - -namespace CC.Yi.IDAL -{ - public partial interface IDbSession - { - DataContext GetDbContent(); - int SaveChanges(); - } - - - -} diff --git a/CC.Yi.Model/CC.Yi.Model.csproj b/CC.Yi.Model/CC.Yi.Model.csproj index dffcf8d1..04d880f5 100644 --- a/CC.Yi.Model/CC.Yi.Model.csproj +++ b/CC.Yi.Model/CC.Yi.Model.csproj @@ -5,28 +5,14 @@ - - True - True - T4DataContext.tt - - - - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - TextTemplatingFileGenerator - T4DataContext.cs - - - @@ -39,4 +25,11 @@ + + + TextTemplatingFileGenerator + T4DataContext.cs + + + diff --git a/CC.Yi.Model/T4DataContext.cs b/CC.Yi.Model/T4DataContext.cs index ab0edf2f..584f6d63 100644 --- a/CC.Yi.Model/T4DataContext.cs +++ b/CC.Yi.Model/T4DataContext.cs @@ -2,7 +2,6 @@ using System; using System.Collections.Generic; using System.Text; - namespace CC.Yi.Model { public partial class DataContext :DbContext diff --git a/CC.Yi.Model/T4DataContext.tt b/CC.Yi.Model/T4DataContext.tt index dcfd940e..2fa74f5b 100644 --- a/CC.Yi.Model/T4DataContext.tt +++ b/CC.Yi.Model/T4DataContext.tt @@ -17,7 +17,6 @@ using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; using System.Text; - namespace CC.Yi.Model { public partial class DataContext :DbContext diff --git a/CC.Yi.Model/student.cs b/CC.Yi.Model/student.cs index 8a11819c..90ee09b7 100644 --- a/CC.Yi.Model/student.cs +++ b/CC.Yi.Model/student.cs @@ -11,6 +11,6 @@ namespace CC.Yi.Model [Key] [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)] public int id { get; set; } - public int name { get; set; } + public string name { get; set; } } } diff --git a/CC.Yi.ViewModel/Program.cs b/CC.Yi.ViewModel/Program.cs deleted file mode 100644 index 69cc429d..00000000 --- a/CC.Yi.ViewModel/Program.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; - -namespace CC.Yi.ViewModel -{ - class Program - { - static void Main(string[] args) - { - Console.WriteLine("Hello World!"); - } - } -} diff --git a/CC.Yi.sln b/CC.Yi.sln index 6e606c50..0a085b83 100644 --- a/CC.Yi.sln +++ b/CC.Yi.sln @@ -29,8 +29,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CC.Yi.ViewModel", "CC.Yi.Vi EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CC.Yi.Common", "CC.Yi.Common\CC.Yi.Common.csproj", "{9D6E5DD7-FA02-4532-8BAC-406FB80AFEAC}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CC.Yi.DALFactory", "CC.Yi.DALFactory\CC.Yi.DALFactory.csproj", "{ACB6D3EE-FADE-4F07-9D12-C9E3A5F72335}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -69,10 +67,6 @@ Global {9D6E5DD7-FA02-4532-8BAC-406FB80AFEAC}.Debug|Any CPU.Build.0 = Debug|Any CPU {9D6E5DD7-FA02-4532-8BAC-406FB80AFEAC}.Release|Any CPU.ActiveCfg = Release|Any CPU {9D6E5DD7-FA02-4532-8BAC-406FB80AFEAC}.Release|Any CPU.Build.0 = Release|Any CPU - {ACB6D3EE-FADE-4F07-9D12-C9E3A5F72335}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {ACB6D3EE-FADE-4F07-9D12-C9E3A5F72335}.Debug|Any CPU.Build.0 = Debug|Any CPU - {ACB6D3EE-FADE-4F07-9D12-C9E3A5F72335}.Release|Any CPU.ActiveCfg = Release|Any CPU - {ACB6D3EE-FADE-4F07-9D12-C9E3A5F72335}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -86,7 +80,6 @@ Global {8827547B-E04B-4430-A0DF-E87FCA40E3AB} = {38B8D898-4BBF-4DDB-8E29-6D6CEB7808C9} {32F323F1-E2FA-4186-AC33-263465012D15} = {38B8D898-4BBF-4DDB-8E29-6D6CEB7808C9} {9D6E5DD7-FA02-4532-8BAC-406FB80AFEAC} = {123D1D39-849C-4220-A973-EB9760421CB3} - {ACB6D3EE-FADE-4F07-9D12-C9E3A5F72335} = {9D0D4A54-057E-46C3-BBFE-CA01F7ECEDAE} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {22DD3529-6AD4-413A-B7B3-D8335E6F47C9} diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/README.md b/README.md new file mode 100644 index 00000000..5e1d2ed9 --- /dev/null +++ b/README.md @@ -0,0 +1,55 @@ +# CC.Yi + +#### 介绍 +基于.NET的MVC三成架构的框架--Yi意框架(意义是为了开发更简易) + +第一版开发完成时间:2021/3/19 (请记住,这是一个值得纪念的日子) + +为了更简易的开发,我们在2021/3/27 加入了vue分支(我们将持续更新) + + +#### 软件架构 +架构:.NET5 +mysql+sql server(后期我们将集成数据+前端Vue,让开发更加简易!) + +操作系统:Windows,Linux + +扩展:EFcore,Autofac,Identity,Castle,Redis,Swagger,T4 ,Nlog(后期我们会添加更多) + +封装:Json处理模块,滑动验证码模块,base64图片处理模块(后期我们会添加更多) + +思想:简单工厂模式,抽象工厂模式,观察者模式,面向AOP思想,面向对象开发 + + +#### 目录结构 +![输入图片说明](https://images.gitee.com/uploads/images/2021/0321/023715_59bef411_3049273.png "屏幕截图.png") + +Model:模型层(first code代码优先添加模型,数据自动生成) + +DAL:数据处理层(处理数据但并未加载进内存) + +BLL:业务逻辑层(数据的逻辑将在这层处理) + +Common:工具层(工具人层,方法已封装,一键调用) + +API:接口层(接入Swagger,可视化测试接口) + + +#### 安装教程 +我们将在之后更新教程手册! + +1. 下载全部源码 +2. 使用Visual Studio 2019在windows环境中打开CC.Yi.sln文件即可 + + +#### 使用说明 +我们将在之后更新教程手册! + +1. 添加一个数据库,并修改连接数据库的配置文件 +2. 添加模型类,使用Add-Migration xxx迁移,再使用Update-Database更新数据库 +3. 向T4Model添加模型名,一键转换生成T4 +4. 控制器构造函数进行依赖注入直接使用 + +#### 联系我们: +QQ:454313500 + + diff --git a/T4Model/说明.txt b/T4Model/说明.txt new file mode 100644 index 00000000..7abbdd18 --- /dev/null +++ b/T4Model/说明.txt @@ -0,0 +1,5 @@ +这里存放T4要生成的模型 +使用英文的 , 分隔 +例如: +student,teacher +点击 生成->转换所有t4模板 即可完成生成 \ No newline at end of file