using JNPF.Common.Configuration; using JNPF.Common.Enums; using JNPF.Common.Extension; using JNPF.Common.Security; using JNPF.DatabaseAccessor; using JNPF.DependencyInjection; using JNPF.DynamicApiController; using JNPF.FriendlyException; using JNPF.Logging.Attributes; using JNPF.VisualData.Entity; using JNPF.VisualData.Entitys.Dto.Screen; using JNPF.VisualData.Entitys.Dto.ScreenCategory; using JNPF.VisualData.Entitys.Dto.ScreenConfig; using JNPF.VisualData.Entitys.Enum; using Mapster; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using SqlSugar; using Yitter.IdGenerator; namespace JNPF.VisualData; /// /// 业务实现:大屏. /// [ApiDescriptionSettings(Tag = "BladeVisual", Name = "Visual", Order = 160)] [Route("api/blade-visual/[controller]")] public class ScreenService : IDynamicApiController, ITransient { /// /// 服务基础仓储. /// private readonly ISqlSugarRepository _visualRepository; /// /// 多租户事务. /// private readonly ITenant _db; /// /// 初始化一个类型的新实例. /// public ScreenService( ISqlSugarRepository visualRepository, ISqlSugarClient context) { _visualRepository = visualRepository; _db = context.AsTenant(); } #region Get /// /// 分页. /// /// [HttpGet("list")] public async Task GetList([FromQuery] ScreenListQueryInput input) { input.category = input.category == null ? 1 : input.category; SqlSugarPagedList? data = await _visualRepository.AsQueryable().Where(v => v.IsDeleted == 0).Where(v => v.Category == input.category) .Select(v => new ScreenListOutput { id = v.Id, backgroundUrl = v.BackgroundUrl, category = v.Category, createDept = v.CreateDept, createTime = SqlFunc.ToString(v.CreateTime), createUser = v.CreateUser, isDeleted = v.IsDeleted, password = v.Password, status = v.Status, title = v.Title, updateTime = SqlFunc.ToString(v.UpdateTime), updateUser = v.UpdateUser }).MergeTable().OrderByDescending(v => v.createTime).OrderByDescending(v => v.updateTime).ToPagedListAsync(input.current, input.size); return new { current = data.pagination.CurrentPage, pages = data.pagination.Total / data.pagination.PageSize, records = data.list, size = data.pagination.PageSize, total = data.pagination.Total }; } /// /// 详情. /// /// [HttpGet("detail")] public async Task GetInfo([FromQuery] string id) { VisualEntity? entity = await _visualRepository.AsQueryable().FirstAsync(v => v.Id == id); VisualConfigEntity? configEntity = await _visualRepository.AsSugarClient().Queryable().FirstAsync(v => v.VisualId == id); return new { config = configEntity.Adapt(), visual = entity.Adapt() }; } /// /// 获取类型. /// /// [HttpGet("category")] public async Task GetCategoryList() { VisualCategoryEntity? entity = await _visualRepository.AsSugarClient().Queryable().FirstAsync(v => v.IsDeleted == 0); return entity.Adapt(); } /// /// 获取图片列表. /// /// [HttpGet("{type}")] public dynamic GetImgFileList(string type) { List? list = new List(); var typeEnum = EnumExtensions.GetEnumDescDictionary(typeof(ScreenImgEnum)); var imgEnum = typeEnum.Where(t => t.Value.Equals(type)).FirstOrDefault(); if (imgEnum.Value != null) { string? path = Path.Combine(FileVariable.BiVisualPath, imgEnum.Value); foreach (FileInfo? item in FileHelper.GetAllFiles(path)) { list.Add(new ScreenImgFileOutput() { link = string.Format("/api/file/VisusalImg/{0}/{1}", type, item.Name), originalName = item.Name }); } } return list; } /// /// 查看图片. /// /// [HttpGet("{type}/{fileName}"), AllowAnonymous, IgnoreLog] public dynamic GetImgFile(string type, string fileName) { var typeEnum = EnumExtensions.GetEnumDescDictionary(typeof(ScreenImgEnum)); var imgEnum = typeEnum.Where(t => t.Value.Equals(type)).FirstOrDefault(); if (imgEnum.Value != null) { string? path = Path.Combine(FileVariable.BiVisualPath, imgEnum.Value, fileName); return new FileStreamResult(new FileStream(path, FileMode.Open), "application/octet-stream") { FileDownloadName = fileName }; } return Task.FromResult(false); } /// /// 大屏下拉框. /// /// [HttpGet("selector")] public async Task GetSelector() { List? screenList = await _visualRepository.AsQueryable().Where(v => v.IsDeleted == 0) .Select(v => new ScreenSelectorOuput { id = v.Id, parentId = SqlFunc.ToString(v.Category), fullName = v.Title, isDeleted = v.IsDeleted }).ToListAsync(); List? categortList = await _visualRepository.AsSugarClient().Queryable().Where(v => v.IsDeleted == 0) .Select(v => new ScreenSelectorOuput { id = v.CategoryValue, parentId = "0", fullName = v.CategoryKey, isDeleted = v.IsDeleted }).ToListAsync(); return new { list = categortList.Union(screenList).ToList().ToTree("0") }; } #endregion #region Post /// /// 新增. /// /// [HttpPost("save")] public async Task Save([FromBody] ScreenCrInput input) { VisualEntity? entity = input.visual.Adapt(); VisualConfigEntity? configEntity = input.config.Adapt(); try { _db.BeginTran(); // 开启事务 VisualEntity? newEntity = await _visualRepository.AsInsertable(entity).CallEntityMethod(m => m.Create()).ExecuteReturnEntityAsync(); configEntity.VisualId = newEntity.Id; await _visualRepository.AsSugarClient().Insertable(configEntity).CallEntityMethod(m => m.Create()).ExecuteCommandAsync(); _db.CommitTran(); return new { id = newEntity.Id }; } catch (Exception) { _db.RollbackTran(); throw Oops.Oh(ErrorCode.COM1000); } } /// /// 修改. /// /// [HttpPost("update")] public async Task Update([FromBody] ScreenUpInput input) { VisualEntity? entity = new VisualEntity(); if (input.visual.backgroundUrl != null) { entity = await _visualRepository.AsQueryable().FirstAsync(v => v.Id == input.visual.id); entity.BackgroundUrl = input.visual.backgroundUrl; } else { entity = input.visual.Adapt(); } VisualConfigEntity? configEntity = input.config.Adapt(); try { _db.BeginTran(); // 开启事务 await _visualRepository.AsUpdateable(entity).IgnoreColumns(ignoreAllNullColumns: true).CallEntityMethod(m => m.LastModify()).ExecuteCommandAsync(); if (configEntity != null) await _visualRepository.AsSugarClient().Updateable(configEntity).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync(); _db.CommitTran(); } catch (Exception) { _db.RollbackTran(); throw Oops.Oh(ErrorCode.COM1000); } } /// /// 逻辑删除. /// /// [HttpPost("remove")] public async Task Remove(string ids) { VisualEntity? entity = await _visualRepository.AsQueryable().FirstAsync(v => v.Id == ids); await _visualRepository.AsUpdateable(entity).CallEntityMethod(m => m.Delete()).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync(); } /// /// 复制. /// /// [HttpPost("copy")] [NonUnify] [UnitOfWork] public async Task Copy(string id) { VisualEntity? entity = await _visualRepository.AsQueryable().FirstAsync(v => v.Id == id); VisualConfigEntity? configEntity = await _visualRepository.AsSugarClient().Queryable().FirstAsync(v => v.VisualId == id); VisualEntity? newEntity = await _visualRepository.AsInsertable(entity).CallEntityMethod(m => m.Create()).ExecuteReturnEntityAsync(); configEntity.VisualId = newEntity.Id; await _visualRepository.AsSugarClient().Insertable(configEntity).CallEntityMethod(m => m.Create()).ExecuteReturnEntityAsync(); return new { code = 200, msg = newEntity.Id }; } /// /// 上传文件. /// /// [HttpPost("put-file/{type}"), AllowAnonymous, IgnoreLog] public async Task SaveFile(string type, IFormFile file) { var typeEnum = EnumExtensions.GetEnumDescDictionary(typeof(ScreenImgEnum)); var imgEnum = typeEnum.Where(t => t.Value.Equals(type)).FirstOrDefault(); if (imgEnum.Value != null) { string? ImgType = Path.GetExtension(file.FileName).Replace(".", string.Empty); if (!this.AllowImageType(ImgType)) throw Oops.Oh(ErrorCode.D5013); var path = imgEnum.Value; string? filePath = Path.Combine(FileVariable.BiVisualPath, path); if (!Directory.Exists(filePath)) Directory.CreateDirectory(filePath); string? fileName = YitIdHelper.NextId().ToString() + "." + ImgType; using (FileStream? stream = File.Create(Path.Combine(filePath, fileName))) { await file.CopyToAsync(stream); } return new { name = "/" + Path.Combine("api", "file", "VisusalImg", path, fileName), link = "/" + Path.Combine("api", "file", "VisusalImg", path, fileName), originalName = file.FileName }; } return Task.FromResult(false); } #endregion #region PrivateMethod /// /// 允许文件类型. /// /// 文件后缀名. /// private bool AllowImageType(string fileExtension) { List? allowExtension = KeyVariable.AllowImageType; string? isExist = allowExtension.Find(a => a == fileExtension.ToLower()); if (!string.IsNullOrEmpty(isExist)) return true; else return false; } #endregion }