添加项目文件。
This commit is contained in:
1529
visualdev/Tnb.VisualDev/CodeGenService.cs
Normal file
1529
visualdev/Tnb.VisualDev/CodeGenService.cs
Normal file
File diff suppressed because it is too large
Load Diff
134
visualdev/Tnb.VisualDev/DashboardService.cs
Normal file
134
visualdev/Tnb.VisualDev/DashboardService.cs
Normal file
@@ -0,0 +1,134 @@
|
||||
using JNPF.Common.Core.Manager;
|
||||
using JNPF.DependencyInjection;
|
||||
using JNPF.DynamicApiController;
|
||||
using JNPF.Extend.Entitys;
|
||||
using JNPF.Extend.Entitys.Dto.Email;
|
||||
using JNPF.Message.Entitys;
|
||||
using JNPF.Message.Interfaces.Message;
|
||||
using JNPF.VisualDev.Entitys.Dto.Dashboard;
|
||||
using JNPF.WorkFlow.Entitys.Entity;
|
||||
using JNPF.WorkFlow.Interfaces.Repository;
|
||||
using Mapster;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using SqlSugar;
|
||||
|
||||
namespace JNPF.VisualDev;
|
||||
|
||||
/// <summary>
|
||||
/// 业务实现:主页显示.
|
||||
/// </summary>
|
||||
[ApiDescriptionSettings(Tag = "VisualDev", Name = "Dashboard", Order = 174)]
|
||||
[Route("api/visualdev/[controller]")]
|
||||
public class DashboardService : IDynamicApiController, ITransient
|
||||
{
|
||||
private readonly ISqlSugarRepository<EmailReceiveEntity> _emailReceiveRepository;
|
||||
|
||||
/// <summary>
|
||||
/// 流程任务.
|
||||
/// </summary>
|
||||
private readonly IFlowTaskRepository _flowTaskRepository;
|
||||
|
||||
/// <summary>
|
||||
/// 系统消息服务.
|
||||
/// </summary>
|
||||
private readonly IMessageService _messageService;
|
||||
|
||||
/// <summary>
|
||||
/// 用户管理.
|
||||
/// </summary>
|
||||
private readonly IUserManager _userManager;
|
||||
|
||||
/// <summary>
|
||||
/// 初始化一个<see cref="DashboardService"/>类型的新实例.
|
||||
/// </summary>
|
||||
public DashboardService(
|
||||
ISqlSugarRepository<EmailReceiveEntity> emailReceiveRepository,
|
||||
IFlowTaskRepository flowTaskRepository,
|
||||
IMessageService messageService,
|
||||
IUserManager userManager)
|
||||
{
|
||||
_emailReceiveRepository = emailReceiveRepository;
|
||||
_flowTaskRepository = flowTaskRepository;
|
||||
_messageService = messageService;
|
||||
_userManager = userManager;
|
||||
}
|
||||
|
||||
#region Get
|
||||
|
||||
/// <summary>
|
||||
/// 获取我的待办.
|
||||
/// </summary>
|
||||
[HttpGet("FlowTodoCount")]
|
||||
public async Task<dynamic> GetFlowTodoCount()
|
||||
{
|
||||
int flowCount = await _emailReceiveRepository.AsSugarClient().Queryable<FlowDelegateEntity>().Where(x => x.CreatorUserId == _userManager.UserId && x.DeleteMark == null).CountAsync();
|
||||
List<FlowTaskEntity>? waitList = await _flowTaskRepository.GetWaitList();
|
||||
List<FlowTaskEntity>? trialList = await _flowTaskRepository.GetTrialList();
|
||||
return new FlowTodoCountOutput()
|
||||
{
|
||||
toBeReviewed = waitList.Count(),
|
||||
entrust = flowCount,
|
||||
flowDone = trialList.Count()
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取通知公告.
|
||||
/// </summary>
|
||||
[HttpGet("Notice")]
|
||||
public async Task<dynamic> GetNotice()
|
||||
{
|
||||
List<NoticeOutput> list = await _emailReceiveRepository.AsSugarClient().Queryable<MessageEntity, MessageReceiveEntity>((a, b) => new JoinQueryInfos(JoinType.Left, a.Id == b.MessageId))
|
||||
.Where((a, b) => a.Type == 1 && a.DeleteMark == null && b.UserId == _userManager.UserId)
|
||||
.Select((a) => new NoticeOutput()
|
||||
{
|
||||
id = a.Id,
|
||||
fullName = a.Title,
|
||||
creatorTime = a.CreatorTime
|
||||
}).ToListAsync();
|
||||
|
||||
return new { list = list };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取待办事项.
|
||||
/// </summary>
|
||||
[HttpGet("FlowTodo")]
|
||||
public async Task<dynamic> GetFlowTodo()
|
||||
{
|
||||
dynamic list = await _flowTaskRepository.GetPortalWaitList();
|
||||
return new { list = list };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取我的待办事项.
|
||||
/// </summary>
|
||||
[HttpGet("MyFlowTodo")]
|
||||
public async Task<dynamic> GetMyFlowTodo()
|
||||
{
|
||||
List<FlowTodoOutput> list = new List<FlowTodoOutput>();
|
||||
(await _flowTaskRepository.GetWaitList()).ForEach(l =>
|
||||
{
|
||||
list.Add(new FlowTodoOutput()
|
||||
{
|
||||
id = l.Id,
|
||||
fullName = l.FlowName,
|
||||
creatorTime = l.CreatorTime
|
||||
});
|
||||
});
|
||||
return new { list = list };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取未读邮件.
|
||||
/// </summary>
|
||||
[HttpGet("Email")]
|
||||
public async Task<dynamic> GetEmail()
|
||||
{
|
||||
List<EmailHomeOutput>? res = (await _emailReceiveRepository.AsQueryable().Where(x => x.Read == 0 && x.CreatorUserId == _userManager.UserId && x.DeleteMark == null)
|
||||
.OrderBy(x => x.CreatorTime, OrderByType.Desc).ToListAsync()).Adapt<List<EmailHomeOutput>>();
|
||||
return new { list = res };
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
376
visualdev/Tnb.VisualDev/PortalService.cs
Normal file
376
visualdev/Tnb.VisualDev/PortalService.cs
Normal file
@@ -0,0 +1,376 @@
|
||||
using JNPF.Common.Core.Manager;
|
||||
using JNPF.Common.Core.Manager.Files;
|
||||
using JNPF.Common.Enums;
|
||||
using JNPF.Common.Extension;
|
||||
using JNPF.Common.Filter;
|
||||
using JNPF.Common.Models.User;
|
||||
using JNPF.Common.Security;
|
||||
using JNPF.DependencyInjection;
|
||||
using JNPF.DynamicApiController;
|
||||
using JNPF.FriendlyException;
|
||||
using JNPF.Systems.Entitys.Permission;
|
||||
using JNPF.Systems.Entitys.System;
|
||||
using JNPF.Systems.Interfaces.Common;
|
||||
using JNPF.VisualDev.Entitys;
|
||||
using JNPF.VisualDev.Entitys.Dto.Portal;
|
||||
using JNPF.VisualDev.Entitys.Dto.VisualDev;
|
||||
using Mapster;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using SqlSugar;
|
||||
|
||||
namespace JNPF.VisualDev;
|
||||
|
||||
/// <summary>
|
||||
/// 业务实现:门户设计.
|
||||
/// </summary>
|
||||
[ApiDescriptionSettings(Tag = "VisualDev", Name = "Portal", Order = 173)]
|
||||
[Route("api/visualdev/[controller]")]
|
||||
public class PortalService : IDynamicApiController, ITransient
|
||||
{
|
||||
/// <summary>
|
||||
/// 服务基础仓储.
|
||||
/// </summary>
|
||||
private readonly ISqlSugarRepository<PortalEntity> _portalRepository;
|
||||
|
||||
/// <summary>
|
||||
/// 用户管理.
|
||||
/// </summary>
|
||||
private readonly IUserManager _userManager;
|
||||
|
||||
/// <summary>
|
||||
/// 文件服务.
|
||||
/// </summary>
|
||||
private readonly IFileManager _fileManager;
|
||||
|
||||
/// <summary>
|
||||
/// 初始化一个<see cref="PortalService"/>类型的新实例.
|
||||
/// </summary>
|
||||
public PortalService(
|
||||
ISqlSugarRepository<PortalEntity> portalRepository,
|
||||
IUserManager userManager,
|
||||
IFileManager fileManager)
|
||||
{
|
||||
_portalRepository = portalRepository;
|
||||
_userManager = userManager;
|
||||
_fileManager = fileManager;
|
||||
}
|
||||
|
||||
#region Get
|
||||
|
||||
/// <summary>
|
||||
/// 列表.
|
||||
/// </summary>
|
||||
/// <param name="input">请求参数.</param>
|
||||
/// <returns>返回列表.</returns>
|
||||
[HttpGet("")]
|
||||
public async Task<dynamic> GetList([FromQuery] VisualDevListQueryInput input)
|
||||
{
|
||||
SqlSugarPagedList<PortalListOutput>? portalList = await _portalRepository.AsSugarClient().Queryable<PortalEntity, UserEntity, UserEntity, DictionaryDataEntity>((a, b, c, d) => new JoinQueryInfos(JoinType.Left, b.Id == a.CreatorUserId, JoinType.Left, c.Id == a.LastModifyUserId, JoinType.Left, d.Id == a.Category))
|
||||
.WhereIF(!string.IsNullOrEmpty(input.keyword), a => a.FullName.Contains(input.keyword) || a.EnCode.Contains(input.keyword))
|
||||
.WhereIF(!string.IsNullOrEmpty(input.category), a => a.Category == input.category).Where(a => a.DeleteMark == null)
|
||||
.OrderBy(a => a.SortCode, OrderByType.Asc)
|
||||
.OrderBy(a => a.CreatorTime, OrderByType.Desc)
|
||||
.OrderBy(a => a.LastModifyTime, OrderByType.Desc)
|
||||
.Select((a, b, c, d) => new PortalListOutput
|
||||
{
|
||||
id = a.Id,
|
||||
fullName = a.FullName,
|
||||
enCode = a.EnCode,
|
||||
deleteMark = SqlFunc.ToString(a.DeleteMark),
|
||||
description = a.Description,
|
||||
category = d.FullName,
|
||||
creatorTime = a.CreatorTime,
|
||||
creatorUser = SqlFunc.MergeString(b.RealName, "/", b.Account),
|
||||
parentId = a.Category,
|
||||
lastModifyUser = SqlFunc.MergeString(c.RealName, SqlFunc.IIF(c.RealName == null, string.Empty, "/"), c.Account),
|
||||
lastModifyTime = SqlFunc.ToDate(a.LastModifyTime),
|
||||
enabledMark = a.EnabledMark,
|
||||
type = a.Type,
|
||||
sortCode = SqlFunc.ToString(a.SortCode)
|
||||
})
|
||||
.ToPagedListAsync(input.currentPage, input.pageSize);
|
||||
|
||||
return PageResult<PortalListOutput>.SqlSugarPageResult(portalList);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取门户侧边框列表.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpGet("Selector")]
|
||||
public async Task<dynamic> GetSelector([FromQuery] string type)
|
||||
{
|
||||
List<PortalSelectOutput>? data = new List<PortalSelectOutput>();
|
||||
if ("1".Equals(type) && !_userManager.IsAdministrator)
|
||||
{
|
||||
List<string>? roleId = await _portalRepository.AsSugarClient().Queryable<RoleEntity>().In(r => r.Id, _userManager.Roles).Where(r => r.EnabledMark == 1 && r.DeleteMark == null).Select(r => r.Id).ToListAsync();
|
||||
var items = await _portalRepository.AsSugarClient().Queryable<AuthorizeEntity>().Where(a => roleId.Contains(a.ObjectId) && a.ItemType == "portal").GroupBy(it => new { it.ItemId }).Select(it => new { it.ItemId }).ToListAsync();
|
||||
if (items.Any())
|
||||
{
|
||||
data = await _portalRepository.AsQueryable().In(p => p.Id, items.Select(it => it.ItemId).ToArray())
|
||||
.Where(p => p.EnabledMark == 1 && p.DeleteMark == null).OrderBy(p => p.SortCode)
|
||||
.Select(s => new PortalSelectOutput
|
||||
{
|
||||
id = s.Id,
|
||||
fullName = s.FullName,
|
||||
parentId = s.Category
|
||||
}).ToListAsync();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
data = await _portalRepository.AsQueryable()
|
||||
.Where(p => p.EnabledMark == 1 && p.DeleteMark == null).OrderBy(o => o.SortCode)
|
||||
.Select(s => new PortalSelectOutput
|
||||
{
|
||||
id = s.Id,
|
||||
fullName = s.FullName,
|
||||
parentId = s.Category,
|
||||
}).ToListAsync();
|
||||
}
|
||||
|
||||
List<string>? parentIds = data.Select(it => it.parentId).Distinct().ToList();
|
||||
List<PortalSelectOutput>? treeList = new List<PortalSelectOutput>();
|
||||
if (parentIds.Any())
|
||||
{
|
||||
treeList = await _portalRepository.AsSugarClient().Queryable<DictionaryDataEntity>().In(it => it.Id, parentIds.ToArray())
|
||||
.Where(d => d.DeleteMark == null && d.EnabledMark == 1).OrderBy(o => o.SortCode)
|
||||
.Select(d => new PortalSelectOutput
|
||||
{
|
||||
id = d.Id,
|
||||
parentId = "0",
|
||||
fullName = d.FullName
|
||||
}).ToListAsync();
|
||||
}
|
||||
|
||||
return new { list = treeList.Union(data).ToList().ToTree("0") };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取门户信息.
|
||||
/// </summary>
|
||||
/// <param name="id">主键id.</param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("{id}")]
|
||||
public async Task<dynamic> GetInfo(string id)
|
||||
{
|
||||
PortalEntity? data = await _portalRepository.AsQueryable().FirstAsync(p => p.Id == id);
|
||||
return data.Adapt<PortalInfoOutput>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 信息.
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("{id}/auth")]
|
||||
public async Task<dynamic> GetInfoAuth(string id)
|
||||
{
|
||||
if (_userManager.Roles != null && !_userManager.IsAdministrator)
|
||||
{
|
||||
List<string>? roleId = await _portalRepository.AsSugarClient().Queryable<RoleEntity>().Where(r =>_userManager.Roles.Contains(r.Id)).Where(r => r.EnabledMark == 1 && r.DeleteMark == null).Select(r => r.Id).ToListAsync();
|
||||
var items = await _portalRepository.AsSugarClient().Queryable<AuthorizeEntity>().Where(a => roleId.Contains(a.ObjectId)).Where(a => a.ItemType == "portal").GroupBy(it => new { it.ItemId }).Select(it => new { it.ItemId }).ToListAsync();
|
||||
if (items.Count == 0) return null;
|
||||
PortalEntity? entity = await _portalRepository.AsQueryable().Where(p => items.Select(it => it.ItemId).Contains(p.Id)).SingleAsync(p => p.Id == id && p.EnabledMark == 1 && p.DeleteMark == null);
|
||||
//_ = entity ?? throw Oops.Oh(ErrorCode.COM1005);
|
||||
if (entity == null) return new PortalInfoAuthOutput();
|
||||
return entity.Adapt<PortalInfoAuthOutput>();
|
||||
}
|
||||
|
||||
if (_userManager.IsAdministrator)
|
||||
{
|
||||
PortalEntity? entity = await _portalRepository.AsQueryable().FirstAsync(p => p.Id == id && p.EnabledMark == 1 && p.DeleteMark == null);
|
||||
//_ = entity ?? throw Oops.Oh(ErrorCode.COM1005);
|
||||
if (entity == null) return new PortalInfoAuthOutput();
|
||||
return entity.Adapt<PortalInfoAuthOutput>();
|
||||
}
|
||||
|
||||
throw Oops.Oh(ErrorCode.D1900);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Post
|
||||
|
||||
/// <summary>
|
||||
/// 门户导出.
|
||||
/// </summary>
|
||||
/// <param name="modelId"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("{modelId}/Actions/ExportData")]
|
||||
public async Task<dynamic> ActionsExportData(string modelId)
|
||||
{
|
||||
// 模板实体
|
||||
PortalEntity? templateEntity = await _portalRepository.AsQueryable().FirstAsync(p => p.Id == modelId);
|
||||
string? jsonStr = templateEntity.ToJsonString();
|
||||
return await _fileManager.Export(jsonStr, templateEntity.FullName, ExportFileType.vp);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 门户导入.
|
||||
/// </summary>
|
||||
/// <param name="file"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("Model/Actions/ImportData")]
|
||||
public async Task ActionsImportData(IFormFile file)
|
||||
{
|
||||
string? fileType = Path.GetExtension(file.FileName).Replace(".", string.Empty);
|
||||
if (!fileType.ToLower().Equals(ExportFileType.vp.ToString())) throw Oops.Oh(ErrorCode.D3006);
|
||||
string? josn = _fileManager.Import(file);
|
||||
PortalEntity? templateEntity = null;
|
||||
try
|
||||
{
|
||||
templateEntity = josn.ToObject<PortalEntity>();
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw Oops.Oh(ErrorCode.D3006);
|
||||
}
|
||||
|
||||
if (templateEntity == null) throw Oops.Oh(ErrorCode.D3006);
|
||||
if (templateEntity != null && templateEntity.FormData.IsNotEmptyOrNull() && templateEntity.FormData.IndexOf("layouyId") <= 0)
|
||||
throw Oops.Oh(ErrorCode.D3006);
|
||||
if (templateEntity.Id.IsNotEmptyOrNull() && await _portalRepository.IsAnyAsync(it => it.Id == templateEntity.Id && it.DeleteMark == null))
|
||||
throw Oops.Oh(ErrorCode.D1400);
|
||||
if (await _portalRepository.IsAnyAsync(it => it.EnCode == templateEntity.EnCode && it.FullName == templateEntity.FullName && it.DeleteMark == null))
|
||||
throw Oops.Oh(ErrorCode.D1400);
|
||||
|
||||
StorageableResult<PortalEntity>? stor = _portalRepository.AsSugarClient().Storageable(templateEntity).Saveable().ToStorage(); // 存在更新不存在插入 根据主键
|
||||
await stor.AsInsertable.ExecuteCommandAsync(); // 执行插入
|
||||
await stor.AsUpdateable.ExecuteCommandAsync(); // 执行更新
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 新建门户信息.
|
||||
/// </summary>
|
||||
/// <param name="input">实体对象.</param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("")]
|
||||
public async Task Create([FromBody] PortalCrInput input)
|
||||
{
|
||||
PortalEntity? entity = input.Adapt<PortalEntity>();
|
||||
if (string.IsNullOrEmpty(entity.Category)) throw Oops.Oh(ErrorCode.D1901);
|
||||
else if (string.IsNullOrEmpty(entity.FullName)) throw Oops.Oh(ErrorCode.D1902);
|
||||
else if (string.IsNullOrEmpty(entity.EnCode)) throw Oops.Oh(ErrorCode.D1903);
|
||||
else await _portalRepository.AsSugarClient().Insertable(entity).CallEntityMethod(m => m.Creator()).ExecuteCommandAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 修改接口.
|
||||
/// </summary>
|
||||
/// <param name="id">主键id.</param>
|
||||
/// <param name="input">参数.</param>
|
||||
/// <returns></returns>
|
||||
[HttpPut("{id}")]
|
||||
public async Task Update(string id, [FromBody] PortalUpInput input)
|
||||
{
|
||||
PortalEntity? entity = input.Adapt<PortalEntity>();
|
||||
int isOk = await _portalRepository.AsSugarClient().Updateable(entity).IgnoreColumns(ignoreAllNullColumns: true).CallEntityMethod(m => m.LastModify()).ExecuteCommandAsync();
|
||||
if (!(isOk > 0)) throw Oops.Oh(ErrorCode.COM1001);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除接口.
|
||||
/// </summary>
|
||||
/// <param name="id">主键id.</param>
|
||||
/// <returns></returns>
|
||||
[HttpDelete("{id}")]
|
||||
public async Task Delete(string id)
|
||||
{
|
||||
PortalEntity? entity = await _portalRepository.AsQueryable().FirstAsync(p => p.Id == id && p.DeleteMark == null);
|
||||
_ = entity ?? throw Oops.Oh(ErrorCode.COM1005);
|
||||
int isOk = await _portalRepository.AsSugarClient().Updateable(entity).CallEntityMethod(m => m.Delete()).UpdateColumns(it => new { it.DeleteMark, it.DeleteTime, it.DeleteUserId }).ExecuteCommandAsync();
|
||||
if (!(isOk > 0)) throw Oops.Oh(ErrorCode.COM1002);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 复制.
|
||||
/// </summary>
|
||||
/// <param name="id">主键值.</param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("{id}/Actions/Copy")]
|
||||
public async Task ActionsCopy(string id)
|
||||
{
|
||||
PortalEntity? newEntity = new PortalEntity();
|
||||
string? random = new Random().NextLetterAndNumberString(5);
|
||||
PortalEntity? entity = await _portalRepository.AsQueryable().FirstAsync(p => p.Id == id && p.DeleteMark == null);
|
||||
newEntity.FullName = entity.FullName + "副本" + random;
|
||||
newEntity.EnCode = entity.EnCode + random;
|
||||
newEntity.Category = entity.Category;
|
||||
newEntity.FormData = entity.FormData;
|
||||
newEntity.Description = entity.Description;
|
||||
newEntity.EnabledMark = 0;
|
||||
newEntity.SortCode = entity.SortCode;
|
||||
newEntity.Type = entity.Type;
|
||||
newEntity.LinkType = entity.LinkType;
|
||||
newEntity.CustomUrl = entity.CustomUrl;
|
||||
|
||||
try
|
||||
{
|
||||
int isOk = await _portalRepository.AsSugarClient().Insertable(newEntity).CallEntityMethod(m => m.Creator()).ExecuteCommandAsync();
|
||||
}
|
||||
catch
|
||||
{
|
||||
if (entity.FullName.Length >= 100 || entity.EnCode.Length >= 50) throw Oops.Oh(ErrorCode.D1403); // 数据长度超过 字段设定长度
|
||||
else throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置默认门户.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpPut("{id}/Actions/SetDefault")]
|
||||
public async Task SetDefault(string id)
|
||||
{
|
||||
UserEntity? userEntity = _userManager.User;
|
||||
_ = userEntity ?? throw Oops.Oh(ErrorCode.D5002);
|
||||
if (userEntity != null)
|
||||
{
|
||||
userEntity.PortalId = id;
|
||||
int isOk = await _portalRepository.AsSugarClient().Updateable<UserEntity>().SetColumns(it => new UserEntity()
|
||||
{
|
||||
PortalId = id,
|
||||
LastModifyTime = SqlFunc.GetDate(),
|
||||
LastModifyUserId = _userManager.UserId
|
||||
}).Where(it => it.Id == userEntity.Id).ExecuteCommandAsync();
|
||||
if (!(isOk > 0)) throw Oops.Oh(ErrorCode.D5014);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region PublicMethod
|
||||
|
||||
/// <summary>
|
||||
/// 获取默认.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[NonAction]
|
||||
public async Task<string> GetDefault()
|
||||
{
|
||||
UserEntity? user = _userManager.User;
|
||||
if (!user.IsAdministrator.ParseToBool())
|
||||
{
|
||||
if (!string.IsNullOrEmpty(user.RoleId))
|
||||
{
|
||||
string[]? roleIds = user.RoleId.Split(',');
|
||||
List<string>? roleId = await _portalRepository.AsSugarClient().Queryable<RoleEntity>().Where(r => roleIds.Contains(r.Id)).Where(r => r.EnabledMark == 1 && r.DeleteMark == null).Select(r => r.Id).ToListAsync();
|
||||
var items = await _portalRepository.AsSugarClient().Queryable<AuthorizeEntity>().Where(a => roleId.Contains(a.ObjectId)).Where(a => a.ItemType == "portal").GroupBy(it => new { it.ItemId }).Select(it => new { it.ItemId }).ToListAsync();
|
||||
if (items.Count == 0) return string.Empty;
|
||||
List<string>? portalList = await _portalRepository.AsQueryable().In(p => p.Id, items.Select(it => it.ItemId).ToArray()).Where(p => p.EnabledMark == 1 && p.DeleteMark == null).OrderBy(o => o.SortCode).Select(s => s.Id).ToListAsync();
|
||||
return portalList.FirstOrDefault();
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
else
|
||||
{
|
||||
List<string>? portalList = await _portalRepository.AsQueryable().Where(p => p.EnabledMark == 1 && p.DeleteMark == null).OrderBy(o => o.SortCode).Select(s => s.Id).ToListAsync();
|
||||
return portalList.FirstOrDefault();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
3353
visualdev/Tnb.VisualDev/RunService.cs
Normal file
3353
visualdev/Tnb.VisualDev/RunService.cs
Normal file
File diff suppressed because it is too large
Load Diff
129
visualdev/Tnb.VisualDev/ScreenCategoryService.cs
Normal file
129
visualdev/Tnb.VisualDev/ScreenCategoryService.cs
Normal file
@@ -0,0 +1,129 @@
|
||||
using JNPF.Common.Enums;
|
||||
using JNPF.DependencyInjection;
|
||||
using JNPF.DynamicApiController;
|
||||
using JNPF.FriendlyException;
|
||||
using JNPF.VisualData.Entity;
|
||||
using JNPF.VisualData.Entitys.Dto.ScreenCategory;
|
||||
using Mapster;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using SqlSugar;
|
||||
using Yitter.IdGenerator;
|
||||
|
||||
namespace JNPF.VisualData;
|
||||
|
||||
/// <summary>
|
||||
/// 业务实现:大屏.
|
||||
/// </summary>
|
||||
[ApiDescriptionSettings(Tag = "BladeVisual", Name = "category", Order = 160)]
|
||||
[Route("api/blade-visual/[controller]")]
|
||||
public class ScreenCategoryService : IDynamicApiController, ITransient
|
||||
{
|
||||
/// <summary>
|
||||
/// 服务基础仓储.
|
||||
/// </summary>
|
||||
private readonly ISqlSugarRepository<VisualCategoryEntity> _visualCategoryRepository;
|
||||
|
||||
/// <summary>
|
||||
/// 初始化一个<see cref="ScreenCategoryService"/>类型的新实例.
|
||||
/// </summary>
|
||||
public ScreenCategoryService(ISqlSugarRepository<VisualCategoryEntity> visualCategoryRepository)
|
||||
{
|
||||
_visualCategoryRepository = visualCategoryRepository;
|
||||
}
|
||||
|
||||
#region Get
|
||||
|
||||
/// <summary>
|
||||
/// 获取大屏分类分页列表.
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("page")]
|
||||
public async Task<dynamic> GetPagetList([FromQuery] ScreenCategoryListQueryInput input)
|
||||
{
|
||||
SqlSugarPagedList<ScreenCategoryListOutput>? data = await _visualCategoryRepository.AsQueryable().Where(v => v.IsDeleted == 0).Select(v => new ScreenCategoryListOutput { id = v.Id, categoryKey = v.CategoryKey, categoryValue = v.CategoryValue, isDeleted = v.IsDeleted }).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 };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取大屏分类列表.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpGet("list")]
|
||||
public async Task<dynamic> GetList([FromQuery] ScreenCategoryListQueryInput input)
|
||||
{
|
||||
SqlSugarPagedList<ScreenCategoryListOutput>? list = await _visualCategoryRepository.AsQueryable().Where(v => v.IsDeleted == 0)
|
||||
.Select(v => new ScreenCategoryListOutput
|
||||
{
|
||||
id = v.Id,
|
||||
categoryKey = v.CategoryKey,
|
||||
categoryValue = v.CategoryValue,
|
||||
isDeleted = v.IsDeleted
|
||||
}).ToPagedListAsync(input.current, input.size);
|
||||
return list.list;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 详情.
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("detail")]
|
||||
public async Task<dynamic> GetInfo(string id)
|
||||
{
|
||||
VisualCategoryEntity? entity = await _visualCategoryRepository.AsQueryable().FirstAsync(v => v.Id == id);
|
||||
return entity.Adapt<ScreenCategoryInfoOutput>();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Post
|
||||
|
||||
/// <summary>
|
||||
/// 新增.
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("save")]
|
||||
public async Task Create([FromBody] ScreenCategoryCrInput input)
|
||||
{
|
||||
bool isExist = await _visualCategoryRepository.IsAnyAsync(v => v.CategoryValue == input.categoryValue && v.IsDeleted == 0);
|
||||
if (isExist) throw Oops.Oh(ErrorCode.D2200);
|
||||
VisualCategoryEntity? entity = input.Adapt<VisualCategoryEntity>();
|
||||
entity.IsDeleted = 0;
|
||||
entity.Id = YitIdHelper.NextId().ToString();
|
||||
int isOk = await _visualCategoryRepository.AsInsertable(entity).ExecuteCommandAsync();
|
||||
if (!(isOk > 0)) throw Oops.Oh(ErrorCode.COM1000);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 修改.
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("update")]
|
||||
public async Task Update([FromBody] ScreenCategoryUpInput input)
|
||||
{
|
||||
bool isExist = await _visualCategoryRepository.IsAnyAsync(v => v.CategoryValue == input.categoryValue && v.Id != input.Id && v.IsDeleted == 0);
|
||||
if (isExist) throw Oops.Oh(ErrorCode.D2200);
|
||||
VisualCategoryEntity? entity = input.Adapt<VisualCategoryEntity>();
|
||||
int isOk = await _visualCategoryRepository.AsUpdateable(entity).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
|
||||
if (!(isOk > 0)) throw Oops.Oh(ErrorCode.COM1001);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除.
|
||||
/// </summary>
|
||||
/// <param name="ids"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("remove")]
|
||||
public async Task Delete(string ids)
|
||||
{
|
||||
List<VisualCategoryEntity>? entity = await _visualCategoryRepository.AsQueryable().In(v => v.Id, ids.Split(',').ToArray()).Where(v => v.IsDeleted == 0).ToListAsync();
|
||||
_ = entity ?? throw Oops.Oh(ErrorCode.COM1005);
|
||||
int isOk = await _visualCategoryRepository.AsUpdateable(entity).IgnoreColumns(ignoreAllNullColumns: true).CallEntityMethod(m => m.Delete()).ExecuteCommandAsync();
|
||||
if (!(isOk > 0)) throw Oops.Oh(ErrorCode.COM1002);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
245
visualdev/Tnb.VisualDev/ScreenDataSourceService.cs
Normal file
245
visualdev/Tnb.VisualDev/ScreenDataSourceService.cs
Normal file
@@ -0,0 +1,245 @@
|
||||
using JNPF.Common.Enums;
|
||||
using JNPF.Common.Extension;
|
||||
using JNPF.DependencyInjection;
|
||||
using JNPF.DynamicApiController;
|
||||
using JNPF.FriendlyException;
|
||||
using JNPF.VisualData.Entity;
|
||||
using JNPF.VisualData.Entitys.Dto.ScreenDataSource;
|
||||
using Mapster;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using SqlSugar;
|
||||
using Yitter.IdGenerator;
|
||||
|
||||
namespace JNPF.VisualData;
|
||||
|
||||
/// <summary>
|
||||
/// 业务实现:大屏.
|
||||
/// </summary>
|
||||
[ApiDescriptionSettings(Tag = "BladeVisual", Name = "db", Order = 160)]
|
||||
[Route("api/blade-visual/[controller]")]
|
||||
public class ScreenDataSourceService : IDynamicApiController, ITransient
|
||||
{
|
||||
/// <summary>
|
||||
/// 客户端初始化.
|
||||
/// </summary>
|
||||
public ISqlSugarClient _sqlSugarClient;
|
||||
|
||||
/// <summary>
|
||||
/// 服务基础仓储.
|
||||
/// </summary>
|
||||
private readonly ISqlSugarRepository<VisualDBEntity> _visualDBRepository;
|
||||
|
||||
/// <summary>
|
||||
/// 初始化一个<see cref="ScreenDataSourceService"/>类型的新实例.
|
||||
/// </summary>
|
||||
public ScreenDataSourceService(
|
||||
ISqlSugarRepository<VisualDBEntity> visualDBRepository,
|
||||
ISqlSugarClient context)
|
||||
{
|
||||
_visualDBRepository = visualDBRepository;
|
||||
_sqlSugarClient = context;
|
||||
}
|
||||
|
||||
#region Get
|
||||
|
||||
/// <summary>
|
||||
/// 分页.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpGet("list")]
|
||||
public async Task<dynamic> GetList([FromQuery] ScreenDataSourceListQueryInput input)
|
||||
{
|
||||
SqlSugarPagedList<ScreenDataSourceListOutput>? data = await _visualDBRepository.AsQueryable().Where(v => v.IsDeleted == 0)
|
||||
.Select(v => new ScreenDataSourceListOutput { id = v.Id, name = v.Name, driverClass = v.DriverClass, password = v.Password, remark = v.Remark, url = v.Url, username = v.UserName, isDeleted = v.IsDeleted })
|
||||
.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 };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 详情.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpGet("detail")]
|
||||
public async Task<dynamic> GetInfo(string id)
|
||||
{
|
||||
VisualDBEntity? entity = await _visualDBRepository.AsQueryable().FirstAsync(v => v.Id == id && v.IsDeleted == 0);
|
||||
return entity.Adapt<ScreenDataSourceInfoOutput>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 下拉数据源.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpGet("db-list")]
|
||||
public async Task<dynamic> GetDBList()
|
||||
{
|
||||
return await _visualDBRepository.AsQueryable().Select(v => new ScreenDataSourceSeleectOutput { id = v.Id, name = v.Name, driverClass = v.DriverClass }).ToListAsync();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Post
|
||||
|
||||
/// <summary>
|
||||
/// 新增与修改.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpPost("submit")]
|
||||
public async Task Submit([FromBody] ScreenDataSourceUpInput input)
|
||||
{
|
||||
VisualDBEntity? entity = input.Adapt<VisualDBEntity>();
|
||||
int isOk = 0;
|
||||
if (input.id == null)
|
||||
isOk = await _visualDBRepository.AsInsertable(entity).IgnoreColumns(ignoreNullColumn: true).CallEntityMethod(m => m.Create()).ExecuteCommandAsync();
|
||||
else
|
||||
isOk = await _visualDBRepository.AsUpdateable(entity).IgnoreColumns(ignoreAllNullColumns: true).CallEntityMethod(m => m.LastModify()).ExecuteCommandAsync();
|
||||
if (!(isOk > 0)) throw Oops.Oh(ErrorCode.COM1000);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 新增.
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("save")]
|
||||
public async Task Create([FromBody] ScreenDataSourceCrInput input)
|
||||
{
|
||||
VisualDBEntity? entity = input.Adapt<VisualDBEntity>();
|
||||
int isOk = await _visualDBRepository.AsInsertable(entity).IgnoreColumns(ignoreNullColumn: true).CallEntityMethod(m => m.Create()).ExecuteCommandAsync();
|
||||
if (!(isOk > 0)) throw Oops.Oh(ErrorCode.COM1000);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 修改.
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("update")]
|
||||
public async Task Update([FromBody] ScreenDataSourceUpInput input)
|
||||
{
|
||||
VisualDBEntity? entity = input.Adapt<VisualDBEntity>();
|
||||
int isOk = await _visualDBRepository.AsUpdateable(entity).IgnoreColumns(ignoreAllNullColumns: true).CallEntityMethod(m => m.LastModify()).ExecuteCommandAsync();
|
||||
if (!(isOk > 0)) throw Oops.Oh(ErrorCode.COM1001);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpPost("remove")]
|
||||
public async Task Delete(string ids)
|
||||
{
|
||||
VisualDBEntity? entity = await _visualDBRepository.AsQueryable().FirstAsync(v => v.Id == ids && v.IsDeleted == 0);
|
||||
_ = entity ?? throw Oops.Oh(ErrorCode.COM1005);
|
||||
int isOk = await _visualDBRepository.AsUpdateable(entity).CallEntityMethod(m => m.Delete()).UpdateColumns(it => new { it.IsDeleted }).ExecuteCommandAsync();
|
||||
if (!(isOk > 0)) throw Oops.Oh(ErrorCode.COM1002);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 数据源测试连接.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpPost("db-test")]
|
||||
public dynamic Test([FromBody] ScreenDataSourceUpInput input)
|
||||
{
|
||||
if (input.id == null)
|
||||
input.id = YitIdHelper.NextId().ToString();
|
||||
|
||||
_sqlSugarClient.AsTenant().AddConnection(new ConnectionConfig()
|
||||
{
|
||||
ConfigId = input.id,
|
||||
DbType = ToDbTytpe(input.driverClass),
|
||||
ConnectionString = ToConnectionString(input.driverClass, input.url, input.username, input.password),
|
||||
InitKeyType = InitKeyType.Attribute,
|
||||
IsAutoCloseConnection = true
|
||||
});
|
||||
_sqlSugarClient = _sqlSugarClient.AsTenant().GetConnectionScope(input.id);
|
||||
if (_sqlSugarClient.Ado.IsValidConnection())
|
||||
return Task.FromResult(true);
|
||||
else
|
||||
throw Oops.Oh(ErrorCode.D1507);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 动态执行SQL.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpPost("dynamic-query")]
|
||||
public async Task<dynamic> Query([FromBody] ScreenDataSourceDynamicQueryInput input)
|
||||
{
|
||||
if (input.sql.IsNullOrEmpty()) throw Oops.Oh(ErrorCode.D1513);
|
||||
if (!string.IsNullOrWhiteSpace(input.id))
|
||||
{
|
||||
VisualDBEntity? entity = await _visualDBRepository.AsQueryable().FirstAsync(v => v.Id == input.id && v.IsDeleted == 0);
|
||||
_sqlSugarClient.AsTenant().AddConnection(new ConnectionConfig()
|
||||
{
|
||||
ConfigId = input.id,
|
||||
DbType = ToDbTytpe(entity.DriverClass),
|
||||
ConnectionString = ToConnectionString(entity.DriverClass, entity.Url, entity.UserName, entity.Password),
|
||||
InitKeyType = InitKeyType.Attribute,
|
||||
IsAutoCloseConnection = true
|
||||
});
|
||||
_sqlSugarClient = _sqlSugarClient.AsTenant().GetConnectionScope(input.id);
|
||||
|
||||
try
|
||||
{
|
||||
return await _sqlSugarClient.Ado.GetDataTableAsync(input.sql);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw Oops.Oh(ErrorCode.D1512, ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
return Task.FromResult(true);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region PrivateMethod
|
||||
|
||||
/// <summary>
|
||||
/// 转换数据库类型.
|
||||
/// </summary>
|
||||
/// <param name="dbType"></param>
|
||||
/// <returns></returns>
|
||||
private SqlSugar.DbType ToDbTytpe(string dbType)
|
||||
{
|
||||
switch (dbType)
|
||||
{
|
||||
case "org.postgresql.Driver":
|
||||
return SqlSugar.DbType.PostgreSQL;
|
||||
case "com.mysql.cj.jdbc.Driver":
|
||||
return SqlSugar.DbType.MySql;
|
||||
case "oracle.jdbc.OracleDriver":
|
||||
return SqlSugar.DbType.Oracle;
|
||||
case "com.microsoft.sqlserver.jdbc.SQLServerDriver":
|
||||
return SqlSugar.DbType.SqlServer;
|
||||
default:
|
||||
throw Oops.Oh(ErrorCode.D1505);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 转换连接字符串.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private string ToConnectionString(string driverClass, string url, string name, string password)
|
||||
{
|
||||
switch (driverClass)
|
||||
{
|
||||
case "org.postgresql.Driver":
|
||||
return string.Format(url, name, password);
|
||||
case "com.mysql.cj.jdbc.Driver":
|
||||
return string.Format(url, name, password);
|
||||
case "oracle.jdbc.OracleDriver":
|
||||
return string.Format(url, name, password);
|
||||
case "com.microsoft.sqlserver.jdbc.SQLServerDriver":
|
||||
return string.Format(url, name, password);
|
||||
default:
|
||||
throw Oops.Oh(ErrorCode.D1505);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
116
visualdev/Tnb.VisualDev/ScreenMapConfigService.cs
Normal file
116
visualdev/Tnb.VisualDev/ScreenMapConfigService.cs
Normal file
@@ -0,0 +1,116 @@
|
||||
using JNPF.Common.Enums;
|
||||
using JNPF.DependencyInjection;
|
||||
using JNPF.DynamicApiController;
|
||||
using JNPF.FriendlyException;
|
||||
using JNPF.VisualData.Entity;
|
||||
using JNPF.VisualData.Entitys.Dto.ScreenMap;
|
||||
using Mapster;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using SqlSugar;
|
||||
using Yitter.IdGenerator;
|
||||
|
||||
namespace JNPF.VisualData;
|
||||
|
||||
/// <summary>
|
||||
/// 业务实现:大屏地图.
|
||||
/// </summary>
|
||||
[ApiDescriptionSettings(Tag = "BladeVisual", Name = "Map", Order = 160)]
|
||||
[Route("api/blade-visual/[controller]")]
|
||||
public class ScreenMapConfigService : IDynamicApiController, ITransient
|
||||
{
|
||||
/// <summary>
|
||||
/// 服务基础仓储.
|
||||
/// </summary>
|
||||
private readonly ISqlSugarRepository<VisualMapEntity> _visualMapRepository;
|
||||
|
||||
/// <summary>
|
||||
/// 初始化一个<see cref="ScreenMapConfigService"/>类型的新实例.
|
||||
/// </summary>
|
||||
public ScreenMapConfigService(ISqlSugarRepository<VisualMapEntity> visualMapRepository)
|
||||
{
|
||||
_visualMapRepository = visualMapRepository;
|
||||
}
|
||||
|
||||
#region Get
|
||||
|
||||
/// <summary>
|
||||
/// 分页.
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("list")]
|
||||
public async Task<dynamic> GetList([FromQuery] ScreenMapListQueryInput input)
|
||||
{
|
||||
SqlSugarPagedList<ScreenMapListOutput>? data = await _visualMapRepository.AsQueryable().Select(v => new ScreenMapListOutput { id = v.Id, name = v.Name }).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 };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 详情
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("detail")]
|
||||
public async Task<dynamic> GetInfo([FromQuery] string id)
|
||||
{
|
||||
VisualMapEntity? entity = await _visualMapRepository.AsQueryable().FirstAsync(v => v.Id == id);
|
||||
return entity.Adapt<ScreenMapInfoOutput>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 数据详情.
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
[NonUnify]
|
||||
[HttpGet("data")]
|
||||
public dynamic GetDataInfo(string id)
|
||||
{
|
||||
VisualMapEntity? entity = _visualMapRepository.AsQueryable().First(v => v.Id == id);
|
||||
return entity.data;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Post
|
||||
|
||||
/// <summary>
|
||||
/// 新增.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpPost("save")]
|
||||
public async Task Create([FromBody] ScreenMapCrInput input)
|
||||
{
|
||||
VisualMapEntity? entity = input.Adapt<VisualMapEntity>();
|
||||
entity.Id = YitIdHelper.NextId().ToString();
|
||||
int isOk = await _visualMapRepository.AsInsertable(entity).IgnoreColumns(ignoreNullColumn: true).ExecuteCommandAsync();
|
||||
if (!(isOk > 0)) throw Oops.Oh(ErrorCode.COM1000);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 修改.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpPost("update")]
|
||||
public async Task Update([FromBody] ScreenMapUpInput input)
|
||||
{
|
||||
VisualMapEntity? entity = input.Adapt<VisualMapEntity>();
|
||||
int isOk = await _visualMapRepository.AsUpdateable(entity).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
|
||||
if (!(isOk > 0)) throw Oops.Oh(ErrorCode.COM1001);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpPost("remove")]
|
||||
public async Task Delete(string ids)
|
||||
{
|
||||
Task<VisualMapEntity>? entity = _visualMapRepository.AsQueryable().FirstAsync(v => v.Id == ids);
|
||||
_ = entity ?? throw Oops.Oh(ErrorCode.COM1005);
|
||||
int isOk = await _visualMapRepository.AsDeleteable().Where(it => ids.Contains(it.Id)).ExecuteCommandAsync();
|
||||
if (!(isOk > 0)) throw Oops.Oh(ErrorCode.COM1002);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
322
visualdev/Tnb.VisualDev/ScreenService.cs
Normal file
322
visualdev/Tnb.VisualDev/ScreenService.cs
Normal file
@@ -0,0 +1,322 @@
|
||||
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;
|
||||
|
||||
/// <summary>
|
||||
/// 业务实现:大屏.
|
||||
/// </summary>
|
||||
[ApiDescriptionSettings(Tag = "BladeVisual", Name = "Visual", Order = 160)]
|
||||
[Route("api/blade-visual/[controller]")]
|
||||
public class ScreenService : IDynamicApiController, ITransient
|
||||
{
|
||||
/// <summary>
|
||||
/// 服务基础仓储.
|
||||
/// </summary>
|
||||
private readonly ISqlSugarRepository<VisualEntity> _visualRepository;
|
||||
|
||||
/// <summary>
|
||||
/// 多租户事务.
|
||||
/// </summary>
|
||||
private readonly ITenant _db;
|
||||
|
||||
/// <summary>
|
||||
/// 初始化一个<see cref="ScreenService"/>类型的新实例.
|
||||
/// </summary>
|
||||
public ScreenService(
|
||||
ISqlSugarRepository<VisualEntity> visualRepository,
|
||||
ISqlSugarClient context)
|
||||
{
|
||||
_visualRepository = visualRepository;
|
||||
_db = context.AsTenant();
|
||||
}
|
||||
|
||||
#region Get
|
||||
|
||||
/// <summary>
|
||||
/// 分页.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpGet("list")]
|
||||
public async Task<dynamic> GetList([FromQuery] ScreenListQueryInput input)
|
||||
{
|
||||
input.category = input.category == null ? 1 : input.category;
|
||||
SqlSugarPagedList<ScreenListOutput>? 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 };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 详情.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpGet("detail")]
|
||||
public async Task<dynamic> GetInfo([FromQuery] string id)
|
||||
{
|
||||
VisualEntity? entity = await _visualRepository.AsQueryable().FirstAsync(v => v.Id == id);
|
||||
VisualConfigEntity? configEntity = await _visualRepository.AsSugarClient().Queryable<VisualConfigEntity>().FirstAsync(v => v.VisualId == id);
|
||||
return new { config = configEntity.Adapt<ScreenConfigInfoOutput>(), visual = entity.Adapt<ScreenInfoOutput>() };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取类型.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpGet("category")]
|
||||
public async Task<dynamic> GetCategoryList()
|
||||
{
|
||||
VisualCategoryEntity? entity = await _visualRepository.AsSugarClient().Queryable<VisualCategoryEntity>().FirstAsync(v => v.IsDeleted == 0);
|
||||
return entity.Adapt<ScreenCategoryListOutput>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取图片列表.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpGet("{type}")]
|
||||
public dynamic GetImgFileList(string type)
|
||||
{
|
||||
List<ScreenImgFileOutput>? list = new List<ScreenImgFileOutput>();
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查看图片.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 大屏下拉框.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpGet("selector")]
|
||||
public async Task<dynamic> GetSelector()
|
||||
{
|
||||
List<ScreenSelectorOuput>? 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<ScreenSelectorOuput>? categortList = await _visualRepository.AsSugarClient().Queryable<VisualCategoryEntity>().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
|
||||
|
||||
/// <summary>
|
||||
/// 新增.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpPost("save")]
|
||||
public async Task<dynamic> Save([FromBody] ScreenCrInput input)
|
||||
{
|
||||
VisualEntity? entity = input.visual.Adapt<VisualEntity>();
|
||||
VisualConfigEntity? configEntity = input.config.Adapt<VisualConfigEntity>();
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 修改.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[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<VisualEntity>();
|
||||
}
|
||||
|
||||
VisualConfigEntity? configEntity = input.config.Adapt<VisualConfigEntity>();
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 逻辑删除.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[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();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 复制.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpPost("copy")]
|
||||
[NonUnify]
|
||||
[UnitOfWork]
|
||||
public async Task<dynamic> Copy(string id)
|
||||
{
|
||||
VisualEntity? entity = await _visualRepository.AsQueryable().FirstAsync(v => v.Id == id);
|
||||
VisualConfigEntity? configEntity = await _visualRepository.AsSugarClient().Queryable<VisualConfigEntity>().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 };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 上传文件.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpPost("put-file/{type}"), AllowAnonymous, IgnoreLog]
|
||||
public async Task<dynamic> 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
|
||||
|
||||
/// <summary>
|
||||
/// 允许文件类型.
|
||||
/// </summary>
|
||||
/// <param name="fileExtension">文件后缀名.</param>
|
||||
/// <returns></returns>
|
||||
private bool AllowImageType(string fileExtension)
|
||||
{
|
||||
List<string>? allowExtension = KeyVariable.AllowImageType;
|
||||
string? isExist = allowExtension.Find(a => a == fileExtension.ToLower());
|
||||
if (!string.IsNullOrEmpty(isExist))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
21
visualdev/Tnb.VisualDev/Tnb.VisualDev.csproj
Normal file
21
visualdev/Tnb.VisualDev/Tnb.VisualDev.csproj
Normal file
@@ -0,0 +1,21 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Import Project="$(SolutionDir)\common.props" />
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<GenerateDocumentationFile>True</GenerateDocumentationFile>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\common\Tnb.Common.Core\Tnb.Common.Core.csproj" />
|
||||
<ProjectReference Include="..\..\extend\Tnb.Extend.Interfaces\Tnb.Extend.Interfaces.csproj" />
|
||||
<ProjectReference Include="..\..\message\Tnb.Message.Interfaces\Tnb.Message.Interfaces.csproj" />
|
||||
<ProjectReference Include="..\..\system\Tnb.Systems.Interfaces\Tnb.Systems.Interfaces.csproj" />
|
||||
<ProjectReference Include="..\..\workflow\Tnb.WorkFlow.Interfaces\Tnb.WorkFlow.Interfaces.csproj" />
|
||||
<ProjectReference Include="..\Tnb.VisualDev.Engine\Tnb.VisualDev.Engine.csproj" />
|
||||
<ProjectReference Include="..\Tnb.VisualDev.Interfaces\Tnb.VisualDev.Interfaces.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
2864
visualdev/Tnb.VisualDev/VisualDevModelDataService.cs
Normal file
2864
visualdev/Tnb.VisualDev/VisualDevModelDataService.cs
Normal file
File diff suppressed because it is too large
Load Diff
1986
visualdev/Tnb.VisualDev/VisualDevService.cs
Normal file
1986
visualdev/Tnb.VisualDev/VisualDevService.cs
Normal file
File diff suppressed because it is too large
Load Diff
488
visualdev/Tnb.VisualDev/VisualdevModelAppService.cs
Normal file
488
visualdev/Tnb.VisualDev/VisualdevModelAppService.cs
Normal file
@@ -0,0 +1,488 @@
|
||||
using JNPF.Common.Configuration;
|
||||
using JNPF.Common.Core.Manager;
|
||||
using JNPF.Common.Core.Manager.Files;
|
||||
using JNPF.Common.Dtos.VisualDev;
|
||||
using JNPF.Common.Enums;
|
||||
using JNPF.Common.Extension;
|
||||
using JNPF.Common.Filter;
|
||||
using JNPF.Common.Models.NPOI;
|
||||
using JNPF.Common.Security;
|
||||
using JNPF.DatabaseAccessor;
|
||||
using JNPF.DataEncryption;
|
||||
using JNPF.DependencyInjection;
|
||||
using JNPF.DynamicApiController;
|
||||
using JNPF.FriendlyException;
|
||||
using JNPF.VisualDev.Engine;
|
||||
using JNPF.VisualDev.Engine.Core;
|
||||
using JNPF.VisualDev.Engine.Security;
|
||||
using JNPF.VisualDev.Entitys;
|
||||
using JNPF.VisualDev.Entitys.Dto.VisualDevModelData;
|
||||
using JNPF.VisualDev.Interfaces;
|
||||
using Mapster;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Yitter.IdGenerator;
|
||||
|
||||
namespace JNPF.VisualDev;
|
||||
|
||||
/// <summary>
|
||||
/// 可视化开发APP基础.
|
||||
/// </summary>
|
||||
[ApiDescriptionSettings(Tag = "VisualDev", Name = "App", Order = 175)]
|
||||
[Route("api/visualdev/OnlineDev/[controller]")]
|
||||
public class VisualdevModelAppService : IDynamicApiController, ITransient
|
||||
{
|
||||
/// <summary>
|
||||
/// 可视化开发基础.
|
||||
/// </summary>
|
||||
private readonly IVisualDevService _visualDevService;
|
||||
|
||||
/// <summary>
|
||||
/// 在线开发运行服务.
|
||||
/// </summary>
|
||||
private readonly IRunService _runService;
|
||||
|
||||
/// <summary>
|
||||
/// 用户管理.
|
||||
/// </summary>
|
||||
private readonly IUserManager _userManager;
|
||||
|
||||
/// <summary>
|
||||
/// 文件服务.
|
||||
/// </summary>
|
||||
private readonly IFileManager _fileManager;
|
||||
|
||||
/// <summary>
|
||||
/// 初始化一个<see cref="VisualdevModelAppService"/>类型的新实例.
|
||||
/// </summary>
|
||||
public VisualdevModelAppService(
|
||||
IVisualDevService visualDevService,
|
||||
IRunService runService,
|
||||
IUserManager userManager,
|
||||
IFileManager fileManager)
|
||||
{
|
||||
_visualDevService = visualDevService;
|
||||
_runService = runService;
|
||||
_userManager = userManager;
|
||||
_fileManager = fileManager;
|
||||
}
|
||||
|
||||
#region Get
|
||||
|
||||
/// <summary>
|
||||
/// 获取列表表单配置JSON.
|
||||
/// </summary>
|
||||
/// <param name="modelId">主键id.</param>
|
||||
/// <param name="type">1 线上版本, 0 草稿版本.</param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("{modelId}/Config")]
|
||||
[NonUnify]
|
||||
public async Task<dynamic> GetData(string modelId, string type)
|
||||
{
|
||||
if (type.IsNullOrEmpty()) type = "1";
|
||||
VisualDevEntity? data = await _visualDevService.GetInfoById(modelId, type.Equals("1"));
|
||||
if (data == null) return new { code = 400, msg = "未找到该模板!" };
|
||||
if (data.EnableFlow.Equals(1) && data.FlowId.IsNullOrWhiteSpace()) return new { code = 400, msg = "该流程功能未绑定流程!" };
|
||||
if (data.WebType.Equals(1) && data.FormData.IsNullOrWhiteSpace()) return new { code = 400, msg = "该模板内表单内容为空,无法预览!" };
|
||||
else if (data.WebType.Equals(2) && data.ColumnData.IsNullOrWhiteSpace()) return new { code = 400, msg = "该模板内列表内容为空,无法预览!" };
|
||||
return new { code = 200, data = data.Adapt<VisualDevModelDataConfigOutput>() };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取列表配置JSON.
|
||||
/// </summary>
|
||||
/// <param name="modelId">主键id.</param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("{modelId}/ColumnData")]
|
||||
public async Task<dynamic> GetColumnData(string modelId)
|
||||
{
|
||||
VisualDevEntity? data = await _visualDevService.GetInfoById(modelId);
|
||||
return new { columnData = data.ColumnData };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取列表配置JSON.
|
||||
/// </summary>
|
||||
/// <param name="modelId">主键id.</param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("{modelId}/FormData")]
|
||||
public async Task<dynamic> GetFormData(string modelId)
|
||||
{
|
||||
VisualDevEntity? data = await _visualDevService.GetInfoById(modelId);
|
||||
return new { formData = data.FormData };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取列表配置JSON.
|
||||
/// </summary>
|
||||
/// <param name="modelId">主键id.</param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("{modelId}/FlowTemplate")]
|
||||
public async Task<dynamic> GetFlowTemplate(string modelId)
|
||||
{
|
||||
VisualDevEntity? data = await _visualDevService.GetInfoById(modelId);
|
||||
return new { flowTemplateJson = data.FlowTemplateJson };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取数据信息.
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <param name="modelId"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("{modelId}/{id}")]
|
||||
public async Task<dynamic> GetInfo(string id, string modelId)
|
||||
{
|
||||
VisualDevEntity? templateEntity = await _visualDevService.GetInfoById(modelId, true); // 模板实体
|
||||
if (!string.IsNullOrEmpty(templateEntity.Tables) && !"[]".Equals(templateEntity.Tables))
|
||||
return new { id = id, data = (await _runService.GetHaveTableInfo(id, templateEntity)).ToJsonString() }; // 有表
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取详情.
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <param name="modelId"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("{modelId}/{id}/DataChange")]
|
||||
public async Task<dynamic> GetDetails(string id, string modelId)
|
||||
{
|
||||
VisualDevEntity? templateEntity = await _visualDevService.GetInfoById(modelId, true); // 模板实体
|
||||
|
||||
if (!string.IsNullOrEmpty(templateEntity.Tables) && !"[]".Equals(templateEntity.Tables))
|
||||
return new { id = id, data = await _runService.GetHaveTableInfoDetails(id, templateEntity) }; // 有表
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Post
|
||||
|
||||
/// <summary>
|
||||
/// 功能导出.
|
||||
/// </summary>
|
||||
/// <param name="modelId"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("{modelId}/Actions/ExportData")]
|
||||
public async Task<dynamic> ActionsExportData(string modelId)
|
||||
{
|
||||
VisualDevEntity? templateEntity = await _visualDevService.GetInfoById(modelId); // 模板实体
|
||||
if (templateEntity.State.Equals(1))
|
||||
{
|
||||
var vREntity = await _visualDevService.GetInfoById(modelId, true);
|
||||
templateEntity = vREntity.Adapt<VisualDevEntity>();
|
||||
templateEntity.State = 0;
|
||||
}
|
||||
string? jsonStr = templateEntity.ToJsonString();
|
||||
return await _fileManager.Export(jsonStr, templateEntity.FullName, ExportFileType.va);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 导入.
|
||||
/// </summary>
|
||||
/// <param name="file"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("Model/Actions/ImportData")]
|
||||
public async Task ActionsActionsImport(IFormFile file)
|
||||
{
|
||||
string? fileType = Path.GetExtension(file.FileName).Replace(".", string.Empty);
|
||||
if (!fileType.ToLower().Equals(ExportFileType.va.ToString())) throw Oops.Oh(ErrorCode.D3006);
|
||||
string? josn = _fileManager.Import(file);
|
||||
VisualDevEntity? templateEntity;
|
||||
try
|
||||
{
|
||||
templateEntity = josn.ToObject<VisualDevEntity>();
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw Oops.Oh(ErrorCode.D3006);
|
||||
}
|
||||
|
||||
if (templateEntity == null || templateEntity.Type.IsNullOrEmpty()) throw Oops.Oh(ErrorCode.D3006);
|
||||
else if (templateEntity.Type != 2) throw Oops.Oh(ErrorCode.D3009);
|
||||
if (await _visualDevService.GetDataExists(templateEntity.EnCode, templateEntity.FullName))
|
||||
throw Oops.Oh(ErrorCode.D1400);
|
||||
await _visualDevService.CreateImportData(templateEntity);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取数据列表.
|
||||
/// </summary>
|
||||
/// <param name="modelId">主键id.</param>
|
||||
/// <param name="input">分页查询条件.</param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("{modelId}/List")]
|
||||
public async Task<dynamic> List(string modelId, [FromBody] VisualDevModelListQueryInput input)
|
||||
{
|
||||
VisualDevEntity? templateEntity = await _visualDevService.GetInfoById(modelId, true);
|
||||
return await _runService.GetListResult(templateEntity, input);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建数据.
|
||||
/// </summary>
|
||||
/// <param name="modelId"></param>
|
||||
/// <param name="visualdevModelDataCrForm"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("{modelId}")]
|
||||
public async Task Create(string modelId, [FromBody] VisualDevModelDataCrInput visualdevModelDataCrForm)
|
||||
{
|
||||
VisualDevEntity? templateEntity = await _visualDevService.GetInfoById(modelId, true);
|
||||
await _runService.Create(templateEntity, visualdevModelDataCrForm);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 修改数据.
|
||||
/// </summary>
|
||||
/// <param name="modelId"></param>
|
||||
/// <param name="id"></param>
|
||||
/// <param name="visualdevModelDataUpForm"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPut("{modelId}/{id}")]
|
||||
public async Task Update(string modelId, string id, [FromBody] VisualDevModelDataUpInput visualdevModelDataUpForm)
|
||||
{
|
||||
VisualDevEntity? templateEntity = await _visualDevService.GetInfoById(modelId, true);
|
||||
await _runService.Update(id, templateEntity, visualdevModelDataUpForm);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除数据.
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <param name="modelId"></param>
|
||||
/// <returns></returns>
|
||||
[HttpDelete("{modelId}/{id}")]
|
||||
public async Task Delete(string id, string modelId)
|
||||
{
|
||||
VisualDevEntity? templateEntity = await _visualDevService.GetInfoById(modelId, true);
|
||||
if (!string.IsNullOrEmpty(templateEntity.Tables) && !"[]".Equals(templateEntity.Tables))
|
||||
await _runService.DelHaveTableInfo(id, templateEntity);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 批量删除.
|
||||
/// </summary>
|
||||
/// <param name="modelId"></param>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("batchDelete/{modelId}")]
|
||||
public async Task BatchDelete(string modelId, [FromBody] VisualDevModelDataBatchDelInput input)
|
||||
{
|
||||
VisualDevEntity? templateEntity = await _visualDevService.GetInfoById(modelId, true);
|
||||
if (!string.IsNullOrEmpty(templateEntity.Tables) && !"[]".Equals(templateEntity.Tables))
|
||||
await _runService.BatchDelHaveTableData(input.ids, templateEntity);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 导出.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpPost("{modelId}/Actions/Export")]
|
||||
public async Task<dynamic> Export(string modelId, [FromBody] VisualDevModelListQueryInput input)
|
||||
{
|
||||
VisualDevEntity? templateEntity = await _visualDevService.GetInfoById(modelId, true);
|
||||
List<VisualDevModelDataEntity> list = new List<VisualDevModelDataEntity>();
|
||||
PageResult<Dictionary<string, object>>? pageList = await _runService.GetListResult(templateEntity, input);
|
||||
|
||||
#region 如果是 分组表格 模板
|
||||
|
||||
ColumnDesignModel? ColumnData = templateEntity.ColumnData.ToObject<ColumnDesignModel>(); // 列配置模型
|
||||
if (ColumnData.type == 3)
|
||||
{
|
||||
List<Dictionary<string, object>>? newValueList = new List<Dictionary<string, object>>();
|
||||
pageList.list.ForEach(item =>
|
||||
{
|
||||
List<Dictionary<string, object>>? tt = item["children"].ToJsonString().ToObject<List<Dictionary<string, object>>>();
|
||||
newValueList.AddRange(tt);
|
||||
});
|
||||
pageList.list = newValueList;
|
||||
}
|
||||
#endregion
|
||||
|
||||
List<Dictionary<string, object>> realList = pageList.list.Copy();
|
||||
var templateInfo = new TemplateParsingBase(templateEntity);
|
||||
var res = GetCreateFirstColumnsHeader(input.selectKey, realList, templateInfo);
|
||||
var firstColumns = res.First().ToObject<Dictionary<string, int>>();
|
||||
var resultList = res.Last().ToObject<List<Dictionary<string, object>>>();
|
||||
var newResultList = new List<Dictionary<string, object>>();
|
||||
resultList.ForEach(row =>
|
||||
{
|
||||
foreach (var item in input.selectKey)
|
||||
{
|
||||
if (row[item].IsNotEmptyOrNull())
|
||||
{
|
||||
newResultList.Add(row);
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
return firstColumns.Any() ? await ExcelCreateModel(templateInfo, resultList, input.selectKey, null, firstColumns) : await ExcelCreateModel(templateInfo, resultList, input.selectKey);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region PublicMethod
|
||||
|
||||
/// <summary>
|
||||
/// Excel 转输出 Model.
|
||||
/// </summary>
|
||||
/// <param name="templateInfo">模板.</param>
|
||||
/// <param name="realList">数据列表.</param>
|
||||
/// <param name="keys"></param>
|
||||
/// <param name="excelName">导出文件名称.</param>
|
||||
/// <param name="firstColumns">手动输入第一行(合并主表列和各个子表列).</param>
|
||||
/// <returns>VisualDevModelDataExportOutput.</returns>
|
||||
public async Task<VisualDevModelDataExportOutput> ExcelCreateModel(TemplateParsingBase templateInfo, List<Dictionary<string, object>> realList, List<string> keys, string excelName = null, Dictionary<string, int> firstColumns = null)
|
||||
{
|
||||
List<ExcelTemplateModel> templateList = new List<ExcelTemplateModel>();
|
||||
VisualDevModelDataExportOutput output = new VisualDevModelDataExportOutput();
|
||||
List<string> columnList = new List<string>();
|
||||
try
|
||||
{
|
||||
ExcelConfig excelconfig = new ExcelConfig();
|
||||
excelconfig.FileName = (excelName.IsNullOrEmpty() ? SnowflakeIdHelper.NextId() : excelName) + ".xls";
|
||||
excelconfig.HeadFont = "微软雅黑";
|
||||
excelconfig.HeadPoint = 10;
|
||||
excelconfig.IsAllSizeColumn = true;
|
||||
excelconfig.ColumnModel = new List<ExcelColumnModel>();
|
||||
foreach (string? item in keys)
|
||||
{
|
||||
FieldsModel? excelColumn = templateInfo.AllFieldsModel.Find(t => t.__vModel__ == item);
|
||||
if (excelColumn != null)
|
||||
{
|
||||
excelconfig.ColumnModel.Add(new ExcelColumnModel() { Column = item, ExcelColumn = excelColumn.__config__.label });
|
||||
columnList.Add(excelColumn.__config__.label);
|
||||
}
|
||||
}
|
||||
|
||||
string? addPath = Path.Combine(FileVariable.TemporaryFilePath, excelconfig.FileName);
|
||||
var fs = firstColumns == null ? ExcelExportHelper<Dictionary<string, object>>.ExportMemoryStream(realList, excelconfig, columnList) : ExcelExportHelper<Dictionary<string, object>>.ExportMemoryStream(realList, excelconfig, columnList, firstColumns);
|
||||
var flag = await _fileManager.UploadFileByType(fs, FileVariable.TemporaryFilePath, excelconfig.FileName);
|
||||
if (flag)
|
||||
{
|
||||
fs.Flush();
|
||||
fs.Close();
|
||||
}
|
||||
output.name = excelconfig.FileName;
|
||||
output.url = "/api/file/Download?encryption=" + DESCEncryption.Encrypt(_userManager.UserId + "|" + excelconfig.FileName + "|" + addPath, "JNPF");
|
||||
return output;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 组装导出带子表得数据,返回 第一个合并行标头,第二个导出数据.
|
||||
/// </summary>
|
||||
/// <param name="selectKey">导出选择列.</param>
|
||||
/// <param name="realList">原数据集合.</param>
|
||||
/// <param name="templateInfo">模板信息.</param>
|
||||
/// <returns>第一行标头 , 导出数据.</returns>
|
||||
public object[] GetCreateFirstColumnsHeader(List<string> selectKey, List<Dictionary<string, object>> realList, TemplateParsingBase templateInfo)
|
||||
{
|
||||
selectKey.ForEach(item =>
|
||||
{
|
||||
realList.ForEach(it =>
|
||||
{
|
||||
if (!it.ContainsKey(item)) it.Add(item, string.Empty);
|
||||
});
|
||||
});
|
||||
|
||||
var newRealList = realList.Copy();
|
||||
|
||||
realList.ForEach(items =>
|
||||
{
|
||||
var rowChildDatas = new Dictionary<string, List<Dictionary<string, object>>>();
|
||||
foreach (var item in items)
|
||||
{
|
||||
if (item.Value != null && item.Key.ToLower().Contains("tablefield") && item.Value is List<Dictionary<string, object>>)
|
||||
{
|
||||
var ctList = item.Value.ToObject<List<Dictionary<string, object>>>();
|
||||
rowChildDatas.Add(item.Key, ctList);
|
||||
}
|
||||
}
|
||||
|
||||
var len = rowChildDatas.Select(x => x.Value.Count()).OrderByDescending(x => x).FirstOrDefault();
|
||||
|
||||
if (len != null && len > 0)
|
||||
{
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
if (i == 0)
|
||||
{
|
||||
var newRealItem = newRealList.Find(x => x["id"].Equals(items["id"]));
|
||||
foreach (var cData in rowChildDatas)
|
||||
{
|
||||
var itemData = cData.Value.FirstOrDefault();
|
||||
if (itemData != null)
|
||||
{
|
||||
foreach (var key in itemData)
|
||||
if (newRealItem.ContainsKey(cData.Key + "-" + key.Key)) newRealItem[cData.Key + "-" + key.Key] = key.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var newRealItem = new Dictionary<string, object>();
|
||||
foreach (var it in items)
|
||||
{
|
||||
if (it.Key.Equals("id")) newRealItem.Add(it.Key, it.Value);
|
||||
else newRealItem.Add(it.Key, string.Empty);
|
||||
}
|
||||
foreach (var cData in rowChildDatas)
|
||||
{
|
||||
if (cData.Value.Count > i)
|
||||
{
|
||||
foreach (var it in cData.Value[i])
|
||||
if (newRealItem.ContainsKey(cData.Key + "-" + it.Key)) newRealItem[cData.Key + "-" + it.Key] = it.Value;
|
||||
}
|
||||
}
|
||||
newRealList.Add(newRealItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var resultList = new List<Dictionary<string, object>>();
|
||||
|
||||
newRealList.ForEach(newRealItem =>
|
||||
{
|
||||
if (!resultList.Any(x => x["id"].Equals(newRealItem["id"]))) resultList.AddRange(newRealList.Where(x => x["id"].Equals(newRealItem["id"])).ToList());
|
||||
});
|
||||
|
||||
var firstColumns = new Dictionary<string, int>();
|
||||
|
||||
if (selectKey.Any(x => x.Contains("-") && x.Contains("tableField")))
|
||||
{
|
||||
var empty = string.Empty;
|
||||
var keyList = selectKey.Select(x => x.Split("-").First()).Distinct().ToList();
|
||||
var mainFieldIndex = 1;
|
||||
keyList.ForEach(item =>
|
||||
{
|
||||
if (item.Contains("tableField"))
|
||||
{
|
||||
var title = templateInfo.AllFieldsModel.FirstOrDefault(x => x.__vModel__.Equals(item))?.__config__.label;
|
||||
firstColumns.Add(title + empty, selectKey.Count(x => x.Contains(item)));
|
||||
empty += " ";
|
||||
mainFieldIndex = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mainFieldIndex == 1) empty += " ";
|
||||
if (!firstColumns.ContainsKey(empty)) firstColumns.Add(empty, mainFieldIndex);
|
||||
else firstColumns[empty] = mainFieldIndex;
|
||||
mainFieldIndex++;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return new object[] { firstColumns, resultList };
|
||||
}
|
||||
#endregion
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user