UNIVPLMDataIntegration/Admin.NET/Admin.NET.Web.Entry/wwwroot/template/service_Service.cs.vm

388 lines
16 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
using Admin.NET.Core.Service;
using Microsoft.AspNetCore.Http;
using System.Linq.Expressions;
using Furion.EventBus;
using OfficeOpenXml.FormulaParsing.Excel.Functions.Text;
@{
string joinTableName = "u";
Dictionary<string, int> definedObjects = new Dictionary<string, int>();
bool haveLikeCdt = false;
string RemoteField="";
string PKName="";
foreach (var column in Model.TableField){
if (column.QueryWhether == "Y" && column.QueryType == "like"){
haveLikeCdt = true;
}
if(column.RemoteVerify){
RemoteField=@column.PropertyName;
}
if(column.ColumnKey == "True"){
PKName=column.PropertyName;
}
}
}
namespace @Model.NameSpace;
/// <summary>
/// @(@Model.BusName)服务
/// </summary>
[ApiDescriptionSettings(@(@Model.ProjectLastName)Const.GroupName, Name = "@(@Model.LowerClassName)", Order = 100)]
public partial class @(@Model.ClassName)Service : IDynamicApiController, ITransient
{
private readonly SysCacheService _sysCacheService;//默认CacheService
private readonly UserManager _userManager;//默认用户管理
private readonly IEventPublisher _eventPublisher;//默认事件总线
private readonly SqlSugarRepository<@(@Model.ClassName)> _@(@Model.LowerClassName)Rep;
@foreach (var column in Model.TableField){
if(@column.EffectType == "ForeignKey"||@column.EffectType == "ApiTreeSelector"){
if(@column.FkEntityName != @Model.ClassName){
@:private readonly SqlSugarRepository<@(@column.FkEntityName)> _@(@column.LowerFkEntityName)Rep;
}
}
}
private TypeAdapterConfig _typeAdapterConfig = TypeAdapterConfig.GlobalSettings;
public @(@Model.ClassName)Service(SqlSugarRepository<@(@Model.ClassName)> @(@Model.LowerClassName)Rep
,SysCacheService sysCacheService
, UserManager userManager
,IEventPublisher eventPublisher
@foreach (var column in Model.TableField){
if(@column.EffectType == "ForeignKey"||@column.EffectType == "ApiTreeSelector"){
if(@column.FkEntityName != @Model.ClassName){
@:,SqlSugarRepository<@(@column.FkEntityName)> @(@column.LowerFkEntityName)Rep
}
}
}
)
{
_@(@Model.LowerClassName)Rep = @(@Model.LowerClassName)Rep;
@foreach (var column in Model.TableField){
if(@column.EffectType == "ForeignKey"||@column.EffectType == "ApiTreeSelector"){
if(@column.FkEntityName != @Model.ClassName){
@:_@(@column.LowerFkEntityName)Rep = @(@column.LowerFkEntityName)Rep;
}
}
}
_typeAdapterConfig.ForType<T, @(@Model.ClassName)>().IgnoreNullValues(true);
_sysCacheService = sysCacheService;
_eventPublisher = eventPublisher;
_userManager = userManager;
}
/// <summary>
/// 分页查询@(@Model.BusName)
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[ApiDescriptionSettings(Name = "page", Description = "分页查询", Order = 1000), HttpPost]
[DisplayName("分页查询@(@Model.BusName)")]
public async Task<SqlSugarPagedList<@(@Model.ClassName)Output>> Page(Page@(@Model.ClassName)Input input)
{
//var query= @(@Model.ClassName)Mid.GetQuery(_@(@Model.LowerClassName)Rep, input);
//var list = await @(@Model.ClassName)Mid.GetQuery(_@(@Model.LowerClassName)Rep, input).MergeTable().ToPagedListAsync(input.Page, input.PageSize);
var list = await @(@Model.ClassName)Mid.GetQuery(_@(@Model.LowerClassName)Rep, input).OrderBuilder(input).ToPagedListAsync(input.Page, input.PageSize);
return list;
}
/// <summary>
/// 增加@(@Model.BusName)
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[ApiDescriptionSettings(Name = "add", Description = "增加@(@Model.BusName)", Order = 990), HttpPost]
[DisplayName("增加@(@Model.BusName)")]
public async Task<object> Add(Add@(@Model.ClassName)Input input)
{
var entity = input.Adapt<@(@Model.ClassName)>(_typeAdapterConfig);
@if(Model.RemoteVerify){
@://验证重复值
@:if (await _@(@Model.LowerClassName)Rep.IsAnyAsync(t => t.@(RemoteField) == entity.@(RemoteField)))
@:{
@://已存在
@:throw Oops.Oh(ErrorCodeEnum.D1006);
@:}
}
await _@(@Model.LowerClassName)Rep.InsertAsync(entity);
return entity.@(@PKName);
}
/// <summary>
/// 删除@(@Model.BusName)
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[ApiDescriptionSettings(Name = "delete", Description = "删除(@Model.BusName)", Order = 980), HttpPost]
[DisplayName("删除@(@Model.BusName)")]
public async Task Delete(Delete@(@Model.ClassName)Input input)
{
@foreach (var column in Model.TableField){
if (@column.ColumnKey == "True"){
@:var entity = await _@(@Model.LowerClassName)Rep.GetFirstAsync(u => u.@(@column.PropertyName) == input.@(@column.PropertyName)) ?? throw Oops.Oh(ErrorCodeEnum.D1002);
}
}
//await _@(@Model.LowerClassName)Rep.FakeDeleteAsync(entity); // 假删除
await _@(@Model.LowerClassName)Rep.DeleteAsync(entity); // 真删除
}
/// <summary>
/// 更新@(@Model.BusName)
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[ApiDescriptionSettings(Name = "update", Description = "更新@(@Model.BusName)", Order = 970), HttpPost]
[DisplayName("更新@(@Model.BusName)")]
public async Task Update(Update@(@Model.ClassName)Input input)
{
var entity = input.Adapt<@(@Model.ClassName)>(_typeAdapterConfig);
entity.Id = input.Id;
@if(Model.RemoteVerify){
@://验证重复值
@:if (await _@(@Model.LowerClassName)Rep.IsAnyAsync(t => t.@(RemoteField) == entity.@(RemoteField) && t.@(@PKName) != entity.@(@PKName)))
@:{
@://已存在
@:throw Oops.Oh(ErrorCodeEnum.D1006);
@:}
}
await _@(@Model.LowerClassName)Rep.AsUpdateable(entity).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
}
/// <summary>
/// 获取@(@Model.BusName)
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[ApiDescriptionSettings(Name = "detail", Description = "获取@(@Model.BusName)", Order = 960), HttpGet]
[DisplayName("获取@(@Model.BusName)")]
public async Task<@(@Model.ClassName)> Detail([FromQuery] QueryById@(@Model.ClassName)Input input)
{
@foreach (var column in Model.TableField){
if (@column.ColumnKey == "True"){
@:return await _@(@Model.LowerClassName)Rep.GetFirstAsync(u => u.@(@column.PropertyName) == input.@(@column.PropertyName));
}
}
}
/// <summary>
/// 获取@(@Model.BusName)列表
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[ApiDescriptionSettings(Name = "list", Description = "获取@(@Model.BusName)列表", Order = 950), HttpPost]
[DisplayName("获取@(@Model.BusName)列表")]
public async Task<List<@(@Model.ClassName)Output>> List(Page@(@Model.ClassName)Input input)
{
return await @(@Model.ClassName)Mid.GetQuery(_@(@Model.LowerClassName)Rep, input).OrderBuilder(input).ToListAsync();
}
/// <summary>
/// 获取@(@Model.BusName)
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[ApiDescriptionSettings(Name = "GetTotalSum", Description = "获取@(@Model.BusName)统计", Order = 960), HttpPost]
[DisplayName("获取@(@Model.BusName)统计")]
public async Task<List<@(@Model.ClassName)Output>> GetTotalSum(Page@(@Model.ClassName)Input input)
{
// 单次查询同时获取统计值
var querystats = @(@Model.ClassName)Mid.GetQuery(_@(@Model.LowerClassName)Rep, input)
@if(@Model.TableField.Any(x=>x.IsGroupBy == "Y")){
@foreach (var column in Model.TableField){
if (@column.IsGroupBy == "Y"){
@: .GroupByIF(input.GroupBy.Contains("@column.PropertyName"), u => u.@column.PropertyName)
}
}
@: //.Having(it => SqlFunc.AggregateCount(it.Id) > 0)//聚合函数过滤
}
.Select(it => new @(@Model.ClassName)Output
{
// count = SqlFunc.AggregateCount(it.Id),
@foreach (var column in Model.TableField){
if (@column.IsGroupBy == "Y"){
@: @(@column.PropertyName) = it.@(@column.PropertyName),
}
if (@column.Statistical == "Y"){
@: @(@column.PropertyName) = SqlFunc.AggregateSum(it.@(@column.PropertyName)) ?? 0,
}
}
});
return await querystats.ToListAsync();
}
/// <summary>
/// 根据输入参数获取@(@Model.BusName)统计
/// 支持双模式聚合配置:
/// 常规模式Field + Function
/// 高级模式CustomExpression支持任意合法SQL表达式
/// 智能条件组合:
/// 多个HAVING条件自动用AND连接
/// 条件表达式自动包裹聚合函数如SUM(cost) > 10000
/// 可扩展支持OR条件
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[ApiDescriptionSettings(Name = "GetAggregTotalSum", Order = 970), HttpPost]
[DisplayName("根据输入参数获取@(@Model.BusName)统计")]
public async Task<List<@(@Model.ClassName)Output>> GetAggregTotalSum(Page@(@Model.ClassName)Input input)
{
var query = @(@Model.ClassName)Mid.GetQuery(_@(@Model.LowerClassName)Rep, input);
// 输入参数示例
//input = new Page@(@Model.ClassName)Input
//{
// GroupBy = ["department", "project"],
// GroupBy = input.GroupBy,
// Aggregations =
// [
// new AggregationConfig
//{
// Field = "cost",
// Function = AggregateFunction.Sum,
// Alias = "totalCost",
// HavingCondition = "> 10000"
//},
//new AggregationConfig
//{
// CustomExpression = "AVG(CAST(response_time AS FLOAT))",
// Alias = "avgResponse",
// HavingCondition = "< 500"
//}
// ]
//};
// 生成SQL示例
// SELECT
// department, project,
// SUM(cost) AS totalCost,
// AVG(CAST(response_time AS FLOAT)) AS avgResponse
// FROM...
// GROUP BY department, project
// HAVING(SUM(cost) > 10000) AND(AVG(CAST(response_time AS FLOAT)) < 500)
@if(@Model.TableField.Any(x=>x.Statistical == "Y")){
@:// 处理分组字段
@:var groupFields = AggregationBuilder.ValidateFields<@(@Model.ClassName)Output>(input.GroupBy, typeof(@(@Model.ClassName)Output));
@:if (groupFields.Count > 0)
@:{
@: query = query.GroupBy(string.Join(",", groupFields));
@:}
@:// 构建聚合配置
@:var aggregator = new AggregationBuilder(
@: configs: input.Aggregations,
@: entityType: typeof(@(@Model.ClassName)),
@: outputType: typeof(@(@Model.ClassName)Output)
@:);
@:// 组合SELECT语句
@:var selectParts = groupFields.Select(f => $"{f} AS {f}")
@: .Concat(aggregator.SelectParts)
@: .ToList();
@:// 应用HAVING条件
@:if (aggregator.HavingConditions.Count > 0)
@:{
@: query = query.Having(string.Join(" AND ", aggregator.HavingConditions));
@:}
@:// 执行查询
@:return await query.Select<@(@Model.ClassName)Output>(string.Join(", ", selectParts)).ToListAsync();
}
else
{
@:return await query.ToListAsync();
}
}
@foreach (var column in Model.TableField){
if(@column.EffectType == "ForeignKey" && (@column.WhetherAddUpdate == "Y" || column.QueryWhether == "Y")){
@:/// <summary>
@:/// 获取@(@column.ColumnComment)列表
@:/// </summary>
@:/// <returns></returns>
@:[ApiDescriptionSettings(Name = "@(LowerFirstLetter(@column.FkEntityName))@(@column.PropertyName)Dropdown", Description = "获取@(@column.ColumnComment)列表", Order = 940), HttpGet]
@:[DisplayName("获取@(@column.ColumnComment)列表")]
@:public async Task<List<LabelValueOutput>> @(@column.FkEntityName)@(@column.PropertyName)Dropdown()
@:{
@:return (await _@(@column.LowerFkEntityName)Rep.GetListAsync(t => t.Id > 0))
@:.Select(u => new LabelValueOutput
@:{
@:Label = u.@(@column.FkColumnName),
@:Value = u.@(@column.FkLinkColumnName).ToString()
@:}
@:).ToList();
@:}
}
}
@foreach (var column in Model.TableField){
if(@column.EffectType == "Upload"){
@:/// <summary>
@:/// 上传@(@column.ColumnComment)
@:/// </summary>
@:/// <param name="file"></param>
@:/// <returns></returns>
@:[ApiDescriptionSettings(Name = "upload@(@column.PropertyName)", Description = "上传@(@column.ColumnComment)", Order = 930), HttpPost]
@:[DisplayName("上传@(@column.ColumnComment)")]
@:public async Task<SysFile> Upload@(@column.PropertyName)([Required] IFormFile file)
@:{
@:var service = App.GetRequiredService<SysFileService>();
@:return await service.UploadFile(new UploadFileInput { File = file, Path = "upload/@(@column.PropertyName)" });
@:}
}
}
@foreach (var column in Model.TableField){
if(@column.EffectType == "ApiTreeSelector" && !definedObjects.ContainsKey("@(@column.FkEntityName)Tree")){
@{definedObjects.Add("@(@column.FkEntityName)Tree", 1);}
@:[ApiDescriptionSettings(Name = "@(LowerFirstLetter(@column.FkEntityName))Tree", Description = "获取@(@column.ColumnComment)列表", Order = 920), HttpGet]
@:[DisplayName("获取@(@column.FkEntityName)Tree")]
@:public async Task<dynamic> @(@column.FkEntityName)Tree()
@:{
@:return await _@(@Model.LowerClassName)Rep.Context.Queryable<@(@column.FkEntityName)>().Select<@(@column.FkEntityName)Output>().ToTreeAsync(u => u.Children, u => u.@(@column.PidColumn), 0);
@:}
}
}
@if(Model.RemoteVerify){
@:/// <summary>
@:/// 检查@(RemoteField)字段是否可用
@:/// </summary>
@:/// <param name="param">检查字段参数</param>
@:/// <returns></returns>
@:[ApiDescriptionSettings(Name = "exists@(RemoteField)",Description = "检查@(RemoteField)字段是否可用", Order = 910), HttpPost]
@:[DisplayName("检查@(RemoteField)字段是否可用")]
@:public async Task<bool> Exists@(RemoteField)Async(Exists@(RemoteField)Input param)
@:{
@:if (string.IsNullOrWhiteSpace(param.FieldValue))
@:{
@:return false;
@:}
@:if (!string.IsNullOrWhiteSpace(param.OldFieldValue))
@:{
@:if (param.FieldValue.Trim() == param.OldFieldValue.Trim())
@:{
@://编辑状态下触发的
@:return true;
@:}
@:}
@:return !(await _@(@Model.LowerClassName)Rep.IsAnyAsync(t => t.@(RemoteField).Equals(param.FieldValue.Trim())));
@:}
}
}
@{
string LowerFirstLetter(string text)
{
return text.ToString()[..1].ToLower() + text[1..]; // 首字母小写
}
}