diff --git a/apihost/Tnb.API.Entry/Configurations/ConnectionStrings.json b/apihost/Tnb.API.Entry/Configurations/ConnectionStrings.json
index cb16c787..2b96adcf 100644
--- a/apihost/Tnb.API.Entry/Configurations/ConnectionStrings.json
+++ b/apihost/Tnb.API.Entry/Configurations/ConnectionStrings.json
@@ -1,24 +1,23 @@
{
"ConnectionStrings": {
"ConfigId": "default",
- "DBName": "tnb_bas",
"DBType": "PostgreSQL", //MySql;SqlServer;Oracle;PostgreSQL;Dm;Kdbndp;Sqlite;
"Host": "localhost",
"Port": "5432",
+ "DBName": "tnb_bas",
"UserName": "totong",
"Password": "IPANyxGSKxIXg0dBM",
//SqlServer
- //"DefaultConnection": "Data Source=192.168.0.214;Initial Catalog={0};User ID=sa;Password=kMaeMP8Yck6b6wA;MultipleActiveResultSets=true"
+ //"DefaultConnection": "server={0},{1};database={2};uid={3};pwd={4};MultipleActiveResultSets=true"
//Kdbndp
- //"DefaultConnection": "Server=192.168.0.103;Port=54321;UID=YANYU;PWD=123456;database=YANSOURCE"
+ //"DefaultConnection": "server={0};port={1};database={2};uid={3};pwd={4};"
//Dm
- //"DefaultConnection": "Server=192.168.0.50; User Id=JNPFTEST; PWD=I97eH!bRfy55qGzF;DATABASE=JNPFTEST"
+ //"DefaultConnection": "server={0};port={1};database={2};uid={3};pwd={4};"
//Oracle
- //"DefaultConnection": "Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.0.19)(PORT=1521))(CONNECT_DATA=(SERVER = DEDICATED)(SERVICE_NAME=JNPFCLOUD)));User Id=JNPFCLOUD;Password=JNPFCLOUD"
+ //"DefaultConnection": "Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST={0})(PORT={1}))(CONNECT_DATA=(SERVER = DEDICATED)(SERVICE_NAME={2})));User Id={3};Password={4}"
//PostgreSQL
- //"DefaultConnection": "PORT=5432;DATABASE=java_boot_dev_postgresql;HOST=192.168.0.103;PASSWORD=123456;USER ID=postgres"
- "DefaultConnection": "server=localhost;port=5432;database=tnb_bas;uid=totong;pwd=IPANyxGSKxIXg0dBM;pooling=true;"
+ "DefaultConnection": "server={0};port={1};database={2};uid={3};pwd={4};pooling=true;"
//MySql
- //"DefaultConnection": "server=192.168.0.10;Database=netcore_test;Uid=netcore_test;Pwd=jhpGB3A88CF57fBC;AllowLoadLocalInfile=true"
+ //"DefaultConnection": "server={0};port={1};database={2};uid={3};pwd={4};sslmode=none;pooling=true;charset=utf8mb4;allowLoadLocalInfile=true;allowPublicKeyRetrieval=true"
}
}
\ No newline at end of file
diff --git a/apihost/Tnb.API.Entry/Extensions/LoggingConfigureExtensions.cs b/apihost/Tnb.API.Entry/Extensions/LoggingConfigureExtensions.cs
new file mode 100644
index 00000000..71001cb9
--- /dev/null
+++ b/apihost/Tnb.API.Entry/Extensions/LoggingConfigureExtensions.cs
@@ -0,0 +1,73 @@
+using System.ComponentModel.DataAnnotations;
+using System.Reflection;
+using JNPF;
+using JNPF.Logging;
+using Spire.Xls;
+using SqlSugar;
+
+namespace Microsoft.Extensions.DependencyInjection;
+
+///
+/// SqlSugar配置拓展.
+///
+public static class LoggingConfigureExtensions
+{
+ const string DATEFORMAT = "HH:mm:ss.fff";
+
+ public static IServiceCollection LoggingConfigure(this IServiceCollection services)
+ {
+ services.AddConsoleFormatter(option =>
+ {
+ option.MessageFormat = LoggerConsoleFormat;
+ }).AddFileLogging(options =>
+ {
+ options.MessageFormat = LoggerFileFormat;
+ options.FileNameRule = fileName => string.Format(fileName, DateTime.Now); // 每天创建一个文件
+ options.HandleWriteError = (writeError) => // 写入失败时启用备用文件
+ {
+ writeError.UseRollbackFileName(Path.GetFileNameWithoutExtension(writeError.CurrentFileName) + "-oops" + Path.GetExtension(writeError.CurrentFileName));
+ };
+ });
+ return services;
+ }
+ private static string LoggerLevelName(LogLevel level)
+ {
+ return level switch
+ {
+ LogLevel.Trace => "Trace",
+ LogLevel.Debug => "Debug",
+ LogLevel.Information => "Info",
+ LogLevel.Warning => "Warn",
+ LogLevel.Error => "Error",
+ LogLevel.Critical => "Crit",
+ _ => "None"
+ };
+ }
+ private static string LoggerFileFormat(LogMessage msg)
+ {
+ var txt = $"{LoggerLevelName(msg.LogLevel)} {msg.LogDateTime.ToString(DATEFORMAT)} {msg.ThreadId}# {msg.Message}";
+ if (msg.Exception != null)
+ {
+ //var EXCEPTION_SEPARATOR_WITHCOLOR = AppendWithColor(default, EXCEPTION_SEPARATOR, logLevelColors).ToString();
+ txt += $"{Environment.NewLine}{msg.Exception}";
+ }
+ return txt;
+ }
+ private static string LoggerConsoleFormat(LogMessage msg)
+ {
+ var fclr = msg.LogLevel switch
+ {
+ LogLevel.Warning => "\u001b[1m\u001b[33m",
+ LogLevel.Error => "\u001b[1m\u001b[31m",
+ _ => "\u001b[39m\u001b[22m"
+ };
+ var txt = $"{fclr}{LoggerLevelName(msg.LogLevel)}\u001b[49m \u001b[36m{msg.LogDateTime.ToString(DATEFORMAT)}\u001b[49m \u001b[39m\u001b[22m{msg.ThreadId}#\u001b[49m {fclr}{msg.Message}\u001b[49m";
+ if (msg.Exception != null)
+ {
+ //var EXCEPTION_SEPARATOR_WITHCOLOR = AppendWithColor(default, EXCEPTION_SEPARATOR, logLevelColors).ToString();
+ txt += $"{Environment.NewLine}{fclr}{msg.Exception}\u001b[49m";
+ }
+ return txt;
+ }
+
+}
\ No newline at end of file
diff --git a/apihost/Tnb.API.Entry/Extensions/SqlSugarConfigureExtensions.cs b/apihost/Tnb.API.Entry/Extensions/SqlSugarConfigureExtensions.cs
index ae206987..37341330 100644
--- a/apihost/Tnb.API.Entry/Extensions/SqlSugarConfigureExtensions.cs
+++ b/apihost/Tnb.API.Entry/Extensions/SqlSugarConfigureExtensions.cs
@@ -15,23 +15,17 @@ public static class SqlSugarConfigureExtensions
public static IServiceCollection SqlSugarConfigure(this IServiceCollection services)
{
// 获取选项
- ConnectionStringsOptions connectionStrings = App.GetConfig("ConnectionStrings", true);
+ ConnectionStringsOptions conn = App.GetConfig("ConnectionStrings", true);
List connectConfigList = new List();
-
- string? connectionStr = connectionStrings.DefaultConnection;
- var dataBase = connectionStrings.DBName;
- var DBType = (DbType)Enum.Parse(typeof(DbType), connectionStrings.DBType);
- var ConfigId = connectionStrings.ConfigId;
- var DBName = connectionStrings.DBName;
-
+ var DBType = (DbType)Enum.Parse(typeof(DbType), conn.DBType);
// 默认数据库
connectConfigList.Add(new ConnectionConfig
{
- ConnectionString = string.Format(connectionStr, DBName),
+ ConnectionString = string.Format(conn.DefaultConnection, conn.Host, conn.Port, conn.DBName, conn.UserName, conn.Password),
DbType = DBType,
IsAutoCloseConnection = true,
- ConfigId = ConfigId,
+ ConfigId = conn.ConfigId,
InitKeyType = InitKeyType.Attribute,
MoreSettings = new ConnMoreSettings()
{
diff --git a/apihost/Tnb.API.Entry/Startup.cs b/apihost/Tnb.API.Entry/Startup.cs
index c26a3e50..20ce7f93 100644
--- a/apihost/Tnb.API.Entry/Startup.cs
+++ b/apihost/Tnb.API.Entry/Startup.cs
@@ -25,6 +25,7 @@ using System;
using System.Text;
using Top.Api;
using JNPF.Common.Security;
+using JNPF.VisualDev;
namespace JNPF.API.Entry;
@@ -32,11 +33,6 @@ public class Startup : AppStartup
{
public void ConfigureServices(IServiceCollection services)
{
- services.AddConsoleFormatter(option =>
- {
- option.MessageFormat = LoggerConsoleFormat;
- });
-
// SqlSugar
services.SqlSugarConfigure();
@@ -140,6 +136,7 @@ public class Startup : AppStartup
services.AddSession();
services.AddMemoryCache(); // 使用本地缓存必须添加
+ services.LoggingConfigure();
// 日志监听
// services.AddMonitorLogging(options =>
//{
@@ -147,16 +144,6 @@ public class Startup : AppStartup
// options.IgnorePropertyTypes = new[] { typeof(byte[]) };
//});
- services.AddFileLogging(options =>
- {
- options.MessageFormat = LoggerFileFormat;
- options.FileNameRule = fileName => string.Format(fileName, DateTime.Now); // 每天创建一个文件
- options.HandleWriteError = (writeError) => // 写入失败时启用备用文件
- {
- writeError.UseRollbackFileName(Path.GetFileNameWithoutExtension(writeError.CurrentFileName) + "-oops" + Path.GetExtension(writeError.CurrentFileName));
- };
- });
-
services.AddUnitOfWork();
services.OSSServiceConfigure();
@@ -164,6 +151,8 @@ public class Startup : AppStartup
services.AddSingleton();
services.AddSchedule();
+
+ services.AddOverideVisualDev();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IServiceProvider serviceProvider, IOptions senparcSetting, IOptions senparcWeixinSetting)
@@ -201,7 +190,8 @@ public class Startup : AppStartup
app.UseInject(string.Empty);
- app.MapWebSocketManager("/api/message/websocket", serviceProvider.GetService());
+ //app.MapWebSocketManager("/api/message/websocket", serviceProvider.GetService());
+ app.MapWebSocketManager("/websocket", serviceProvider.GetService());
app.UseEndpoints(endpoints =>
{
@@ -212,45 +202,4 @@ public class Startup : AppStartup
serviceProvider.GetRequiredService().StartTimerJob();
}
-
- const string DATEFORMAT = "HH:mm:ss.fff";
- private string LoggerLevelName(LogLevel level)
- {
- return level switch
- {
- LogLevel.Trace => "Trace",
- LogLevel.Debug => "Debug",
- LogLevel.Information => "Info",
- LogLevel.Warning => "Warn",
- LogLevel.Error => "Error",
- LogLevel.Critical => "Crit",
- _ => "None"
- };
- }
- private string LoggerFileFormat(LogMessage msg)
- {
- var txt = $"{LoggerLevelName(msg.LogLevel)} {msg.LogDateTime.ToString(DATEFORMAT)} {msg.ThreadId}# {msg.Message}";
- if (msg.Exception != null)
- {
- //var EXCEPTION_SEPARATOR_WITHCOLOR = AppendWithColor(default, EXCEPTION_SEPARATOR, logLevelColors).ToString();
- txt += $"{Environment.NewLine}{msg.Exception}";
- }
- return txt;
- }
- private string LoggerConsoleFormat(LogMessage msg)
- {
- var fclr = msg.LogLevel switch
- {
- LogLevel.Warning => "\u001b[1m\u001b[33m",
- LogLevel.Error => "\u001b[1m\u001b[31m",
- _ => "\u001b[39m\u001b[22m"
- };
- var txt = $"{fclr}{LoggerLevelName(msg.LogLevel)}\u001b[49m \u001b[36m{msg.LogDateTime.ToString(DATEFORMAT)}\u001b[49m \u001b[39m\u001b[22m{msg.ThreadId}#\u001b[49m {fclr}{msg.Message}\u001b[49m";
- if (msg.Exception != null)
- {
- //var EXCEPTION_SEPARATOR_WITHCOLOR = AppendWithColor(default, EXCEPTION_SEPARATOR, logLevelColors).ToString();
- txt += $"{Environment.NewLine}{fclr}{msg.Exception}\u001b[49m";
- }
- return txt;
- }
}
\ No newline at end of file
diff --git a/common/Tnb.Common/Security/SuperQueryHelper.cs b/common/Tnb.Common/Security/SuperQueryHelper.cs
index b27f1b05..eaa6f636 100644
--- a/common/Tnb.Common/Security/SuperQueryHelper.cs
+++ b/common/Tnb.Common/Security/SuperQueryHelper.cs
@@ -1086,13 +1086,13 @@ public class SuperQueryHelper
private static List> GetUserRelationByUserId(string fieldValue)
{
// 获取数据库连接选项
- ConnectionStringsOptions connectionStrings = App.GetConfig("ConnectionStrings", true);
+ ConnectionStringsOptions conn = App.GetConfig("ConnectionStrings", true);
SqlSugarClient db = new SqlSugarClient(new ConnectionConfig
{
- ConnectionString = string.Format(connectionStrings.DefaultConnection, connectionStrings.DBName),
- DbType = (SqlSugar.DbType)Enum.Parse(typeof(SqlSugar.DbType), connectionStrings.DBType),
+ ConnectionString = string.Format(conn.DefaultConnection, conn.Host, conn.Port, conn.DBName, conn.UserName, conn.Password),
+ DbType = (DbType)Enum.Parse(typeof(DbType), conn.DBType),
IsAutoCloseConnection = true,
- ConfigId = connectionStrings.ConfigId,
+ ConfigId = conn.ConfigId,
InitKeyType = InitKeyType.Attribute,
MoreSettings = new ConnMoreSettings()
{
diff --git a/common/Tnb.Common/Tnb.Common.csproj b/common/Tnb.Common/Tnb.Common.csproj
index c37766cd..329ae4cb 100644
--- a/common/Tnb.Common/Tnb.Common.csproj
+++ b/common/Tnb.Common/Tnb.Common.csproj
@@ -23,7 +23,7 @@
-
+
diff --git a/visualdev/Tnb.VisualDev.Engine/OverideVisualDev/IOverideVisualDevService.cs b/visualdev/Tnb.VisualDev.Engine/OverideVisualDev/IOverideVisualDevService.cs
new file mode 100644
index 00000000..492348c2
--- /dev/null
+++ b/visualdev/Tnb.VisualDev.Engine/OverideVisualDev/IOverideVisualDevService.cs
@@ -0,0 +1,43 @@
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Threading.Tasks;
+using JNPF.Common.Dtos.VisualDev;
+using JNPF.Common.Extension;
+using JNPF.DependencyInjection;
+using JNPF.VisualDev.Entitys;
+using JNPF.VisualDev.Entitys.Dto.VisualDevModelData;
+using JNPF.VisualDev.Interfaces;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.Mvc.Filters;
+
+namespace JNPF.VisualDev
+{
+ public interface IVisualDevOverideActionManager : ISingleton
+ {
+ void Set(string modelId, IOverideVisualDevService overideVisualDev);
+
+ IOverideVisualDevService? GetOrDefault(string modelId);
+ }
+
+ public interface IOverideVisualDevService
+ {
+ //string ModelId { get; set; }
+ OverideVisualDevFunc OverideFuncs { get; }
+
+ //Task? GetList(VisualDevModelListQueryInput input);
+ //Task? GetInfo(string id);
+ //Task? GetDetails(string id, string modelId);
+ //Task? Create(VisualDevModelDataCrInput visualdevModelDataCrForm);
+ //Task? Update(string id, VisualDevModelDataUpInput visualdevModelDataUpForm);
+ //Task? Delete(string id);
+ //Task? BatchDelete(VisualDevModelDataBatchDelInput input);
+ //Task? Export(VisualDevModelListQueryInput input);
+ //Task? Import(IFormFile file);
+ }
+
+}
diff --git a/visualdev/Tnb.VisualDev.Engine/OverideVisualDev/OverideVisualDevAttribute.cs b/visualdev/Tnb.VisualDev.Engine/OverideVisualDev/OverideVisualDevAttribute.cs
new file mode 100644
index 00000000..b7bd9033
--- /dev/null
+++ b/visualdev/Tnb.VisualDev.Engine/OverideVisualDev/OverideVisualDevAttribute.cs
@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using JNPF.Common.Extension;
+using JNPF.VisualDev.Entitys;
+using JNPF.VisualDev.Interfaces;
+using Microsoft.AspNetCore.Mvc.Filters;
+
+namespace JNPF.VisualDev
+{
+ [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
+ public class OverideVisualDevAttribute : Attribute
+ {
+ public string ModelId { get; set; }
+ public OverideVisualDevAttribute(string modelId)
+ {
+ ModelId = modelId;
+ }
+ }
+}
diff --git a/visualdev/Tnb.VisualDev.Engine/OverideVisualDev/OverideVisualDevFunc.cs b/visualdev/Tnb.VisualDev.Engine/OverideVisualDev/OverideVisualDevFunc.cs
new file mode 100644
index 00000000..419ee057
--- /dev/null
+++ b/visualdev/Tnb.VisualDev.Engine/OverideVisualDev/OverideVisualDevFunc.cs
@@ -0,0 +1,32 @@
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Threading.Tasks;
+using JNPF.Common.Dtos.VisualDev;
+using JNPF.Common.Extension;
+using JNPF.DependencyInjection;
+using JNPF.VisualDev.Entitys;
+using JNPF.VisualDev.Entitys.Dto.VisualDevModelData;
+using JNPF.VisualDev.Interfaces;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.Mvc.Filters;
+
+namespace JNPF.VisualDev
+{
+ public class OverideVisualDevFunc
+ {
+ public Func>? GetListAsync { get; set; } = null;
+ public Func>? GetAsync { get; set; } = null;
+ public Func>? GetDetailsAsync { get; set; } = null;
+ public Func>? CreateAsync { get; set; } = null;
+ public Func>? UpdateAsync { get; set; } = null;
+ public Func? DeleteAsync { get; set; } = null;
+ public Func? DeleteRangeAsync { get; set; } = null;
+ public Func>? ExportAsync { get; set; } = null;
+ public Func>? ImportAsync { get; set; } = null;
+ }
+}
diff --git a/visualdev/Tnb.VisualDev.Engine/OverideVisualDev/OverideVisualDevManager.cs b/visualdev/Tnb.VisualDev.Engine/OverideVisualDev/OverideVisualDevManager.cs
new file mode 100644
index 00000000..0e449307
--- /dev/null
+++ b/visualdev/Tnb.VisualDev.Engine/OverideVisualDev/OverideVisualDevManager.cs
@@ -0,0 +1,38 @@
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Threading.Tasks;
+using JNPF.Common.Extension;
+using JNPF.DependencyInjection;
+using JNPF.VisualDev.Entitys;
+using JNPF.VisualDev.Interfaces;
+using Microsoft.AspNetCore.Mvc.Filters;
+
+namespace JNPF.VisualDev
+{
+ public class OverideVisualDevManager
+ {
+ private static ConcurrentDictionary actions = new ConcurrentDictionary();
+ public OverideVisualDevManager()
+ {
+ }
+
+ public static IOverideVisualDevService? GetOrDefault(string modelId)
+ {
+ var tp = actions.GetOrDefault(modelId);
+ if (tp != null) { return (IOverideVisualDevService)App.GetService(tp); }
+ return null;
+ }
+
+ public static void Add(string modelId, Type overideVisualDev)
+ {
+ if (!actions.ContainsKey(modelId))
+ {
+ actions.TryAdd(modelId, overideVisualDev);
+ }
+ }
+ }
+}
diff --git a/visualdev/Tnb.VisualDev.Engine/OverideVisualDev/OverideVisualDevServiceCollectionExtensions.cs b/visualdev/Tnb.VisualDev.Engine/OverideVisualDev/OverideVisualDevServiceCollectionExtensions.cs
new file mode 100644
index 00000000..f7c72bdd
--- /dev/null
+++ b/visualdev/Tnb.VisualDev.Engine/OverideVisualDev/OverideVisualDevServiceCollectionExtensions.cs
@@ -0,0 +1,31 @@
+using JNPF.DependencyInjection;
+using JNPF.Reflection;
+using Microsoft.Extensions.DependencyInjection;
+
+namespace JNPF.VisualDev
+{
+ [SuppressSniffer]
+ public static class OverideVisualDevServiceCollectionExtensions
+ {
+ ///
+ /// 添加重写在线开发接口的服务
+ ///
+ ///
+ ///
+ public static IServiceCollection AddOverideVisualDev(this IServiceCollection services)
+ {
+ var actions = App.EffectiveTypes.Where(u => u.IsClass && !u.IsInterface && !u.IsAbstract && typeof(IOverideVisualDevService).IsAssignableFrom(u)).ToList();
+ foreach (var item in actions)
+ {
+ var attr = item.GetAttribute();
+ if (attr != null)
+ {
+ OverideVisualDevManager.Add(attr.ModelId, item);
+ }
+ }
+
+ return services;
+ }
+
+ }
+}
diff --git a/visualdev/Tnb.VisualDev/VisualDevModelDataService.cs b/visualdev/Tnb.VisualDev/VisualDevModelDataService.cs
index 823670c7..d4e1cf68 100644
--- a/visualdev/Tnb.VisualDev/VisualDevModelDataService.cs
+++ b/visualdev/Tnb.VisualDev/VisualDevModelDataService.cs
@@ -37,2677 +37,1498 @@ using Yitter.IdGenerator;
namespace JNPF.VisualDev
{
+ ///
+ /// 可视化开发基础.
+ ///
+ [ApiDescriptionSettings(Tag = "VisualDev", Name = "OnlineDev", Order = 172)]
+ [Route("api/visualdev/[controller]")]
+ public class VisualDevModelDataService : IDynamicApiController, ITransient
+ {
+ ///
+ /// 服务基础仓储.
+ ///
+ private readonly ISqlSugarRepository _visualDevRepository; // 在线开发功能实体
+
///
/// 可视化开发基础.
///
- [ApiDescriptionSettings(Tag = "VisualDev", Name = "OnlineDev", Order = 172)]
- [Route("api/visualdev/[controller]")]
- public class VisualDevModelDataService : IDynamicApiController, ITransient
+ 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)
{
- ///
- /// 服务基础仓储.
- ///
- private readonly ISqlSugarRepository _visualDevRepository; // 在线开发功能实体
+ _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();
+ }
- ///
- /// 可视化开发基础.
- ///
- private readonly IVisualDevService _visualDevService;
+ #region Get
- ///
- /// 在线开发运行服务.
- ///
- private readonly RunService _runService;
+ ///
+ /// 获取列表表单配置JSON.
+ ///
+ /// 主键id.
+ /// 1 线上版本, 0 草稿版本.
+ ///
+ [HttpGet("{modelId}/Config")]
+ [NonUnify]
- ///
- /// 单据.
- ///
- private readonly IBillRullService _billRuleService;
+ 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 = data.Adapt() };
+ }
- ///
- /// 用户管理.
- ///
- private readonly IUserManager _userManager;
+ ///
+ /// 获取列表配置JSON.
+ ///
+ /// 主键id.
+ ///
+ [HttpGet("{modelId}/ColumnData")]
+ public async Task GetColumnData(string modelId)
+ {
+ VisualDevEntity? data = await _visualDevService.GetInfoById(modelId);
+ return new { columnData = data.ColumnData };
+ }
- ///
- /// 缓存管理.
- ///
- private readonly ICacheManager _cacheManager;
+ ///
+ /// 获取列表配置JSON.
+ ///
+ /// 主键id.
+ ///
+ [HttpGet("{modelId}/FormData")]
+ public async Task GetFormData(string modelId)
+ {
+ VisualDevEntity? data = await _visualDevService.GetInfoById(modelId);
+ return new { formData = data.FormData };
+ }
- ///
- /// 文件服务.
- ///
- private readonly IFileManager _fileManager;
+ ///
+ /// 获取列表配置JSON.
+ ///
+ /// 主键id.
+ ///
+ [HttpGet("{modelId}/FlowTemplate")]
+ public async Task GetFlowTemplate(string modelId)
+ {
+ VisualDevEntity? data = await _visualDevService.GetInfoById(modelId);
+ return new { flowTemplateJson = data.FlowTemplateJson };
+ }
- ///
- /// 工作流.
- ///
- private readonly IFlowTaskService _flowTaskService;
+ ///
+ /// 获取数据信息.
+ ///
+ ///
+ ///
+ ///
+ [HttpGet("{modelId}/{id}")]
+ public async Task GetInfo(string id, string modelId)
+ {
+ var overideSvc = OverideVisualDevManager.GetOrDefault(modelId);
+ if (overideSvc != null && overideSvc.OverideFuncs.GetAsync != null)
+ {
+ return await overideSvc.OverideFuncs.GetAsync(id);
+ }
+ else
+ {
+ VisualDevEntity? templateEntity = await _visualDevService.GetInfoById(modelId, true); // 模板实体
- ///
- /// 数据连接服务.
- ///
- private readonly IDbLinkService _dbLinkService;
+ // 有表
+ if (!string.IsNullOrEmpty(templateEntity.Tables) && !"[]".Equals(templateEntity.Tables))
+ return new { id = id, data = (await _runService.GetHaveTableInfo(id, templateEntity)).ToJsonString() };
+ else
+ return null;
+ }
+ }
- ///
- /// 切库.
- ///
- private readonly IDataBaseManager _databaseService;
+ ///
+ /// 获取详情.
+ ///
+ ///
+ ///
+ ///
+ [HttpGet("{modelId}/{id}/DataChange")]
+ public async Task GetDetails(string id, string modelId)
+ {
+ var overideSvc = OverideVisualDevManager.GetOrDefault(modelId);
+ if (overideSvc != null && overideSvc.OverideFuncs.GetDetailsAsync != null)
+ {
+ return await overideSvc.OverideFuncs.GetDetailsAsync(id);
+ }
+ else
+ {
+ VisualDevEntity? templateEntity = await _visualDevService.GetInfoById(modelId, true); // 模板实体
- ///
- /// 数据接口.
- ///
- private readonly IDataInterfaceService _dataInterfaceService;
+ // 有表
+ if (!string.IsNullOrEmpty(templateEntity.Tables) && !"[]".Equals(templateEntity.Tables))
+ return new { id = id, data = await _runService.GetHaveTableInfoDetails(id, templateEntity) };
+ else
+ return null;
+ }
+ }
- ///
- /// 多租户事务.
- ///
- private readonly ITenant _db;
+ #endregion
- ///
- /// 初始化一个类型的新实例.
- ///
- 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)
+ #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)
+ {
+ var overideSvc = OverideVisualDevManager.GetOrDefault(modelId);
+ if (overideSvc != null && overideSvc.OverideFuncs.GetListAsync != null)
+ {
+ return await overideSvc.OverideFuncs.GetListAsync(input);
+ }
+ else
+ {
+ VisualDevEntity? templateEntity = await _visualDevService.GetInfoById(modelId, true);
+ return await _runService.GetListResult(templateEntity, input);
+ }
+ }
+
+ ///
+ /// 创建数据.
+ ///
+ ///
+ ///
+ ///
+ [HttpPost("{modelId}")]
+ public async Task Create(string modelId, [FromBody] VisualDevModelDataCrInput visualdevModelDataCrForm)
+ {
+ 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)
+ {
+ 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)
+ {
+ 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)
+ {
+ 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);
+ List list = new List();
+ 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 =>
{
- _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();
+ 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>();
+ resultList.ForEach(row =>
+ {
+ foreach (var item in input.selectKey)
+ {
+ if (row[item].IsNotEmptyOrNull())
+ {
+ newResultList.Add(row);
+ break;
+ }
+ }
+ });
+
+ var excelName = string.Format("{0}", SnowflakeIdHelper.NextId());
+ _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__;
}
- #region Get
-
- ///
- /// 获取列表表单配置JSON.
- ///
- /// 主键id.
- /// 1 线上版本, 0 草稿版本.
- ///
- [HttpGet("{modelId}/Config")]
- [NonUnify]
-
- public async Task GetData(string modelId, string type)
+ resData = excelData.ToObject>>();
+ if (resData.Any())
{
- 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 = data.Adapt() };
+ 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);
+ }
- ///
- /// 获取列表配置JSON.
- ///
- /// 主键id.
- ///
- [HttpGet("{modelId}/ColumnData")]
- public async Task GetColumnData(string modelId)
+ try
+ {
+ // 带子表字段数据导入
+ if (isChildTable)
{
- VisualDevEntity? data = await _visualDevService.GetInfoById(modelId);
- return new { columnData = data.ColumnData };
- }
+ 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;
+ });
- ///
- /// 获取列表配置JSON.
- ///
- /// 主键id.
- ///
- [HttpGet("{modelId}/FormData")]
- public async Task GetFormData(string modelId)
- {
- VisualDevEntity? data = await _visualDevService.GetInfoById(modelId);
- return new { formData = data.FormData };
- }
+ // 单条数据 (多行子表数据合并)
+ if (isNextRow)
+ {
+ singleForm.ForEach(item => addItem.Add(item, dataItem[item]));
- ///
- /// 获取列表配置JSON.
- ///
- /// 主键id.
- ///
- [HttpGet("{modelId}/FlowTemplate")]
- public async Task GetFlowTemplate(string modelId)
- {
- VisualDevEntity? data = await _visualDevService.GetInfoById(modelId);
- return new { flowTemplateJson = data.FlowTemplateJson };
- }
+ // 子表数据
+ 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]);
+ });
- ///
- /// 获取数据信息.
- ///
- ///
- ///
- ///
- [HttpGet("{modelId}/{id}")]
- public async Task GetInfo(string id, string modelId)
- {
- VisualDevEntity? templateEntity = await _visualDevService.GetInfoById(modelId, true); // 模板实体
+ addItem.Add(item, new List> { childAddItem });
+ });
- // 有表
- 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) };
+ newData.Add(addItem);
+ }
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);
- }
+ 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]);
+ });
- ///
- /// 导入.
- ///
- ///
- ///
- [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)
- {
- 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();
- 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>();
- resultList.ForEach(row =>
- {
- foreach (var item in input.selectKey)
- {
- if (row[item].IsNotEmptyOrNull())
- {
- newResultList.Add(row);
- break;
- }
- }
- });
-
- var excelName = string.Format("{0}", SnowflakeIdHelper.NextId());
- _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)
+ if (!item.ContainsKey(citem))
{
- 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);
+ item.Add(citem, new List> { childAddItem });
}
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);
- }
+ 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