You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
481 lines
16 KiB
481 lines
16 KiB
using System.Collections;
|
|
using System.Data;
|
|
using System.Reflection;
|
|
using SqlSugar;
|
|
using Tiobon.Core.Common.DB.Dapper;
|
|
|
|
namespace Tiobon.Core.Controllers;
|
|
|
|
/// <summary>
|
|
/// 增删改查基础服务
|
|
/// </summary>
|
|
/// <typeparam name="IServiceBase"></typeparam>
|
|
/// <typeparam name="TEntity"></typeparam>
|
|
/// <typeparam name="TEntityDto"></typeparam>
|
|
/// <typeparam name="TInsertDto"></typeparam>
|
|
/// <typeparam name="TEditDto"></typeparam>
|
|
public class BaseController<IServiceBase, TEntity, TEntityDto, TInsertDto, TEditDto> : Controller
|
|
{
|
|
#region 初始化
|
|
protected IServiceBase _service;
|
|
/// <summary>
|
|
/// 初始化 (注入)
|
|
/// </summary>
|
|
public BaseController(IServiceBase service)
|
|
{
|
|
_service = service;
|
|
}
|
|
#endregion
|
|
|
|
|
|
#region 基础接口
|
|
|
|
#region 查询
|
|
/// <summary>
|
|
/// 根据条件查询数据
|
|
/// </summary>
|
|
/// <param name="body">条件</param>
|
|
/// <returns></returns>
|
|
[HttpPost, Route("Query")]
|
|
public virtual async Task<ServicePageResult<TEntityDto>> QueryByFilter([FromBody] QueryBody body)
|
|
{
|
|
var data = (await InvokeServiceAsync("QueryFilterPage", [body])) as ServicePageResult<TEntityDto>;
|
|
return data;
|
|
}
|
|
|
|
public static T ConvertTo<T>(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}.");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 根据Id查询数据
|
|
/// </summary>
|
|
/// <param name="Id">主键ID</param>
|
|
/// <returns></returns>
|
|
[HttpPost("Query/{Id}")]
|
|
public virtual async Task<ServiceResult<TEntityDto>> QueryById(long Id)
|
|
{
|
|
var entity = await InvokeServiceAsync("QueryById", [Id]);
|
|
if (entity is null)
|
|
return Failed<TEntityDto>("获取失败");
|
|
else
|
|
return Success<TEntityDto>(ConvertTo<TEntityDto>(entity), "获取成功");
|
|
}
|
|
/// <summary>
|
|
/// 查询菜单表单信息
|
|
/// </summary>
|
|
/// <param name="body">body</param>
|
|
/// <returns></returns>
|
|
[HttpPost("QueryForm")]
|
|
public virtual async Task<ServiceFormResult<TEntityDto>> QueryForm([FromBody] QueryForm body)
|
|
{
|
|
var entity = await InvokeServiceAsync("QueryForm", [body]) as ServiceFormResult<TEntityDto>;
|
|
return entity;
|
|
}
|
|
#endregion
|
|
|
|
#region 新增
|
|
/// <summary>
|
|
/// 新增数据
|
|
/// </summary>
|
|
/// <param name="insertModel"></param>
|
|
/// <returns></returns>
|
|
[HttpPost("Insert")]
|
|
public virtual async Task<ServiceResult<string>> Insert([FromBody] TInsertDto insertModel)
|
|
{
|
|
var data = Success<string>(null, "新增成功");
|
|
var id = Convert.ToInt64(await InvokeServiceAsync("Add", [insertModel]));
|
|
data.Success = id > 0;
|
|
if (data.Success)
|
|
data.Data = id.ObjToString();
|
|
else
|
|
return Failed<string>("新增失败");
|
|
|
|
return data;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 批量新增数据
|
|
/// </summary>
|
|
/// <param name="insertModels"></param>
|
|
[HttpPost, Route("BulkInsert")]
|
|
public virtual async Task<ServiceResult<List<long>>> BulkInsert([FromBody] List<TInsertDto> insertModels)
|
|
{
|
|
var data = Success<List<long>>(null, "新增成功");
|
|
var ids = await InvokeServiceAsync("Add", [insertModels]) as List<long>;
|
|
data.Success = ids.Any();
|
|
if (data.Success)
|
|
data.Data = ids;
|
|
else
|
|
return Failed<List<long>>("新增失败");
|
|
|
|
return data;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region 更新
|
|
/// <summary>
|
|
/// 更新数据
|
|
/// </summary>
|
|
/// <param name="Id">主键ID</param>
|
|
/// <param name="editModel"></param>
|
|
/// <returns></returns>
|
|
[HttpPost("Update/{Id}")]
|
|
public virtual async Task<ServiceResult> Put(long Id, [FromBody] TEditDto editModel)
|
|
{
|
|
var data = Success("更新成功");
|
|
var flag = Convert.ToBoolean(await InvokeServiceAsync("Update", [Id, editModel]));
|
|
if (!flag)
|
|
return Failed("更新失败");
|
|
return data;
|
|
}
|
|
/// <summary>
|
|
/// 批量更新数据
|
|
/// </summary>
|
|
/// <param name="editModels"></param>
|
|
[HttpPost, Route("BulkUpdate")]
|
|
public virtual async Task<ServiceResult> BulkUpdate([FromBody] Dictionary<long, TEditDto> editModels)
|
|
{
|
|
var data = Success("更新成功");
|
|
var flag = Convert.ToBoolean(await InvokeServiceAsync("Update", [editModels]));
|
|
if (!flag)
|
|
return Failed("更新失败");
|
|
return data;
|
|
}
|
|
#endregion
|
|
|
|
#region 删除
|
|
/// <summary>
|
|
/// 删除数据
|
|
/// </summary>
|
|
/// <param name="Id">主键ID</param>
|
|
/// <returns></returns>
|
|
[HttpPost("Delete/{Id}")]
|
|
public virtual async Task<ServiceResult> 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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 批量删除数据
|
|
/// </summary>
|
|
/// <param name="Ids">主键IDs</param>
|
|
/// <returns></returns>
|
|
[HttpPost, Route("BulkDelete")]
|
|
public virtual async Task<ServiceResult> 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导出
|
|
/// <summary>
|
|
/// Excel导出
|
|
/// </summary>
|
|
/// <param name="body"></param>
|
|
/// <returns></returns>
|
|
//[HttpPost, Route("ExportExcel")]
|
|
//public async Task<ServiceResult<ExcelData>> ExportExcel([FromBody] QueryExport body)
|
|
//{
|
|
// var data = (await InvokeServiceAsync("ExportExcel", [body])) as ServiceResult<ExcelData>;
|
|
// return data;
|
|
//}
|
|
|
|
[HttpPost, Route("ExportExcel")]
|
|
public virtual async Task<ServiceResult<ExcelData>> 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<TEntityDto>;
|
|
|
|
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<QueryExportColumn>(sql);
|
|
|
|
var fieldDescs = new Dictionary<string, string>();
|
|
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<ExcelData>.OprateSuccess("导出成功", result);
|
|
}
|
|
/// <summary>
|
|
/// 列名按照前端显示顺序导出
|
|
/// </summary>
|
|
/// <param name="columns"></param>
|
|
/// <param name="ExportFields"></param>
|
|
/// <returns></returns>
|
|
public static (List<string>, List<string>) Sort(Dictionary<string, string> columns, List<string> ExportFields)
|
|
{
|
|
List<string> fields = new List<string>();
|
|
List<string> colunms = new List<string>();
|
|
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<TEntityDto> list, Dictionary<string, string> fieldDescs = null, params string[] propertyName)
|
|
{
|
|
var (fields, colunms) = Sort(fieldDescs, null);
|
|
|
|
List<string> propertyNameList = new List<string>();
|
|
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<ServiceResult<ExcelData>> ImportExcel(IFormFile file)
|
|
{
|
|
var data = (await InvokeServiceAsync("ImportExcel", [file])) as ServiceResult<ExcelData>;
|
|
return data;
|
|
}
|
|
#endregion
|
|
|
|
#region Excel下载
|
|
[HttpGet("DownExcelTemplate"), AllowAnonymous]
|
|
public async Task<IActionResult> DownloadExcel(string menuName)
|
|
{
|
|
var result = (await InvokeServiceAsync("DownloadExcel", [menuName])) as ServiceResult<string>;
|
|
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
|
|
|
|
///// <summary>
|
|
///// 反射调用service方法
|
|
///// </summary>
|
|
///// <param name="methodName"></param>
|
|
///// <param name="parameters"></param>
|
|
///// <returns></returns>
|
|
//[NonAction]
|
|
//private object InvokeService(string methodName, object[] parameters)
|
|
//{
|
|
// return _service.GetType().GetMethod(methodName).Invoke(_service, parameters);
|
|
//}
|
|
///// <summary>
|
|
///// 反射调用service方法
|
|
///// </summary>
|
|
///// <param name="methodName"></param>
|
|
///// <param name="types">为要调用重载的方法参数类型:new Type[] { typeof(SaveDataModel)</param>
|
|
///// <param name="parameters"></param>
|
|
///// <returns></returns>
|
|
//[NonAction]
|
|
//private object InvokeService(string methodName, Type[] types, object[] parameters) => _service.GetType().GetMethod(methodName, types).Invoke(_service, parameters);
|
|
|
|
|
|
[NonAction]
|
|
private async Task<object> 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<T> Success<T>(T data, string message = "成功")
|
|
{
|
|
return new ServiceResult<T>() { Success = true, Message = message, Data = data, };
|
|
}
|
|
|
|
// [NonAction]
|
|
//public ServiceResult<T> Success<T>(T data, string msg = "成功",bool success = true)
|
|
//{
|
|
// return new ServiceResult<T>()
|
|
// {
|
|
// 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<T> Failed<T>(string message = "失败", int status = 500)
|
|
{
|
|
return new ServiceResult<T>() { Success = false, Status = status, Message = message, Data = default, };
|
|
}
|
|
|
|
//Mapper.Map(data).ToANew<TEntityDto>()
|
|
|
|
[NonAction]
|
|
public ServiceResult<PageModel<T>> SuccessPage<T>(int page, int dataCount, int pageSize, List<T> data, int pageCount, string message = "获取成功")
|
|
{
|
|
return new ServiceResult<PageModel<T>>() { Success = true, Message = message, Data = new PageModel<T>(page, dataCount, pageSize, data) };
|
|
}
|
|
|
|
[NonAction]
|
|
public ServiceResult<PageModel<T>> SuccessPage<T>(PageModel<T> pageModel, string message = "获取成功")
|
|
{
|
|
return new ServiceResult<PageModel<T>>() { Success = true, Message = message, Data = pageModel };
|
|
}
|
|
} |