using JNPF.Common.Configuration;
using JNPF.Common.Const;
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.Helper;
using JNPF.Common.Manager;
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.Logging.Attributes;
using JNPF.RemoteRequest.Extensions;
using JNPF.Systems.Entitys.Model.DataInterFace;
using JNPF.Systems.Entitys.Permission;
using JNPF.Systems.Entitys.System;
using JNPF.Systems.Interfaces.System;
using JNPF.VisualDev.Engine;
using JNPF.VisualDev.Engine.Core;
using JNPF.VisualDev.Entitys;
using JNPF.VisualDev.Entitys.Dto.VisualDev;
using JNPF.VisualDev.Entitys.Dto.VisualDevModelData;
using JNPF.VisualDev.Interfaces;
using JNPF.WorkFlow.Entitys.Entity;
using JNPF.WorkFlow.Interfaces.Service;
using Mapster;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json.Linq;
using SqlSugar;
namespace JNPF.VisualDev
{
///
/// 可视化开发基础.
///
[ApiDescriptionSettings(Tag = "VisualDev", Name = "OnlineDev", Order = 172)]
[Route("api/visualdev/[controller]")]
public class VisualDevModelDataService : IDynamicApiController, ITransient
{
///
/// 服务基础仓储.
///
private readonly ISqlSugarRepository _visualDevRepository; // 在线开发功能实体
///
/// 可视化开发基础.
///
private readonly IVisualDevService _visualDevService;
///
/// 在线开发运行服务.
///
private readonly RunService _runService;
///
/// 单据.
///
private readonly IBillRullService _billRuleService;
///
/// 用户管理.
///
private readonly IUserManager _userManager;
///
/// 缓存管理.
///
private readonly ICacheManager _cacheManager;
///
/// 文件服务.
///
private readonly IFileManager _fileManager;
///
/// 工作流.
///
private readonly IFlowTaskService _flowTaskService;
///
/// 数据连接服务.
///
private readonly IDbLinkService _dbLinkService;
///
/// 切库.
///
private readonly IDataBaseManager _databaseService;
///
/// 数据接口.
///
private readonly IDataInterfaceService _dataInterfaceService;
///
/// 多租户事务.
///
private readonly ITenant _db;
///
/// 初始化一个类型的新实例.
///
public VisualDevModelDataService(
ISqlSugarRepository visualDevRepository,
IVisualDevService visualDevService,
RunService runService,
IDbLinkService dbLinkService,
IDataInterfaceService dataInterfaceService,
IUserManager userManager,
IDataBaseManager databaseService,
IBillRullService billRuleService,
ICacheManager cacheManager,
IFlowTaskService flowTaskService,
IFileManager fileManager,
ISqlSugarClient context)
{
_visualDevRepository = visualDevRepository;
_visualDevService = visualDevService;
_databaseService = databaseService;
_dbLinkService = dbLinkService;
_runService = runService;
_billRuleService = billRuleService;
_userManager = userManager;
_cacheManager = cacheManager;
_flowTaskService = flowTaskService;
_fileManager = fileManager;
_dataInterfaceService = dataInterfaceService;
_db = context.AsTenant();
}
#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.IsNotEmptyOrNull()) 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 = GetVisualDevModelDataConfig(data) };
}
///
/// 获取列表配置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)
{
// modified by PhilPan 2023-04-12 重写接口
var overideSvc = OverideVisualDevManager.GetOrDefault(modelId);
if (overideSvc != null && overideSvc.OverideFuncs.GetAsync != null)
{
return await overideSvc.OverideFuncs.GetAsync(id);
}
VisualDevEntity? templateEntity = await _visualDevService.GetInfoById(modelId, true); // 模板实体
// 有表
if (!string.IsNullOrEmpty(templateEntity.Tables) && !"[]".Equals(templateEntity.Tables))
// modified by PhilPan 2023-04-12 返回值不序列化成字符串
return new { id = id, data = (await _runService.GetHaveTableInfo(id, templateEntity)) };
else
return null;
}
///
/// 获取详情.
///
///
///
///
[HttpGet("{modelId}/{id}/DataChange")]
public async Task GetDetails(string id, string modelId)
{
//modified by PhilPan 2023-04-12 重写接口
var overideSvc = OverideVisualDevManager.GetOrDefault(modelId);
if (overideSvc != null && overideSvc.OverideFuncs.GetDetailsAsync != null)
{
return await overideSvc.OverideFuncs.GetDetailsAsync(id);
}
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 _visualDevRepository.AsSugarClient().Queryable().FirstAsync(v => v.Id == modelId && v.DeleteMark == null);
templateEntity = vREntity.Adapt();
templateEntity.State = 0;
}
string? jsonStr = templateEntity.ToJsonString();
return await _fileManager.Export(jsonStr, templateEntity.FullName, ExportFileType.vdd);
}
///
/// 导入.
///
///
///
[HttpPost("Model/Actions/ImportData")]
public async Task ActionsActionsImport(IFormFile file)
{
string? fileType = Path.GetExtension(file.FileName).Replace(".", string.Empty);
if (!fileType.ToLower().Equals(ExportFileType.vdd.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 != 1) 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)
{
//modified by PhilPan 2023-04-12 重写接口
var overideSvc = OverideVisualDevManager.GetOrDefault(modelId);
if (overideSvc != null && overideSvc.OverideFuncs.GetListAsync != null)
{
return await overideSvc.OverideFuncs.GetListAsync(input);
}
VisualDevEntity? templateEntity = await _visualDevService.GetInfoById(modelId, true);
return await _runService.GetListResult(templateEntity, input);
}
///
/// 外链获取数据列表.
///
/// 主键id.
/// 分页查询条件.
///
[HttpPost("{modelId}/ListLink")]
[AllowAnonymous]
[IgnoreLog]
public async Task ListLink(string modelId, [FromBody] VisualDevModelListQueryInput input)
{
VisualDevEntity? templateEntity = await _visualDevService.GetInfoById(modelId, true);
if (templateEntity == null) throw Oops.Oh(ErrorCode.D1420);
return await _runService.GetListResult(templateEntity, input);
}
///
/// 创建数据.
///
///
///
///
[HttpPost("{modelId}")]
public async Task Create(string modelId, [FromBody] VisualDevModelDataCrInput visualdevModelDataCrForm)
{
//modified by PhilPan 2023-04-12 重写接口
var overideSvc = OverideVisualDevManager.GetOrDefault(modelId);
if (overideSvc != null && overideSvc.OverideFuncs.CreateAsync != null)
{
await overideSvc.OverideFuncs.CreateAsync(visualdevModelDataCrForm);
}
else
{
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)
{
//modified by PhilPan 2023-04-12 重写接口
var overideSvc = OverideVisualDevManager.GetOrDefault(modelId);
if (overideSvc != null && overideSvc.OverideFuncs.UpdateAsync != null)
{
await overideSvc.OverideFuncs.UpdateAsync(id, visualdevModelDataUpForm);
}
else
{
VisualDevEntity? templateEntity = await _visualDevService.GetInfoById(modelId, true);
await _runService.Update(id, templateEntity, visualdevModelDataUpForm);
}
}
///
/// 删除数据.
///
///
///
///
[HttpDelete("{modelId}/{id}")]
public async Task Delete(string id, string modelId)
{
//modified by PhilPan 2023-04-12 重写接口
var overideSvc = OverideVisualDevManager.GetOrDefault(modelId);
if (overideSvc != null && overideSvc.OverideFuncs.DeleteAsync != null)
{
await overideSvc.OverideFuncs.DeleteAsync(id);
}
else
{
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)
{
//modified by PhilPan 2023-04-12 重写接口
var overideSvc = OverideVisualDevManager.GetOrDefault(modelId);
if (overideSvc != null && overideSvc.OverideFuncs.DeleteRangeAsync != null)
{
await overideSvc.OverideFuncs.DeleteRangeAsync(input);
}
else
{
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);
if (input.dataType == "1") input.pageSize = 99999999;
PageResult>? pageList = await _runService.GetListResult(templateEntity, input);
// 如果是 分组表格 模板
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;
}
List> realList = pageList.list.Copy();
var templateInfo = new TemplateParsingBase(templateEntity);
var res = GetCreateFirstColumnsHeader(input.selectKey, realList, templateInfo.AllFieldsModel);
var firstColumns = res.First().ToObject>();
var resultList = res.Last().ToObject>>();
var newResultList = new List>();
// 行内编辑
if (templateInfo.ColumnData.type.Equals(4))
{
resultList.ForEach(row =>
{
foreach (var data in row) if (data.Key.Contains("_name") && row.ContainsKey(data.Key.Replace("_name", string.Empty))) row[data.Key.Replace("_name", string.Empty)] = data.Value;
});
}
resultList.ForEach(row =>
{
foreach (var item in input.selectKey)
{
if (row[item].IsNotEmptyOrNull())
{
newResultList.Add(row);
break;
}
}
});
var excelName = string.Format("表单信息{0}", DateTime.Now.ToString("yyyyMMddHHmmssf"));
_cacheManager.Set(excelName + ".xls", string.Empty);
return firstColumns.Any() ? await ExcelCreateModel(templateInfo.AllFieldsModel, resultList, input.selectKey, excelName, firstColumns)
: await ExcelCreateModel(templateInfo.AllFieldsModel, resultList, input.selectKey, excelName);
}
///
/// 模板下载.
///
///
[HttpGet("{modelId}/TemplateDownload")]
public async Task TemplateDownload(string modelId)
{
var tInfo = await GetUploaderTemplateInfoAsync(modelId);
if (tInfo.selectKey == null || !tInfo.selectKey.Any()) throw Oops.Oh(ErrorCode.D1411);
// 初始化 一条空数据
List>? dataList = new List>();
// 赋予默认值
var dicItem = new Dictionary();
tInfo.AllFieldsModel.Where(x => tInfo.selectKey.Contains(x.__vModel__)).ToList().ForEach(item =>
{
switch (item.__config__.jnpfKey)
{
case JnpfKeyConst.CREATEUSER:
case JnpfKeyConst.MODIFYUSER:
case JnpfKeyConst.CREATETIME:
case JnpfKeyConst.MODIFYTIME:
case JnpfKeyConst.CURRORGANIZE:
case JnpfKeyConst.CURRPOSITION:
case JnpfKeyConst.CURRDEPT:
case JnpfKeyConst.BILLRULE:
dicItem.Add(item.__vModel__, "系统自动生成");
break;
case JnpfKeyConst.COMSELECT:
dicItem.Add(item.__vModel__, item.multiple ? "例:拓通智联/产品部,拓通智联/技术部" : "例:拓通智联/技术部");
break;
case JnpfKeyConst.DEPSELECT:
dicItem.Add(item.__vModel__, item.multiple ? "例:产品部/部门编码,技术部/部门编码" : "例:技术部/部门编码");
break;
case JnpfKeyConst.POSSELECT:
dicItem.Add(item.__vModel__, item.multiple ? "例:技术经理/岗位编码,技术员/岗位编码" : "例:技术员/岗位编码");
break;
case JnpfKeyConst.USERSSELECT:
dicItem.Add(item.__vModel__, item.selectType.Equals("all") ? "例:拓通智联/产品部,产品部/部门编码,技术经理/岗位编码,研发人员/角色编码,A分组/分组编码,张三/账号" : "例:李四/账号");
break;
case JnpfKeyConst.USERSELECT:
dicItem.Add(item.__vModel__, item.multiple ? "例:张三/账号,李四/账号" : "例:张三/账号");
break;
case JnpfKeyConst.ROLESELECT:
dicItem.Add(item.__vModel__, item.multiple ? "例:研发人员/角色编码,测试人员/角色编码" : "例:研发人员/角色编码");
break;
case JnpfKeyConst.GROUPSELECT:
dicItem.Add(item.__vModel__, item.multiple ? "例:A分组/分组编码,B分组/分组编码" : "例:A分组/分组编码");
break;
case JnpfKeyConst.DATE:
dicItem.Add(item.__vModel__, string.Format("例:{0}", item.format));
break;
case JnpfKeyConst.TIME:
dicItem.Add(item.__vModel__, "例: HH:mm:ss");
break;
case JnpfKeyConst.ADDRESS:
switch (item.level)
{
case 0:
dicItem.Add(item.__vModel__, item.multiple ? "例:福建省,广东省" : "例:福建省");
break;
case 1:
dicItem.Add(item.__vModel__, item.multiple ? "例:福建省/莆田市,广东省/广州市" : "例:福建省/莆田市");
break;
case 2:
dicItem.Add(item.__vModel__, item.multiple ? "例:福建省/莆田市/城厢区,广东省/广州市/荔湾区" : "例:福建省/莆田市/城厢区");
break;
case 3:
dicItem.Add(item.__vModel__, item.multiple ? "例:福建省/莆田市/城厢区/霞林街道,广东省/广州市/荔湾区/沙面街道" : "例:福建省/莆田市/城厢区/霞林街道");
break;
}
break;
default:
dicItem.Add(item.__vModel__, string.Empty);
break;
}
});
dicItem.Add("id", "id");
dataList.Add(dicItem);
var excelName = string.Format("{0} 导入模板_{1}", tInfo.FullName, SnowflakeIdHelper.NextId());
var res = GetCreateFirstColumnsHeader(tInfo.selectKey, dataList, tInfo.AllFieldsModel);
var firstColumns = res.First().ToObject>();
var resultList = res.Last().ToObject>>();
_cacheManager.Set(excelName + ".xls", string.Empty);
return firstColumns.Any() ? await ExcelCreateModel(tInfo.AllFieldsModel, resultList, tInfo.selectKey, excelName, firstColumns)
: await ExcelCreateModel(tInfo.AllFieldsModel, resultList, tInfo.selectKey, excelName);
}
///
/// 上传文件.
///
///
///
[HttpPost("Uploader")]
public async Task Uploader(IFormFile file)
{
var _filePath = _fileManager.GetPathByType(string.Empty);
var _fileName = DateTime.Now.ToString("yyyyMMdd") + "_" + SnowflakeIdHelper.NextId() + Path.GetExtension(file.FileName);
var stream = file.OpenReadStream();
await _fileManager.UploadFileByType(stream, _filePath, _fileName);
return new { name = _fileName, url = string.Format("/api/File/Image/{0}/{1}", string.Empty, _fileName) };
}
///
/// 导入预览.
///
///
[HttpGet("{modelId}/ImportPreview")]
public async Task ImportPreview(string modelId, string fileName)
{
var tInfo = await GetUploaderTemplateInfoAsync(modelId);
var resData = new List>();
var headerRow = new List();
var isChildTable = tInfo.ColumnData.columnList.Any(x => tInfo.ChildTableFields.ContainsKey(x.__vModel__));
try
{
var FileEncode = tInfo.AllFieldsModel.Where(x => tInfo.selectKey.Contains(x.__vModel__)).ToList();
string? savePath = Path.Combine(FileVariable.TemporaryFilePath, fileName);
// 得到数据
global::System.Data.DataTable? excelData = ExcelImportHelper.ToDataTable(savePath);
if (isChildTable) excelData = ExcelImportHelper.ToDataTable(savePath, 0, 1);
if (excelData.Columns.Count > tInfo.selectKey.Count) excelData.Columns.RemoveAt(tInfo.selectKey.Count);
foreach (object? item in excelData.Columns)
{
excelData.Columns[item.ToString()].ColumnName = FileEncode.Where(x => x.__config__.label == item.ToString()).FirstOrDefault().__vModel__;
}
resData = excelData.ToObject>>();
if (resData.Any())
{
if (isChildTable)
{
var hRow = resData[1].Copy();
foreach (var item in hRow)
{
if (item.Key.Contains("tableField") && item.Key.Contains("-"))
{
var childVModel = item.Key.Split("-").First();
if (!headerRow.Any(x => x.id.Equals(childVModel)))
{
var child = new List();
hRow.Where(x => x.Key.Contains(childVModel)).ToList().ForEach(x =>
{
child.Add(new { id = x.Key.Replace(childVModel + "-", string.Empty), fullName = x.Value.ToString().Replace(string.Format("({0})", x.Key), string.Empty) });
});
headerRow.Add(new { id = childVModel, fullName = tInfo.AllFieldsModel.Find(x => x.__vModel__.Equals(childVModel)).__config__.label.Replace(string.Format("({0})", childVModel), string.Empty), children = child });
}
}
else
{
headerRow.Add(new { id = item.Key, fullName = item.Value.ToString().Replace(string.Format("({0})", item.Key), string.Empty) });
}
}
resData.Remove(resData.First());
resData.Remove(resData.First());
}
else
{
foreach (var item in resData.First().Copy()) headerRow.Add(new { id = item.Key, fullName = item.Value.ToString().Replace(string.Format("({0})", item.Key), string.Empty) });
resData.Remove(resData.First());
}
}
}
catch (Exception e)
{
throw Oops.Oh(ErrorCode.D1410);
}
try
{
// 带子表字段数据导入
if (isChildTable)
{
var newData = new List>();
var singleForm = tInfo.selectKey.Where(x => !x.Contains("tableField")).ToList();
var childTableVModel = tInfo.AllFieldsModel.Where(x => x.__config__.jnpfKey.Equals(JnpfKeyConst.TABLE)).Select(x => x.__vModel__).ToList();
resData.ForEach(dataItem =>
{
var addItem = new Dictionary();
var isNextRow = false;
singleForm.ForEach(item =>
{
if (dataItem[item].IsNotEmptyOrNull()) isNextRow = true;
});
// 单条数据 (多行子表数据合并)
if (isNextRow)
{
singleForm.ForEach(item => addItem.Add(item, dataItem[item]));
// 子表数据
childTableVModel.ForEach(item =>
{
var childAddItem = new Dictionary();
tInfo.selectKey.Where(x => x.Contains(item)).ToList().ForEach(it =>
{
childAddItem.Add(it.Replace(item + "-", string.Empty), dataItem[it]);
});
addItem.Add(item, new List> { childAddItem });
});
newData.Add(addItem);
}
else
{
var item = newData.LastOrDefault();
if (item != null)
{
// 子表数据
childTableVModel.ForEach(citem =>
{
var childAddItem = new Dictionary();
tInfo.selectKey.Where(x => x.Contains(citem)).ToList().ForEach(it =>
{
childAddItem.Add(it.Replace(citem + "-", string.Empty), dataItem[it]);
});
if (!item.ContainsKey(citem))
{
item.Add(citem, new List> { childAddItem });
}
else
{
var childList = item[citem].ToObject>>();
childList.Add(childAddItem);
item[citem] = childList;
}
});
}
else
{
singleForm.ForEach(item => addItem.Add(item, dataItem[item]));
// 子表数据
childTableVModel.ForEach(item =>
{
var childAddItem = new Dictionary();
tInfo.selectKey.Where(x => x.Contains(item)).ToList().ForEach(it =>
{
childAddItem.Add(it.Replace(item + "-", string.Empty), dataItem[it]);
});
addItem.Add(item, new List> { childAddItem });
});
newData.Add(addItem);
}
}
});
resData = newData;
}
}
catch
{
throw Oops.Oh(ErrorCode.D1412);
}
resData.ForEach(items =>
{
foreach(var item in items)
{
var vmodel = tInfo.AllFieldsModel.FirstOrDefault(x => x.__vModel__.Equals(item.Key));
if (vmodel != null && vmodel.__config__.jnpfKey.Equals(JnpfKeyConst.DATE) && item.Value.IsNotEmptyOrNull()) items[item.Key] = item.Value + " ";
}
});
// 返回结果
return new { dataRow = resData, headerRow = headerRow };
}
///
/// 导入数据的错误报告.
///
///
///
[HttpPost("{modelId}/ImportExceptionData")]
[UnitOfWork]
public async Task ExportExceptionData(string modelId, [FromBody] VisualDevImportDataInput list)
{
var tInfo = await GetUploaderTemplateInfoAsync(modelId);
//object[]? res = await ImportMenuData(tInfo, list.list, tInfo.visualDevEntity);
// 错误数据
tInfo.selectKey.Add("errorsInfo");
tInfo.AllFieldsModel.Add(new FieldsModel() { __vModel__ = "errorsInfo", __config__ = new ConfigModel() { label = "异常原因" } });
for (var i = 0; i < list.list.Count(); i++) list.list[i].Add("id", i);
var result = GetCreateFirstColumnsHeader(tInfo.selectKey, list.list, tInfo.AllFieldsModel);
var firstColumns = result.First().ToObject>();
var resultList = result.Last().ToObject>>();
_cacheManager.Set(string.Format("{0} 导入错误报告.xls", tInfo.FullName), string.Empty);
return firstColumns.Any()
? await ExcelCreateModel(tInfo.AllFieldsModel, resultList, tInfo.selectKey, string.Format("{0} 导入错误报告", tInfo.FullName), firstColumns)
: await ExcelCreateModel(tInfo.AllFieldsModel, resultList, tInfo.selectKey, string.Format("{0} 导入错误报告", tInfo.FullName));
}
///
/// 导入数据.
///
///
///
[HttpPost("{modelId}/ImportData")]
[UnitOfWork]
public async Task ImportData(string modelId, [FromBody] VisualDevImportDataInput list)
{
var tInfo = await GetUploaderTemplateInfoAsync(modelId);
object[]? res = await ImportMenuData(tInfo, list.list, tInfo.visualDevEntity);
var addlist = res.First() as List>;
var errorlist = res.Last() as List>;
var result = new VisualDevImportDataOutput()
{
snum = addlist.Count,
fnum = errorlist.Count,
failResult = errorlist,
resultType = errorlist.Count < 1 ? 0 : 1
};
return result;
}
#endregion
#region PublicMethod
///
/// Excel 转输出 Model.
///
/// 控件集合.
/// 数据列表.
///
/// 导出文件名称.
/// 手动输入第一行(合并主表列和各个子表列).
/// VisualDevModelDataExportOutput.
public async Task ExcelCreateModel(List fieldList, List> realList, List keys, string excelName = null, Dictionary firstColumns = null)
{
VisualDevModelDataExportOutput output = new VisualDevModelDataExportOutput();
try
{
List columnList = new List();
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 = fieldList.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, List fieldList)
{
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> || item.Value.GetType().Name.Equals("JArray")))
{
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.ToLower().Contains("tablefield")))
{
var empty = string.Empty;
var keyList = selectKey.Select(x => x.Split("-").First()).Distinct().ToList();
var mainFieldIndex = 1;
keyList.ForEach(item =>
{
if (item.ToLower().Contains("tablefield"))
{
var title = fieldList.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
#region PrivateMethod
///
/// 获取导出模板信息.
///
///
///
private async Task GetUploaderTemplateInfoAsync(string modelId)
{
VisualDevEntity? templateEntity = await _visualDevService.GetInfoById(modelId, true);
var tInfo = new TemplateParsingBase(templateEntity);
tInfo.DbLink = await _dbLinkService.GetInfo(templateEntity.DbLinkId);
if (tInfo.DbLink == null) tInfo.DbLink = _databaseService.GetTenantDbLink(_userManager.TenantId, _userManager.TenantDbName); // 当前数据库连接
var tableList = _databaseService.GetFieldList(tInfo.DbLink, tInfo.MainTableName); // 获取主表所有列
var mainPrimary = tableList.Find(t => t.primaryKey); // 主表主键
if (mainPrimary == null || mainPrimary.IsNullOrEmpty()) throw Oops.Oh(ErrorCode.D1402); // 主表未设置主键
tInfo.MainPrimary = mainPrimary.field;
tInfo.AllFieldsModel = tInfo.AllFieldsModel.Where(x => !x.__config__.jnpfKey.Equals(JnpfKeyConst.UPLOADFZ)
&& !x.__config__.jnpfKey.Equals(JnpfKeyConst.UPLOADIMG)
&& !x.__config__.jnpfKey.Equals(JnpfKeyConst.COLORPICKER)
&& !x.__config__.jnpfKey.Equals(JnpfKeyConst.POPUPTABLESELECT)
&& !x.__config__.jnpfKey.Equals(JnpfKeyConst.RELATIONFORM)
&& !x.__config__.jnpfKey.Equals(JnpfKeyConst.POPUPSELECT)
&& !x.__config__.jnpfKey.Equals(JnpfKeyConst.RELATIONFORMATTR)
&& !x.__config__.jnpfKey.Equals(JnpfKeyConst.POPUPATTR)
&& !x.__config__.jnpfKey.Equals(JnpfKeyConst.QRCODE)
&& !x.__config__.jnpfKey.Equals(JnpfKeyConst.BARCODE)
&& !x.__config__.jnpfKey.Equals(JnpfKeyConst.CALCULATE)).ToList();
tInfo.AllFieldsModel.Where(x => x.__vModel__.IsNotEmptyOrNull()).ToList().ForEach(item => item.__config__.label = string.Format("{0}({1})", item.__config__.label, item.__vModel__));
return tInfo;
}
///
/// 导入数据.
///
/// 模板信息.
/// 数据集合.
/// 开发实体.
/// [成功列表,失败列表].
private async Task