using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Internal; using OfficeOpenXml.FormulaParsing.Excel.Functions.Text; using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Linq.Expressions; using System.Text; using System.Threading.Tasks; using VolPro.Core.DBManager; using VolPro.Core.DbSqlSugar; using VolPro.Core.Extensions; using VolPro.Core.Infrastructure; using VolPro.Core.ManageUser; using VolPro.Core.WorkFlow; using VolPro.Entity.DomainModels; namespace VolPro.Core.Print { public class PrintContainer { public static List _print = new List(); private static PrintContainer _instance; public static PrintContainer Instance { get { if (_instance != null) { return _instance; } _instance = new PrintContainer(); return _instance; } } /// /// /// /// /// 打印分类的名称 /// 可以打印的字段 /// /// public PrintContainer Use(string name, [NotNull] Expression> printFields, List customFields = null) { if (_print.Any(x => x.TableType == typeof(T))) { return Instance; } Type type = typeof(T); _print.Add(new PrintOptions() { TableType = type, Name = name ?? type.GetEntityTableCnName(), TableName = type.Name, Fields = printFields.GetExpressionProperty(), CustomFields = customFields }); return Instance; } public PrintContainer Use( string name, [NotNull] Expression> printFields, List customFields, string detailName, [NotNull] Expression> detailPrintFields, List detailCustomFields = null) where Detail : class { return Use(name, printFields, customFields, detail: new PrintDetailOptions() { Name = detailName, PrintFields = detailPrintFields, CustomFields = detailCustomFields }); } /// /// /// /// 打印的主表 /// 打印的明细表 /// 打印分类的名称 /// 可以打印的字段 /// 打印的明细表名称 /// 可以打印的明细表字段 /// /// public PrintContainer Use(string name, [NotNull] Expression> printFields, string detailName, [NotNull] Expression> detailPrintFields ) where Detail : class { return Instance.Use(name, printFields, null, detailName, detailPrintFields); } public PrintContainer Use(string name, [NotNull] Expression> printFields, List customFields, [NotNull] PrintDetailOptions detail ) where Detail : class { return Instance.Use(name, printFields, customFields, detail, null); } public PrintContainer Use(string name, [NotNull] Expression> printFields, List customFields, [NotNull] PrintDetailOptions detail1, PrintDetailOptions detail2 ) where Detail1 : class where Detail2 : class { return Instance.Use(name, printFields, customFields, detail1, detail2, null); } public PrintContainer Use(string name, [NotNull] Expression> printFields, List customFields, [NotNull] PrintDetailOptions detail1, PrintDetailOptions detail2, PrintDetailOptions detail3 ) where Detail1 : class where Detail2 : class where Detail3 : class { if (_print.Any(x => x.TableType == typeof(T))) { return Instance; } Type type = typeof(T); var PrintDetails = new List(); if (detail1 != null) { PrintDetails.Add(GetPrintDetail(detail1)); } if (detail2 != null) { PrintDetails.Add(GetPrintDetail(detail2)); } if (detail3 != null) { PrintDetails.Add(GetPrintDetail(detail3)); } _print.Add(new PrintOptions() { TableType = type, Name = name ?? type.GetEntityTableCnName(), TableName = type.Name, Fields = printFields.GetExpressionProperty(), CustomFields = customFields, PrintDetails = PrintDetails }); return Instance; } private PrintDetail GetPrintDetail(PrintDetailOptions detail) where T : class { return new PrintDetail() { DetailTableType = typeof(T), DetailName = detail.Name ?? typeof(T).GetEntityTableCnName(), DetailTableName = typeof(T).Name, DetailFields = detail.PrintFields.GetExpressionProperty(), CustomgFields = detail.CustomFields }; } /// /// 获取下拉框数据源 /// /// public static object GetSelect() { //只显示有权限的表 var permissions = UserContext.Current.Permissions; return _print .Where(x => permissions.Any(c => c.TableName == x.TableName.ToLower())) .Select(s => new { key = s.TableName, value = s.Name }).ToList(); } /// /// 获取下拉框数据源 /// /// public static object GetOptions(string table) { //只显示有权限的表 var permissions = UserContext.Current.Permissions; var query = _print .Where(x => permissions.Any(c => c.TableName == x.TableName.ToLower())); if (!string.IsNullOrEmpty(table)) { query = query.Where(x => x.TableName == table); } // .GroupBy(c=>new { c.TableName}) var data = query.Select(s => new { s.TableName, s.Name, Fields = s.Fields.Select(x => x).ToList(),//.Union((s.CustomFields?.Select(s=>s.Field)??new List()).ToList()).ToList(), details = (s.PrintDetails ?? new List()) //.Select(c=>c.DetailFields) //s.DetailName, //s.DetailTableName, //DetailFields = (s.DetailFields ?? new string[] { }).Select(x => x).ToList().Union((s.DetailCustomgFields?.Select(s => s.Field) ?? new List()).ToList()).ToList(), }).ToList(); var tables = data.Select(s => s.TableName).ToList(); //明细表配置 var detailTableNames = data.SelectMany(x => x.details.Select(c => c.DetailTableName)).Where(x => x != null); tables.AddRange(detailTableNames); var tableOptions = DBServerProvider.DbContext.Set().Where(x => tables.Contains(x.TableName)) .OrderByDescending(x => x.OrderNo) .Select(s => new { s.TableName, name = s.ColumnCnName, width = s.ColumnWidth, field = s.ColumnName, s.EditType, s.DropNo, TableType = s.IsImage }) .ToList(); var options = data.Select(s => new { s.TableName, s.Name, Fields = tableOptions.Where(c => c.TableName == s.TableName && s.Fields.Contains(c.field)).ToList(), //明细表 TemplateDetails = s.details.Select(c => new { c.DetailName, c.DetailTableName, DetailFields = tableOptions.Where(x => x.TableName == c.DetailTableName && c.DetailFields.Contains(x.field)) .Select(s => new { s.field, s.name, TableType = s.TableType ?? -1 }).ToList() .Union((c.CustomgFields ?? new List()).Select(s => new { field = s.Field, name = s.Name, TableType = -1 })) }) }).ToList(); return options; } public static async Task GetPrintDataAsync(PrintQuery query) { var ops = _print.Where(x => x.TableName == query.Table).FirstOrDefault(); //if ((query.Detail || query.BatchMainAndDetail) && ops.DetailTableType == null) //{ // throw new Exception($"startup里面必须配置[{ops.TableName}]的明细表"); //} query.TemplateName = await DBServerProvider.DbContext.Set() .Where(x => x.PrintOptionsId == query.TemplateId) .Select(ops => ops.CustomName).FirstOrDefaultAsync(); var list = typeof(PrintContainer).GetMethod("GetDataAsync") .MakeGenericMethod(new Type[] { ops.TableType }) .Invoke(null, new object[] { query.Ids, query.Table, ops.Fields.Select(x => x).ToList(), ops.PrintDetails, query, ops }) as Task; return await list; } /// /// 获取明细表配置 /// /// /// /// /// /// /// /// /// /// public static async Task GetDataAsync(object[] ids, string table, List fields, List printDetails, PrintQuery parms, PrintOptions ops) where T : class,new() //where Detail : class { if (ids == null || ids.Length == 0) { return new List>(); } string key = typeof(T).GetKeyName(); if (parms.Detail || (printDetails?.Count > 0)) { fields.Add(key); } //else if (parms.BatchMainAndDetail || parms.BatchMain) //{ //} //else //{ // //不是批量打印的,默认只查第一条 // ids = new object[] { ids[0] }; //} PrintFilter filter = new PrintCustom(); var express = key.CreateExpression(ids, Enums.LinqExpressionType.In); var dbContext = DBServerProvider.GetEntityDbContext(); var queryable = dbContext.Set().Where(express); queryable = filter.Query(queryable, parms); var entities = await queryable.ToListAsync(); //主表数据 List> list = await ConvertListAsync(entities, ids, table, fields, parms); if (printDetails == null) { printDetails = new List(); } foreach (var mainData in list) { //获取明细表 foreach (var detail in printDetails) { var pro = detail.DetailTableType.GetProperty(key); if (pro == null) { throw new Exception($"明细表必须包括主表字段[{key}]"); } //var detailExpress = key.CreateExpression(ids, Enums.LinqExpressionType.In); //var detailQueryable = DBServerProvider.GetEFDbContext().Set().Where(detailExpress); //detailQueryable = filter.QueryDetail(detailQueryable, parms); //var detailEntities = await detailQueryable.ToListAsync(); fields = detail.DetailFields.ToList(); fields.Add(key); //var detailList = await ConvertListAsync(detailEntities, ids, detail.DetailTableName, fields, parms); var obj = typeof(PrintContainer).GetMethod("GetDetailDataAsync") .MakeGenericMethod(new Type[] { detail.DetailTableType }) .Invoke(null, new object[] { key, ids, fields, parms }); var detailList = await (obj as Task>>); string keyValue = mainData[key].ToString(); List> detailDic = new List>(); ; foreach (var detailItem in detailList) { if (detailItem[key].ToString() == keyValue) { detailDic.Add(detailItem); } } mainData[detail.DetailTableName] = detailDic; } } list = filter.QueryResult(list, parms, dbContext); return list; } public static async Task>> GetDetailDataAsync(string key, object[] ids, List fields, PrintQuery parms) where Detail : class, new() { PrintFilter filter = new PrintCustom(); var detailExpress = key.CreateExpression(ids, Enums.LinqExpressionType.In); var detailQueryable = DBServerProvider.GetEntityDbContext().Set(true).Where(detailExpress); detailQueryable = filter.QueryDetail(detailQueryable, parms); var detailEntities = await detailQueryable.ToListAsync(); var data = await ConvertListAsync(detailEntities, ids, typeof(Detail).Name, fields, parms); return data; } private static async Task>> ConvertListAsync(List entities, object[] ids, string table, List fields, PrintQuery query) { var columns = await DBServerProvider.DbContext.Set().Where(c => c.TableName == table).ToListAsync(); var tableOptions = columns.Where(c => fields.Contains(c.ColumnName)). Select(s => new { s.ColumnName, s.ColumnCnName, s.DropNo, s.ColumnType, isDate = s.IsImage == 4 || s.EditType == "date" }); List dictionaries = new List(); var dicNos = tableOptions.Select(s => s.DropNo).ToList(); if (dicNos.Count > 0) { dictionaries = DictionaryManager.GetDictionaries(dicNos, true).ToList(); } List> list = new List>(); var properties = typeof(T).GetProperties(); foreach (var data in entities) { Dictionary item = new Dictionary(); foreach (var field in fields) { var property = properties.Where(c => c.Name == field).FirstOrDefault(); var option = tableOptions.Where(c => c.ColumnName == field).FirstOrDefault(); string value = null; if (option.ColumnType == "decimal") { var deciVal = property.GetValue(data); if (deciVal != null) { value = ((decimal)deciVal).ToString("G29"); } } else { value = property.GetValue(data)?.ToString(); } string name = option?.ColumnCnName; if (string.IsNullOrEmpty(name)) { name = property.GetDisplayName(); } if (option == null || string.IsNullOrEmpty(value)) { item[property.Name] = value = value ?? ""; continue; } if (option.isDate) { value = value.GetDateTime().Value.ToString("yyyy-MM-dd"); } else if (!string.IsNullOrEmpty(option.DropNo)) { string val = dictionaries.Where(c => c.DicNo == option.DropNo).FirstOrDefault() ?.Sys_DictionaryList //这里多选的暂时没处理 ?.Where(c => c.DicValue == value)?.Select(s => s.DicName) .FirstOrDefault(); if (!string.IsNullOrEmpty(val)) { value = val; } } item[property.Name] = value; } list.Add(item); } return list; } } }