using System.Collections; using System.Data; using System.Reflection; using SqlSugar; using Tiobon.Core.Common.DB.Dapper; namespace Tiobon.Core.Controllers; /// /// 增删改查基础服务 /// /// /// /// /// /// public class BaseController : Controller { #region 初始化 protected IServiceBase _service; /// /// 初始化 (注入) /// public BaseController(IServiceBase service) { _service = service; } #endregion #region 基础接口 #region 查询 /// /// 根据条件查询数据 /// /// 条件 /// [HttpPost, Route("Query")] public virtual async Task> QueryByFilter([FromBody] QueryBody body) { var data = (await InvokeServiceAsync("QueryFilterPage", [body])) as ServicePageResult; return data; } public static T ConvertTo(object input) { if (input == null) { throw new ArgumentNullException(nameof(input)); } // 当T是Nullable类型时,需要获取其基础类型 Type targetType = typeof(T); Type nullableType = Nullable.GetUnderlyingType(targetType); targetType = nullableType ?? targetType; // 检查input是否已经是T类型 if (input is T) { return (T)input; } // 尝试转换 try { return (T)Convert.ChangeType(input, targetType); } catch (InvalidCastException) { throw new InvalidOperationException($"Cannot convert an instance of type {input.GetType().Name} to type {typeof(T).Name}."); } } /// /// 根据Id查询数据 /// /// 主键ID /// [HttpPost("Query/{Id}")] public virtual async Task> QueryById(long Id) { var entity = await InvokeServiceAsync("QueryById", [Id]); if (entity is null) return Failed("获取失败"); else return Success(ConvertTo(entity), "获取成功"); } /// /// 查询菜单表单信息 /// /// body /// [HttpPost("QueryForm")] public virtual async Task> QueryForm([FromBody] QueryForm body) { var entity = await InvokeServiceAsync("QueryForm", [body]) as ServiceFormResult; return entity; } #endregion #region 新增 /// /// 新增数据 /// /// /// [HttpPost("Insert")] public virtual async Task> Insert([FromBody] TInsertDto insertModel) { var data = Success(null, "新增成功"); var id = Convert.ToInt64(await InvokeServiceAsync("Add", [insertModel])); data.Success = id > 0; if (data.Success) data.Data = id.ObjToString(); else return Failed("新增失败"); return data; } /// /// 批量新增数据 /// /// [HttpPost, Route("BulkInsert")] public virtual async Task>> BulkInsert([FromBody] List insertModels) { var data = Success>(null, "新增成功"); var ids = await InvokeServiceAsync("Add", [insertModels]) as List; data.Success = ids.Any(); if (data.Success) data.Data = ids; else return Failed>("新增失败"); return data; } #endregion #region 更新 /// /// 更新数据 /// /// 主键ID /// /// [HttpPost("Update/{Id}")] public virtual async Task Put(long Id, [FromBody] TEditDto editModel) { var data = Success("更新成功"); var flag = Convert.ToBoolean(await InvokeServiceAsync("Update", [Id, editModel])); if (!flag) return Failed("更新失败"); return data; } /// /// 批量更新数据 /// /// [HttpPost, Route("BulkUpdate")] public virtual async Task BulkUpdate([FromBody] Dictionary editModels) { var data = Success("更新成功"); var flag = Convert.ToBoolean(await InvokeServiceAsync("Update", [editModels])); if (!flag) return Failed("更新失败"); return data; } #endregion #region 删除 /// /// 删除数据 /// /// 主键ID /// [HttpPost("Delete/{Id}")] public virtual async Task Delete(long Id) { var data = Success("作废成功"); var isExist = Convert.ToBoolean(await InvokeServiceAsync("AnyAsync", [Id])); if (!isExist) return Failed("作废失败"); data.Success = Convert.ToBoolean(await InvokeServiceAsync("DeleteById1", [Id])); if (!data.Success) return Failed("作废失败"); return data; } /// /// 批量删除数据 /// /// 主键IDs /// [HttpPost, Route("BulkDelete")] public virtual async Task BulkDelete([FromBody] long[] Ids) { var data = Success($"成功作废({Ids.Count()}笔数据)"); data.Success = Convert.ToBoolean(await InvokeServiceAsync("DeleteByIds1", [Ids])); if (!data.Success) return Failed("作废失败"); return data; } #endregion #endregion #region Excel导出 /// /// Excel导出 /// /// /// //[HttpPost, Route("ExportExcel")] //public async Task> ExportExcel([FromBody] QueryExport body) //{ // var data = (await InvokeServiceAsync("ExportExcel", [body])) as ServiceResult; // return data; //} [HttpPost, Route("ExportExcel")] public virtual async Task> ExportExcel([FromBody] QueryExport body) { QueryBody filter = new QueryBody(); filter.pageNum = 1; filter.pageSize = 1000000; filter.langId = body.langId; var condition = "1=1"; if (body.exportSet.SelectRowKeys != null && body.exportSet.SelectRowKeys.Any()) condition += $" AND Id IN({string.Join(",", body.exportSet.SelectRowKeys)})"; var data = (await InvokeServiceAsync("QueryFilterPage", [filter, condition, true])) as ServicePageResult; string sql = $@"SELECT * FROM Ghrs_PageSettingQuery WHERE IsEnable = 1 AND PageNo = '{body.menuName}' AND (defaultHidden = 'false' OR defaultHidden is null) ORDER BY SortNo ASC"; var columns = DbAccess.QueryList(sql); var fieldDescs = new Dictionary(); if (body.exportSet.ExFields.Any()) body.exportSet.ExFields.ForEach(x => { if (columns.Any(o => o.field == x)) fieldDescs.Add(x, columns.FirstOrDefault(o => o.field == x)?.label); }); else fieldDescs = columns.ToDictionary(item => item.field, item => item.label); var dt = ToDataTable(data.result.DT_TableDataT1, fieldDescs, null); // 获取所有列名 var dtColumns = dt.Columns; var id = SnowFlakeSingle.instance.getID(); var physicsPath = $"{Environment.CurrentDirectory}{Path.DirectorySeparatorChar}wwwroot"; var path = $"{$"{Path.DirectorySeparatorChar}files{Path.DirectorySeparatorChar}export{Path.DirectorySeparatorChar}{id}{Path.DirectorySeparatorChar}"}"; if (!Directory.Exists(physicsPath + path)) Directory.CreateDirectory(physicsPath + path); path = path + body.exportSet.TitleName + ".xlsx"; NPOIHelper.ExportExcel(dt, body.exportSet.TitleName, "sheet1", physicsPath + path); var result = new ExcelData(); result.filePath = path; result.fileName = body.exportSet.TitleName + ".xlsx"; return ServiceResult.OprateSuccess("导出成功", result); } /// /// 列名按照前端显示顺序导出 /// /// /// /// 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 DataTable ToDataTable(List list, Dictionary fieldDescs = null, params string[] propertyName) { var (fields, colunms) = Sort(fieldDescs, null); List propertyNameList = new List(); if (propertyName != null) { propertyNameList.AddRange(propertyName); } DataTable result = new DataTable(); if (list.Count > 0) { PropertyInfo[] propertys = list[0].GetType().GetProperties(); for (int i = 0; i < fields.Count; i++) { foreach (PropertyInfo pi in propertys) { if (propertyNameList.Count == 0) { //if (DBNull.Value.Equals(pi.PropertyType)) //{ // // pi.PropertyType = DateTime; //} Type colType = pi.PropertyType; if (colType.IsGenericType && colType.GetGenericTypeDefinition() == typeof(Nullable<>)) { colType = colType.GetGenericArguments()[0]; } if (fields[i] == pi.Name) { result.Columns.Add(colunms[i], colType); } //result.Columns.Add(pi.Name, pi.PropertyType); } else { if (propertyNameList.Contains(pi.Name)) { if (fields[i] == pi.Name) result.Columns.Add(fields[i], pi.PropertyType); } } } } for (int i = 0; i < list.Count; i++) { ArrayList tempList = new ArrayList(); for (int j = 0; j < fields.Count; j++) { foreach (PropertyInfo pi in propertys) { if (fields[j] == pi.Name) { if (propertyNameList.Count == 0) { object obj = pi.GetValue(list[i], null); tempList.Add(obj); } else { if (propertyNameList.Contains(pi.Name)) { object obj = pi.GetValue(list[i], null); tempList.Add(obj); } } } } } object[] array = tempList.ToArray(); result.LoadDataRow(array, true); } } return result; } #endregion #region Excel导入 [HttpPost("ImportExcel")] public async Task> ImportExcel(IFormFile file) { var data = (await InvokeServiceAsync("ImportExcel", [file])) as ServiceResult; return data; } #endregion #region Excel下载 [HttpGet("DownExcelTemplate"), AllowAnonymous] public async Task DownloadExcel(string menuName) { var result = (await InvokeServiceAsync("DownloadExcel", [menuName])) as ServiceResult; string path = result.Data; FileStream fs = new FileStream(path, FileMode.OpenOrCreate); fs.Close(); return File(new FileStream(path, FileMode.Open), "application/octet-stream", result.Message); } #endregion ///// ///// 反射调用service方法 ///// ///// ///// ///// //[NonAction] //private object InvokeService(string methodName, object[] parameters) //{ // return _service.GetType().GetMethod(methodName).Invoke(_service, parameters); //} ///// ///// 反射调用service方法 ///// ///// ///// 为要调用重载的方法参数类型:new Type[] { typeof(SaveDataModel) ///// ///// //[NonAction] //private object InvokeService(string methodName, Type[] types, object[] parameters) => _service.GetType().GetMethod(methodName, types).Invoke(_service, parameters); [NonAction] private async Task InvokeServiceAsync(string methodName, object[] parameters) { var task = _service.GetType().InvokeMember(methodName, BindingFlags.InvokeMethod, null, _service, parameters) as Task; if (task != null) await task; var result = task?.GetType().GetProperty("Result")?.GetValue(task); return result; } [NonAction] public ServiceResult Success(T data, string message = "成功") { return new ServiceResult() { Success = true, Message = message, Data = data, }; } // [NonAction] //public ServiceResult Success(T data, string msg = "成功",bool success = true) //{ // return new ServiceResult() // { // success = success, // msg = msg, // response = data, // }; //} [NonAction] public ServiceResult Success(string message = "成功") { return new ServiceResult() { Success = true, Message = message, Data = null, }; } [NonAction] public ServiceResult Failed(string message = "失败", int status = 500) { return new ServiceResult() { Success = false, Status = status, Message = message, Data = null, }; } [NonAction] public ServiceResult Failed(string message = "失败", int status = 500) { return new ServiceResult() { Success = false, Status = status, Message = message, Data = default, }; } //Mapper.Map(data).ToANew() [NonAction] public ServiceResult> SuccessPage(int page, int dataCount, int pageSize, List data, int pageCount, string message = "获取成功") { return new ServiceResult>() { Success = true, Message = message, Data = new PageModel(page, dataCount, pageSize, data) }; } [NonAction] public ServiceResult> SuccessPage(PageModel pageModel, string message = "获取成功") { return new ServiceResult>() { Success = true, Message = message, Data = pageModel }; } }