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;
///
/// 可视化开发APP基础.
///
[ApiDescriptionSettings(Tag = "VisualDev", Name = "App", Order = 175)]
[Route("api/visualdev/OnlineDev/[controller]")]
public class VisualdevModelAppService : IDynamicApiController, ITransient
{
///
/// 可视化开发基础.
///
private readonly IVisualDevService _visualDevService;
///
/// 在线开发运行服务.
///
private readonly IRunService _runService;
///
/// 用户管理.
///
private readonly IUserManager _userManager;
///
/// 文件服务.
///
private readonly IFileManager _fileManager;
///
/// 初始化一个类型的新实例.
///
public VisualdevModelAppService(
IVisualDevService visualDevService,
IRunService runService,
IUserManager userManager,
IFileManager fileManager)
{
_visualDevService = visualDevService;
_runService = runService;
_userManager = userManager;
_fileManager = fileManager;
}
#region Get
///
/// 获取列表表单配置JSON.
///
/// 主键id.
/// 1 线上版本, 0 草稿版本.
///
[HttpGet("{modelId}/Config")]
[NonUnify]
public async Task 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() };
}
///
/// 获取列表配置JSON.
///
/// 主键id.
///
[HttpGet("{modelId}/ColumnData")]
public async Task GetColumnData(string modelId)
{
VisualDevEntity? data = await _visualDevService.GetInfoById(modelId);
return new { columnData = data.ColumnData };
}
///
/// 获取列表配置JSON.
///
/// 主键id.
///
[HttpGet("{modelId}/FormData")]
public async Task GetFormData(string modelId)
{
VisualDevEntity? data = await _visualDevService.GetInfoById(modelId);
return new { formData = data.FormData };
}
///
/// 获取列表配置JSON.
///
/// 主键id.
///
[HttpGet("{modelId}/FlowTemplate")]
public async Task GetFlowTemplate(string modelId)
{
VisualDevEntity? data = await _visualDevService.GetInfoById(modelId);
return new { flowTemplateJson = data.FlowTemplateJson };
}
///
/// 获取数据信息.
///
///
///
///
[HttpGet("{modelId}/{id}")]
public async Task 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;
}
///
/// 获取详情.
///
///
///
///
[HttpGet("{modelId}/{id}/DataChange")]
public async Task 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
///
/// 功能导出.
///
///
///
[HttpPost("{modelId}/Actions/ExportData")]
public async Task ActionsExportData(string modelId)
{
VisualDevEntity? templateEntity = await _visualDevService.GetInfoById(modelId); // 模板实体
if (templateEntity.State.Equals(1))
{
var vREntity = await _visualDevService.GetInfoById(modelId, true);
templateEntity = vREntity.Adapt();
templateEntity.State = 0;
}
string? jsonStr = templateEntity.ToJsonString();
return await _fileManager.Export(jsonStr, templateEntity.FullName, ExportFileType.va);
}
///
/// 导入.
///
///
///
[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();
}
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);
}
///
/// 获取数据列表.
///
/// 主键id.
/// 分页查询条件.
///
[HttpPost("{modelId}/List")]
public async Task List(string modelId, [FromBody] VisualDevModelListQueryInput input)
{
VisualDevEntity? templateEntity = await _visualDevService.GetInfoById(modelId, true);
return await _runService.GetListResult(templateEntity, input);
}
///
/// 创建数据.
///
///
///
///
[HttpPost("{modelId}")]
public async Task Create(string modelId, [FromBody] VisualDevModelDataCrInput visualdevModelDataCrForm)
{
VisualDevEntity? templateEntity = await _visualDevService.GetInfoById(modelId, true);
await _runService.Create(templateEntity, visualdevModelDataCrForm);
}
///
/// 修改数据.
///
///
///
///
///
[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);
}
///
/// 删除数据.
///
///
///
///
[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);
}
///
/// 批量删除.
///
///
///
///
[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);
}
///
/// 导出.
///
///
[HttpPost("{modelId}/Actions/Export")]
public async Task Export(string modelId, [FromBody] VisualDevModelListQueryInput input)
{
VisualDevEntity? templateEntity = await _visualDevService.GetInfoById(modelId, true);
List list = new List();
PageResult>? pageList = await _runService.GetListResult(templateEntity, input);
#region 如果是 分组表格 模板
ColumnDesignModel? ColumnData = templateEntity.ColumnData.ToObject(); // 列配置模型
if (ColumnData.type == 3)
{
List>? newValueList = new List>();
pageList.list.ForEach(item =>
{
List>? tt = item["children"].ToJsonString().ToObject>>();
newValueList.AddRange(tt);
});
pageList.list = newValueList;
}
#endregion
List> realList = pageList.list.Copy();
var templateInfo = new TemplateParsingBase(templateEntity);
var res = GetCreateFirstColumnsHeader(input.selectKey, realList, templateInfo);
var firstColumns = res.First().ToObject>();
var resultList = res.Last().ToObject>>();
var newResultList = new List>();
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
///
/// Excel 转输出 Model.
///
/// 模板.
/// 数据列表.
///
/// 导出文件名称.
/// 手动输入第一行(合并主表列和各个子表列).
/// VisualDevModelDataExportOutput.
public async Task ExcelCreateModel(TemplateParsingBase templateInfo, List> realList, List keys, string excelName = null, Dictionary firstColumns = null)
{
List templateList = new List();
VisualDevModelDataExportOutput output = new VisualDevModelDataExportOutput();
List columnList = new List();
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();
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>.ExportMemoryStream(realList, excelconfig, columnList) : ExcelExportHelper>.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;
}
}
///
/// 组装导出带子表得数据,返回 第一个合并行标头,第二个导出数据.
///
/// 导出选择列.
/// 原数据集合.
/// 模板信息.
/// 第一行标头 , 导出数据.
public object[] GetCreateFirstColumnsHeader(List selectKey, List> 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>>();
foreach (var item in items)
{
if (item.Value != null && item.Key.ToLower().Contains("tablefield") && item.Value is List>)
{
var ctList = item.Value.ToObject>>();
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();
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>();
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();
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
}