From 2f56152fab0fa1ba70af42c8c24d7b32df2d2f5f Mon Sep 17 00:00:00 2001 From: xiaochanghai Date: Tue, 7 May 2024 14:52:09 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9BaseService=20Excel=E5=AF=BC?= =?UTF-8?q?=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/Base/BaseController.cs | 14 + Tiobon.Core.Api/Tiobon.Core.xml | 7 + .../Attribute/ExportDatatAttribute.cs | 42 +++ .../Extensions/IQueryableExtensions.cs | 351 ++++++++++++++++++ Tiobon.Core.Common/Helper/LoggerHelper.cs | 32 ++ Tiobon.Core.Common/Tiobon.Core.Common.csproj | 1 + Tiobon.Core.DataAccess/ReportHelper.cs | 68 ++++ Tiobon.Core.IServices/BASE/IBaseServices.cs | 1 + Tiobon.Core.Repository/BASE/BaseRepository.cs | 61 +-- Tiobon.Core.Services/BASE/BaseServices.cs | 9 + Tiobon.Core.Services/CommonServices.cs | 8 + .../Tiobon.Core.Services.csproj | 1 + Tiobon.Core/Tiobon.Core.Model.xml | 5 + Tiobon.Core/Tiobon.Core.xml | 14 + 14 files changed, 585 insertions(+), 29 deletions(-) create mode 100644 Tiobon.Core.Common/Attribute/ExportDatatAttribute.cs create mode 100644 Tiobon.Core.Common/Extensions/IQueryableExtensions.cs create mode 100644 Tiobon.Core.Common/Helper/LoggerHelper.cs create mode 100644 Tiobon.Core.DataAccess/ReportHelper.cs diff --git a/Tiobon.Core.Api/Controllers/Base/BaseController.cs b/Tiobon.Core.Api/Controllers/Base/BaseController.cs index d9ea99b6..576ec5b9 100644 --- a/Tiobon.Core.Api/Controllers/Base/BaseController.cs +++ b/Tiobon.Core.Api/Controllers/Base/BaseController.cs @@ -193,6 +193,20 @@ public class BaseController + /// Excel导出 + /// + /// + /// + [HttpPost, Route("Export")] + public async Task> Export([FromBody] QueryBody body) + { + var data = (await InvokeServiceAsync("Export", [body])) as ServiceResult; + return data; + } + #endregion + ///// ///// 反射调用service方法 ///// diff --git a/Tiobon.Core.Api/Tiobon.Core.xml b/Tiobon.Core.Api/Tiobon.Core.xml index 4bbc1e99..f5346e86 100644 --- a/Tiobon.Core.Api/Tiobon.Core.xml +++ b/Tiobon.Core.Api/Tiobon.Core.xml @@ -134,6 +134,13 @@ 主键IDs + + + Excel导出 + + + + 博客管理 diff --git a/Tiobon.Core.Common/Attribute/ExportDatatAttribute.cs b/Tiobon.Core.Common/Attribute/ExportDatatAttribute.cs new file mode 100644 index 00000000..6090b510 --- /dev/null +++ b/Tiobon.Core.Common/Attribute/ExportDatatAttribute.cs @@ -0,0 +1,42 @@ +namespace Tiobon.Core.Common; +/// +/// 视图类属性是字典值时根据属性值获取字典值 +/// +[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, Inherited = false, AllowMultiple = false)] +public sealed class ExportDatatAttribute : Attribute +{ + /// + /// 数据源字段名 + /// + public string ExportDataName { get; } + + /// + /// 数据源的model类型 + /// + public Type ExportDataType { get; } + + /// + /// 数据类型,(1)序列 (2)嵌套model (3)数据项 + /// + public string ExportDataFlag { get; } + + /// + /// 动态数据的字段名和类型 + /// + /// 数据源字段名 + /// 数据源的类型(typeof(类名)) + public ExportDatatAttribute(string name, Type type) + { + ExportDataName = name; + ExportDataType = type; + } + + /// + /// 标识 + /// + /// (1)序列 (2)嵌套model (3)数据项 + public ExportDatatAttribute(string flag) + { + ExportDataFlag = flag; + } +} \ No newline at end of file diff --git a/Tiobon.Core.Common/Extensions/IQueryableExtensions.cs b/Tiobon.Core.Common/Extensions/IQueryableExtensions.cs new file mode 100644 index 00000000..1abf731e --- /dev/null +++ b/Tiobon.Core.Common/Extensions/IQueryableExtensions.cs @@ -0,0 +1,351 @@ +using System.Collections; +using System.ComponentModel; +using System.Reflection; +using OfficeOpenXml; +using OfficeOpenXml.Style; +using SixLabors.ImageSharp; +using Tiobon.Core.Common.Helper; + +namespace Tiobon.Core.Common.Extensions; + +public static class IQueryableExtensions +{ + static int EXPORT_FILE_PAGESIZE = 10000; + /// + /// IQueryable数据写入文件(Excel) + /// + /// + /// + /// + /// + /// + /// + /// + /// + public static void IntoFileFromLinqExcel(this IQueryable db, string fname, string splitstr, List exportFields, List exportFieldsWidth, string headText = "", string totalText = "", bool isNeedItemNo = false) where T : class + { + if (db.IsNull()) + return; + //查询文件状态 + if (File.Exists(fname)) + { + LoggerHelper.SendLog("文件已生成 " + fname); + return; + } + LoggerHelper.SendLog("正在生成文件 " + fname); + DateTime dt_start = DateTime.Now; + if (!File.Exists(fname)) + File.Create(fname).Close(); + //获取需要导出的字段 + Dictionary fieldDescs = GetFieldDesc(); + int dbCount = db.Count(); + + //列名排序,返回有序列表 + var (fields, colunms) = Sort(fieldDescs, exportFields); + using (FileStream stream = File.Create(fname)) + { + using (ExcelPackage package = new ExcelPackage(stream)) + { + ExcelWorksheet worksheet = package.Workbook.Worksheets.Add("sheet1"); + + + var colunmsCount = colunms.Count; + + var startCol = 0; + var startRow = 1; // 初始行数 + if (isNeedItemNo) + startCol = 1; + + + if (!string.IsNullOrEmpty(headText)) + { + worksheet.Cells[startRow, 1].Value = headText; + worksheet.Cells[startRow, 1, 1, colunmsCount + startCol].Merge = true; + worksheet.Cells[startRow, 1, 1, colunmsCount + startCol].Style.Font.Bold = true; + worksheet.Cells[startRow, 1, 1, colunmsCount + startCol].Style.HorizontalAlignment = ExcelHorizontalAlignment.Center; // Alignment is center + worksheet.Cells[startRow, 1, 1, colunmsCount + startCol].Style.Font.Size = 14; + startRow++; + } + + if (isNeedItemNo) + { + worksheet.Cells[startRow, 1].Value = "序号"; + worksheet.Cells[startRow, 1, startRow, 1].Style.Font.Bold = true; + worksheet.Cells[startRow, 1, startRow, 1].Style.VerticalAlignment = OfficeOpenXml.Style.ExcelVerticalAlignment.Center; + worksheet.Cells[startRow, 1, startRow, 1].Style.HorizontalAlignment = OfficeOpenXml.Style.ExcelHorizontalAlignment.Center; + } + + //写入列名 + for (int i = 0; i < fields.Count; ++i) + { + worksheet.Cells[startRow, i + 1 + startCol].Value = fields[i]; + worksheet.Cells[startRow, i + 1 + startCol, startRow, i + 1 + startCol].Style.Font.Bold = true; + worksheet.Cells[startRow, i + 1 + startCol, startRow, i + 1 + startCol].Style.VerticalAlignment = OfficeOpenXml.Style.ExcelVerticalAlignment.Center; + worksheet.Cells[startRow, i + 1 + startCol, startRow, i + 1 + startCol].Style.HorizontalAlignment = OfficeOpenXml.Style.ExcelHorizontalAlignment.Center; + } + + startRow++; + + //查看数据是否过大,需要分页 + int totalPageNum = (dbCount + EXPORT_FILE_PAGESIZE - 1) / EXPORT_FILE_PAGESIZE; + //遍历每一页 + for (int pageNum = 0; pageNum < totalPageNum; ++pageNum) + { + var list = db.Skip(pageNum * EXPORT_FILE_PAGESIZE).Take(EXPORT_FILE_PAGESIZE).ToList(); + //遍历每行 + for (int row = 0; row < list.Count; ++row) + { + if (isNeedItemNo) + { + worksheet.Cells[row + startRow, 1].Value = row + 1; + worksheet.Cells[row + startRow, 1, row + startRow, 1].Style.VerticalAlignment = OfficeOpenXml.Style.ExcelVerticalAlignment.Center; + worksheet.Cells[row + startRow, 1, row + startRow, 1].Style.HorizontalAlignment = OfficeOpenXml.Style.ExcelHorizontalAlignment.Center; + } + //遍历需要写入文件的字段 + for (int i = 0; i < colunms.Count; ++i) + { + worksheet.Cells[row + startRow, i + 1 + startCol].Value = ConvertData2String(list[row], colunms[i]); + worksheet.Cells[row + startRow, i + 1 + startCol, row + startRow, i + 1 + startCol].Style.VerticalAlignment = OfficeOpenXml.Style.ExcelVerticalAlignment.Center; + worksheet.Cells[row + startRow, i + 1 + startCol, row + startRow, i + 1 + startCol].Style.HorizontalAlignment = OfficeOpenXml.Style.ExcelHorizontalAlignment.Center; + } + } + } + + if (!string.IsNullOrEmpty(totalText)) + { + worksheet.Cells[dbCount + startRow, 1].Value = "总计:"; + worksheet.Cells[dbCount + startRow, 1, dbCount + startRow, 1].Style.VerticalAlignment = OfficeOpenXml.Style.ExcelVerticalAlignment.Center; + worksheet.Cells[dbCount + startRow, 1, dbCount + startRow, 1].Style.HorizontalAlignment = OfficeOpenXml.Style.ExcelHorizontalAlignment.Center; + + worksheet.Cells[dbCount + startRow, 2, dbCount + startRow, colunms.Count + startCol].Value = totalText; + worksheet.Cells[dbCount + startRow, 2, dbCount + startRow, colunms.Count + startCol].Merge = true; + startRow++; + } + + using (ExcelRange r = worksheet.Cells[1, 1, dbCount + startRow - 1, fields.Count + startCol]) + { + r.Style.Border.Top.Style = ExcelBorderStyle.Thin; + r.Style.Border.Left.Style = ExcelBorderStyle.Thin; + r.Style.Border.Right.Style = ExcelBorderStyle.Thin; + r.Style.Border.Bottom.Style = ExcelBorderStyle.Thin; + + r.Style.Border.Top.Color.SetColor(Color.Black); + r.Style.Border.Left.Color.SetColor(Color.Black); + r.Style.Border.Right.Color.SetColor(Color.Black); + r.Style.Border.Bottom.Color.SetColor(Color.Black); + } + if (isNeedItemNo) + { + worksheet.Column(1).Width = 20;//设置列宽为默认值 + } + //设置列宽 + if (exportFieldsWidth == null || exportFieldsWidth.Count < fields.Count) + { + for (int i = 0; i < fields.Count; ++i) + { + worksheet.Column(i + 1 + startCol).Width = 20;//设置列宽为默认值 + } + } + else + { + for (int i = 0; i < fields.Count; ++i) + { + worksheet.Column(i + 1 + startCol).Width = exportFieldsWidth[i];//设置列宽为前段配置的值 + } + } + + package.Workbook.Properties.Title = "数据导出"; + package.Workbook.Properties.Author = "SUZHOUEU"; + package.Workbook.Properties.Comments = "苏州一优信息技术有限公司提供技术支持!"; + + package.Workbook.Properties.Company = "苏州一优信息技术有限公司"; + + package.Workbook.Properties.SetCustomPropertyValue("Checked by", "SimonHsiao"); + package.Workbook.Properties.SetCustomPropertyValue("AssemblyName", "SUZHOUEU"); + + package.Save(); + + } + } + LoggerHelper.SendLog("生成文件 " + fname + " 完毕 " + dbCount + " 耗时 " + (int)(DateTime.Now - dt_start).TotalSeconds); + } + private static string ConvertData2String(T t, string field) where T : class + { + if (t.FieldTypeIsDateTime(field)) + { + DateTime? time = t.GetDateTimeValueFromField(field); + if (time != null) + { + if (time.Value.ToString("HH:mm:ss") == "00:00:00") + { + return time.Value.ToString("yyyy-MM-dd"); + } + else + { + return time.Value.ToString("yyyy-MM-dd HH:mm:ss"); + } + } + else + { + return string.Empty; + } + } + else + { + return t.GetStringValueFromField(field); + } + } + /// + /// 列名按照前端显示顺序导出 + /// + /// + /// + /// + public static (List, List) Sort(Dictionary columns, List ExportFields) + { + List fields = new List(); + List colunms = new List(); + if (ExportFields == null || ExportFields.Count == 0) + { + return (columns.Keys.ToList(), columns.Values.ToList()); + } + + foreach (var field in ExportFields) + { + foreach (var item in columns) + { + if (item.Key == field) + { + fields.Add(item.Key); + colunms.Add(item.Value); + } + } + } + + return (fields, colunms); + } + + /// + /// 获取数据 + /// + /// 对象 + /// + /// + public static List GetPropertyData(T obj, List colunms) where T : class + { + List data = new List(); + //声明obj的类型 + Type type = obj.GetType(); + // 获取obj类型的所有属性信息 + System.Reflection.PropertyInfo[] PropertyList = type.GetProperties(); + //循环每一个属性 + foreach (var item in PropertyList) + { + // 获取自定义特性 + object[] export = item.GetCustomAttributes(typeof(ExportDatatAttribute), true); + object[] descript = item.GetCustomAttributes(typeof(DescriptionAttribute), true); + //判断是否需要导出 + if (export.Length > 0) + { + //取值 + var exdesc = ((ExportDatatAttribute)export[0]); + // 是否嵌套 + if (exdesc != null) + { + //是否是序列 + if (exdesc.ExportDataFlag == "1") + { + var tmp = item.GetValue(obj) as IEnumerable; //List + if (tmp != null) + { + foreach (var o in tmp) + { + data.AddRange(GetPropertyData(o, colunms)); + } + } + } + // 如果是嵌套model + else if (exdesc.ExportDataFlag == "2") + { + var tmp = item.GetValue(obj); + if (tmp != null) + { + data.AddRange(GetPropertyData(tmp, colunms)); + } + } + else if (exdesc.ExportDataFlag == "3") + { + if (colunms.Contains(item.Name)) + { + data.Add(item.GetValue(obj).ToString()); + } + } + } + } + else if (descript.Length > 0) + { + if (colunms.Contains(item.Name)) + { + data.Add(item.GetValue(obj).ToString()); + } + } + } + return data; + } + + #region 获取字段描述 + /// + /// 对象字段描述 + /// + private static Dictionary> m_FieldDesc = new Dictionary>(); + + /// + /// 获取字段的描述(描述 - 列名) + /// + /// + /// + public static Dictionary GetFieldDesc() + { + var type = typeof(T).ToString(); + lock (m_FieldDesc) + { + if (m_FieldDesc.ContainsKey(type)) + return m_FieldDesc[type]; + } + Dictionary dic = new Dictionary(); + try + { + PropertyInfo[] peroperties = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance); + if (peroperties != null) + { + foreach (PropertyInfo property in peroperties) + { + object[] objs = property.GetCustomAttributes(typeof(DescriptionAttribute), true); + if (objs.Length > 0) + { + var desc = ((DescriptionAttribute)objs[0]).Description.Trim(); + if (!dic.ContainsKey(desc)) + { + dic.Add(desc, property.Name); + } + else + { + dic[desc] = property.Name; + } + } + } + } + } + catch //(Exception ex) + { + } + lock (m_FieldDesc) + { + if (!m_FieldDesc.ContainsKey(type)) + m_FieldDesc.Add(type, dic); + } + return dic; + } + #endregion + +} \ No newline at end of file diff --git a/Tiobon.Core.Common/Helper/LoggerHelper.cs b/Tiobon.Core.Common/Helper/LoggerHelper.cs new file mode 100644 index 00000000..dbd0813f --- /dev/null +++ b/Tiobon.Core.Common/Helper/LoggerHelper.cs @@ -0,0 +1,32 @@ +namespace Tiobon.Core.Common.Helper; + +/// +/// 日志操作 +/// +public static class LoggerHelper +{ + /// + /// console日志 + /// + /// + public static void Info(string msg) + { + Console.WriteLine($"{DateTime.Now:HH:mm:ss} {msg}"); + } + /// + /// 正常日志 + /// + /// + public static void SendLog(string msg) + { + Console.WriteLine($"{DateTime.Now:HH:mm:ss} {msg}"); + } + /// + /// 错误日志 + /// + /// + public static void SendLogError(string msg) + { + Console.WriteLine($"{DateTime.Now:HH:mm:ss} {msg}"); + } +} diff --git a/Tiobon.Core.Common/Tiobon.Core.Common.csproj b/Tiobon.Core.Common/Tiobon.Core.Common.csproj index 643cbbfb..a8dfb746 100644 --- a/Tiobon.Core.Common/Tiobon.Core.Common.csproj +++ b/Tiobon.Core.Common/Tiobon.Core.Common.csproj @@ -43,6 +43,7 @@ + diff --git a/Tiobon.Core.DataAccess/ReportHelper.cs b/Tiobon.Core.DataAccess/ReportHelper.cs new file mode 100644 index 00000000..ac14bf2e --- /dev/null +++ b/Tiobon.Core.DataAccess/ReportHelper.cs @@ -0,0 +1,68 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Linq.Dynamic.Core; +using System.Threading.Tasks; +using SqlSugar; +using Tiobon.Core.Common; +using Tiobon.Core.Common.DB; +using Tiobon.Core.Common.Extensions; +using Tiobon.Core.Model.Models; +namespace Tiobon.Core.DataAccess; + +/// +/// 报表辅助类 +/// +public static class ReportHelper +{ + + #region 文件下载 + /// + /// 生成文件,并通知用户下载(IQueryable) + /// + /// + /// + /// 导出模块名称(JobSetting.xxx) + /// + /// + /// + /// + /// + /// + /// + public static async Task SendFile(IQueryable list, string modelName, List exportFields, List exportFieldsWidth, string sort = null, string headText = "", string totalText = "", bool isNeedItemNo = false) where T : class + { + + if (list == null) + throw new Exception("生成文件失败"); + //生成文件至文件服务器 + var fid = SnowFlakeSingle.Instance.NextId(); + var path = $"{$"{Environment.CurrentDirectory}{Path.DirectorySeparatorChar}wwwroot{Path.DirectorySeparatorChar}files{Path.DirectorySeparatorChar}export{Path.DirectorySeparatorChar}{fid}{Path.DirectorySeparatorChar}"}"; + if (!Directory.Exists(path)) + Directory.CreateDirectory(path); + var fname = $"{modelName}.xlsx"; + + list = string.IsNullOrEmpty(sort) ? list : list.OrderBy(sort); + list.IntoFileFromLinqExcel(path + fname, ",", exportFields, exportFieldsWidth, headText, totalText, isNeedItemNo); + + using var _context = ContextFactory.CreateContext(); + + Ghre_Attachment fileAttachment = new Ghre_Attachment(); + fileAttachment.Id = fid; + fileAttachment.AttachFileName = fname; + fileAttachment.CreateBy = App.User.ID; + fileAttachment.CreateTime = DateTime.Now; + fileAttachment.AttachmentName = fname; + fileAttachment.AttachFileExtension = "xlsx"; + fileAttachment.AttachFileSize = 0; + fileAttachment.PhysicsPath = $"/files/export/{fid}/" + fname; + fileAttachment.AttachmentType = "xlsx"; + + await _context.Ghre_Attachment.AddAsync(fileAttachment); + await _context.SaveChangesAsync(); + return fid; + } + #endregion + +} \ No newline at end of file diff --git a/Tiobon.Core.IServices/BASE/IBaseServices.cs b/Tiobon.Core.IServices/BASE/IBaseServices.cs index c440fc4e..d49ffac3 100644 --- a/Tiobon.Core.IServices/BASE/IBaseServices.cs +++ b/Tiobon.Core.IServices/BASE/IBaseServices.cs @@ -141,6 +141,7 @@ namespace Tiobon.Core.IServices.BASE Task> QueryPage(Expression> whereExpression, int pageIndex = 1, int pageSize = 20, string orderByFields = null); Task> QueryFilterPage([FromBody] QueryBody body); + Task> Export([FromBody] QueryBody body); Task> QueryMuch( Expression> joinExpression, diff --git a/Tiobon.Core.Repository/BASE/BaseRepository.cs b/Tiobon.Core.Repository/BASE/BaseRepository.cs index 891b8ea4..caddac92 100644 --- a/Tiobon.Core.Repository/BASE/BaseRepository.cs +++ b/Tiobon.Core.Repository/BASE/BaseRepository.cs @@ -473,39 +473,42 @@ namespace Tiobon.Core.Repository.Base var query = _db.Queryable(); string conditions = "1=1"; - foreach (JProperty jProperty in filter.jsonParam.Properties()) - { - var name = jProperty.Name; - var value = jProperty.Value.ToString(); - if (!string.IsNullOrWhiteSpace(value)) + if (filter.jsonParam != null) + foreach (JProperty jProperty in filter.jsonParam.Properties()) { - var jsonParam = JsonConvert.DeserializeObject(value); - - switch (jsonParam.operationKey) + var name = jProperty.Name; + var value = jProperty.Value.ToString(); + if (!string.IsNullOrWhiteSpace(value)) { - case "Include": - conditions += $" AND {name} LIKE '%{jsonParam.columnValue}%'"; - break; - case "NotInclude": - conditions += $" AND {name} NOT LIKE '%{jsonParam.columnValue}%'"; - break; - case "IsNull": - conditions += $" AND {name} IS NULL"; - break; - case "NotNull": - conditions += $" AND {name} IS NOT NULL"; - break; - case "Equal": - conditions += $" AND {name} ='{jsonParam.columnValue}'"; - break; - case "NotEqual": - conditions += $" AND {name} !='{jsonParam.columnValue}'"; - break; - default: - break; + var jsonParam = JsonConvert.DeserializeObject(value); + + switch (jsonParam.operationKey) + { + case "Include": + conditions += $" AND {name} LIKE '%{jsonParam.columnValue}%'"; + break; + case "NotInclude": + conditions += $" AND {name} NOT LIKE '%{jsonParam.columnValue}%'"; + break; + case "IsNull": + conditions += $" AND {name} IS NULL"; + break; + case "NotNull": + conditions += $" AND {name} IS NOT NULL"; + break; + case "Equal": + conditions += $" AND {name} ='{jsonParam.columnValue}'"; + break; + case "NotEqual": + conditions += $" AND {name} !='{jsonParam.columnValue}'"; + break; + default: + break; + } } } - } + if (filter.pageSize == 0) + filter.pageSize = 10000; query = query.Where(conditions); var list = await query .OrderByIF(!string.IsNullOrEmpty(filter.Sorting), filter.Sorting) diff --git a/Tiobon.Core.Services/BASE/BaseServices.cs b/Tiobon.Core.Services/BASE/BaseServices.cs index 7a19b03d..344f79df 100644 --- a/Tiobon.Core.Services/BASE/BaseServices.cs +++ b/Tiobon.Core.Services/BASE/BaseServices.cs @@ -4,6 +4,7 @@ using System.Reflection; using AgileObjects.AgileMapper; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using MySqlX.XDevAPI.Common; using SqlSugar; using Tiobon.Core.Common; using Tiobon.Core.Common.DB.Dapper; @@ -12,6 +13,7 @@ using Tiobon.Core.Common.Enums; using Tiobon.Core.Common.Extensions; using Tiobon.Core.Common.Helper; using Tiobon.Core.Common.UserManager; +using Tiobon.Core.DataAccess; using Tiobon.Core.IRepository.Base; using Tiobon.Core.IServices.BASE; using Tiobon.Core.Model; @@ -788,6 +790,13 @@ public class BaseServices : IBaseServ return new ServicePageResult(body.pageNum, data.result.DT_TablePageInfoT1.TotalCount, body.pageSize, Mapper.Map(data.result.DT_TableDataT1).ToANew>()); + } + public async Task> Export(QueryBody body) + { + var data = await BaseDal.QueryFilterPage(body); + var fileId = await ReportHelper.SendFile(data.result.DT_TableDataT1.AsQueryable(), $"测试测试", null, null, null, null); + return ServiceResult.OprateSuccess("导出成功", fileId); + } public async Task> QueryMuch(Expression> joinExpression, Expression> selectExpression, Expression> whereLambda = null) where T : class, new() diff --git a/Tiobon.Core.Services/CommonServices.cs b/Tiobon.Core.Services/CommonServices.cs index fefb4016..34569359 100644 --- a/Tiobon.Core.Services/CommonServices.cs +++ b/Tiobon.Core.Services/CommonServices.cs @@ -276,6 +276,14 @@ public partial class CommonServices : BaseServices>, ICommon sql = string.Format(sql, param.menuName, App.User.ID, param.langId); result.JM_PageControlT1.Toolbar = DbAccess.QueryList(sql); + if (param.menuName == "F_QuestionBank") + { + var toolbar = result.JM_PageControlT1.Toolbar.Where(x => x.fnKey == "NewYN").FirstOrDefault(); + if (toolbar != null) { toolbar.fnKey = "TBD1YN"; } + toolbar = result.JM_PageControlT1.Toolbar.Where(x => x.fnKey == "UpdateYN").FirstOrDefault(); + if (toolbar != null) { toolbar.fnKey = "TBD2YN"; } + } + #endregion #region 定义表格页面的栏位, 含 表格栏位, 常用查询栏位, 高级查询栏位,可编辑栏位 diff --git a/Tiobon.Core.Services/Tiobon.Core.Services.csproj b/Tiobon.Core.Services/Tiobon.Core.Services.csproj index 6557920a..d92bb106 100644 --- a/Tiobon.Core.Services/Tiobon.Core.Services.csproj +++ b/Tiobon.Core.Services/Tiobon.Core.Services.csproj @@ -26,6 +26,7 @@ + diff --git a/Tiobon.Core/Tiobon.Core.Model.xml b/Tiobon.Core/Tiobon.Core.Model.xml index 882a816e..ade0160c 100644 --- a/Tiobon.Core/Tiobon.Core.Model.xml +++ b/Tiobon.Core/Tiobon.Core.Model.xml @@ -3297,6 +3297,11 @@ 题目(Dto.View) + + + 答案 + + 题目答案(Dto.View) diff --git a/Tiobon.Core/Tiobon.Core.xml b/Tiobon.Core/Tiobon.Core.xml index dd91cc29..f5346e86 100644 --- a/Tiobon.Core/Tiobon.Core.xml +++ b/Tiobon.Core/Tiobon.Core.xml @@ -134,6 +134,13 @@ 主键IDs + + + Excel导出 + + + + 博客管理 @@ -525,6 +532,13 @@ 题目(Controller) + + + 根据Id查询数据 + + 主键ID + + 新增数据