From 714d1a36c4031b1e4557020f17dc5cb78859696b Mon Sep 17 00:00:00 2001 From: chenchun <454313500@qq.com> Date: Mon, 2 Jan 2023 17:27:12 +0800 Subject: [PATCH 01/10] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BE=9B=E5=BA=94?= =?UTF-8?q?=E5=95=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Config/SwaggerDoc.xml | 6 +++ .../Controllers/ERP/SupplierController.cs | 33 +++++++++++++++ .../ERP/Supplier/ConstConfig/SupplierConst.cs | 12 ++++++ .../Supplier/MapperConfig/SupplierProfile.cs | 20 +++++++++ .../ERP/Supplier/SupplierCreateUpdateInput.cs | 41 +++++++++++++++++++ .../ERP/Supplier/SupplierGetListOutput.cs | 40 ++++++++++++++++++ .../ERP/ISupplierService.cs | 15 +++++++ .../ERP/SupplierService.cs | 26 ++++++++++++ 8 files changed, 193 insertions(+) create mode 100644 Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Controllers/ERP/SupplierController.cs create mode 100644 Yi.Framework.Net6/Yi.Framework.DtoModel/ERP/Supplier/ConstConfig/SupplierConst.cs create mode 100644 Yi.Framework.Net6/Yi.Framework.DtoModel/ERP/Supplier/MapperConfig/SupplierProfile.cs create mode 100644 Yi.Framework.Net6/Yi.Framework.DtoModel/ERP/Supplier/SupplierCreateUpdateInput.cs create mode 100644 Yi.Framework.Net6/Yi.Framework.DtoModel/ERP/Supplier/SupplierGetListOutput.cs create mode 100644 Yi.Framework.Net6/Yi.Framework.Interface/ERP/ISupplierService.cs create mode 100644 Yi.Framework.Net6/Yi.Framework.Service/ERP/SupplierService.cs diff --git a/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Config/SwaggerDoc.xml b/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Config/SwaggerDoc.xml index 7842f01f..e936bdbf 100644 --- a/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Config/SwaggerDoc.xml +++ b/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Config/SwaggerDoc.xml @@ -181,6 +181,12 @@ + + + 查 + + + 账户管理 diff --git a/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Controllers/ERP/SupplierController.cs b/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Controllers/ERP/SupplierController.cs new file mode 100644 index 00000000..0d6f5b00 --- /dev/null +++ b/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Controllers/ERP/SupplierController.cs @@ -0,0 +1,33 @@ +using Brick.IFServer.Controllers; +using Microsoft.AspNetCore.Mvc; +using Yi.Framework.Common.Models; +using Yi.Framework.DtoModel.ERP.Supplier; +using Yi.Framework.Interface.ERP; + +namespace Yi.Framework.ApiMicroservice.Controllers.ERP +{ + [ApiController] + [Route("[controller]")] + public class SupplierController:ControllerBase + { + private readonly ILogger _logger; + private readonly ISupplierService _supplierService; + public SupplierController(ILogger logger, ISupplierService supplierService) + { + _logger = logger; + _supplierService = supplierService; + } + + /// + /// 查 + /// + /// + [HttpGet] + public async Task>> GetList() + { + var result = await _supplierService.GetListAsync(); + + return Result>.Success().SetData(result); + } + } +} diff --git a/Yi.Framework.Net6/Yi.Framework.DtoModel/ERP/Supplier/ConstConfig/SupplierConst.cs b/Yi.Framework.Net6/Yi.Framework.DtoModel/ERP/Supplier/ConstConfig/SupplierConst.cs new file mode 100644 index 00000000..a923042a --- /dev/null +++ b/Yi.Framework.Net6/Yi.Framework.DtoModel/ERP/Supplier/ConstConfig/SupplierConst.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Yi.Framework.DtoModel.ERP.Supplier.ConstConfig +{ + public class SupplierConst + { + } +} diff --git a/Yi.Framework.Net6/Yi.Framework.DtoModel/ERP/Supplier/MapperConfig/SupplierProfile.cs b/Yi.Framework.Net6/Yi.Framework.DtoModel/ERP/Supplier/MapperConfig/SupplierProfile.cs new file mode 100644 index 00000000..decb6804 --- /dev/null +++ b/Yi.Framework.Net6/Yi.Framework.DtoModel/ERP/Supplier/MapperConfig/SupplierProfile.cs @@ -0,0 +1,20 @@ +using AutoMapper; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Yi.Framework.Model.ERP.Entitys; + +namespace Yi.Framework.DtoModel.ERP.Supplier.MapperConfig +{ + public class SupplierProfile:Profile + { + public SupplierProfile() + { + CreateMap(); + CreateMap(); + + } + } +} diff --git a/Yi.Framework.Net6/Yi.Framework.DtoModel/ERP/Supplier/SupplierCreateUpdateInput.cs b/Yi.Framework.Net6/Yi.Framework.DtoModel/ERP/Supplier/SupplierCreateUpdateInput.cs new file mode 100644 index 00000000..abbac95e --- /dev/null +++ b/Yi.Framework.Net6/Yi.Framework.DtoModel/ERP/Supplier/SupplierCreateUpdateInput.cs @@ -0,0 +1,41 @@ +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Yi.Framework.Model.Base; + +namespace Yi.Framework.DtoModel.ERP.Supplier +{ + public class SupplierCreateUpdateInput : EntityDto + { + /// + /// 供应商编码 + /// + public string Code { get; set; } + + /// + /// 供应商名称 + /// + public string Name { get; set; } + + /// + /// 供应商地址 + /// + public string Address { get; set; } + + /// + /// 电话 + /// + public long Phone { get; set; } + /// + /// 传真 + /// + public string Fax { get; set; } + /// + /// 邮箱 + /// + public string Email { get; set; } + } +} diff --git a/Yi.Framework.Net6/Yi.Framework.DtoModel/ERP/Supplier/SupplierGetListOutput.cs b/Yi.Framework.Net6/Yi.Framework.DtoModel/ERP/Supplier/SupplierGetListOutput.cs new file mode 100644 index 00000000..7513c005 --- /dev/null +++ b/Yi.Framework.Net6/Yi.Framework.DtoModel/ERP/Supplier/SupplierGetListOutput.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Yi.Framework.Model.Base; + +namespace Yi.Framework.DtoModel.ERP.Supplier +{ + public class SupplierGetListOutput: EntityDto + { + /// + /// 供应商编码 + /// + public string Code { get; set; } + + /// + /// 供应商名称 + /// + public string Name { get; set; } + + /// + /// 供应商地址 + /// + public string Address { get; set; } + + /// + /// 电话 + /// + public long Phone { get; set; } + /// + /// 传真 + /// + public string Fax { get; set; } + /// + /// 邮箱 + /// + public string Email { get; set; } + } +} diff --git a/Yi.Framework.Net6/Yi.Framework.Interface/ERP/ISupplierService.cs b/Yi.Framework.Net6/Yi.Framework.Interface/ERP/ISupplierService.cs new file mode 100644 index 00000000..8e0d9f3b --- /dev/null +++ b/Yi.Framework.Net6/Yi.Framework.Interface/ERP/ISupplierService.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Yi.Framework.DtoModel.ERP.Supplier; +using Yi.Framework.Interface.Base.Crud; + +namespace Yi.Framework.Interface.ERP +{ + public interface ISupplierService : ICrudAppService + { + Task> GetListAsync(); + } +} diff --git a/Yi.Framework.Net6/Yi.Framework.Service/ERP/SupplierService.cs b/Yi.Framework.Net6/Yi.Framework.Service/ERP/SupplierService.cs new file mode 100644 index 00000000..fbd94364 --- /dev/null +++ b/Yi.Framework.Net6/Yi.Framework.Service/ERP/SupplierService.cs @@ -0,0 +1,26 @@ +using AutoMapper; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Yi.Framework.DtoModel.ERP.Supplier; +using Yi.Framework.Interface.ERP; +using Yi.Framework.Model.ERP.Entitys; +using Yi.Framework.Repository; +using Yi.Framework.Service.Base.Crud; + +namespace Yi.Framework.Service.ERP +{ + public class SupplierService : CrudAppService, ISupplierService + { + public SupplierService(IRepository repository, IMapper mapper) : base(repository, mapper) + { + } + + public async Task> GetListAsync() + { + return await MapToGetListOutputDtosAsync(await Repository.GetListAsync()); + } + } +} From 762c455b53a98a1dc4ca623e5bcf8be6fc2f712a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=A9=99=E5=AD=90?= <454313500@qq.com> Date: Mon, 2 Jan 2023 21:18:38 +0800 Subject: [PATCH 02/10] =?UTF-8?q?=E5=88=A0=E9=99=A4=E5=A4=9A=E4=BD=99?= =?UTF-8?q?=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitattributes | 63 -------------- WebFirst/database/sqlite.db | Bin 651264 -> 0 bytes .../Yi.Framework.Uow/IUnitOfWork.cs | 13 --- .../Interceptors/UnitOfWorkAttribute.cs | 44 ---------- .../Interceptors/UnitOfWorkInterceptor.cs | 78 ------------------ .../UowIServiceCollectionExtensions.cs | 21 ----- .../Yi.Framework.Uow/UnitOfWork.cs | 75 ----------------- .../Yi.Framework.Uow/Yi.Framework.Uow.csproj | 17 ---- 8 files changed, 311 deletions(-) delete mode 100644 .gitattributes delete mode 100644 WebFirst/database/sqlite.db delete mode 100644 Yi.Framework.Net6/Yi.Framework.Uow/IUnitOfWork.cs delete mode 100644 Yi.Framework.Net6/Yi.Framework.Uow/Interceptors/UnitOfWorkAttribute.cs delete mode 100644 Yi.Framework.Net6/Yi.Framework.Uow/Interceptors/UnitOfWorkInterceptor.cs delete mode 100644 Yi.Framework.Net6/Yi.Framework.Uow/Microsoft/ApsNetCore/Extensions/UowIServiceCollectionExtensions.cs delete mode 100644 Yi.Framework.Net6/Yi.Framework.Uow/UnitOfWork.cs delete mode 100644 Yi.Framework.Net6/Yi.Framework.Uow/Yi.Framework.Uow.csproj diff --git a/.gitattributes b/.gitattributes deleted file mode 100644 index 1ff0c423..00000000 --- a/.gitattributes +++ /dev/null @@ -1,63 +0,0 @@ -############################################################################### -# Set default behavior to automatically normalize line endings. -############################################################################### -* text=auto - -############################################################################### -# Set default behavior for command prompt diff. -# -# This is need for earlier builds of msysgit that does not have it on by -# default for csharp files. -# Note: This is only used by command line -############################################################################### -#*.cs diff=csharp - -############################################################################### -# Set the merge driver for project and solution files -# -# Merging from the command prompt will add diff markers to the files if there -# are conflicts (Merging from VS is not affected by the settings below, in VS -# the diff markers are never inserted). Diff markers may cause the following -# file extensions to fail to load in VS. An alternative would be to treat -# these files as binary and thus will always conflict and require user -# intervention with every merge. To do so, just uncomment the entries below -############################################################################### -#*.sln merge=binary -#*.csproj merge=binary -#*.vbproj merge=binary -#*.vcxproj merge=binary -#*.vcproj merge=binary -#*.dbproj merge=binary -#*.fsproj merge=binary -#*.lsproj merge=binary -#*.wixproj merge=binary -#*.modelproj merge=binary -#*.sqlproj merge=binary -#*.wwaproj merge=binary - -############################################################################### -# behavior for image files -# -# image files are treated as binary by default. -############################################################################### -#*.jpg binary -#*.png binary -#*.gif binary - -############################################################################### -# diff behavior for common document formats -# -# Convert binary document formats to text before diffing them. This feature -# is only available from the command line. Turn it on by uncommenting the -# entries below. -############################################################################### -#*.doc diff=astextplain -#*.DOC diff=astextplain -#*.docx diff=astextplain -#*.DOCX diff=astextplain -#*.dot diff=astextplain -#*.DOT diff=astextplain -#*.pdf diff=astextplain -#*.PDF diff=astextplain -#*.rtf diff=astextplain -#*.RTF diff=astextplain diff --git a/WebFirst/database/sqlite.db b/WebFirst/database/sqlite.db deleted file mode 100644 index eec321e30a1205207d76f2edd68679d631ab6412..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 651264 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⪼YvZI3e2`NIX9K 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

&~s4UiazP{~UYYsgmt(?Asi>=bjB4 zHr##3x)?%1^7G3GN3Ez=JQ(Nd3ojQ+#f9mC#{HuGXFs(rwja?aHFE~_wA8DWSH8XS z-n%IH_nUA06!)94Z>M)R?$d_hjcFM5ia#cY+1VJ|9Q)L#0M=(ex-NFKf_Uo5`jY&6 z`OAO2^6tfzAARHUTR%ex)=Y0>uW0=#Ok&0?;x5gJocw#`2dGK-^NAe6KVvlR-5k67 zZt56KDO$H+!Z2yQpeUy|{%Ylw@BQXmZ_brUg_(iI9&N%LEi_^EiX+HA;hEiyQEkEs zo9dMfuNY=T8%AMMy>i3r%)v%-b8P2lF`ePN*Ttw}S9Q8vN8AzBbz^VE>#IL_>GJp9 z$9F4ly>|I)KfUz9_b;D&84m;kNz-Hm>&#dNKd zJ;nZ6dG{+TKl&zbkrplP#3EzT6FKz{BZCc(#H^)BtNj&>mAm;$C9LyI$gY3`B*DkDl<=oY`|LXFKFRPVF zHg;)Gpi3$=C;sp!R^E91$`5|bpFphcbh@!q%x4E?zaLw0p;TF($f;N2xmPZrVj$la z)B790w>h?B2LMaSRb$z0d^C`i^-h4v=;_LPFJW|R=tp)o41su>o?1Nq3|~U4_4LOY zpW7U}{q~IrF~w3(YYP&_iy__P3laZa%; zG$Gj$n;h#(U()`eW4(=p#@~*iR2uO&`S;2ze{<#CAMnwS8I3zd)4Q<(6kkuh%D=p{ zs*bdycQiic2JX@Ajriu+U3bwwL`PF5GFVUXe=lFWc=ZECZ%21F?hekYkM=hH3vDiv zN6WuDuRdxtJ{5{rA024?GmVKV4y|6f@#>?y8=uq|fa1{Vm5o31^aTCoi+=UzZ?F9NC2R8m zn%|Yr+{t^N&Ogfth5iacdGiM=KfX9$C}nC#`xOKOm4R z|MGh)7hYa@>z8V2cQ!U?=LIXB!T#Z`FMqG`n?L`iMY5B3G;WjhB>DRS?o`L>+!|_i z4jYYILOpO~d*kL{BzSmdV|{QEJlxy3DIf_R9%!u7mRiw~dgVq@hj%w(+EObzQmq`~S~yZ&;QwCv z)_W_z`kF3?LP$LFnG1E=OC*Sbogb|ptzQ1h>z97@ohv_i@5+0BCRsSJUlUvUZZs1& z=ZZgfNuC?r5S2O96WP}v;YzFk1T zS{=qs!Big6_J%*W@|_D1xZ-mhU`4FhW!Si``F0Ru(@Co?mBlKDm|`SLGU_OHJE($%-#}=qW4r+%zVKi{QhA^(4 z7--<&wKQoZd8t=!GT4dTjiM$TDalK{vdLf=W=R_+s0@Z-3feGA@=~vCGT4cOjm+j) zDg}v#j7;Md6gViDM=N3-CUVW62tDVOuj>nX{Eo&+rap7vD5_*f2A43o_ZnjqkH9q;O&|I3wce|P20*L7v@#OE4|Vy#Ih z6jQV2IFaL16C`>^W5I1kAg_6iyyQ&eUu#CcXNgkfg1VS=(D3^T0_qnM9+Wn)7y!cPUq>r`*!k$`xeG8)H1;dN@D zaa5bI!lruVhS#axjY)073Y+Sc4X+sHh&D`6ykeNc+As>6>Xi+zQ#%_E2gfUH_MZ=k zSJ><)LgDq;K;t28!U~(}l^b4CakcjUfJ-9VII_m35r(?b5I*bVN<=b;T3$~ iKybWH_crzi#Ot)tcpwyB;oKhACakcjUb*3Q`u_*muj%jr diff --git a/Yi.Framework.Net6/Yi.Framework.Uow/IUnitOfWork.cs b/Yi.Framework.Net6/Yi.Framework.Uow/IUnitOfWork.cs deleted file mode 100644 index b98951b2..00000000 --- a/Yi.Framework.Net6/Yi.Framework.Uow/IUnitOfWork.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System.Data; - -namespace Yi.Framework.Uow -{ - public interface IUnitOfWork : IDisposable - { - public void Init(bool isTransactional, IsolationLevel? isolationLevel, int? timeout); - public void BeginTran(); - - public void CommitTran(); - public void RollbackTran(); - } -} \ No newline at end of file diff --git a/Yi.Framework.Net6/Yi.Framework.Uow/Interceptors/UnitOfWorkAttribute.cs b/Yi.Framework.Net6/Yi.Framework.Uow/Interceptors/UnitOfWorkAttribute.cs deleted file mode 100644 index 3d681c2d..00000000 --- a/Yi.Framework.Net6/Yi.Framework.Uow/Interceptors/UnitOfWorkAttribute.cs +++ /dev/null @@ -1,44 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Data; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Yi.Framework.Uow.Interceptors -{ - public class UnitOfWorkAttribute : Attribute// : AbstractInterceptorAttribute - { - public UnitOfWorkAttribute(bool isTransactional = true) - { - IsTransactional = isTransactional; - } - public UnitOfWorkAttribute(IsolationLevel isolationLevel, bool isTransactional = true) : this(isTransactional) - { - IsolationLevel = isolationLevel; - } - public UnitOfWorkAttribute(IsolationLevel isolationLevel, int timeout, bool isTransactional = true) : this(isolationLevel, isTransactional) - { - Timeout = timeout; - } - - public bool IsTransactional { get; } - - public IsolationLevel? IsolationLevel { get; } - - ///

- /// Milliseconds - /// - public int? Timeout { get; } - public bool IsDisabled { get; } - - - //public override Task Invoke(AspectContext context, AspectDelegate next) - //{ - // if (IsTransactional) - // { - // ServiceLocator.in.getservice() - // } - //} - } -} diff --git a/Yi.Framework.Net6/Yi.Framework.Uow/Interceptors/UnitOfWorkInterceptor.cs b/Yi.Framework.Net6/Yi.Framework.Uow/Interceptors/UnitOfWorkInterceptor.cs deleted file mode 100644 index 912d2d10..00000000 --- a/Yi.Framework.Net6/Yi.Framework.Uow/Interceptors/UnitOfWorkInterceptor.cs +++ /dev/null @@ -1,78 +0,0 @@ -using Castle.DynamicProxy; -using Nest; -using System; -using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; -using System.Linq; -using System.Reflection; -using System.Text; -using System.Threading.Tasks; - -namespace Yi.Framework.Uow.Interceptors -{ - public class UnitOfWorkInterceptor : IInterceptor - { - private readonly IUnitOfWork _unitOfWork; - public UnitOfWorkInterceptor(IUnitOfWork unitOfWork) - { - _unitOfWork = unitOfWork; - } - - public void Intercept(IInvocation invocation) - { - if (!IsUnitOfWorkMethod(invocation.Method, out var uowAttr)) - { - invocation.Proceed(); - return; - } - - try - { - _unitOfWork.BeginTran(); - //执行被拦截的方法 - invocation.Proceed(); - _unitOfWork.CommitTran(); - } - catch (Exception ex) - { - _unitOfWork.RollbackTran(); - throw ex; - } - } - - - public static bool IsUnitOfWorkMethod( MethodInfo methodInfo,out UnitOfWorkAttribute unitOfWorkAttribute) - { - - //Method declaration - var attrs = methodInfo.GetCustomAttributes(true).OfType().ToArray(); - if (attrs.Any()) - { - unitOfWorkAttribute = attrs.First(); - return !unitOfWorkAttribute.IsDisabled; - } - - if (methodInfo.DeclaringType != null) - { - //Class declaration - attrs = methodInfo.DeclaringType.GetTypeInfo().GetCustomAttributes(true).OfType().ToArray(); - if (attrs.Any()) - { - unitOfWorkAttribute = attrs.First(); - return !unitOfWorkAttribute.IsDisabled; - } - - ////Conventional classes - //if (typeof(IUnitOfWorkEnabled).GetTypeInfo().IsAssignableFrom(methodInfo.DeclaringType)) - //{ - // unitOfWorkAttribute = null; - // return true; - //} - } - - unitOfWorkAttribute = null; - return false; - } - - } -} diff --git a/Yi.Framework.Net6/Yi.Framework.Uow/Microsoft/ApsNetCore/Extensions/UowIServiceCollectionExtensions.cs b/Yi.Framework.Net6/Yi.Framework.Uow/Microsoft/ApsNetCore/Extensions/UowIServiceCollectionExtensions.cs deleted file mode 100644 index bd424fdc..00000000 --- a/Yi.Framework.Net6/Yi.Framework.Uow/Microsoft/ApsNetCore/Extensions/UowIServiceCollectionExtensions.cs +++ /dev/null @@ -1,21 +0,0 @@ -using Microsoft.Extensions.DependencyInjection; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Yi.Framework.Uow; -using Yi.Framework.Uow.Interceptors; - -namespace Microsoft.Extensions.DependencyInjection -{ - public static class UowIServiceCollectionExtensions - { - public static void AddUnitOfWork(this IServiceCollection services) - { - services.AddScoped(typeof(IUnitOfWork), typeof(UnitOfWork)); - - services.AddSingleton(); - } - } -} diff --git a/Yi.Framework.Net6/Yi.Framework.Uow/UnitOfWork.cs b/Yi.Framework.Net6/Yi.Framework.Uow/UnitOfWork.cs deleted file mode 100644 index 84c74df1..00000000 --- a/Yi.Framework.Net6/Yi.Framework.Uow/UnitOfWork.cs +++ /dev/null @@ -1,75 +0,0 @@ -using SqlSugar; -using System; -using System.Collections.Generic; -using System.Data; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Yi.Framework.Uow -{ - public class UnitOfWork : IUnitOfWork - { - - public bool IsTransactional { get; protected set; } - - public IsolationLevel? IsolationLevel { get; protected set; } - - /// - /// Milliseconds - /// - public int? Timeout { get; protected set; } - - public void Init(bool isTransactional, IsolationLevel? isolationLevel, int? timeout) - { - IsTransactional = isTransactional; - IsolationLevel = isolationLevel; - Timeout = timeout; - } - - public ISqlSugarClient SugarClient { get; set; } - /// - /// 因为sqlsugarclient的生命周期是作用域的,也就是说一个请求线程内是共用一个client,暂时先直接注入 - /// - /// - public UnitOfWork(ISqlSugarClient sqlSugarClient) - { - this.SugarClient = sqlSugarClient; - } - - - public void Dispose() - { - SugarClient?.Dispose(); - SugarClient?.Close(); - } - - - - public void BeginTran() - { - if (IsTransactional) - { - if (IsolationLevel.HasValue) - { - SugarClient.Ado.BeginTran(IsolationLevel.Value); - } - else - { - SugarClient.Ado.BeginTran(); - } - } - } - - public void CommitTran() - { - if (IsTransactional) - SugarClient.Ado.CommitTran(); - } - public void RollbackTran() - { - if (IsTransactional) - SugarClient.Ado.RollbackTran(); - } - } -} diff --git a/Yi.Framework.Net6/Yi.Framework.Uow/Yi.Framework.Uow.csproj b/Yi.Framework.Net6/Yi.Framework.Uow/Yi.Framework.Uow.csproj deleted file mode 100644 index 8ac127cb..00000000 --- a/Yi.Framework.Net6/Yi.Framework.Uow/Yi.Framework.Uow.csproj +++ /dev/null @@ -1,17 +0,0 @@ - - - - net6.0 - enable - enable - - - - - - - - - - - From dba67d71277d190d1d82cdab677b5e871a21d61f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=A9=99=E5=AD=90?= <454313500@qq.com> Date: Mon, 2 Jan 2023 23:32:40 +0800 Subject: [PATCH 03/10] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BE=9B=E5=BA=94?= =?UTF-8?q?=E5=95=86=E5=AE=9A=E4=B9=89=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Config/SwaggerDoc.xml | 32 +- .../Controllers/ERP/SupplierController.cs | 61 ++- .../yi-sqlsugar-dev.db | Bin 307200 -> 307200 bytes .../ERP/ISupplierService.cs | 3 +- .../RABC/SeedData/DictionaryInfoSeed.cs | 4 +- .../Yi.Framework.Repository.csproj | 4 - .../Base/Crud/AbstractKeyCrudAppService.cs | 7 +- .../ERP/SupplierService.cs | 12 +- .../AspNetCoreExtensions/SqlsugarExtension.cs | 1 + .../MiddlewareExtend/ErrorHandExtension.cs | 6 +- .../src/views/system/menu/index.vue | 2 +- Yi.Vue3.x.RuoYi/src/api/erp/supplierApi.js | 45 ++ .../src/views/ERP/supplier/index.vue | 396 ++++++++++++++++++ 13 files changed, 549 insertions(+), 24 deletions(-) create mode 100644 Yi.Vue3.x.RuoYi/src/api/erp/supplierApi.js create mode 100644 Yi.Vue3.x.RuoYi/src/views/ERP/supplier/index.vue diff --git a/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Config/SwaggerDoc.xml b/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Config/SwaggerDoc.xml index e936bdbf..3e639770 100644 --- a/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Config/SwaggerDoc.xml +++ b/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Config/SwaggerDoc.xml @@ -181,12 +181,40 @@
- + - 查 + 分页查 + + + 单查 + + + + + + 增 + + + + + + + 更 + + + + + + + + 删 + + + + 账户管理 diff --git a/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Controllers/ERP/SupplierController.cs b/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Controllers/ERP/SupplierController.cs index 0d6f5b00..1bfad73e 100644 --- a/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Controllers/ERP/SupplierController.cs +++ b/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Controllers/ERP/SupplierController.cs @@ -7,8 +7,8 @@ using Yi.Framework.Interface.ERP; namespace Yi.Framework.ApiMicroservice.Controllers.ERP { [ApiController] - [Route("[controller]")] - public class SupplierController:ControllerBase + [Route("api/[controller]/[action]")] + public class SupplierController : ControllerBase { private readonly ILogger _logger; private readonly ISupplierService _supplierService; @@ -19,15 +19,64 @@ namespace Yi.Framework.ApiMicroservice.Controllers.ERP } /// - /// 查 + /// 分页查 /// /// [HttpGet] - public async Task>> GetList() + public async Task PageList([FromQuery] SupplierCreateUpdateInput input, [FromQuery] PageParModel page) { - var result = await _supplierService.GetListAsync(); + var result = await _supplierService.PageListAsync(input, page); + return Result.Success().SetData(result); + } - return Result>.Success().SetData(result); + /// + /// 单查 + /// + /// + [HttpGet] + [Route("{id}")] + public async Task GetById(long id) + { + var result = await _supplierService.GetByIdAsync(id); + return Result.Success().SetData(result); + } + + /// + /// 增 + /// + /// + /// + [HttpPost] + public async Task Create(SupplierCreateUpdateInput input) + { + var result = await _supplierService.CreateAsync(input); + return Result.Success().SetData(result); + } + + /// + /// 更 + /// + /// + /// + /// + [HttpPut] + [Route("{id}")] + public async Task Update(long id, SupplierCreateUpdateInput input) + { + var result = await _supplierService.UpdateAsync(id, input); + return Result.Success().SetData(result); + } + + /// + /// 删 + /// + /// + /// + [HttpDelete] + public async Task Del(List ids) + { + await _supplierService.DeleteAsync(ids); + return Result.Success(); } } } diff --git a/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/yi-sqlsugar-dev.db b/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/yi-sqlsugar-dev.db index ccd667bb1fd1ab2b8c760873cf74e795d59f2584..616040b2de43658f59db95d2ab445ee6f45ee0a2 100644 GIT binary patch delta 1572 zcma)6TTC2P7(TPJJG-;D8K}#OfV3nHU}5&mnaj?OTI~`wqEb_1(Fc^d*HxJimA zY1Tin<06=97++~G@(zP?Dh!w_OgB?Xg}s+j#lJzy-EC#5>QWy70%*{`yMI8xx#6!t z5DE2=uZL(qLMkt)D8$J~4nkS!%)Y;}KDT^(VkR@5NG)u9Ww!zVg8H}jeENI$A9lZC zGx+=_-$~4O_^$`+3-|<)3k9JdLb>D4hm*IH6DHqLlBEvnWA`3Np}$vKN#q&P?PC!< zp37s5cf9$d59Y%xK<0Sojz=sk;LRdAy!bf_pjn(fGJ*dD%p&oP9~WG{h%Dox-Yh15 z+Q68)w^w_K^lGm~ynO5eU>2FzyldWRZvb5IeC&DJopqmfSGhiOJ@35hoOUYo4Z4G- z92Xr&?Z4Yc><>{_sSe6!o3e@4@2ziHE6IywljToK(h?%RBu)?>y@+k9icmgkp944y zlO3SC(&3;9>{Ui6L;GLB^4r0Qe-G0r1cF&2K(BEwEn)fo zOzVrpVr{S1=#P(&0+x0q?U1an(k}WsHt!clyfwJ10pC^w`4xHU z*o(Wh5wG&{o-0vB0tW>c5+!kWJCVU?D;}qvIz$I3bH=iYoP^*hF;+5uiUq%}oXadv zXA)=D7tXIwp1~M3HXM!iXpup+M~e+@t?M3DK^6J@)k&Y?E0o|(iT_mi-xB$aM?n>e z9Ntb|4hhjnf3ydioo}`in-$n90$N{Z+z(WWX4HklMWRllj`Iit< zg`g_&IGQ5lA+H4rF-Ed>gpBSm2!Aq%w?dMHkj52)j06^dpejNRDFV+c(uw+Q(2*@0 z5;&OdhtJ}tGTZaR^Gf{C40^1y8bd3&mb;i0gpI*(RXV+6_v$Hdqx%q5jF+09sUIJ2n zw-NA25GC0>(USuMTt|OzlO<1AQC-qJd+82-VPd0QLzpg`Udqg*_RwYPa6gbZ_x&A%pW}n`zNrDUv3^Hu% z82GpHXYot&9p@|EEcC&EZL)$u&gOOBjqV?X6bK^;< { - Task> GetListAsync(); + Task>> PageListAsync(SupplierCreateUpdateInput input, PageParModel page); } } diff --git a/Yi.Framework.Net6/Yi.Framework.Model/RABC/SeedData/DictionaryInfoSeed.cs b/Yi.Framework.Net6/Yi.Framework.Model/RABC/SeedData/DictionaryInfoSeed.cs index 330cd05b..3cd320f2 100644 --- a/Yi.Framework.Net6/Yi.Framework.Model/RABC/SeedData/DictionaryInfoSeed.cs +++ b/Yi.Framework.Net6/Yi.Framework.Model/RABC/SeedData/DictionaryInfoSeed.cs @@ -54,7 +54,7 @@ namespace Yi.Framework.Model.RABC.SeedData { Id = SnowFlakeSingle.Instance.NextId(), DictLabel = "显示", - DictValue = "0", + DictValue = "true", DictType = "sys_show_hide", OrderNum = 100, Remark = "显示菜单", @@ -66,7 +66,7 @@ namespace Yi.Framework.Model.RABC.SeedData { Id = SnowFlakeSingle.Instance.NextId(), DictLabel = "隐藏", - DictValue = "1", + DictValue = "false", DictType = "sys_show_hide", OrderNum = 99, Remark = "隐藏菜单", diff --git a/Yi.Framework.Net6/Yi.Framework.Repository/Yi.Framework.Repository.csproj b/Yi.Framework.Net6/Yi.Framework.Repository/Yi.Framework.Repository.csproj index 239ac7ef..4ba9aaad 100644 --- a/Yi.Framework.Net6/Yi.Framework.Repository/Yi.Framework.Repository.csproj +++ b/Yi.Framework.Net6/Yi.Framework.Repository/Yi.Framework.Repository.csproj @@ -6,10 +6,6 @@ disable - - - - diff --git a/Yi.Framework.Net6/Yi.Framework.Service/Base/Crud/AbstractKeyCrudAppService.cs b/Yi.Framework.Net6/Yi.Framework.Service/Base/Crud/AbstractKeyCrudAppService.cs index 00f1585d..f31d825e 100644 --- a/Yi.Framework.Net6/Yi.Framework.Service/Base/Crud/AbstractKeyCrudAppService.cs +++ b/Yi.Framework.Net6/Yi.Framework.Service/Base/Crud/AbstractKeyCrudAppService.cs @@ -68,7 +68,8 @@ namespace Yi.Framework.Service.Base.Crud TryToSetTenantId(entity); - await Repository.InsertAsync(entity); + //这边需要进行判断,实体是什么guid还是雪花id + await Repository.InsertReturnSnowflakeIdAsync(entity); var entitydto = await MapToGetOutputDtoAsync(entity); return entitydto; @@ -80,7 +81,7 @@ namespace Yi.Framework.Service.Base.Crud /// /// /// - public virtual Task DeleteAsync(IEnumerable ids) + public virtual Task DeleteAsync(IEnumerable ids) { throw new NotImplementedException(); } @@ -110,7 +111,7 @@ namespace Yi.Framework.Service.Base.Crud /// /// /// - protected virtual Task UpdateValidAsync(TEntity idEntity, TUpdateInput dto) + protected virtual Task UpdateValidAsync(TEntity idEntity, TUpdateInput dto) { return Task.CompletedTask; } diff --git a/Yi.Framework.Net6/Yi.Framework.Service/ERP/SupplierService.cs b/Yi.Framework.Net6/Yi.Framework.Service/ERP/SupplierService.cs index fbd94364..1f9cd40e 100644 --- a/Yi.Framework.Net6/Yi.Framework.Service/ERP/SupplierService.cs +++ b/Yi.Framework.Net6/Yi.Framework.Service/ERP/SupplierService.cs @@ -1,9 +1,11 @@ using AutoMapper; +using SqlSugar; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using Yi.Framework.Common.Models; using Yi.Framework.DtoModel.ERP.Supplier; using Yi.Framework.Interface.ERP; using Yi.Framework.Model.ERP.Entitys; @@ -17,10 +19,14 @@ namespace Yi.Framework.Service.ERP public SupplierService(IRepository repository, IMapper mapper) : base(repository, mapper) { } - - public async Task> GetListAsync() + public async Task>> PageListAsync(SupplierCreateUpdateInput input, PageParModel page) { - return await MapToGetListOutputDtosAsync(await Repository.GetListAsync()); + RefAsync totalNumber = 0; + var data = await Repository._DbQueryable + .WhereIF(input.Code is not null,u=>u.Code.Contains(input.Code)) + .WhereIF(input.Name is not null, u => u.Name.Contains(input.Name)) + .ToPageListAsync(page.PageNum, page.PageSize, totalNumber); + return new PageModel> { Total = totalNumber.Value, Data = await MapToGetListOutputDtosAsync(data) }; } } } diff --git a/Yi.Framework.Net6/Yi.Framework.WebCore/AspNetCoreExtensions/SqlsugarExtension.cs b/Yi.Framework.Net6/Yi.Framework.WebCore/AspNetCoreExtensions/SqlsugarExtension.cs index 421b8397..f2d3ac47 100644 --- a/Yi.Framework.Net6/Yi.Framework.WebCore/AspNetCoreExtensions/SqlsugarExtension.cs +++ b/Yi.Framework.Net6/Yi.Framework.WebCore/AspNetCoreExtensions/SqlsugarExtension.cs @@ -118,6 +118,7 @@ namespace Yi.Framework.WebCore.AspNetCoreExtensions { sb.Append($"\r\n参数:{i.ParameterName},参数值:{i.Value}"); } + sb.Append( $"\r\n 完整SQL:{UtilMethods.GetSqlString(DbType.MySql, s, p)}"); _logger?.LogInformation(sb.ToString()); } diff --git a/Yi.Framework.Net6/Yi.Framework.WebCore/MiddlewareExtend/ErrorHandExtension.cs b/Yi.Framework.Net6/Yi.Framework.WebCore/MiddlewareExtend/ErrorHandExtension.cs index bbebf049..8b91d51b 100644 --- a/Yi.Framework.Net6/Yi.Framework.WebCore/MiddlewareExtend/ErrorHandExtension.cs +++ b/Yi.Framework.Net6/Yi.Framework.WebCore/MiddlewareExtend/ErrorHandExtension.cs @@ -19,11 +19,12 @@ namespace Yi.Framework.WebCore.MiddlewareExtend public class ErrorHandExtension { private readonly RequestDelegate next; + private readonly ILogger _logger; //private readonly IErrorHandle _errorHandle; - public ErrorHandExtension(RequestDelegate next/*, IErrorHandle errorHandle*/) + public ErrorHandExtension(RequestDelegate next, ILoggerFactory loggerFactory /*, IErrorHandle errorHandle*/) { this.next = next; - //this._logger = loggerFactory.CreateLogger(); + this._logger = loggerFactory.CreateLogger(); //_errorHandle = errorHandle; } @@ -40,6 +41,7 @@ namespace Yi.Framework.WebCore.MiddlewareExtend } catch (Exception ex) { + _logger.LogError("系统错误",ex); //await _errorHandle.Invoer(context, ex); var statusCode = context.Response.StatusCode; if (ex is ArgumentException) diff --git a/Yi.Vue3.X.RuoYi/src/views/system/menu/index.vue b/Yi.Vue3.X.RuoYi/src/views/system/menu/index.vue index 1990ffef..83f71ca7 100644 --- a/Yi.Vue3.X.RuoYi/src/views/system/menu/index.vue +++ b/Yi.Vue3.X.RuoYi/src/views/system/menu/index.vue @@ -258,7 +258,7 @@ {{ dict.label }} diff --git a/Yi.Vue3.x.RuoYi/src/api/erp/supplierApi.js b/Yi.Vue3.x.RuoYi/src/api/erp/supplierApi.js new file mode 100644 index 00000000..8694b055 --- /dev/null +++ b/Yi.Vue3.x.RuoYi/src/api/erp/supplierApi.js @@ -0,0 +1,45 @@ +import request from '@/utils/request' + +// 分页查询 +export function listData(query) { + return request({ + url: '/supplier/pageList', + method: 'get', + params: query + }) +} + +// id查询 +export function getData(code) { + return request({ + url: '/supplier/getById/' + code, + method: 'get' + }) +} + +// 新增 +export function addData(data) { + return request({ + url: '/supplier/create', + method: 'post', + data: data + }) +} + +// 修改 +export function updateData(id,data) { + return request({ + url: `/supplier/update/${id}`, + method: 'put', + data: data + }) +} + +// 删除 +export function delData(code) { + return request({ + url: '/supplier/del', + method: 'delete', + data:"string"==typeof(code)?[code]:code + }) +} diff --git a/Yi.Vue3.x.RuoYi/src/views/ERP/supplier/index.vue b/Yi.Vue3.x.RuoYi/src/views/ERP/supplier/index.vue new file mode 100644 index 00000000..853ced64 --- /dev/null +++ b/Yi.Vue3.x.RuoYi/src/views/ERP/supplier/index.vue @@ -0,0 +1,396 @@ + + + \ No newline at end of file From 8b55373794f178c60944a464586d619dc620ead1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E6=B7=B3?= Date: Tue, 3 Jan 2023 16:03:11 +0800 Subject: [PATCH 04/10] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=96=87=E4=BB=B6helpe?= =?UTF-8?q?r?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Yi.Framework.Common/Helper/FileHelper.cs | 78 +++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/Yi.Framework.Net6/Yi.Framework.Common/Helper/FileHelper.cs b/Yi.Framework.Net6/Yi.Framework.Common/Helper/FileHelper.cs index 4e13d382..7ae1c0c4 100644 --- a/Yi.Framework.Net6/Yi.Framework.Common/Helper/FileHelper.cs +++ b/Yi.Framework.Net6/Yi.Framework.Common/Helper/FileHelper.cs @@ -407,6 +407,84 @@ namespace Yi.Framework.Common.Helper return folder.Select(x => x.Name).ToList(); } + /// + /// 文件内容替换 + /// + public static string FileContentReplace(string path, string oldStr, string newStr) + { + var content = File.ReadAllText(path); + if (content.Contains(oldStr)) + { + File.Delete(path); + File.WriteAllText(path, content.Replace(oldStr, newStr)); + } + + return path; + } + /// + /// 文件名称 + /// + public static string FileNameReplace(string path, string oldStr, string newStr) + { + string fileName = Path.GetFileName(path); + if (!fileName.Contains(oldStr)) + { + return path; + } + + string? directoryName = Path.GetDirectoryName(path); + string newFileName = fileName.Replace(oldStr, newStr); + string newPath = Path.Combine(directoryName ?? "", newFileName); + File.Move(path, newPath); + + return newPath; + } + /// + /// 目录名替换 + /// + public static string DirectoryNameReplace(string path, string oldStr, string newStr) + { + string fileName = Path.GetFileName(path); + if (!fileName.Contains(oldStr)) + { + return path; + } + + string? directoryName = Path.GetDirectoryName(path); + string newFileName = fileName.Replace(oldStr, newStr); + string newPath = Path.Combine(directoryName ?? "", newFileName); + Directory.Move(path, newPath); + return newPath; + } + + /// + /// 全部信息递归替换 + /// + /// + /// + /// + public static void AllInfoReplace(string dirPath, string oldStr, string newStr) + { + var path = DirectoryNameReplace(dirPath, oldStr, newStr); + var dirInfo = new DirectoryInfo(path); + var files = dirInfo.GetFiles(); + var dirs = dirInfo.GetDirectories(); + if (files.Length > 0) + { + foreach (var f in files) + { + FileContentReplace(f.FullName, oldStr, newStr); + FileNameReplace(f.FullName, oldStr, newStr); + } + } + if (dirs.Length > 0) + { + foreach (var d in dirs) + { + AllInfoReplace(d.FullName, oldStr, newStr); + } + } + } } } From ff2cf68b081417f1e921728419a97ea1401959d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E6=B7=B3?= Date: Tue, 3 Jan 2023 18:05:57 +0800 Subject: [PATCH 05/10] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=A8=A1=E6=9D=BF?= =?UTF-8?q?=E7=94=9F=E6=88=90=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../yi-sqlsugar-dev.db | Bin 307200 -> 307200 bytes .../Abstract/AbstractTemplateProvider.cs | 43 ++ .../Abstract/ITemplateProvider.cs | 41 ++ .../Yi.Framework.Template/FileHelper.cs | 490 ++++++++++++++++++ .../Yi.Framework.Template/Program.cs | 14 + .../Provider/ServceTemplateProvider.cs | 19 + .../Template/ServiceTemplate.txt | 32 ++ .../Yi.Framework.Template/TemplateFactory.cs | 38 ++ .../Yi.Framework.Template.csproj | 43 +- .../Yi.Framework.Template/vue3-ruoyi/api.js | 45 -- .../Yi.Framework.Template/vue3-ruoyi/api.tt | 54 -- .../Yi.Framework.Template/vue3-ruoyi/view.tt | 315 ----------- .../Yi.Framework.Template/vue3-ruoyi/view.vue | 1 - 13 files changed, 683 insertions(+), 452 deletions(-) create mode 100644 Yi.Framework.Net6/Yi.Framework.Template/Abstract/AbstractTemplateProvider.cs create mode 100644 Yi.Framework.Net6/Yi.Framework.Template/Abstract/ITemplateProvider.cs create mode 100644 Yi.Framework.Net6/Yi.Framework.Template/FileHelper.cs create mode 100644 Yi.Framework.Net6/Yi.Framework.Template/Program.cs create mode 100644 Yi.Framework.Net6/Yi.Framework.Template/Provider/ServceTemplateProvider.cs create mode 100644 Yi.Framework.Net6/Yi.Framework.Template/Template/ServiceTemplate.txt create mode 100644 Yi.Framework.Net6/Yi.Framework.Template/TemplateFactory.cs delete mode 100644 Yi.Framework.Net6/Yi.Framework.Template/vue3-ruoyi/api.js delete mode 100644 Yi.Framework.Net6/Yi.Framework.Template/vue3-ruoyi/api.tt delete mode 100644 Yi.Framework.Net6/Yi.Framework.Template/vue3-ruoyi/view.tt delete mode 100644 Yi.Framework.Net6/Yi.Framework.Template/vue3-ruoyi/view.vue diff --git a/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/yi-sqlsugar-dev.db b/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/yi-sqlsugar-dev.db index 616040b2de43658f59db95d2ab445ee6f45ee0a2..41e9f4b692d2f7b3db888630afbd991619ec7101 100644 GIT binary patch delta 138 zcmZp8Ak^?cXo57O_e2?IM(@UitqF`v;+c(kvnI1Qq;D1!_`@@~{yZy3#6;uwP67 TemplateDic { get; set; } + + public void Bak() { + + } + + public virtual void Build() + { + var templateData = GetTemplateData(); + foreach (var ky in TemplateDic) + { + templateData = templateData.Replace(ky.Key, ky.Value); + } + File.WriteAllText(BuildPath, templateData); + } + + + protected virtual string GetTemplateData() + { + return File.ReadAllText(TemplatePath); + } + + protected void AddTemplateDic(string oldStr, string newStr) + { + TemplateDic=new Dictionary(); + TemplateDic.Add(oldStr, newStr); + } + } +} diff --git a/Yi.Framework.Net6/Yi.Framework.Template/Abstract/ITemplateProvider.cs b/Yi.Framework.Net6/Yi.Framework.Template/Abstract/ITemplateProvider.cs new file mode 100644 index 00000000..b57d17be --- /dev/null +++ b/Yi.Framework.Net6/Yi.Framework.Template/Abstract/ITemplateProvider.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Yi.Framework.Template.Abstract +{ + public interface ITemplateProvider + { + /// + /// 构建生成路径 + /// + string BuildPath { get; set; } + + /// + /// 模板文件路径 + /// + string TemplatePath { get; set; } + + /// + /// 备份文件路径 + /// + string BakPath { get; set; } + + + /// + /// 开始构建 + /// + /// + void Build(); + + /// + /// 生成备份 + /// + /// + void Bak(); + + + } +} diff --git a/Yi.Framework.Net6/Yi.Framework.Template/FileHelper.cs b/Yi.Framework.Net6/Yi.Framework.Template/FileHelper.cs new file mode 100644 index 00000000..7ae1c0c4 --- /dev/null +++ b/Yi.Framework.Net6/Yi.Framework.Template/FileHelper.cs @@ -0,0 +1,490 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; + +namespace Yi.Framework.Common.Helper +{ + public class FileHelper : IDisposable + { + + private bool _alreadyDispose = false; + + + + #region 构造函数 + public FileHelper() + { + // + // TODO: 在此处添加构造函数逻辑 + // + } + ~FileHelper() + { + Dispose(); ; + } + + protected virtual void Dispose(bool isDisposing) + { + if (_alreadyDispose) return; + _alreadyDispose = true; + } + #endregion + + #region IDisposable 成员 + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + #endregion + + #region 取得文件后缀名 + /**************************************** + * 函数名称:GetPostfixStr + * 功能说明:取得文件后缀名 + * 参 数:filename:文件名称 + * 调用示列: + * string filename = "aaa.aspx"; + * string s = EC.FileObj.GetPostfixStr(filename); + *****************************************/ + /// + /// 取后缀名 + /// + /// 文件名 + /// .gif|.html格式 + public static string GetPostfixStr(string filename) + { + int start = filename.LastIndexOf("."); + int length = filename.Length; + string postfix = filename.Substring(start, length - start); + return postfix; + } + #endregion + + #region 根据文件大小获取指定前缀的可用文件名 + /// + /// 根据文件大小获取指定前缀的可用文件名 + /// + /// 文件夹 + /// 文件前缀 + /// 文件大小(1m) + /// 文件后缀(.log) + /// 可用文件名 + //public static string GetAvailableFileWithPrefixOrderSize(string folderPath, string prefix, int size = 1 * 1024 * 1024, string ext = ".log") + //{ + // var allFiles = new DirectoryInfo(folderPath); + // var selectFiles = allFiles.GetFiles().Where(fi => fi.Name.ToLower().Contains(prefix.ToLower()) && fi.Extension.ToLower() == ext.ToLower() && fi.Length < size).OrderByDescending(d=>d.Name).ToList(); + + // if (selectFiles.Count > 0) + // { + // return selectFiles.FirstOrDefault().FullName; + // } + + // return Path.Combine(folderPath, $@"{prefix}_{DateTime.Now.DateToTimeStamp()}.log"); + //} + //public static string GetAvailableFileNameWithPrefixOrderSize(string _contentRoot, string prefix, int size = 1 * 1024 * 1024, string ext = ".log") + //{ + // var folderPath = Path.Combine(_contentRoot, "Log"); + // if (!Directory.Exists(folderPath)) + // { + // Directory.CreateDirectory(folderPath); + // } + + // var allFiles = new DirectoryInfo(folderPath); + // var selectFiles = allFiles.GetFiles().Where(fi => fi.Name.ToLower().Contains(prefix.ToLower()) && fi.Extension.ToLower() == ext.ToLower() && fi.Length < size).OrderByDescending(d => d.Name).ToList(); + + // if (selectFiles.Count > 0) + // { + // return selectFiles.FirstOrDefault().Name.Replace(".log",""); + // } + + // return $@"{prefix}_{DateTime.Now.DateToTimeStamp()}"; + //} + #endregion + + #region 写文件 + /**************************************** + * 函数名称:WriteFile + * 功能说明:写文件,会覆盖掉以前的内容 + * 参 数:Path:文件路径,Strings:文本内容 + * 调用示列: + * string Path = Server.MapPath("Default2.aspx"); + * string Strings = "这是我写的内容啊"; + * EC.FileObj.WriteFile(Path,Strings); + *****************************************/ + /// + /// 写文件 + /// + /// 文件路径 + /// 文件内容 + public static void WriteFile(string Path, string Strings) + { + if (!File.Exists(Path)) + { + FileStream f = File.Create(Path); + f.Close(); + } + StreamWriter f2 = new StreamWriter(Path, false, System.Text.Encoding.GetEncoding("gb2312")); + f2.Write(Strings); + f2.Close(); + f2.Dispose(); + } + + /// + /// 写文件 + /// + /// 文件路径 + /// 文件内容 + /// 编码格式 + public static void WriteFile(string Path, string Strings, Encoding encode) + { + if (!File.Exists(Path)) + { + FileStream f = File.Create(Path); + f.Close(); + } + StreamWriter f2 = new StreamWriter(Path, false, encode); + f2.Write(Strings); + f2.Close(); + f2.Dispose(); + } + #endregion + + #region 读文件 + /**************************************** + * 函数名称:ReadFile + * 功能说明:读取文本内容 + * 参 数:Path:文件路径 + * 调用示列: + * string Path = Server.MapPath("Default2.aspx"); + * string s = EC.FileObj.ReadFile(Path); + *****************************************/ + /// + /// 读文件 + /// + /// 文件路径 + /// + public static string ReadFile(string Path) + { + string s = ""; + if (!File.Exists(Path)) + s = "不存在相应的目录"; + else + { + StreamReader f2 = new StreamReader(Path, System.Text.Encoding.GetEncoding("gb2312")); + s = f2.ReadToEnd(); + f2.Close(); + f2.Dispose(); + } + + return s; + } + + /// + /// 读文件 + /// + /// 文件路径 + /// 编码格式 + /// + public static string ReadFile(string Path, Encoding encode) + { + string s = ""; + if (!File.Exists(Path)) + s = "不存在相应的目录"; + else + { + StreamReader f2 = new StreamReader(Path, encode); + s = f2.ReadToEnd(); + f2.Close(); + f2.Dispose(); + } + + return s; + } + #endregion + + #region 追加文件 + /**************************************** + * 函数名称:FileAdd + * 功能说明:追加文件内容 + * 参 数:Path:文件路径,strings:内容 + * 调用示列: + * string Path = Server.MapPath("Default2.aspx"); + * string Strings = "新追加内容"; + * EC.FileObj.FileAdd(Path, Strings); + *****************************************/ + /// + /// 追加文件 + /// + /// 文件路径 + /// 内容 + public static void FileAdd(string Path, string strings) + { + StreamWriter sw = File.AppendText(Path); + sw.Write(strings); + sw.Flush(); + sw.Close(); + } + #endregion + + #region 拷贝文件 + /**************************************** + * 函数名称:FileCoppy + * 功能说明:拷贝文件 + * 参 数:OrignFile:原始文件,NewFile:新文件路径 + * 调用示列: + * string orignFile = Server.MapPath("Default2.aspx"); + * string NewFile = Server.MapPath("Default3.aspx"); + * EC.FileObj.FileCoppy(OrignFile, NewFile); + *****************************************/ + /// + /// 拷贝文件 + /// + /// 原始文件 + /// 新文件路径 + public static void FileCoppy(string orignFile, string NewFile) + { + File.Copy(orignFile, NewFile, true); + } + + #endregion + + #region 删除文件 + /**************************************** + * 函数名称:FileDel + * 功能说明:删除文件 + * 参 数:Path:文件路径 + * 调用示列: + * string Path = Server.MapPath("Default3.aspx"); + * EC.FileObj.FileDel(Path); + *****************************************/ + /// + /// 删除文件 + /// + /// 路径 + public static void FileDel(string Path) + { + File.Delete(Path); + } + #endregion + + #region 移动文件 + /**************************************** + * 函数名称:FileMove + * 功能说明:移动文件 + * 参 数:OrignFile:原始路径,NewFile:新文件路径 + * 调用示列: + * string orignFile = Server.MapPath("../说明.txt"); + * string NewFile = Server.MapPath("http://www.cnblogs.com/说明.txt"); + * EC.FileObj.FileMove(OrignFile, NewFile); + *****************************************/ + /// + /// 移动文件 + /// + /// 原始路径 + /// 新路径 + public static void FileMove(string orignFile, string NewFile) + { + File.Move(orignFile, NewFile); + } + #endregion + + #region 在当前目录下创建目录 + /**************************************** + * 函数名称:FolderCreate + * 功能说明:在当前目录下创建目录 + * 参 数:OrignFolder:当前目录,NewFloder:新目录 + * 调用示列: + * string orignFolder = Server.MapPath("test/"); + * string NewFloder = "new"; + * EC.FileObj.FolderCreate(OrignFolder, NewFloder); + *****************************************/ + /// + /// 在当前目录下创建目录 + /// + /// 当前目录 + /// 新目录 + public static void FolderCreate(string orignFolder, string NewFloder) + { + Directory.SetCurrentDirectory(orignFolder); + Directory.CreateDirectory(NewFloder); + } + #endregion + + #region 递归删除文件夹目录及文件 + /**************************************** + * 函数名称:DeleteFolder + * 功能说明:递归删除文件夹目录及文件 + * 参 数:dir:文件夹路径 + * 调用示列: + * string dir = Server.MapPath("test/"); + * EC.FileObj.DeleteFolder(dir); + *****************************************/ + /// + /// 递归删除文件夹目录及文件 + /// + /// + /// + public static void DeleteFolder(string dir) + { + if (Directory.Exists(dir)) //如果存在这个文件夹删除之 + { + foreach (string d in Directory.GetFileSystemEntries(dir)) + { + if (File.Exists(d)) + File.Delete(d); //直接删除其中的文件 + else + DeleteFolder(d); //递归删除子文件夹 + } + Directory.Delete(dir); //删除已空文件夹 + } + + } + #endregion + + #region 将指定文件夹下面的所有内容copy到目标文件夹下面 果目标文件夹为只读属性就会报错。 + /**************************************** + * 函数名称:CopyDir + * 功能说明:将指定文件夹下面的所有内容copy到目标文件夹下面 果目标文件夹为只读属性就会报错。 + * 参 数:srcPath:原始路径,aimPath:目标文件夹 + * 调用示列: + * string srcPath = Server.MapPath("test/"); + * string aimPath = Server.MapPath("test1/"); + * EC.FileObj.CopyDir(srcPath,aimPath); + *****************************************/ + /// + /// 指定文件夹下面的所有内容copy到目标文件夹下面 + /// + /// 原始路径 + /// 目标文件夹 + public static void CopyDir(string srcPath, string aimPath) + { + try + { + // 检查目标目录是否以目录分割字符结束如果不是则添加之 + if (aimPath[aimPath.Length - 1] != Path.DirectorySeparatorChar) + aimPath += Path.DirectorySeparatorChar; + // 判断目标目录是否存在如果不存在则新建之 + if (!Directory.Exists(aimPath)) + Directory.CreateDirectory(aimPath); + // 得到源目录的文件列表,该里面是包含文件以及目录路径的一个数组 + //如果你指向copy目标文件下面的文件而不包含目录请使用下面的方法 + //string[] fileList = Directory.GetFiles(srcPath); + string[] fileList = Directory.GetFileSystemEntries(srcPath); + //遍历所有的文件和目录 + foreach (string file in fileList) + { + //先当作目录处理如果存在这个目录就递归Copy该目录下面的文件 + + if (Directory.Exists(file)) + CopyDir(file, aimPath + Path.GetFileName(file)); + //否则直接Copy文件 + else + File.Copy(file, aimPath + Path.GetFileName(file), true); + } + + } + catch (Exception ee) + { + throw new Exception(ee.ToString()); + } + } + #endregion + + /// + /// 获取目录下全部文件名 + /// + /// + /// + /// + public static List GetAllFileNames(string path, string pattern = "*") + { + List folder = new DirectoryInfo(path).GetFiles(pattern).ToList(); + + return folder.Select(x => x.Name).ToList(); + } + /// + /// 文件内容替换 + /// + public static string FileContentReplace(string path, string oldStr, string newStr) + { + var content = File.ReadAllText(path); + + if (content.Contains(oldStr)) + { + File.Delete(path); + File.WriteAllText(path, content.Replace(oldStr, newStr)); + } + + return path; + } + /// + /// 文件名称 + /// + public static string FileNameReplace(string path, string oldStr, string newStr) + { + string fileName = Path.GetFileName(path); + if (!fileName.Contains(oldStr)) + { + return path; + } + + string? directoryName = Path.GetDirectoryName(path); + string newFileName = fileName.Replace(oldStr, newStr); + string newPath = Path.Combine(directoryName ?? "", newFileName); + File.Move(path, newPath); + + return newPath; + } + /// + /// 目录名替换 + /// + public static string DirectoryNameReplace(string path, string oldStr, string newStr) + { + string fileName = Path.GetFileName(path); + if (!fileName.Contains(oldStr)) + { + return path; + } + + string? directoryName = Path.GetDirectoryName(path); + string newFileName = fileName.Replace(oldStr, newStr); + string newPath = Path.Combine(directoryName ?? "", newFileName); + Directory.Move(path, newPath); + return newPath; + } + + /// + /// 全部信息递归替换 + /// + /// + /// + /// + public static void AllInfoReplace(string dirPath, string oldStr, string newStr) + { + var path = DirectoryNameReplace(dirPath, oldStr, newStr); + var dirInfo = new DirectoryInfo(path); + var files = dirInfo.GetFiles(); + var dirs = dirInfo.GetDirectories(); + if (files.Length > 0) + { + foreach (var f in files) + { + FileContentReplace(f.FullName, oldStr, newStr); + FileNameReplace(f.FullName, oldStr, newStr); + } + } + if (dirs.Length > 0) + { + foreach (var d in dirs) + { + AllInfoReplace(d.FullName, oldStr, newStr); + } + } + } + } +} diff --git a/Yi.Framework.Net6/Yi.Framework.Template/Program.cs b/Yi.Framework.Net6/Yi.Framework.Template/Program.cs new file mode 100644 index 00000000..8e300ecd --- /dev/null +++ b/Yi.Framework.Net6/Yi.Framework.Template/Program.cs @@ -0,0 +1,14 @@ +using Yi.Framework.Template; +using Yi.Framework.Template.Provider; + +TemplateFactory templateFactory = new(); + +//选择需要生成的模板提供者 +templateFactory.CreateTemplateProviders((option) => +{ + option.Add(new ServceTemplateProvider()); + +}); + +//开始构建模板 +templateFactory.BuildTemplate(); \ No newline at end of file diff --git a/Yi.Framework.Net6/Yi.Framework.Template/Provider/ServceTemplateProvider.cs b/Yi.Framework.Net6/Yi.Framework.Template/Provider/ServceTemplateProvider.cs new file mode 100644 index 00000000..5259b5ee --- /dev/null +++ b/Yi.Framework.Net6/Yi.Framework.Template/Provider/ServceTemplateProvider.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Yi.Framework.Template.Abstract; + +namespace Yi.Framework.Template.Provider +{ + public class ServceTemplateProvider : AbstractTemplateProvider + { + public ServceTemplateProvider() + { + BuildPath = "E:\\Yi\\Yi.Framework.Net6\\Yi.Framework.Template\\Code\\ServiceNewTemplate.txt"; + TemplatePath = "E:\\Yi\\Yi.Framework.Net6\\Yi.Framework.Template\\Template\\ServiceTemplate.txt"; + AddTemplateDic("Yi.Framework", "Yi.TTT"); + } + } +} diff --git a/Yi.Framework.Net6/Yi.Framework.Template/Template/ServiceTemplate.txt b/Yi.Framework.Net6/Yi.Framework.Template/Template/ServiceTemplate.txt new file mode 100644 index 00000000..c22f11eb --- /dev/null +++ b/Yi.Framework.Net6/Yi.Framework.Template/Template/ServiceTemplate.txt @@ -0,0 +1,32 @@ +using AutoMapper; +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Yi.Framework.Common.Models; +using Yi.Framework.DtoModel.ERP.Supplier; +using Yi.Framework.Interface.ERP; +using Yi.Framework.Model.ERP.Entitys; +using Yi.Framework.Repository; +using Yi.Framework.Service.Base.Crud; + +namespace Yi.Framework.Service.ERP +{ + public class SupplierService : CrudAppService, ISupplierService + { + public SupplierService(IRepository repository, IMapper mapper) : base(repository, mapper) + { + } + public async Task>> PageListAsync(SupplierCreateUpdateInput input, PageParModel page) + { + RefAsync totalNumber = 0; + var data = await Repository._DbQueryable + .WhereIF(input.Code is not null,u=>u.Code.Contains(input.Code)) + .WhereIF(input.Name is not null, u => u.Name.Contains(input.Name)) + .ToPageListAsync(page.PageNum, page.PageSize, totalNumber); + return new PageModel> { Total = totalNumber.Value, Data = await MapToGetListOutputDtosAsync(data) }; + } + } +} diff --git a/Yi.Framework.Net6/Yi.Framework.Template/TemplateFactory.cs b/Yi.Framework.Net6/Yi.Framework.Template/TemplateFactory.cs new file mode 100644 index 00000000..76c879fc --- /dev/null +++ b/Yi.Framework.Net6/Yi.Framework.Template/TemplateFactory.cs @@ -0,0 +1,38 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Yi.Framework.Template.Abstract; +using Yi.Framework.Template.Provider; + +namespace Yi.Framework.Template +{ + public class TemplateFactory + { + private List _templateProviders; + + public void CreateTemplateProviders(Action> action) + { + _templateProviders=new List(); + action(_templateProviders); + } + + public void BuildTemplate() + { + foreach (var provider in _templateProviders) + { + provider.Build(); + } + } + + public void BakTemplate() + { + foreach (var provider in _templateProviders) + { + provider.Bak(); + } + } + + } +} diff --git a/Yi.Framework.Net6/Yi.Framework.Template/Yi.Framework.Template.csproj b/Yi.Framework.Net6/Yi.Framework.Template/Yi.Framework.Template.csproj index 2a3b0053..eca3d7cc 100644 --- a/Yi.Framework.Net6/Yi.Framework.Template/Yi.Framework.Template.csproj +++ b/Yi.Framework.Net6/Yi.Framework.Template/Yi.Framework.Template.csproj @@ -4,47 +4,16 @@ net6.0 enable enable + Exe - - - True - True - view.tt - - - - - - True - True - view.tt - - - - - - view.vue - TextTemplatingFileGenerator - - - TextTemplatingFileGenerator - api.js - - - True - True - api.tt - - - True - True - view.tt - - - + + + + + diff --git a/Yi.Framework.Net6/Yi.Framework.Template/vue3-ruoyi/api.js b/Yi.Framework.Net6/Yi.Framework.Template/vue3-ruoyi/api.js deleted file mode 100644 index 403e94c0..00000000 --- a/Yi.Framework.Net6/Yi.Framework.Template/vue3-ruoyi/api.js +++ /dev/null @@ -1,45 +0,0 @@ -import request from '@/utils/request' - -// 分页查询 -export function listData(query) { - return request({ - url: '/article/pageList', - method: 'get', - params: query - }) -} - -// id查询 -export function getData(code) { - return request({ - url: '/article/getById/' + code, - method: 'get' - }) -} - -// 新增 -export function addData(data) { - return request({ - url: '/article/add', - method: 'post', - data: data - }) -} - -// 修改 -export function updateData(data) { - return request({ - url: '/article/update', - method: 'put', - data: data - }) -} - -// 删除 -export function delData(code) { - return request({ - url: '/article/delList', - method: 'delete', - data:"string"==typeof(code)?[code]:code - }) -} diff --git a/Yi.Framework.Net6/Yi.Framework.Template/vue3-ruoyi/api.tt b/Yi.Framework.Net6/Yi.Framework.Template/vue3-ruoyi/api.tt deleted file mode 100644 index a32440e8..00000000 --- a/Yi.Framework.Net6/Yi.Framework.Template/vue3-ruoyi/api.tt +++ /dev/null @@ -1,54 +0,0 @@ -<#@ template debug="false" hostspecific="false" language="C#" #> -<#@ assembly name="System.Core" #> -<#@ import namespace="System.Linq" #> -<#@ import namespace="System.Text" #> -<#@ import namespace="System.Collections.Generic" #> -<#@ output extension=".js" #> -<# -var entityName="article"; -#> -import request from '@/utils/request' - -// 分页查询 -export function listData(query) { - return request({ - url: '/<#= entityName #>/pageList', - method: 'get', - params: query - }) -} - -// id查询 -export function getData(code) { - return request({ - url: '/<#= entityName #>/getById/' + code, - method: 'get' - }) -} - -// 新增 -export function addData(data) { - return request({ - url: '/<#= entityName #>/add', - method: 'post', - data: data - }) -} - -// 修改 -export function updateData(data) { - return request({ - url: '/<#= entityName #>/update', - method: 'put', - data: data - }) -} - -// 删除 -export function delData(code) { - return request({ - url: '/<#= entityName #>/delList', - method: 'delete', - data:"string"==typeof(code)?[code]:code - }) -} diff --git a/Yi.Framework.Net6/Yi.Framework.Template/vue3-ruoyi/view.tt b/Yi.Framework.Net6/Yi.Framework.Template/vue3-ruoyi/view.tt deleted file mode 100644 index af02e22f..00000000 --- a/Yi.Framework.Net6/Yi.Framework.Template/vue3-ruoyi/view.tt +++ /dev/null @@ -1,315 +0,0 @@ -<#@ template debug="false" hostspecific="false" language="C#" #> -<#@ assembly name="System.Core" #> -<#@ import namespace="System.Linq" #> -<#@ import namespace="System.Text" #> -<#@ import namespace="System.Collections.Generic" #> -<#@ output extension=".vue" #> -<# -var entityName="article"; -var path="/business/articleApi"; -var entityRemark="文章"; -var perCode="business:article"; -var dataDic=new Dictionary(){ -{"title","文章标题"}, -}; -var isStart=false; -#> -// -<#if(isStart){ - -#> - - - - - -<#} - #> \ No newline at end of file diff --git a/Yi.Framework.Net6/Yi.Framework.Template/vue3-ruoyi/view.vue b/Yi.Framework.Net6/Yi.Framework.Template/vue3-ruoyi/view.vue deleted file mode 100644 index 6eae1eb0..00000000 --- a/Yi.Framework.Net6/Yi.Framework.Template/vue3-ruoyi/view.vue +++ /dev/null @@ -1 +0,0 @@ -// From 53b4674da4088b6b2f805d8b875dab5eb790f6f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E6=B7=B3?= Date: Tue, 3 Jan 2023 18:14:18 +0800 Subject: [PATCH 06/10] Create ProgramTemplateProvider.cs --- .../Abstract/ProgramTemplateProvider.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 Yi.Framework.Net6/Yi.Framework.Template/Abstract/ProgramTemplateProvider.cs diff --git a/Yi.Framework.Net6/Yi.Framework.Template/Abstract/ProgramTemplateProvider.cs b/Yi.Framework.Net6/Yi.Framework.Template/Abstract/ProgramTemplateProvider.cs new file mode 100644 index 00000000..3007f732 --- /dev/null +++ b/Yi.Framework.Net6/Yi.Framework.Template/Abstract/ProgramTemplateProvider.cs @@ -0,0 +1,12 @@ +//using System; +//using System.Collections.Generic; +//using System.Linq; +//using System.Text; +//using System.Threading.Tasks; + +//namespace Yi.Framework.Template.Abstract +//{ +// public abstract ProgramTemplateProvider: AbstractTemplateProvider +// { +// } +//} From 62c5470efe0a1c937145ba38f014335d3044a2a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=A9=99=E5=AD=90?= <454313500@qq.com> Date: Tue, 3 Jan 2023 20:06:16 +0800 Subject: [PATCH 07/10] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E7=94=9F=E6=88=90=E5=99=A8=E6=A8=A1=E5=9D=97service=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Abstract/AbstractTemplateProvider.cs | 31 +- .../Abstract/ITemplateProvider.cs | 6 +- .../Abstract/ProgramTemplateProvider.cs | 72 ++- .../Const/TemplateConst.cs | 21 + .../Yi.Framework.Template/FileHelper.cs | 490 ------------------ .../Yi.Framework.Template/Program.cs | 10 +- .../Provider/ServceTemplateProvider.cs | 11 +- .../Template/ServiceTemplate.txt | 16 +- 8 files changed, 119 insertions(+), 538 deletions(-) create mode 100644 Yi.Framework.Net6/Yi.Framework.Template/Const/TemplateConst.cs delete mode 100644 Yi.Framework.Net6/Yi.Framework.Template/FileHelper.cs diff --git a/Yi.Framework.Net6/Yi.Framework.Template/Abstract/AbstractTemplateProvider.cs b/Yi.Framework.Net6/Yi.Framework.Template/Abstract/AbstractTemplateProvider.cs index 9c2ca37c..cf35c614 100644 --- a/Yi.Framework.Net6/Yi.Framework.Template/Abstract/AbstractTemplateProvider.cs +++ b/Yi.Framework.Net6/Yi.Framework.Template/Abstract/AbstractTemplateProvider.cs @@ -3,40 +3,33 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; -using Yi.Framework.Common.Helper; namespace Yi.Framework.Template.Abstract { public abstract class AbstractTemplateProvider : ITemplateProvider { - public string BuildPath { get; set; } - public string TemplatePath { get; set; } - public string BakPath { get; set; } - private Dictionary TemplateDic { get; set; } + public virtual string? BuildPath { get; set; } + public string? TemplatePath { get; set; } + public string? BakPath { get; set; } + protected Dictionary TemplateDic { get; set; } = new Dictionary(); - public void Bak() { - - } + public abstract void Bak(); - public virtual void Build() - { - var templateData = GetTemplateData(); - foreach (var ky in TemplateDic) - { - templateData = templateData.Replace(ky.Key, ky.Value); - } - File.WriteAllText(BuildPath, templateData); - } + public abstract void Build(); protected virtual string GetTemplateData() { + if (TemplatePath is null) + { + throw new ArgumentNullException(nameof(TemplatePath)); + } return File.ReadAllText(TemplatePath); } - protected void AddTemplateDic(string oldStr, string newStr) + protected void AddTemplateDic(string oldStr, string newStr) { - TemplateDic=new Dictionary(); + TemplateDic.Add(oldStr, newStr); } } diff --git a/Yi.Framework.Net6/Yi.Framework.Template/Abstract/ITemplateProvider.cs b/Yi.Framework.Net6/Yi.Framework.Template/Abstract/ITemplateProvider.cs index b57d17be..5ac81801 100644 --- a/Yi.Framework.Net6/Yi.Framework.Template/Abstract/ITemplateProvider.cs +++ b/Yi.Framework.Net6/Yi.Framework.Template/Abstract/ITemplateProvider.cs @@ -11,17 +11,17 @@ namespace Yi.Framework.Template.Abstract /// /// 构建生成路径 /// - string BuildPath { get; set; } + string? BuildPath { get; set; } /// /// 模板文件路径 /// - string TemplatePath { get; set; } + string? TemplatePath { get; set; } /// /// 备份文件路径 /// - string BakPath { get; set; } + string? BakPath { get; set; } /// diff --git a/Yi.Framework.Net6/Yi.Framework.Template/Abstract/ProgramTemplateProvider.cs b/Yi.Framework.Net6/Yi.Framework.Template/Abstract/ProgramTemplateProvider.cs index 3007f732..68bd7561 100644 --- a/Yi.Framework.Net6/Yi.Framework.Template/Abstract/ProgramTemplateProvider.cs +++ b/Yi.Framework.Net6/Yi.Framework.Template/Abstract/ProgramTemplateProvider.cs @@ -1,12 +1,62 @@ -//using System; -//using System.Collections.Generic; -//using System.Linq; -//using System.Text; -//using System.Threading.Tasks; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Yi.Framework.Template.Const; -//namespace Yi.Framework.Template.Abstract -//{ -// public abstract ProgramTemplateProvider: AbstractTemplateProvider -// { -// } -//} +namespace Yi.Framework.Template.Abstract +{ + + public abstract class ProgramTemplateProvider : AbstractTemplateProvider + { + public ProgramTemplateProvider(string modelName, string entityName) + { + ModelName = modelName; + EntityName = entityName; + base.AddTemplateDic(TemplateConst.EntityName, EntityName); + base.AddTemplateDic(TemplateConst.ModelName, ModelName); + } + /// + /// 实体名称 + /// + public string EntityName { get; set; } + /// + /// 模块名称 + /// + public string ModelName { get; set; } + + /// + /// 重写构建路径,替换实体名称与模块名称 + /// + public override string? BuildPath + { + get => base.BuildPath; + set + { + value = value!.Replace(TemplateConst.EntityName, EntityName); + value = value.Replace(TemplateConst.ModelName, ModelName); + base.BuildPath = value; + } + } + + public override void Build() + { + if (BuildPath is null) + { + throw new ArgumentNullException(nameof(BuildPath)); + } + var templateData = GetTemplateData(); + foreach (var ky in TemplateDic) + { + templateData = templateData.Replace(ky.Key, ky.Value); + } + File.WriteAllText(BuildPath, templateData); + } + + public override void Bak() + { + throw new NotImplementedException(); + } + } +} diff --git a/Yi.Framework.Net6/Yi.Framework.Template/Const/TemplateConst.cs b/Yi.Framework.Net6/Yi.Framework.Template/Const/TemplateConst.cs new file mode 100644 index 00000000..02a6a6ca --- /dev/null +++ b/Yi.Framework.Net6/Yi.Framework.Template/Const/TemplateConst.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Yi.Framework.Template.Const +{ + public class TemplateConst + { + /// + /// 模块名称 + /// + public const string ModelName = "#ModelName#"; + + /// + /// 实体名称 + /// + public const string EntityName = "#EntityName#"; + } +} diff --git a/Yi.Framework.Net6/Yi.Framework.Template/FileHelper.cs b/Yi.Framework.Net6/Yi.Framework.Template/FileHelper.cs deleted file mode 100644 index 7ae1c0c4..00000000 --- a/Yi.Framework.Net6/Yi.Framework.Template/FileHelper.cs +++ /dev/null @@ -1,490 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; - -namespace Yi.Framework.Common.Helper -{ - public class FileHelper : IDisposable - { - - private bool _alreadyDispose = false; - - - - #region 构造函数 - public FileHelper() - { - // - // TODO: 在此处添加构造函数逻辑 - // - } - ~FileHelper() - { - Dispose(); ; - } - - protected virtual void Dispose(bool isDisposing) - { - if (_alreadyDispose) return; - _alreadyDispose = true; - } - #endregion - - #region IDisposable 成员 - - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - #endregion - - #region 取得文件后缀名 - /**************************************** - * 函数名称:GetPostfixStr - * 功能说明:取得文件后缀名 - * 参 数:filename:文件名称 - * 调用示列: - * string filename = "aaa.aspx"; - * string s = EC.FileObj.GetPostfixStr(filename); - *****************************************/ - /// - /// 取后缀名 - /// - /// 文件名 - /// .gif|.html格式 - public static string GetPostfixStr(string filename) - { - int start = filename.LastIndexOf("."); - int length = filename.Length; - string postfix = filename.Substring(start, length - start); - return postfix; - } - #endregion - - #region 根据文件大小获取指定前缀的可用文件名 - /// - /// 根据文件大小获取指定前缀的可用文件名 - /// - /// 文件夹 - /// 文件前缀 - /// 文件大小(1m) - /// 文件后缀(.log) - /// 可用文件名 - //public static string GetAvailableFileWithPrefixOrderSize(string folderPath, string prefix, int size = 1 * 1024 * 1024, string ext = ".log") - //{ - // var allFiles = new DirectoryInfo(folderPath); - // var selectFiles = allFiles.GetFiles().Where(fi => fi.Name.ToLower().Contains(prefix.ToLower()) && fi.Extension.ToLower() == ext.ToLower() && fi.Length < size).OrderByDescending(d=>d.Name).ToList(); - - // if (selectFiles.Count > 0) - // { - // return selectFiles.FirstOrDefault().FullName; - // } - - // return Path.Combine(folderPath, $@"{prefix}_{DateTime.Now.DateToTimeStamp()}.log"); - //} - //public static string GetAvailableFileNameWithPrefixOrderSize(string _contentRoot, string prefix, int size = 1 * 1024 * 1024, string ext = ".log") - //{ - // var folderPath = Path.Combine(_contentRoot, "Log"); - // if (!Directory.Exists(folderPath)) - // { - // Directory.CreateDirectory(folderPath); - // } - - // var allFiles = new DirectoryInfo(folderPath); - // var selectFiles = allFiles.GetFiles().Where(fi => fi.Name.ToLower().Contains(prefix.ToLower()) && fi.Extension.ToLower() == ext.ToLower() && fi.Length < size).OrderByDescending(d => d.Name).ToList(); - - // if (selectFiles.Count > 0) - // { - // return selectFiles.FirstOrDefault().Name.Replace(".log",""); - // } - - // return $@"{prefix}_{DateTime.Now.DateToTimeStamp()}"; - //} - #endregion - - #region 写文件 - /**************************************** - * 函数名称:WriteFile - * 功能说明:写文件,会覆盖掉以前的内容 - * 参 数:Path:文件路径,Strings:文本内容 - * 调用示列: - * string Path = Server.MapPath("Default2.aspx"); - * string Strings = "这是我写的内容啊"; - * EC.FileObj.WriteFile(Path,Strings); - *****************************************/ - /// - /// 写文件 - /// - /// 文件路径 - /// 文件内容 - public static void WriteFile(string Path, string Strings) - { - if (!File.Exists(Path)) - { - FileStream f = File.Create(Path); - f.Close(); - } - StreamWriter f2 = new StreamWriter(Path, false, System.Text.Encoding.GetEncoding("gb2312")); - f2.Write(Strings); - f2.Close(); - f2.Dispose(); - } - - /// - /// 写文件 - /// - /// 文件路径 - /// 文件内容 - /// 编码格式 - public static void WriteFile(string Path, string Strings, Encoding encode) - { - if (!File.Exists(Path)) - { - FileStream f = File.Create(Path); - f.Close(); - } - StreamWriter f2 = new StreamWriter(Path, false, encode); - f2.Write(Strings); - f2.Close(); - f2.Dispose(); - } - #endregion - - #region 读文件 - /**************************************** - * 函数名称:ReadFile - * 功能说明:读取文本内容 - * 参 数:Path:文件路径 - * 调用示列: - * string Path = Server.MapPath("Default2.aspx"); - * string s = EC.FileObj.ReadFile(Path); - *****************************************/ - /// - /// 读文件 - /// - /// 文件路径 - /// - public static string ReadFile(string Path) - { - string s = ""; - if (!File.Exists(Path)) - s = "不存在相应的目录"; - else - { - StreamReader f2 = new StreamReader(Path, System.Text.Encoding.GetEncoding("gb2312")); - s = f2.ReadToEnd(); - f2.Close(); - f2.Dispose(); - } - - return s; - } - - /// - /// 读文件 - /// - /// 文件路径 - /// 编码格式 - /// - public static string ReadFile(string Path, Encoding encode) - { - string s = ""; - if (!File.Exists(Path)) - s = "不存在相应的目录"; - else - { - StreamReader f2 = new StreamReader(Path, encode); - s = f2.ReadToEnd(); - f2.Close(); - f2.Dispose(); - } - - return s; - } - #endregion - - #region 追加文件 - /**************************************** - * 函数名称:FileAdd - * 功能说明:追加文件内容 - * 参 数:Path:文件路径,strings:内容 - * 调用示列: - * string Path = Server.MapPath("Default2.aspx"); - * string Strings = "新追加内容"; - * EC.FileObj.FileAdd(Path, Strings); - *****************************************/ - /// - /// 追加文件 - /// - /// 文件路径 - /// 内容 - public static void FileAdd(string Path, string strings) - { - StreamWriter sw = File.AppendText(Path); - sw.Write(strings); - sw.Flush(); - sw.Close(); - } - #endregion - - #region 拷贝文件 - /**************************************** - * 函数名称:FileCoppy - * 功能说明:拷贝文件 - * 参 数:OrignFile:原始文件,NewFile:新文件路径 - * 调用示列: - * string orignFile = Server.MapPath("Default2.aspx"); - * string NewFile = Server.MapPath("Default3.aspx"); - * EC.FileObj.FileCoppy(OrignFile, NewFile); - *****************************************/ - /// - /// 拷贝文件 - /// - /// 原始文件 - /// 新文件路径 - public static void FileCoppy(string orignFile, string NewFile) - { - File.Copy(orignFile, NewFile, true); - } - - #endregion - - #region 删除文件 - /**************************************** - * 函数名称:FileDel - * 功能说明:删除文件 - * 参 数:Path:文件路径 - * 调用示列: - * string Path = Server.MapPath("Default3.aspx"); - * EC.FileObj.FileDel(Path); - *****************************************/ - /// - /// 删除文件 - /// - /// 路径 - public static void FileDel(string Path) - { - File.Delete(Path); - } - #endregion - - #region 移动文件 - /**************************************** - * 函数名称:FileMove - * 功能说明:移动文件 - * 参 数:OrignFile:原始路径,NewFile:新文件路径 - * 调用示列: - * string orignFile = Server.MapPath("../说明.txt"); - * string NewFile = Server.MapPath("http://www.cnblogs.com/说明.txt"); - * EC.FileObj.FileMove(OrignFile, NewFile); - *****************************************/ - /// - /// 移动文件 - /// - /// 原始路径 - /// 新路径 - public static void FileMove(string orignFile, string NewFile) - { - File.Move(orignFile, NewFile); - } - #endregion - - #region 在当前目录下创建目录 - /**************************************** - * 函数名称:FolderCreate - * 功能说明:在当前目录下创建目录 - * 参 数:OrignFolder:当前目录,NewFloder:新目录 - * 调用示列: - * string orignFolder = Server.MapPath("test/"); - * string NewFloder = "new"; - * EC.FileObj.FolderCreate(OrignFolder, NewFloder); - *****************************************/ - /// - /// 在当前目录下创建目录 - /// - /// 当前目录 - /// 新目录 - public static void FolderCreate(string orignFolder, string NewFloder) - { - Directory.SetCurrentDirectory(orignFolder); - Directory.CreateDirectory(NewFloder); - } - #endregion - - #region 递归删除文件夹目录及文件 - /**************************************** - * 函数名称:DeleteFolder - * 功能说明:递归删除文件夹目录及文件 - * 参 数:dir:文件夹路径 - * 调用示列: - * string dir = Server.MapPath("test/"); - * EC.FileObj.DeleteFolder(dir); - *****************************************/ - /// - /// 递归删除文件夹目录及文件 - /// - /// - /// - public static void DeleteFolder(string dir) - { - if (Directory.Exists(dir)) //如果存在这个文件夹删除之 - { - foreach (string d in Directory.GetFileSystemEntries(dir)) - { - if (File.Exists(d)) - File.Delete(d); //直接删除其中的文件 - else - DeleteFolder(d); //递归删除子文件夹 - } - Directory.Delete(dir); //删除已空文件夹 - } - - } - #endregion - - #region 将指定文件夹下面的所有内容copy到目标文件夹下面 果目标文件夹为只读属性就会报错。 - /**************************************** - * 函数名称:CopyDir - * 功能说明:将指定文件夹下面的所有内容copy到目标文件夹下面 果目标文件夹为只读属性就会报错。 - * 参 数:srcPath:原始路径,aimPath:目标文件夹 - * 调用示列: - * string srcPath = Server.MapPath("test/"); - * string aimPath = Server.MapPath("test1/"); - * EC.FileObj.CopyDir(srcPath,aimPath); - *****************************************/ - /// - /// 指定文件夹下面的所有内容copy到目标文件夹下面 - /// - /// 原始路径 - /// 目标文件夹 - public static void CopyDir(string srcPath, string aimPath) - { - try - { - // 检查目标目录是否以目录分割字符结束如果不是则添加之 - if (aimPath[aimPath.Length - 1] != Path.DirectorySeparatorChar) - aimPath += Path.DirectorySeparatorChar; - // 判断目标目录是否存在如果不存在则新建之 - if (!Directory.Exists(aimPath)) - Directory.CreateDirectory(aimPath); - // 得到源目录的文件列表,该里面是包含文件以及目录路径的一个数组 - //如果你指向copy目标文件下面的文件而不包含目录请使用下面的方法 - //string[] fileList = Directory.GetFiles(srcPath); - string[] fileList = Directory.GetFileSystemEntries(srcPath); - //遍历所有的文件和目录 - foreach (string file in fileList) - { - //先当作目录处理如果存在这个目录就递归Copy该目录下面的文件 - - if (Directory.Exists(file)) - CopyDir(file, aimPath + Path.GetFileName(file)); - //否则直接Copy文件 - else - File.Copy(file, aimPath + Path.GetFileName(file), true); - } - - } - catch (Exception ee) - { - throw new Exception(ee.ToString()); - } - } - #endregion - - /// - /// 获取目录下全部文件名 - /// - /// - /// - /// - public static List GetAllFileNames(string path, string pattern = "*") - { - List folder = new DirectoryInfo(path).GetFiles(pattern).ToList(); - - return folder.Select(x => x.Name).ToList(); - } - /// - /// 文件内容替换 - /// - public static string FileContentReplace(string path, string oldStr, string newStr) - { - var content = File.ReadAllText(path); - - if (content.Contains(oldStr)) - { - File.Delete(path); - File.WriteAllText(path, content.Replace(oldStr, newStr)); - } - - return path; - } - /// - /// 文件名称 - /// - public static string FileNameReplace(string path, string oldStr, string newStr) - { - string fileName = Path.GetFileName(path); - if (!fileName.Contains(oldStr)) - { - return path; - } - - string? directoryName = Path.GetDirectoryName(path); - string newFileName = fileName.Replace(oldStr, newStr); - string newPath = Path.Combine(directoryName ?? "", newFileName); - File.Move(path, newPath); - - return newPath; - } - /// - /// 目录名替换 - /// - public static string DirectoryNameReplace(string path, string oldStr, string newStr) - { - string fileName = Path.GetFileName(path); - if (!fileName.Contains(oldStr)) - { - return path; - } - - string? directoryName = Path.GetDirectoryName(path); - string newFileName = fileName.Replace(oldStr, newStr); - string newPath = Path.Combine(directoryName ?? "", newFileName); - Directory.Move(path, newPath); - return newPath; - } - - /// - /// 全部信息递归替换 - /// - /// - /// - /// - public static void AllInfoReplace(string dirPath, string oldStr, string newStr) - { - var path = DirectoryNameReplace(dirPath, oldStr, newStr); - var dirInfo = new DirectoryInfo(path); - var files = dirInfo.GetFiles(); - var dirs = dirInfo.GetDirectories(); - if (files.Length > 0) - { - foreach (var f in files) - { - FileContentReplace(f.FullName, oldStr, newStr); - FileNameReplace(f.FullName, oldStr, newStr); - } - } - if (dirs.Length > 0) - { - foreach (var d in dirs) - { - AllInfoReplace(d.FullName, oldStr, newStr); - } - } - } - } -} diff --git a/Yi.Framework.Net6/Yi.Framework.Template/Program.cs b/Yi.Framework.Net6/Yi.Framework.Template/Program.cs index 8e300ecd..1a8070ef 100644 --- a/Yi.Framework.Net6/Yi.Framework.Template/Program.cs +++ b/Yi.Framework.Net6/Yi.Framework.Template/Program.cs @@ -4,11 +4,17 @@ using Yi.Framework.Template.Provider; TemplateFactory templateFactory = new(); //选择需要生成的模板提供者 + +string modelName = "ERP"; +string entityName = "Test"; + templateFactory.CreateTemplateProviders((option) => { - option.Add(new ServceTemplateProvider()); + option.Add(new ServceTemplateProvider(modelName, entityName)); }); //开始构建模板 -templateFactory.BuildTemplate(); \ No newline at end of file +templateFactory.BuildTemplate(); +Console.WriteLine("Yi.Framework.Template模板生成完成!"); +Console.ReadKey(); \ No newline at end of file diff --git a/Yi.Framework.Net6/Yi.Framework.Template/Provider/ServceTemplateProvider.cs b/Yi.Framework.Net6/Yi.Framework.Template/Provider/ServceTemplateProvider.cs index 5259b5ee..6098e8bc 100644 --- a/Yi.Framework.Net6/Yi.Framework.Template/Provider/ServceTemplateProvider.cs +++ b/Yi.Framework.Net6/Yi.Framework.Template/Provider/ServceTemplateProvider.cs @@ -4,16 +4,17 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using Yi.Framework.Template.Abstract; +using Yi.Framework.Template.Const; namespace Yi.Framework.Template.Provider { - public class ServceTemplateProvider : AbstractTemplateProvider + public class ServceTemplateProvider : ProgramTemplateProvider { - public ServceTemplateProvider() + public ServceTemplateProvider(string modelName, string entityName) : base( modelName,entityName) { - BuildPath = "E:\\Yi\\Yi.Framework.Net6\\Yi.Framework.Template\\Code\\ServiceNewTemplate.txt"; - TemplatePath = "E:\\Yi\\Yi.Framework.Net6\\Yi.Framework.Template\\Template\\ServiceTemplate.txt"; - AddTemplateDic("Yi.Framework", "Yi.TTT"); + BuildPath = $@"D:\CC.Yi\CC.Yi\Yi.Framework.Net6\Yi.Framework.Template\Code\{TemplateConst.EntityName}Entity.cs"; + TemplatePath = $@"D:\CC.Yi\CC.Yi\Yi.Framework.Net6\Yi.Framework.Template\Template\ServiceTemplate.txt"; + AddTemplateDic("Yi.Framework", "Yi.Test"); } } } diff --git a/Yi.Framework.Net6/Yi.Framework.Template/Template/ServiceTemplate.txt b/Yi.Framework.Net6/Yi.Framework.Template/Template/ServiceTemplate.txt index c22f11eb..fec61106 100644 --- a/Yi.Framework.Net6/Yi.Framework.Template/Template/ServiceTemplate.txt +++ b/Yi.Framework.Net6/Yi.Framework.Template/Template/ServiceTemplate.txt @@ -6,27 +6,27 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using Yi.Framework.Common.Models; -using Yi.Framework.DtoModel.ERP.Supplier; -using Yi.Framework.Interface.ERP; -using Yi.Framework.Model.ERP.Entitys; +using Yi.Framework.DtoModel.#ModelName#.#EntityName#; +using Yi.Framework.Interface.#ModelName#; +using Yi.Framework.Model.#ModelName#.Entitys; using Yi.Framework.Repository; using Yi.Framework.Service.Base.Crud; -namespace Yi.Framework.Service.ERP +namespace Yi.Framework.Service.#ModelName# { - public class SupplierService : CrudAppService, ISupplierService + public class #EntityName#Service : CrudAppService<#EntityName#Entity, #EntityName#GetListOutput, long, #EntityName#CreateUpdateInput>, I#EntityName#Service { - public SupplierService(IRepository repository, IMapper mapper) : base(repository, mapper) + public #EntityName#Service(IRepository<#EntityName#Entity> repository, IMapper mapper) : base(repository, mapper) { } - public async Task>> PageListAsync(SupplierCreateUpdateInput input, PageParModel page) + public async Task>> PageListAsync(#EntityName#CreateUpdateInput input, PageParModel page) { RefAsync totalNumber = 0; var data = await Repository._DbQueryable .WhereIF(input.Code is not null,u=>u.Code.Contains(input.Code)) .WhereIF(input.Name is not null, u => u.Name.Contains(input.Name)) .ToPageListAsync(page.PageNum, page.PageSize, totalNumber); - return new PageModel> { Total = totalNumber.Value, Data = await MapToGetListOutputDtosAsync(data) }; + return new PageModel> { Total = totalNumber.Value, Data = await MapToGetListOutputDtosAsync(data) }; } } } From 03dcb7d8602720cf08f8d9b4e8879364777e37f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=A9=99=E5=AD=90?= <454313500@qq.com> Date: Tue, 3 Jan 2023 21:03:07 +0800 Subject: [PATCH 08/10] =?UTF-8?q?=E5=AE=8C=E5=96=84=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E7=94=9F=E6=88=90=E5=99=A8=E8=87=AA=E5=8A=A8=E7=94=9F=E6=88=90?= =?UTF-8?q?=E7=9B=AE=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Abstract/ProgramTemplateProvider.cs | 4 ++++ .../Yi.Framework.Template/Program.cs | 2 +- .../Provider/IServceTemplateProvider.cs | 19 +++++++++++++++++++ .../Provider/ServceTemplateProvider.cs | 5 ++--- .../Template/IServiceTemplate.txt | 16 ++++++++++++++++ .../Yi.Framework.Template.csproj | 12 ++++++++++-- 6 files changed, 52 insertions(+), 6 deletions(-) create mode 100644 Yi.Framework.Net6/Yi.Framework.Template/Provider/IServceTemplateProvider.cs create mode 100644 Yi.Framework.Net6/Yi.Framework.Template/Template/IServiceTemplate.txt diff --git a/Yi.Framework.Net6/Yi.Framework.Template/Abstract/ProgramTemplateProvider.cs b/Yi.Framework.Net6/Yi.Framework.Template/Abstract/ProgramTemplateProvider.cs index 68bd7561..e86a14bc 100644 --- a/Yi.Framework.Net6/Yi.Framework.Template/Abstract/ProgramTemplateProvider.cs +++ b/Yi.Framework.Net6/Yi.Framework.Template/Abstract/ProgramTemplateProvider.cs @@ -51,6 +51,10 @@ namespace Yi.Framework.Template.Abstract { templateData = templateData.Replace(ky.Key, ky.Value); } + if (!Directory.Exists(Path.GetDirectoryName(BuildPath))) + { + Directory.CreateDirectory(Path.GetDirectoryName(BuildPath)!); + } File.WriteAllText(BuildPath, templateData); } diff --git a/Yi.Framework.Net6/Yi.Framework.Template/Program.cs b/Yi.Framework.Net6/Yi.Framework.Template/Program.cs index 1a8070ef..cfe78381 100644 --- a/Yi.Framework.Net6/Yi.Framework.Template/Program.cs +++ b/Yi.Framework.Net6/Yi.Framework.Template/Program.cs @@ -11,7 +11,7 @@ string entityName = "Test"; templateFactory.CreateTemplateProviders((option) => { option.Add(new ServceTemplateProvider(modelName, entityName)); - + option.Add(new IServceTemplateProvider(modelName, entityName)); }); //开始构建模板 diff --git a/Yi.Framework.Net6/Yi.Framework.Template/Provider/IServceTemplateProvider.cs b/Yi.Framework.Net6/Yi.Framework.Template/Provider/IServceTemplateProvider.cs new file mode 100644 index 00000000..414b9d8d --- /dev/null +++ b/Yi.Framework.Net6/Yi.Framework.Template/Provider/IServceTemplateProvider.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Yi.Framework.Template.Abstract; +using Yi.Framework.Template.Const; + +namespace Yi.Framework.Template.Provider +{ + public class IServceTemplateProvider : ProgramTemplateProvider + { + public IServceTemplateProvider(string modelName, string entityName) : base( modelName,entityName) + { + BuildPath = $@"..\..\..\Code\Yi.Framework.Interface\{TemplateConst.ModelName}\I{TemplateConst.EntityName}Service.cs"; + TemplatePath = $@"..\..\..\Template\IServiceTemplate.txt"; + } + } +} diff --git a/Yi.Framework.Net6/Yi.Framework.Template/Provider/ServceTemplateProvider.cs b/Yi.Framework.Net6/Yi.Framework.Template/Provider/ServceTemplateProvider.cs index 6098e8bc..9db4ae64 100644 --- a/Yi.Framework.Net6/Yi.Framework.Template/Provider/ServceTemplateProvider.cs +++ b/Yi.Framework.Net6/Yi.Framework.Template/Provider/ServceTemplateProvider.cs @@ -12,9 +12,8 @@ namespace Yi.Framework.Template.Provider { public ServceTemplateProvider(string modelName, string entityName) : base( modelName,entityName) { - BuildPath = $@"D:\CC.Yi\CC.Yi\Yi.Framework.Net6\Yi.Framework.Template\Code\{TemplateConst.EntityName}Entity.cs"; - TemplatePath = $@"D:\CC.Yi\CC.Yi\Yi.Framework.Net6\Yi.Framework.Template\Template\ServiceTemplate.txt"; - AddTemplateDic("Yi.Framework", "Yi.Test"); + BuildPath = $@"..\..\..\Code\Yi.Framework.Service\{TemplateConst.ModelName}\{TemplateConst.EntityName}Service.cs"; + TemplatePath = $@"..\..\..\Template\ServiceTemplate.txt"; } } } diff --git a/Yi.Framework.Net6/Yi.Framework.Template/Template/IServiceTemplate.txt b/Yi.Framework.Net6/Yi.Framework.Template/Template/IServiceTemplate.txt new file mode 100644 index 00000000..b1f20b7a --- /dev/null +++ b/Yi.Framework.Net6/Yi.Framework.Template/Template/IServiceTemplate.txt @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Yi.Framework.Common.Models; +using Yi.Framework.DtoModel.#ModelName#.#EntityName#; +using Yi.Framework.Interface.Base.Crud; + +namespace Yi.Framework.Interface.#ModelName# +{ + public interface I#EntityName#Service : ICrudAppService<#EntityName#GetListOutput, long, #EntityName#CreateUpdateInput> + { + Task>> PageListAsync(#EntityName#CreateUpdateInput input, PageParModel page); + } +} diff --git a/Yi.Framework.Net6/Yi.Framework.Template/Yi.Framework.Template.csproj b/Yi.Framework.Net6/Yi.Framework.Template/Yi.Framework.Template.csproj index eca3d7cc..33d02daa 100644 --- a/Yi.Framework.Net6/Yi.Framework.Template/Yi.Framework.Template.csproj +++ b/Yi.Framework.Net6/Yi.Framework.Template/Yi.Framework.Template.csproj @@ -12,8 +12,16 @@ - - + + + + + + Always + + + Always + From 7838cd1a6a5f7b1638ba469933126e1f17bf0feb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=A9=99=E5=AD=90?= <454313500@qq.com> Date: Tue, 3 Jan 2023 21:03:29 +0800 Subject: [PATCH 09/10] Update Yi.Framework.Template.csproj --- .../Yi.Framework.Template/Yi.Framework.Template.csproj | 1 + 1 file changed, 1 insertion(+) diff --git a/Yi.Framework.Net6/Yi.Framework.Template/Yi.Framework.Template.csproj b/Yi.Framework.Net6/Yi.Framework.Template/Yi.Framework.Template.csproj index 33d02daa..82887671 100644 --- a/Yi.Framework.Net6/Yi.Framework.Template/Yi.Framework.Template.csproj +++ b/Yi.Framework.Net6/Yi.Framework.Template/Yi.Framework.Template.csproj @@ -12,6 +12,7 @@ + From fbcd004b7ea282105c6fd02a31cfa42a0d31c069 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E6=B7=B3?= Date: Wed, 4 Jan 2023 13:40:30 +0800 Subject: [PATCH 10/10] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=90=84=E4=B8=AA?= =?UTF-8?q?=E6=9C=A8=E5=9D=97=E4=BB=A3=E7=A0=81=E7=94=9F=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/ERP/SupplierController.cs | 3 +- .../Controllers/StudentController.cs | 3 +- .../Abstract/ModelTemplateProvider.cs | 116 ++++++++++++++++++ .../Abstract/ProgramTemplateProvider.cs | 23 ++-- .../Const/TemplateConst.cs | 19 ++- .../Yi.Framework.Template/Program.cs | 29 +++-- .../Provider/Server/ConstTemplateProvider.cs | 19 +++ .../Server/ControllerTemplateProvider.cs | 19 +++ .../CreateUpdateInputTemplateProvider.cs | 20 +++ .../Server/GetListOutputTemplateProvider.cs | 20 +++ .../{ => Server}/IServceTemplateProvider.cs | 8 +- .../Server/ProfileTemplateProvider.cs | 19 +++ .../{ => Server}/ServceTemplateProvider.cs | 8 +- .../Provider/Site/ApiTemplateProvider.cs | 19 +++ .../Template/Server/ConstTemplate.txt | 12 ++ .../Template/Server/ControllerTemplate.txt | 81 ++++++++++++ .../Server/CreateUpdateInputTemplate.txt | 15 +++ .../Template/Server/GetListOutputTemplate.txt | 14 +++ .../{ => Server}/IServiceTemplate.txt | 0 .../Template/Server/ProfileTemplate.txt | 20 +++ .../Template/{ => Server}/ServiceTemplate.txt | 0 .../Template/Site/ApiTemplate.txt | 45 +++++++ .../Yi.Framework.Template.csproj | 26 +++- 23 files changed, 505 insertions(+), 33 deletions(-) create mode 100644 Yi.Framework.Net6/Yi.Framework.Template/Abstract/ModelTemplateProvider.cs create mode 100644 Yi.Framework.Net6/Yi.Framework.Template/Provider/Server/ConstTemplateProvider.cs create mode 100644 Yi.Framework.Net6/Yi.Framework.Template/Provider/Server/ControllerTemplateProvider.cs create mode 100644 Yi.Framework.Net6/Yi.Framework.Template/Provider/Server/CreateUpdateInputTemplateProvider.cs create mode 100644 Yi.Framework.Net6/Yi.Framework.Template/Provider/Server/GetListOutputTemplateProvider.cs rename Yi.Framework.Net6/Yi.Framework.Template/Provider/{ => Server}/IServceTemplateProvider.cs (54%) create mode 100644 Yi.Framework.Net6/Yi.Framework.Template/Provider/Server/ProfileTemplateProvider.cs rename Yi.Framework.Net6/Yi.Framework.Template/Provider/{ => Server}/ServceTemplateProvider.cs (54%) create mode 100644 Yi.Framework.Net6/Yi.Framework.Template/Provider/Site/ApiTemplateProvider.cs create mode 100644 Yi.Framework.Net6/Yi.Framework.Template/Template/Server/ConstTemplate.txt create mode 100644 Yi.Framework.Net6/Yi.Framework.Template/Template/Server/ControllerTemplate.txt create mode 100644 Yi.Framework.Net6/Yi.Framework.Template/Template/Server/CreateUpdateInputTemplate.txt create mode 100644 Yi.Framework.Net6/Yi.Framework.Template/Template/Server/GetListOutputTemplate.txt rename Yi.Framework.Net6/Yi.Framework.Template/Template/{ => Server}/IServiceTemplate.txt (100%) create mode 100644 Yi.Framework.Net6/Yi.Framework.Template/Template/Server/ProfileTemplate.txt rename Yi.Framework.Net6/Yi.Framework.Template/Template/{ => Server}/ServiceTemplate.txt (100%) create mode 100644 Yi.Framework.Net6/Yi.Framework.Template/Template/Site/ApiTemplate.txt diff --git a/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Controllers/ERP/SupplierController.cs b/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Controllers/ERP/SupplierController.cs index 1bfad73e..1a10baf5 100644 --- a/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Controllers/ERP/SupplierController.cs +++ b/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Controllers/ERP/SupplierController.cs @@ -1,5 +1,4 @@ -using Brick.IFServer.Controllers; -using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc; using Yi.Framework.Common.Models; using Yi.Framework.DtoModel.ERP.Supplier; using Yi.Framework.Interface.ERP; diff --git a/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Controllers/StudentController.cs b/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Controllers/StudentController.cs index 6417b387..b436afe9 100644 --- a/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Controllers/StudentController.cs +++ b/Yi.Framework.Net6/Yi.Framework.ApiMicroservice/Controllers/StudentController.cs @@ -1,10 +1,9 @@ - using Microsoft.AspNetCore.Mvc; using Yi.Framework.Common.Models; using Yi.Framework.DtoModel.RABC.Student; using Yi.Framework.Interface.RABC; -namespace Brick.IFServer.Controllers +namespace Yi.Framework.ApiMicroservice.Controllers.ERP { [ApiController] [Route("[controller]")] diff --git a/Yi.Framework.Net6/Yi.Framework.Template/Abstract/ModelTemplateProvider.cs b/Yi.Framework.Net6/Yi.Framework.Template/Abstract/ModelTemplateProvider.cs new file mode 100644 index 00000000..a6f3ef05 --- /dev/null +++ b/Yi.Framework.Net6/Yi.Framework.Template/Abstract/ModelTemplateProvider.cs @@ -0,0 +1,116 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Yi.Framework.Template.Const; + +namespace Yi.Framework.Template.Abstract +{ + public abstract class ModelTemplateProvider : ProgramTemplateProvider + { + + public ModelTemplateProvider(string modelName, string entityName) : base(modelName, entityName) + { + AddIgnoreEntityField("Id", "TenantId"); + } + + private string entityPath; + + /// + /// 实体路径,该类生成需要实体与模板两个同时构建成 + /// + public string EntityPath + { + get => this.entityPath; + set + { + value = value!.Replace(TemplateConst.EntityName, EntityName); + value = value.Replace(TemplateConst.ModelName, ModelName); + this.entityPath = value; + } + } + + + /// + /// 生成模板忽略实体字段 + /// + private List IgnoreEntityFields { get; set; } = new(); + + public override void Build() + { + if (BuildPath is null) + { + throw new ArgumentNullException(nameof(BuildPath)); + } + //模板信息 + var templateData = GetTemplateData(); + + //实体信息 + var enetityDatas = GetEntityData().ToList(); + + //获取全部属性字段 + for (var i = enetityDatas.Count() - 1; i >= 0; i--) + { + //不是字段属性直接删除跳过 + if (!enetityDatas[i].Contains("{ get; set; }")) + { + enetityDatas.RemoveAt(i); + continue; + } + //是字段属性,同时还包含忽略字段 + foreach (var IgnoreEntityField in IgnoreEntityFields) + { + if (enetityDatas[i].Contains(IgnoreEntityField)) + { + enetityDatas.RemoveAt(i); + continue; + } + } + } + + //拼接实体字段 + var entityFieldsbuild = string.Join("\r\n", enetityDatas); + + + //模板替换属性字段 + templateData = templateData.Replace(TemplateConst.EntityField, entityFieldsbuild); + + templateData = base.ReplaceTemplateDic(templateData); + + if (!Directory.Exists(Path.GetDirectoryName(BuildPath))) + { + Directory.CreateDirectory(Path.GetDirectoryName(BuildPath)!); + } + File.WriteAllText(BuildPath, templateData); + } + + /// + /// 获取实体信息 + /// + /// + /// + public virtual string[] GetEntityData() + { + if (TemplatePath is null) + { + throw new ArgumentNullException(nameof(entityPath)); + } + if (!File.Exists(entityPath)) + { + throw new FileNotFoundException($"请检查路径:{entityPath}\r\n未包含实体:{EntityName}"); + } + + return File.ReadAllLines(entityPath); + } + + /// + /// 添加忽略实体字段 + /// + /// + public void AddIgnoreEntityField(params string[] field) + { + IgnoreEntityFields.AddRange(field); + } + } +} diff --git a/Yi.Framework.Net6/Yi.Framework.Template/Abstract/ProgramTemplateProvider.cs b/Yi.Framework.Net6/Yi.Framework.Template/Abstract/ProgramTemplateProvider.cs index e86a14bc..8cad5e9a 100644 --- a/Yi.Framework.Net6/Yi.Framework.Template/Abstract/ProgramTemplateProvider.cs +++ b/Yi.Framework.Net6/Yi.Framework.Template/Abstract/ProgramTemplateProvider.cs @@ -16,6 +16,8 @@ namespace Yi.Framework.Template.Abstract EntityName = entityName; base.AddTemplateDic(TemplateConst.EntityName, EntityName); base.AddTemplateDic(TemplateConst.ModelName, ModelName); + base.AddTemplateDic(TemplateConst.LowerEntityName, EntityName.Substring(0, 1).ToLower() + EntityName.Substring(1)); + base.AddTemplateDic(TemplateConst.LowerModelName, ModelName.ToLower()); } /// /// 实体名称 @@ -34,12 +36,22 @@ namespace Yi.Framework.Template.Abstract get => base.BuildPath; set { - value = value!.Replace(TemplateConst.EntityName, EntityName); - value = value.Replace(TemplateConst.ModelName, ModelName); + value = ReplaceTemplateDic(value!); + base.BuildPath = value; } } + public string ReplaceTemplateDic(string str) + { + foreach (var ky in TemplateDic) + { + str = str.Replace(ky.Key, ky.Value); + } + return str; + } + + public override void Build() { if (BuildPath is null) @@ -47,12 +59,9 @@ namespace Yi.Framework.Template.Abstract throw new ArgumentNullException(nameof(BuildPath)); } var templateData = GetTemplateData(); - foreach (var ky in TemplateDic) - { - templateData = templateData.Replace(ky.Key, ky.Value); - } + templateData = ReplaceTemplateDic(templateData); if (!Directory.Exists(Path.GetDirectoryName(BuildPath))) - { + { Directory.CreateDirectory(Path.GetDirectoryName(BuildPath)!); } File.WriteAllText(BuildPath, templateData); diff --git a/Yi.Framework.Net6/Yi.Framework.Template/Const/TemplateConst.cs b/Yi.Framework.Net6/Yi.Framework.Template/Const/TemplateConst.cs index 02a6a6ca..5dc0ea9e 100644 --- a/Yi.Framework.Net6/Yi.Framework.Template/Const/TemplateConst.cs +++ b/Yi.Framework.Net6/Yi.Framework.Template/Const/TemplateConst.cs @@ -9,13 +9,28 @@ namespace Yi.Framework.Template.Const public class TemplateConst { /// - /// 模块名称 + /// 模块名称大写 /// public const string ModelName = "#ModelName#"; /// - /// 实体名称 + /// 模块名称小写 + /// + public const string LowerModelName = "#LowerModelName#"; + + /// + /// 实体名称大驼峰 /// public const string EntityName = "#EntityName#"; + + /// + /// 实体名称小驼峰 + /// + public const string LowerEntityName = "#LowerEntityName#"; + + /// + /// 实体字段 + /// + public const string EntityField = "#EntityField#"; } } diff --git a/Yi.Framework.Net6/Yi.Framework.Template/Program.cs b/Yi.Framework.Net6/Yi.Framework.Template/Program.cs index cfe78381..0961099d 100644 --- a/Yi.Framework.Net6/Yi.Framework.Template/Program.cs +++ b/Yi.Framework.Net6/Yi.Framework.Template/Program.cs @@ -1,20 +1,31 @@ using Yi.Framework.Template; -using Yi.Framework.Template.Provider; +using Yi.Framework.Template.Provider.Server; +using Yi.Framework.Template.Provider.Site; TemplateFactory templateFactory = new(); //选择需要生成的模板提供者 string modelName = "ERP"; -string entityName = "Test"; +List entityNames =new (){ "Supplier", "Purchase", "PurchaseDetails" }; -templateFactory.CreateTemplateProviders((option) => +foreach (var entityName in entityNames) { - option.Add(new ServceTemplateProvider(modelName, entityName)); - option.Add(new IServceTemplateProvider(modelName, entityName)); -}); + templateFactory.CreateTemplateProviders((option) => + { + option.Add(new ServceTemplateProvider(modelName, entityName)); + option.Add(new IServceTemplateProvider(modelName, entityName)); + option.Add(new CreateUpdateInputTemplateProvider(modelName, entityName)); + option.Add(new GetListOutputTemplateProvider(modelName, entityName)); + option.Add(new ConstTemplateProvider(modelName, entityName)); + option.Add(new ProfileTemplateProvider(modelName, entityName)); + option.Add(new ControllerTemplateProvider(modelName, entityName)); + option.Add(new ApiTemplateProvider(modelName, entityName)); + }); + //开始构建模板 + templateFactory.BuildTemplate(); + Console.WriteLine($"Yi.Framework.Template:{entityName}构建完成!"); +} -//开始构建模板 -templateFactory.BuildTemplate(); -Console.WriteLine("Yi.Framework.Template模板生成完成!"); +Console.WriteLine("Yi.Framework.Template:模板全部生成完成!"); Console.ReadKey(); \ No newline at end of file diff --git a/Yi.Framework.Net6/Yi.Framework.Template/Provider/Server/ConstTemplateProvider.cs b/Yi.Framework.Net6/Yi.Framework.Template/Provider/Server/ConstTemplateProvider.cs new file mode 100644 index 00000000..8cbed5bd --- /dev/null +++ b/Yi.Framework.Net6/Yi.Framework.Template/Provider/Server/ConstTemplateProvider.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Yi.Framework.Template.Abstract; +using Yi.Framework.Template.Const; + +namespace Yi.Framework.Template.Provider.Server +{ + internal class ConstTemplateProvider : ProgramTemplateProvider + { + public ConstTemplateProvider(string modelName, string entityName) : base(modelName, entityName) + { + BuildPath = $@"..\..\..\Code_Server\Yi.Framework.DtoModel\{TemplateConst.ModelName}\{TemplateConst.EntityName}\ConstConfig\{TemplateConst.EntityName}Const.cs"; + TemplatePath = $@"..\..\..\Template\Server\ConstTemplate.txt"; + } + } +} diff --git a/Yi.Framework.Net6/Yi.Framework.Template/Provider/Server/ControllerTemplateProvider.cs b/Yi.Framework.Net6/Yi.Framework.Template/Provider/Server/ControllerTemplateProvider.cs new file mode 100644 index 00000000..1ed12e25 --- /dev/null +++ b/Yi.Framework.Net6/Yi.Framework.Template/Provider/Server/ControllerTemplateProvider.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Yi.Framework.Template.Abstract; +using Yi.Framework.Template.Const; + +namespace Yi.Framework.Template.Provider.Server +{ + public class ControllerTemplateProvider : ProgramTemplateProvider + { + public ControllerTemplateProvider(string modelName, string entityName) : base(modelName, entityName) + { + BuildPath = $@"..\..\..\Code_Server\Yi.Framework.ApiMicroservice\Controllers\{TemplateConst.ModelName}\{TemplateConst.EntityName}Controller.cs"; + TemplatePath = $@"..\..\..\Template\Server\ControllerTemplate.txt"; + } + } +} diff --git a/Yi.Framework.Net6/Yi.Framework.Template/Provider/Server/CreateUpdateInputTemplateProvider.cs b/Yi.Framework.Net6/Yi.Framework.Template/Provider/Server/CreateUpdateInputTemplateProvider.cs new file mode 100644 index 00000000..b808d7ef --- /dev/null +++ b/Yi.Framework.Net6/Yi.Framework.Template/Provider/Server/CreateUpdateInputTemplateProvider.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Yi.Framework.Template.Abstract; +using Yi.Framework.Template.Const; + +namespace Yi.Framework.Template.Provider.Server +{ + public class CreateUpdateInputTemplateProvider : ModelTemplateProvider + { + public CreateUpdateInputTemplateProvider(string modelName, string entityName) : base(modelName, entityName) + { + BuildPath = $@"..\..\..\Code_Server\Yi.Framework.DtoModel\{TemplateConst.ModelName}\{TemplateConst.EntityName}\{TemplateConst.EntityName}CreateUpdateInput.cs"; + TemplatePath = $@"..\..\..\Template\Server\CreateUpdateInputTemplate.txt"; + EntityPath = $@"..\..\..\..\Yi.Framework.Model\{TemplateConst.ModelName}\Entitys\{TemplateConst.EntityName}Entity.cs"; + } + } +} diff --git a/Yi.Framework.Net6/Yi.Framework.Template/Provider/Server/GetListOutputTemplateProvider.cs b/Yi.Framework.Net6/Yi.Framework.Template/Provider/Server/GetListOutputTemplateProvider.cs new file mode 100644 index 00000000..fa6df140 --- /dev/null +++ b/Yi.Framework.Net6/Yi.Framework.Template/Provider/Server/GetListOutputTemplateProvider.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Yi.Framework.Template.Abstract; +using Yi.Framework.Template.Const; + +namespace Yi.Framework.Template.Provider.Server +{ + public class GetListOutputTemplateProvider : ModelTemplateProvider + { + public GetListOutputTemplateProvider(string modelName, string entityName) : base(modelName, entityName) + { + BuildPath = $@"..\..\..\Code_Server\Yi.Framework.DtoModel\{TemplateConst.ModelName}\{TemplateConst.EntityName}\{TemplateConst.EntityName}GetListOutput.cs"; + TemplatePath = $@"..\..\..\Template\Server\GetListOutputTemplate.txt"; + EntityPath = $@"..\..\..\..\Yi.Framework.Model\{TemplateConst.ModelName}\Entitys\{TemplateConst.EntityName}Entity.cs"; + } + } +} diff --git a/Yi.Framework.Net6/Yi.Framework.Template/Provider/IServceTemplateProvider.cs b/Yi.Framework.Net6/Yi.Framework.Template/Provider/Server/IServceTemplateProvider.cs similarity index 54% rename from Yi.Framework.Net6/Yi.Framework.Template/Provider/IServceTemplateProvider.cs rename to Yi.Framework.Net6/Yi.Framework.Template/Provider/Server/IServceTemplateProvider.cs index 414b9d8d..fa53c8c6 100644 --- a/Yi.Framework.Net6/Yi.Framework.Template/Provider/IServceTemplateProvider.cs +++ b/Yi.Framework.Net6/Yi.Framework.Template/Provider/Server/IServceTemplateProvider.cs @@ -6,14 +6,14 @@ using System.Threading.Tasks; using Yi.Framework.Template.Abstract; using Yi.Framework.Template.Const; -namespace Yi.Framework.Template.Provider +namespace Yi.Framework.Template.Provider.Server { public class IServceTemplateProvider : ProgramTemplateProvider { - public IServceTemplateProvider(string modelName, string entityName) : base( modelName,entityName) + public IServceTemplateProvider(string modelName, string entityName) : base(modelName, entityName) { - BuildPath = $@"..\..\..\Code\Yi.Framework.Interface\{TemplateConst.ModelName}\I{TemplateConst.EntityName}Service.cs"; - TemplatePath = $@"..\..\..\Template\IServiceTemplate.txt"; + BuildPath = $@"..\..\..\Code_Server\Yi.Framework.Interface\{TemplateConst.ModelName}\I{TemplateConst.EntityName}Service.cs"; + TemplatePath = $@"..\..\..\Template\Server\IServiceTemplate.txt"; } } } diff --git a/Yi.Framework.Net6/Yi.Framework.Template/Provider/Server/ProfileTemplateProvider.cs b/Yi.Framework.Net6/Yi.Framework.Template/Provider/Server/ProfileTemplateProvider.cs new file mode 100644 index 00000000..5211c537 --- /dev/null +++ b/Yi.Framework.Net6/Yi.Framework.Template/Provider/Server/ProfileTemplateProvider.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Yi.Framework.Template.Abstract; +using Yi.Framework.Template.Const; + +namespace Yi.Framework.Template.Provider.Server +{ + public class ProfileTemplateProvider : ProgramTemplateProvider + { + public ProfileTemplateProvider(string modelName, string entityName) : base(modelName, entityName) + { + BuildPath = $@"..\..\..\Code_Server\Yi.Framework.DtoModel\{TemplateConst.ModelName}\{TemplateConst.EntityName}\MapperConfig\{TemplateConst.EntityName}Profile.cs"; + TemplatePath = $@"..\..\..\Template\Server\ProfileTemplate.txt"; + } + } +} diff --git a/Yi.Framework.Net6/Yi.Framework.Template/Provider/ServceTemplateProvider.cs b/Yi.Framework.Net6/Yi.Framework.Template/Provider/Server/ServceTemplateProvider.cs similarity index 54% rename from Yi.Framework.Net6/Yi.Framework.Template/Provider/ServceTemplateProvider.cs rename to Yi.Framework.Net6/Yi.Framework.Template/Provider/Server/ServceTemplateProvider.cs index 9db4ae64..79a0695b 100644 --- a/Yi.Framework.Net6/Yi.Framework.Template/Provider/ServceTemplateProvider.cs +++ b/Yi.Framework.Net6/Yi.Framework.Template/Provider/Server/ServceTemplateProvider.cs @@ -6,14 +6,14 @@ using System.Threading.Tasks; using Yi.Framework.Template.Abstract; using Yi.Framework.Template.Const; -namespace Yi.Framework.Template.Provider +namespace Yi.Framework.Template.Provider.Server { public class ServceTemplateProvider : ProgramTemplateProvider { - public ServceTemplateProvider(string modelName, string entityName) : base( modelName,entityName) + public ServceTemplateProvider(string modelName, string entityName) : base(modelName, entityName) { - BuildPath = $@"..\..\..\Code\Yi.Framework.Service\{TemplateConst.ModelName}\{TemplateConst.EntityName}Service.cs"; - TemplatePath = $@"..\..\..\Template\ServiceTemplate.txt"; + BuildPath = $@"..\..\..\Code_Server\Yi.Framework.Service\{TemplateConst.ModelName}\{TemplateConst.EntityName}Service.cs"; + TemplatePath = $@"..\..\..\Template\Server\ServiceTemplate.txt"; } } } diff --git a/Yi.Framework.Net6/Yi.Framework.Template/Provider/Site/ApiTemplateProvider.cs b/Yi.Framework.Net6/Yi.Framework.Template/Provider/Site/ApiTemplateProvider.cs new file mode 100644 index 00000000..8f3afb2e --- /dev/null +++ b/Yi.Framework.Net6/Yi.Framework.Template/Provider/Site/ApiTemplateProvider.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Yi.Framework.Template.Abstract; +using Yi.Framework.Template.Const; + +namespace Yi.Framework.Template.Provider.Site +{ + public class ApiTemplateProvider : ProgramTemplateProvider + { + public ApiTemplateProvider(string modelName, string entityName) : base(modelName, entityName) + { + BuildPath = $@"..\..\..\Code_Site\src\api\{TemplateConst.ModelName}\{TemplateConst.LowerEntityName}Api.js"; + TemplatePath = $@"..\..\..\Template\Site\ApiTemplate.txt"; + } + } +} diff --git a/Yi.Framework.Net6/Yi.Framework.Template/Template/Server/ConstTemplate.txt b/Yi.Framework.Net6/Yi.Framework.Template/Template/Server/ConstTemplate.txt new file mode 100644 index 00000000..4c589964 --- /dev/null +++ b/Yi.Framework.Net6/Yi.Framework.Template/Template/Server/ConstTemplate.txt @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Yi.Framework.DtoModel.#ModelName#.#EntityName#.ConstConfig +{ + public class #EntityName#Const + { + } +} diff --git a/Yi.Framework.Net6/Yi.Framework.Template/Template/Server/ControllerTemplate.txt b/Yi.Framework.Net6/Yi.Framework.Template/Template/Server/ControllerTemplate.txt new file mode 100644 index 00000000..2951131e --- /dev/null +++ b/Yi.Framework.Net6/Yi.Framework.Template/Template/Server/ControllerTemplate.txt @@ -0,0 +1,81 @@ +using Microsoft.AspNetCore.Mvc; +using Yi.Framework.Common.Models; +using Yi.Framework.DtoModel.#ModelName#.#EntityName#; +using Yi.Framework.Interface.#ModelName#; + +namespace Yi.Framework.ApiMicroservice.Controllers.#ModelName# +{ + [ApiController] + [Route("api/[controller]/[action]")] + public class #EntityName#Controller : ControllerBase + { + private readonly ILogger<#EntityName#Controller> _logger; + private readonly I#EntityName#Service _#LowerEntityName#Service; + public #EntityName#Controller(ILogger<#EntityName#Controller> logger, I#EntityName#Service #LowerEntityName#Service) + { + _logger = logger; + _#LowerEntityName#Service = #LowerEntityName#Service; + } + + /// + /// 分页查 + /// + /// + [HttpGet] + public async Task PageList([FromQuery] #EntityName#CreateUpdateInput input, [FromQuery] PageParModel page) + { + var result = await _#LowerEntityName#Service.PageListAsync(input, page); + return Result.Success().SetData(result); + } + + /// + /// 单查 + /// + /// + [HttpGet] + [Route("{id}")] + public async Task GetById(long id) + { + var result = await _#LowerEntityName#Service.GetByIdAsync(id); + return Result.Success().SetData(result); + } + + /// + /// 增 + /// + /// + /// + [HttpPost] + public async Task Create(#EntityName#CreateUpdateInput input) + { + var result = await _#LowerEntityName#Service.CreateAsync(input); + return Result.Success().SetData(result); + } + + /// + /// 更 + /// + /// + /// + /// + [HttpPut] + [Route("{id}")] + public async Task Update(long id, #EntityName#CreateUpdateInput input) + { + var result = await _#LowerEntityName#Service.UpdateAsync(id, input); + return Result.Success().SetData(result); + } + + /// + /// 删 + /// + /// + /// + [HttpDelete] + public async Task Del(List ids) + { + await _#LowerEntityName#Service.DeleteAsync(ids); + return Result.Success(); + } + } +} diff --git a/Yi.Framework.Net6/Yi.Framework.Template/Template/Server/CreateUpdateInputTemplate.txt b/Yi.Framework.Net6/Yi.Framework.Template/Template/Server/CreateUpdateInputTemplate.txt new file mode 100644 index 00000000..de35e69a --- /dev/null +++ b/Yi.Framework.Net6/Yi.Framework.Template/Template/Server/CreateUpdateInputTemplate.txt @@ -0,0 +1,15 @@ +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Yi.Framework.Model.Base; + +namespace Yi.Framework.DtoModel.#ModelName#.#EntityName# +{ + public class #EntityName#CreateUpdateInput : EntityDto + { +#EntityField# + } +} diff --git a/Yi.Framework.Net6/Yi.Framework.Template/Template/Server/GetListOutputTemplate.txt b/Yi.Framework.Net6/Yi.Framework.Template/Template/Server/GetListOutputTemplate.txt new file mode 100644 index 00000000..52e3c644 --- /dev/null +++ b/Yi.Framework.Net6/Yi.Framework.Template/Template/Server/GetListOutputTemplate.txt @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Yi.Framework.Model.Base; + +namespace Yi.Framework.DtoModel.#ModelName#.#EntityName# +{ + public class #EntityName#GetListOutput: EntityDto + { +#EntityField# + } +} diff --git a/Yi.Framework.Net6/Yi.Framework.Template/Template/IServiceTemplate.txt b/Yi.Framework.Net6/Yi.Framework.Template/Template/Server/IServiceTemplate.txt similarity index 100% rename from Yi.Framework.Net6/Yi.Framework.Template/Template/IServiceTemplate.txt rename to Yi.Framework.Net6/Yi.Framework.Template/Template/Server/IServiceTemplate.txt diff --git a/Yi.Framework.Net6/Yi.Framework.Template/Template/Server/ProfileTemplate.txt b/Yi.Framework.Net6/Yi.Framework.Template/Template/Server/ProfileTemplate.txt new file mode 100644 index 00000000..f545b835 --- /dev/null +++ b/Yi.Framework.Net6/Yi.Framework.Template/Template/Server/ProfileTemplate.txt @@ -0,0 +1,20 @@ +using AutoMapper; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Yi.Framework.Model.#ModelName#.Entitys; + +namespace Yi.Framework.DtoModel.#ModelName#.#EntityName#.MapperConfig +{ + public class Suppli#ModelName#rofile:Profile + { + public Suppli#ModelName#rofile() + { + CreateMap<#EntityName#CreateUpdateInput, #EntityName#Entity>(); + CreateMap<#EntityName#Entity, #EntityName#GetListOutput>(); + + } + } +} diff --git a/Yi.Framework.Net6/Yi.Framework.Template/Template/ServiceTemplate.txt b/Yi.Framework.Net6/Yi.Framework.Template/Template/Server/ServiceTemplate.txt similarity index 100% rename from Yi.Framework.Net6/Yi.Framework.Template/Template/ServiceTemplate.txt rename to Yi.Framework.Net6/Yi.Framework.Template/Template/Server/ServiceTemplate.txt diff --git a/Yi.Framework.Net6/Yi.Framework.Template/Template/Site/ApiTemplate.txt b/Yi.Framework.Net6/Yi.Framework.Template/Template/Site/ApiTemplate.txt new file mode 100644 index 00000000..dc12e694 --- /dev/null +++ b/Yi.Framework.Net6/Yi.Framework.Template/Template/Site/ApiTemplate.txt @@ -0,0 +1,45 @@ +import request from '@/utils/request' + +// 分页查询 +export function listData(query) { + return request({ + url: '/#LowerEntityName#/pageList', + method: 'get', + params: query + }) +} + +// id查询 +export function getData(code) { + return request({ + url: '/#LowerEntityName#/getById/' + code, + method: 'get' + }) +} + +// 新增 +export function addData(data) { + return request({ + url: '/#LowerEntityName#/create', + method: 'post', + data: data + }) +} + +// 修改 +export function updateData(id,data) { + return request({ + url: `/#LowerEntityName#/update/${id}`, + method: 'put', + data: data + }) +} + +// 删除 +export function delData(code) { + return request({ + url: '/#LowerEntityName#/del', + method: 'delete', + data:"string"==typeof(code)?[code]:code + }) +} diff --git a/Yi.Framework.Net6/Yi.Framework.Template/Yi.Framework.Template.csproj b/Yi.Framework.Net6/Yi.Framework.Template/Yi.Framework.Template.csproj index 82887671..49318819 100644 --- a/Yi.Framework.Net6/Yi.Framework.Template/Yi.Framework.Template.csproj +++ b/Yi.Framework.Net6/Yi.Framework.Template/Yi.Framework.Template.csproj @@ -7,22 +7,42 @@ Exe + - - + Always - + Always + + Always + + + Always + + + Always + + + Always + + + + Always + + + + Always +