| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338 |
- // Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
- //
- // 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
- //
- // 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
- using Admin.NET.Core.Service;
- using Microsoft.AspNetCore.Http;
- namespace @(Model.NameSpace);
- /// <summary>
- /// @(Model.BusName)服务 🧩
- /// </summary>
- [ApiDescriptionSettings(@(Model.ProjectLastName)Const.GroupName, Order = 100)]
- public class @(Model.ClassName)Service : IDynamicApiController, ITransient
- {
- private readonly SqlSugarRepository<@(Model.ClassName)> _@(Model.LowerClassName)Rep;
- @foreach(var kv in Model.InjectServiceMap) {
- @:private readonly @(kv.Key) _@(kv.Value);
- }
- public @(Model.ClassName)Service(SqlSugarRepository<@(Model.ClassName)> @(Model.LowerClassName)Rep@(Model.InjectServiceArgs))
- {
- _@(Model.LowerClassName)Rep = @(Model.LowerClassName)Rep;
- @foreach(var kv in Model.InjectServiceMap) {
- @:_@(kv.Value) = @(kv.Value);
- }
- }
- /// <summary>
- /// 分页查询@(Model.BusName) 🔖
- /// </summary>
- /// <param name="input"></param>
- /// <returns></returns>
- [DisplayName("分页查询@(Model.BusName)")]
- [ApiDescriptionSettings(Name = "Page"), HttpPost]
- public async Task<SqlSugarPagedList<@(Model.ClassName)Output>> Page(Page@(Model.ClassName)Input input)
- {
- input.Keyword = input.Keyword?.Trim();
- var query = _@(Model.LowerClassName)Rep.AsQueryable()
- @{
- string joinTableName = "u";
- var queryFields = Model.TableField.Where(u => u.WhetherQuery == "Y");
- // 关键字模糊查询
- if (queryFields.Any(u => u.QueryType == "like")) {
- @:.WhereIF(!string.IsNullOrEmpty(input.Keyword), u => @string.Join(" || ", queryFields.Where(u => u.QueryType == "like").Select(col => $"u.{col.PropertyName}.Contains(input.Keyword)")))
- }
- // 字段组合查询
- foreach(var column in queryFields) {
- if (column.NetType.TrimEnd('?') == "string") {
- @:.WhereIF(!string.IsNullOrWhiteSpace(input.@(column.PropertyName)), u => u.@(column.PropertyName)@(column.QueryType == "like" ? $".Contains(input.{column.PropertyName}.Trim())" : $" {column.QueryType} input.{column.PropertyName}.Trim()"))
- } else if (column.NetType.TrimEnd('?') == "int" || column.NetType.TrimEnd('?') == "long") {
- @:.WhereIF(input.@(column.PropertyName) != null, u => u.@(column.PropertyName) @(column.QueryType) input.@(column.PropertyName))
- } else if (column.NetType.TrimEnd('?').EndsWith("Enum")) {
- @:.WhereIF(input.@(column.PropertyName).HasValue, u => u.@(column.PropertyName) == input.@(column.PropertyName))
- } else if (column.NetType.TrimEnd('?') == "DateTime" && column.QueryType == "~") {
- @:.WhereIF(input.@(column.PropertyName)Range?.Length == 2, u => u.@(column.PropertyName) >= input.@(column.PropertyName)Range[0] && u.@(column.PropertyName) <= input.@(column.PropertyName)Range[1])
- }
- }
- // 联表
- if (Model.HasJoinTable) {
- foreach (var column in Model.TableField.Where(u => u.EffectType == "ForeignKey" || u.EffectType == "ApiTreeSelector")){
- var joinTableAlias = Regex.Replace(column.LowerPropertyName, "[iI]d$", "");
- joinTableName += ", " + joinTableAlias;
- @:.LeftJoin<@column.FkEntityName>((@joinTableName) => u.@(column.PropertyName) == @joinTableAlias.@(column.EffectType == "ForeignKey" ? column.FkLinkColumnName : column.FkLinkColumnName))
- }
- // 查询列表
- @:.Select((@joinTableName) => new @(Model.ClassName)Output
- @:{
- foreach (var column in Model.TableField) {
- var joinTableAlias = Regex.Replace(column.LowerPropertyName, "[iI]d$", "");
- if (column.EffectType == "ForeignKey") {
- var columnList = column.FkDisplayColumnList.Select(n => $"{{{joinTableAlias}.{n}}}").ToList();
- @:@(column.PropertyName) = u.@(column.PropertyName),
- @:@(column.PropertyName)FkColumn = $"@(string.Join("-", columnList))",
- } else if (column.EffectType == "ApiTreeSelector") {
- var columnList = column.FkDisplayColumnList.Select(n => $"{{{joinTableAlias}.{n}}}").ToList();
- @:@(column.PropertyName) = u.@(column.PropertyName),
- @:@(column.PropertyName)Display = $"@(string.Join("-", columnList))",
- } else {
- @:@(column.PropertyName) = u.@(column.PropertyName),
- }
- }
- @:});
- } else {
- // 无联表
- @:.Select<@(Model.ClassName)Output>();
- }
- }
- return await query.OrderBuilder(input).ToPagedListAsync(input.Page, input.PageSize);
- }
- /// <summary>
- /// 增加@(Model.BusName) ➕
- /// </summary>
- /// <param name="input"></param>
- /// <returns></returns>
- [DisplayName("增加@(Model.BusName)")]
- [ApiDescriptionSettings(Name = "Add"), HttpPost]
- public async Task<long> Add(Add@(Model.ClassName)Input input)
- {
- var entity = input.Adapt<@(Model.ClassName)>();
- @foreach (var config in Model.AddUpdateUniqueConfigList) {
- @:if (await _@(Model.LowerClassName)Rep.IsAnyAsync(u => @(string.Join(" && ", @config.Columns.Select(x => $"u.{x} != null && u.{x} == input.{x}"))))) throw Oops.Oh("@(config.Message)已存在");
- }
- return await _@(Model.LowerClassName)Rep.InsertAsync(entity) ? entity.Id : 0;
- }
- /// <summary>
- /// 删除@(Model.BusName) ❌
- /// </summary>
- /// <param name="input"></param>
- /// <returns></returns>
- [DisplayName("删除@(Model.BusName)")]
- [ApiDescriptionSettings(Name = "Delete"), HttpPost]
- public async Task Delete(Delete@(Model.ClassName)Input input)
- {
- var entity = await _@(Model.LowerClassName)Rep.GetFirstAsync(u => @Model.PrimaryKeysFormat(" && ", "u.{0} == input.{0}")) ?? throw Oops.Oh(ErrorCodeEnum.D1002);
- await _@(Model.LowerClassName)Rep.FakeDeleteAsync(entity); //假删除
- //await _@(Model.LowerClassName)Rep.DeleteAsync(entity); //真删除
- }
- /// <summary>
- /// 批量删除@(Model.BusName) ❌
- /// </summary>
- /// <param name="input"></param>
- /// <returns></returns>
- [DisplayName("批量删除@(Model.BusName)")]
- [ApiDescriptionSettings(Name = "BatchDelete"), HttpPost]
- public async Task<int> BatchDelete([Required(ErrorMessage = "主键列表不能为空")]List<Delete@(Model.ClassName)Input> input)
- {
- var list = await _@(Model.LowerClassName)Rep.AsQueryable().In(u => new { @string.Join(", ", Model.PrimaryKeyFieldList.Select(n => $"u.{n}")) }, input).ToListAsync();
- return await _@(Model.LowerClassName)Rep.FakeDeleteAsync(list); //假删除
- //return await _@(Model.LowerClassName)Rep.DeleteAsync(list); //真删除
- }
- /// <summary>
- /// 更新@(Model.BusName) ✏️
- /// </summary>
- /// <param name="input"></param>
- /// <returns></returns>
- [DisplayName("更新@(Model.BusName)")]
- [ApiDescriptionSettings(Name = "Update"), HttpPost]
- public async Task Update(Update@(Model.ClassName)Input input)
- {
- @{
- var primaryKeyWhere = string.Join(" && ", Model.PrimaryKeyFieldList.Select(n => $"u.{n} == input.{n}"));
- foreach (var config in Model.AddUpdateUniqueConfigList) {
- @:if (await _@(Model.LowerClassName)Rep.IsAnyAsync(u => !(@primaryKeyWhere) && @(string.Join(" && ", config.Columns.Select(x => $"u.{x} != null && u.{x} == input.{x}"))))) throw Oops.Oh("@(config.Message)已存在");
- }
- }
- var entity = input.Adapt<@(Model.ClassName)>();
- await _@(Model.LowerClassName)Rep.AsUpdateable(entity).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
- }
- @if (Model.HasSetStatus) {
- @:
- @:/// <summary>
- @:/// 设置@(Model.BusName)状态 🚫
- @:/// </summary>
- @:/// <param name="input"></param>
- @:/// <returns></returns>
- @:[DisplayName("设置@(Model.BusName)状态")]
- @:[ApiDescriptionSettings(Name = "SetStatus"), HttpPost]
- @:public async Task Set@(Model.ClassName)Status(BaseStatusInput input)
- @:{
- @:await _@(Model.LowerClassName)Rep.AsUpdateable().SetColumns(u => u.Status, input.Status).Where(u => u.Id == input.Id).ExecuteCommandAsync();
- @:}
- }
- /// <summary>
- /// 获取@(Model.BusName)详情 ℹ️
- /// </summary>
- /// <param name="input"></param>
- /// <returns></returns>
- [DisplayName("获取@(Model.BusName)详情")]
- [ApiDescriptionSettings(Name = "Detail"), HttpGet]
- public async Task<@(Model.ClassName)> Detail([FromQuery] QueryById@(Model.ClassName)Input input)
- {
- return await _@(Model.LowerClassName)Rep.GetFirstAsync(u => @Model.PrimaryKeysFormat(" && ", "u.{0} == input.{0}"));
- }
- /// <summary>
- /// 获取@(Model.BusName)列表 🔖
- /// </summary>
- /// <param name="input"></param>
- /// <returns></returns>
- [DisplayName("获取@(Model.BusName)列表")]
- [ApiDescriptionSettings(Name = "List"), HttpGet]
- public async Task<List<@(Model.ClassName)Output>> List([FromQuery] Page@(Model.ClassName)Input input)
- {
- return await _@(Model.LowerClassName)Rep.AsQueryable().Select<@(Model.ClassName)Output>().ToListAsync();
- }
- @foreach (var column in Model.TableField.Where(u => u.EffectType == "ForeignKey" && (u.WhetherAddUpdate == "Y" || u.WhetherQuery == "Y"))){
- @:
- var dropdownName = $"{column.FkEntityName}{column.PropertyName.TrimEnd("Id")}Dropdown";
- @:/// <summary>
- @:/// 获取@(column.ColumnComment)列表 🔖
- @:/// </summary>
- @:/// <returns></returns>
- @:[DisplayName("获取@(column.ColumnComment)列表")]
- @:[ApiDescriptionSettings(Name = "@(dropdownName)"), HttpGet]
- @:public async Task<dynamic> @(dropdownName)([FromQuery]bool all)
- @:{
- var columnList = column.FkDisplayColumnList.Select(name => $"{{u.{name}}}").ToList();
- @:return await _@(Model.LowerClassName)Rep.Context.Queryable<@(column.FkEntityName)>()
- @:.InnerJoinIF<@Model.ClassName>(!all, (u, r) => u.@(column.FkLinkColumnName) == r.@(column.PropertyName))
- @:.Select(u => new
- @:{
- @:Label = $"@(string.Join("-", columnList))",
- @:Value = u.@(column.FkLinkColumnName)
- @:}
- @:).ToListAsync();
- @:}
- }
- @foreach (var column in Model.AddUpdateFieldList) {
- @:
- @:/// <summary>
- @:/// 上传@(column.ColumnComment) ⬆️
- @:/// </summary>
- @:/// <param name="file"></param>
- @:/// <returns></returns>
- @:[DisplayName("上传@(column.ColumnComment)")]
- @:[ApiDescriptionSettings(Name = "Upload@(column.PropertyName)"), HttpPost]
- @:public async Task<SysFile> Upload@(column.PropertyName)([Required] IFormFile file)
- @:{
- @:return await _sysFileService.UploadFile(new FileUploadInput { File = file, SavePath = "upload/@(Model.ClassName)/@(column.PropertyName)" });
- @:}
- }
- @if (Model.ImportFieldList.Count > 0) {
- @:
- @:/// <summary>
- @:/// 下载@(Model.BusName)数据导入模板 ⬇️
- @:/// </summary>
- @:/// <returns></returns>
- @:[DisplayName("下载@(Model.BusName)数据导入模板")]
- @:[ApiDescriptionSettings(Name = "Import"), HttpGet, NonUnify]
- @:public IActionResult DownloadTemplate()
- @:{
- var fieldsList = Model.ImportFieldList.Where(u => u.EffectType == "ForeignKey" || u.EffectType == "ApiTreeSelector").ToList();
- if (fieldsList.Any()) {
- @:return ExcelHelper.ExportTemplate(new List<Export@(Model.ClassName)Output>(), "@(Model.BusName)导入模板", (_, info) =>
- @:{
- foreach (var column in fieldsList) {
- var columnList = column.FkDisplayColumnList.Select(n => $"{{u.{n}}}").ToList();
- @:if (nameof(Export@(Model.ClassName)Output.@(column.PropertyName)Label) == info.Name) return _@(Model.LowerClassName)Rep.Context.Queryable<@(column.FkEntityName)>().Select(u => $"@(string.Join("-", columnList))").Distinct().ToList();
- }
- @:return null;
- @:});
- } else {
- @:return ExcelHelper.ExportTemplate(new List<Export@(Model.ClassName)Output>(), "@(Model.BusName)导入模板");
- }
- @:}
- @:
- @:/// <summary>
- @:/// 导入@(Model.BusName)记录 💾
- @:/// </summary>
- @:/// <returns></returns>
- @:[DisplayName("导入@(Model.BusName)记录")]
- @:[ApiDescriptionSettings(Name = "Import"), HttpPost, NonUnify, UnitOfWork]
- @:public IActionResult ImportData([Required] IFormFile file)
- @:{
- @:lock (this)
- @:{
- var dictTableField = Model.TableField.Where(x => x.WhetherImport == "Y" && x.EffectType == "DictSelector") ?? default;
- foreach (var column in dictTableField){
- @:var @(column.LowerPropertyName)DictMap = _sysDictTypeService.GetDataList(new GetDataDictTypeInput { Code = "@(column.DictTypeCode)" }).Result.ToDictionary(x => x.Value, x => x.Code);
- }
- @:var stream = ExcelHelper.ImportData<Import@(Model.ClassName)Input, @(Model.ClassName)>(file, (list, markerErrorAction) =>
- @:{
- @:_@(Model.LowerClassName)Rep.Context.Utilities.PageEach(list, 2048, pageItems =>
- @:{
- foreach (var column in Model.ImportFieldList.Where(u => u.EffectType == "ForeignKey" || u.EffectType == "ApiTreeSelector")) {
- @:// 链接 @(column.ColumnComment)
- @:var @(column.LowerPropertyName)LabelList = pageItems.Where(x => x.@(column.PropertyName)Label != null).Select(x => x.@(column.PropertyName)Label).Distinct().ToList();
- @:if (@(column.LowerPropertyName)LabelList.Any()) {
- var columnList = column.FkDisplayColumnList.Select(n => $"{{u.{n}}}").ToList();
- @:var @(column.LowerPropertyName)LinkMap = _@(Model.LowerClassName)Rep.Context.Queryable<@(column.FkEntityName)>().Where(u => @(column.LowerPropertyName)LabelList.Contains($"@(string.Join("-", columnList))")).ToList().ToDictionary(u => $"@(string.Join("-", columnList))", u => u.@(column.FkLinkColumnName));
- @:pageItems.ForEach(e => e.@(column.PropertyName) = @(column.LowerPropertyName)LinkMap?.GetValueOrDefault(e.@(column.PropertyName)Label, default));
- @:}
- }
- @:
- @:// 校验并过滤必填基本类型为null的字段
- @:var rows = pageItems.Where(x => {
- foreach (var column in Model.ImportFieldList.Where(x => x.WhetherRequired == "Y" && Regex.IsMatch(x.NetType, "(int|long|double|float|bool|Enum[?]?)"))){
- @:if (x.@(column.PropertyName) == null){
- @:x.Error = "@(column.ColumnComment)不能为空";
- @:return false;
- @:}
- }
- @:return true;
- @:}).Adapt<List<@(Model.ClassName)>>();
- if (dictTableField.Any()) {
- @:
- @:// 映射字典值
- @:foreach(var row in rows) {
- foreach (var column in dictTableField){
- @:row.@(column.PropertyName) = @(column.LowerPropertyName)DictMap.GetValueOrDefault(row.@(column.PropertyName) ?? "");
- }
- @:}
- }
- @:
- @:var storageable = _@(Model.LowerClassName)Rep.Context.Storageable(rows)
- foreach (var column in Model.ImportFieldList){
- if (column.WhetherRequired == "Y"){
- if(column.NetType.TrimEnd('?') == "string"){
- @:.SplitError(it => string.IsNullOrWhiteSpace(it.Item.@(column.PropertyName)), "@(column.ColumnComment)不能为空")
- } else if(column.NetType.EndsWith('?') == true){
- @:.SplitError(it => it.Item.@(column.PropertyName) == null, "@(column.ColumnComment)不能为空")
- }}
- if (column.NetType?.TrimEnd('?') == "string"){
- @:.SplitError(it => it.Item.@(column.PropertyName)?.Length > @(column.ColumnLength), "@(column.ColumnComment)长度不能超过@(column.ColumnLength)个字符")
- }}
- foreach (var config in Model.ImportUniqueConfigList) {
- @:.WhereColumns(it => new { @(string.Join(", ", config.Columns.Select(x => $"it.{x}"))) }).SplitError(it => it.Any(), "@(config.Message)已存在")
- }
- @:.SplitInsert(_ => true)
- @:.ToStorage();
- @:
- @:storageable.BulkCopy();
- @:storageable.BulkUpdate();
- @:
- @:// 标记错误信息
- @:markerErrorAction.Invoke(storageable, pageItems, rows);
- @:});
- @:});
- @:
- @:return stream;
- @:}
- @:}
- }
- }
|