using Furion.DatabaseAccessor;
using Furion.DatabaseAccessor.Extensions;
using Furion.DependencyInjection;
using Furion.DynamicApiController;
using Furion.FriendlyException;
using Admin.NET.Core;
using Mapster;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System.Linq.Dynamic.Core;
using Microsoft.AspNetCore.Http;
using System.Text;
using System.Web;
using System.ComponentModel;
using System.Data;
namespace @Model.NameSpace
{
///
/// @(@Model.BusName)服务
///
[ApiDescriptionSettings("@Model.ModuleName", Name = "@Model.ClassName", Order = 100)]
[Route("api")]
public class @(@Model.ClassName)Service : I@(@Model.ClassName)Service, IDynamicApiController, ITransient
{
private readonly IRepository<@(@Model.ClassName),@(@Model.DatabaseName)> _@(@Model.CamelizeClassName)Rep;
@foreach (var column in Model.TableField){
if(@column.EffectType == "fk" && @column.FkEntityName != "" && @column.FkColumnName != ""){
@:private readonly IRepository<@(@column.FkEntityName)> _@(@column.LowerFkEntityName)Rep;
}
}
private readonly IRepository _sysDictTypeRep;
private readonly IRepository _sysDictDataRep;
private readonly ISysExcelTemplateService _sysExcelTemplateService;
private readonly static object _lock = new();
@if(@Model.IsFile)
{
@:private readonly IRepository _sysFileInfoRep;
}
public @(@Model.ClassName)Service(
@foreach (var column in Model.TableField){
if(@column.EffectType == "fk" && @column.FkEntityName != "" && @column.FkColumnName != ""){
@:IRepository<@(@column.FkEntityName)> @(@column.LowerFkEntityName)Rep,
}
}
IRepository<@(@Model.ClassName),@(@Model.DatabaseName)> @(@Model.CamelizeClassName)Rep
@if(@Model.IsFile)
{
@:,IRepository sysFileInfoRep,
}
,IRepository sysDictTypeRep
,IRepository sysDictDataRep
,ISysExcelTemplateService sysExcelTemplateService
)
{
@foreach (var column in Model.TableField){
if(@column.EffectType == "fk" && @column.FkEntityName != "" && @column.FkColumnName != ""){
@:_@(@column.LowerFkEntityName)Rep = @(@column.LowerFkEntityName)Rep;
}
}
_@(@Model.CamelizeClassName)Rep = @(@Model.CamelizeClassName)Rep;
@if(@Model.IsFile)
{
@:_sysFileInfoRep = sysFileInfoRep;
}
_sysDictTypeRep = sysDictTypeRep;
_sysDictDataRep = sysDictDataRep;
_sysExcelTemplateService = sysExcelTemplateService;
}
///
/// 分页查询@(@Model.BusName)
///
///
///
[HttpGet("@Model.ClassName/page")]
public async Task> Page([FromQuery] @(@Model.ClassName)Search input)
{
var @(@Model.CamelizeClassName)s = await _@(@Model.CamelizeClassName)Rep.DetachedEntities
@foreach (var column in Model.TableField){
if (@column.QueryWhether == "Y"){
if (@column.NetType == "string"){
if (@column.QueryType == "like"){
@:.Where(!string.IsNullOrEmpty(input.@column.ColumnName), u => EF.Functions.Like(u.@(@column.ColumnName), $"%{input.@(@column.ColumnName).Trim()}%"))
} else {
@:.Where(!string.IsNullOrEmpty(input.@column.ColumnName), u => u.@(@column.ColumnName) @column.QueryType input.@(@column.ColumnName))
}
} else {
if (@column.EffectType == "fk"){
@:.Where(input.@column.ColumnName > 0, u => u.@(@column.ColumnName) @column.QueryType input.@(@column.ColumnName))
}
if (@column.EffectType == "datepicker" && @column.QueryType == "between"){
@:.Where(input.@column.ColumnName!=null, u => u.@(@column.ColumnName)>= Convert.ToDateTime(input.@(@column.ColumnName)[0]+" 00:00:00") && u.@(@column.ColumnName)<= Convert.ToDateTime(input.@(@column.ColumnName)[1]+" 23:59:59"))
}
else if (@column.EffectType == "datetimepicker" && @column.QueryType == "between"){
@:.Where(input.@column.ColumnName!=null, u => u.@(@column.ColumnName)>= Convert.ToDateTime(input.@(@column.ColumnName)[0]) && u.@(@column.ColumnName)<= Convert.ToDateTime(input.@(@column.ColumnName)[1]))
}
else {
@:.Where(input.@column.ColumnName != null, u => u.@(@column.ColumnName) @column.QueryType input.@(@column.ColumnName))
}
}
}
}
.OrderBy(PageInputOrder.OrderBuilder<@(@Model.ClassName)Search>(input))
.ProjectToType<@(@Model.ClassName)Output>()
.ToADPagedListAsync(input.PageNo, input.PageSize);
@if(@Model.IsFile)
{
@:@(@Model.CamelizeClassName)s.Rows.ToList().ForEach(item =>
@:{
foreach (var column in Model.FileTableField){
@:item.@(@column.ColumnName) = item.@(@column.ColumnName)_Str.GetFiles(_sysFileInfoRep);
}
@:});
}
return @(@Model.CamelizeClassName)s;
}
///
/// 不分页查询@(@Model.BusName)列表
///
/// @(@Model.BusName)查询参数
/// (@Model.BusName)实例列表
[HttpGet("@Model.ClassName/listNonPage")]
public async Task> ListNonPageAsync([FromQuery] @(@Model.ClassName)SearchNonPage input)
{
@foreach (var column in Model.TableField)
{
if (@column.QueryWhether == "Y")
{
if(@column.NetType == "string" && @column.QueryType != "isNotNull"){
@:var p@(@column.ColumnName) = input.@(@column.ColumnName)?.Trim() ?? "";
} else if(@column.QueryType != "isNotNull"){
@:var p@(@column.ColumnName) = input.@(@column.ColumnName);
}
}
}
var @(@Model.CamelizeClassName)s = await _@(@Model.CamelizeClassName)Rep.DetachedEntities
@foreach (var column in Model.TableField)
{
if (@column.QueryWhether == "Y")
{
if(@column.QueryType == "isNotNull")
{
@:.Where(u => u.@(@column.ColumnName) != null)
}
else if (@column.NetType == "string")
{
if (@column.QueryType == "like")
{
@:.Where(!string.IsNullOrEmpty(p@(@column.ColumnName)), u => EF.Functions.Like(u.@(@column.ColumnName), $"%{p@(@column.ColumnName)}%"))
} else
{
@:.Where(!string.IsNullOrEmpty(p@(@column.ColumnName)), u => u.@(@column.ColumnName) @column.QueryType p@(@column.ColumnName))
}
} else if (@column.EffectType == "datepicker"&&@column.QueryType == "between")
{
@:.Where(input.@column.ColumnName!=null, u => u.@(@column.ColumnName)>= Convert.ToDateTime(input.@(@column.ColumnName)[0]+" 00:00:00") && u.@(@column.ColumnName)<= Convert.ToDateTime(input.@(@column.ColumnName)[1]+" 23:59:59"))
} else if (@column.EffectType == "datetimepicker" && @column.QueryType == "between"){
@:.Where(input.@column.ColumnName!=null, u => u.@(@column.ColumnName)>= Convert.ToDateTime(input.@(@column.ColumnName)[0]) && u.@(@column.ColumnName)<= Convert.ToDateTime(input.@(@column.ColumnName)[1]))
}else if (@column.EffectType == "fk")
{
@:.Where(p@(@column.ColumnName) > 0, u => u.@(@column.ColumnName) @column.QueryType p@(@column.ColumnName))
} else {
@:.Where(p@(@column.ColumnName) != null, u => u.@(@column.ColumnName) @column.QueryType p@(@column.ColumnName))
}
}
}
.OrderBy(PageInputOrder.OrderNonPageBuilder(input))
.ProjectToType<@(@Model.ClassName)Output>()
.ToListAsync();
@if(@Model.IsFile)
{
@:@(@Model.CamelizeClassName)s.ForEach(item =>
@:{
foreach (var column in Model.FileTableField){
@:item.@(@column.ColumnName) = item.@(@column.ColumnName)_Str.GetFiles(_sysFileInfoRep);
}
@:});
}
return @(@Model.CamelizeClassName)s;
}
///
/// 获取@(@Model.BusName)
///
///
///
[HttpGet("@Model.ClassName/detail")]
public async Task<@(@Model.ClassName)Output> Get([FromQuery] Querye@(@Model.ClassName)Input input)
{
@foreach (var column in Model.TableField){
if (@column.ColumnKey == "True"){
@:return (await _@(@Model.CamelizeClassName)Rep.DetachedEntities.FirstOrDefaultAsync(u => u.@(@column.ColumnName) == input.@(@column.ColumnName))).Adapt<@(@Model.ClassName)Output>();
}else{
if (@Model.IsOnlyQuery == true){
@:return null;
}
}
}
}
///
/// 获取@(@Model.BusName)列表
///
///
///
[HttpGet("@Model.ClassName/list")]
public async Task> List([FromQuery] @(@Model.ClassName)Input input)
{
return await _@(@Model.CamelizeClassName)Rep.DetachedEntities.ProjectToType<@(@Model.ClassName)Output>().ToListAsync();
}
@foreach (var column in Model.TableField){
if(@column.EffectType == "fk" && @column.FkEntityName != "" && @column.FkColumnName != ""){
@:
@:///
@:/// 获取@(@column.FkEntityName)列表
@:///
@:///
@:[HttpGet("fk@(@column.FkEntityName)")]
@:public async Task Fk@(@column.FkEntityName)List()
@:{
@:var list = await _@(@column.LowerFkEntityName)Rep.DetachedEntities.ToListAsync();
@:return list.Select(e => new {Code = e.Id, Name = e.@(@column.FkColumnName)});
@:}
}
}
#region 增、删、改
///
/// 增加@(@Model.BusName)
///
///
///
[HttpPost("@Model.ClassName/add")]
public async Task Add(Add@(@Model.ClassName)Input input)
{
var @(@Model.CamelizeClassName) = input.Adapt<@(@Model.ClassName)>();
//验证
await CheckExisit(@(@Model.CamelizeClassName));
@(@Model.CamelizeClassName).CreatedUserId = @(@Model.CamelizeClassName).UpdatedUserId = SysHelper.GetUserId();
@(@Model.CamelizeClassName).CreatedUserName = @(@Model.CamelizeClassName).UpdatedUserName = SysHelper.GetUserName();
@(@Model.CamelizeClassName).CreatedTime = @(@Model.CamelizeClassName).UpdatedTime = SysHelper.GetNowTime();
await _@(@Model.CamelizeClassName)Rep.InsertAsync(@(@Model.CamelizeClassName));
}
///
/// 删除@(@Model.BusName)
///
///
///
[HttpPost("@Model.ClassName/delete")]
public async Task Delete(Delete@(@Model.ClassName)Input input)
{
@foreach (var column in Model.TableField){
if (@column.ColumnKey == "True"){
@:var @(@Model.CamelizeClassName) = await _@(@Model.CamelizeClassName)Rep.FirstOrDefaultAsync(u => u.@(@column.ColumnName) == input.@(@column.ColumnName));
@:await _@(@Model.CamelizeClassName)Rep.DeleteAsync(@(@Model.CamelizeClassName));
}
}
}
///
/// 更新@(@Model.BusName)
///
///
///
[HttpPost("@Model.ClassName/edit")]
public async Task Update(Update@(@Model.ClassName)Input input)
{
var isExist = await _@(@Model.CamelizeClassName)Rep.AnyAsync(u => u.Id == input.Id, false);
if (!isExist) throw Oops.Oh(ErrorCode.D1002);
var @(@Model.CamelizeClassName) = input.Adapt<@(@Model.ClassName)>();
//验证
await CheckExisit(@(@Model.CamelizeClassName),true);
@(@Model.CamelizeClassName).UpdatedUserId = SysHelper.GetUserId();
@(@Model.CamelizeClassName).UpdatedUserName = SysHelper.GetUserName();
@(@Model.CamelizeClassName).UpdatedTime = SysHelper.GetNowTime();
await _@(@Model.CamelizeClassName)Rep.UpdateAsync(@(@Model.CamelizeClassName),ignoreNullValues:true);
}
#endregion
#region 导入
///
/// Excel模板导入@(@Model.BusName)功能
///
/// Excel模板文件
/// 导入的记录数
[HttpPost("@Model.ClassName/importExcel")]
public async Task ImportExcelAsync(IFormFile file)
{
int _HeadStartLine = 2;//第1行是说明,第2行是列名
int _DataStartLine = 3;//第3行开始是数据
DataTable importDataTable = ExcelUtil.ImportExcelToDataTable(file, _HeadStartLine, _DataStartLine);
var addList =await CommonImport(importDataTable, _DataStartLine);
lock (_lock)
{
_@(@Model.CamelizeClassName)Rep.InsertAsync(addList);
}
await Task.CompletedTask;
return addList.Count;
}
///
/// DataTable转换实体对象列表
///
///
/// 模版列名开始行
///
private async Task> CommonImport(DataTable dataTable, int dataStartLine)
{
var details = new List<@(@Model.ClassName)>();
int index = dataStartLine;//模版列名开始行
foreach (System.Data.DataRow row in dataTable.Rows)
{
index++;
//导入模版定制化代码(替换模版使用)
@Model.ImportExcelCustomizationContent
details.Add(addItem);
}
//验重
await CheckExisitForImport(details);
return details;
}
///
/// 根据版本下载@(@Model.BusName)的Excel导入模板
///
/// 模板版本
/// 下载的模板文件
[HttpGet("@Model.ClassName/downloadExcelTemplate")]
public IActionResult DownloadExcelTemplate([FromQuery] string version)
{
string _path = TemplateConst.EXCEL_TEMPLATEFILE_导入模版路径 + $"\\@Model.ClassName{TemplateConst.EXCEL_TEMPLATEFILE_导入模版名称后缀}.xlsx";
var fileName = HttpUtility.UrlEncode($"导入模板(@Model.BusName).xlsx", Encoding.GetEncoding("UTF-8"));
return new FileStreamResult(new FileStream(_path, FileMode.Open), "application/octet-stream") { FileDownloadName = fileName };
}
#endregion
#region 私有方法
///
/// 根据联合主键验证数据是否已存在-数据库
///
///
///
///
private async Task CheckExisit( @(@Model.ClassName) input,bool isEdit=false)
{
@{
var columnIndex = 0;
}
@foreach (var column in Model.TableField)
{
if (@column.WhetherUnionKey == "Y")
{
columnIndex++;
if (@columnIndex == 1)
{
@:bool isExist = false;
@:if (!isEdit)//新增
@:{
@://数据是否存在重复
@:isExist = await _@(@Model.CamelizeClassName)Rep.AnyAsync(u =>
@:u.@(@column.ColumnName).Equals(input.@column.ColumnName)
}
else
{
@:&&u.@(@column.ColumnName).Equals(input.@column.ColumnName)
}
}
}
@if(columnIndex>0){
@:,false);
@:}
@:else//编辑
@:{
}
@{
columnIndex=0;//初始化索引 下面编辑的逻辑使用
}
@foreach (var column in Model.TableField)
{
if (@column.WhetherUnionKey == "Y")
{
columnIndex++;
if (@columnIndex == 1)
{
@://当前编辑数据以外是否存在重复
@: isExist = await _@(@Model.CamelizeClassName)Rep.AnyAsync(u =>
@:u.Id != input.Id
@:&&u.@(@column.ColumnName).Equals(input.@column.ColumnName)
}
else
{
@:&&u.@(@column.ColumnName).Equals(input.@column.ColumnName)
}
}
}
@if(columnIndex>0)
{
@:,false);
@:}
}
@if(columnIndex>0){
@:if (isExist) throw Oops.Oh(ErrorCode.E0001);
}else{
@://没有配置联合主键,不需要验重
}
}
///
/// 根据联合主键验证数据是否已存在-导入时验证
///
///
///
private async Task CheckExisitForImport(List<@(@Model.ClassName)> inputs)
{
//根据联合主键验证表格中中是否已存在相同数据
@{
var index = 0;
bool isCheck = false;
string message = string.Empty;
}
@foreach (var column in Model.TableField)
{
if (@column.WhetherUnionKey == "Y")
{
isCheck = true;
message += "," + @column.ColumnComment + "[{item." + @column.ColumnName + "}]";
}
}
@if (isCheck)
{
@:if (inputs?.Count <= 0)
@:{
@: throw Oops.Oh($"导入数据不能为空");
@:}
@://数据是否重复
@:var existExcelItem = inputs.GroupBy(g => new {
}
@foreach (var column in Model.TableField)
{
if (@column.WhetherUnionKey == "Y")
{
index++;
if (@index == 1)
{
@:g.@(@column.ColumnName)
}
else
{
@:,g.@(@column.ColumnName)
}
}
}
@if (isCheck)
{
index=0;
@:})
@:.Where(g => g.Count() > 1)
@:.Select(s => new {
}
@foreach (var column in Model.TableField)
{
if (@column.WhetherUnionKey == "Y")
{
index++;
if (@index == 1)
{
@:s.Key.@(@column.ColumnName)
}
else
{
@:,s.Key.@(@column.ColumnName)
}
}
}
@if (isCheck)
{
@:}).FirstOrDefault();
@:if (existExcelItem != null)
@:{
@:var item= existExcelItem.Adapt<@(@Model.ClassName)>();
@:throw Oops.Oh($"导入的表格中@(@message)已存在");
@:}
}
@if (isCheck)
{ @://根据联合主键验证数据库中是否已存在相同数据
@:var existDBItem = await _@(@Model.CamelizeClassName)Rep.DetachedEntities.FirstOrDefaultAsync(w=>
@: inputs.Select(s=>""
}
@foreach (var column in Model.TableField)
{
if (@column.WhetherUnionKey == "Y")
{
@: +s.@(@column.ColumnName)
}
}
@if (isCheck)
{
@:)
@:.Contains(""
}
@foreach (var column in Model.TableField)
{
if (@column.WhetherUnionKey == "Y")
{
@: +w.@(@column.ColumnName)
}
}
@if (isCheck)
{
@: ));
@: if (existDBItem != null)
@:{
@:var item= existDBItem.Adapt<@(@Model.ClassName)>();
@:throw Oops.Oh($"系统中@(@message)已存在");
@:}
}
}
#endregion
}
}