文件内容 DefaultAppService.cs 35 KB 34068 字符
using PasteApeart.Application.Contracts;
using PasteApeart.Handler;
using Microsoft.AspNetCore.Mvc;
using PasteForm.Helper;
using System.Dynamic;
using System.Linq.Dynamic.Core;
using System.Reflection;
using System.Text;
using System.Text.Json;

namespace PasteApeart.Application
{
    /// <summary>
    /// 默认读取 这个很关键,实现了统一的新增 更新 详细 列表规范读取 相当于兜底的!
    /// Version.2025.07.005
    /// Version.2026.01.10
    /// 当前还有一个问题,就是Page不是采用LeftJoin的,是分次查询,因为LeftJoin的组合有问题,目前还在找办法,Queryable死活会被转换成DbSet... .. .
    ///</summary>
    [TypeFilter(typeof(RoleAttribute), Arguments = new object[] { "data", "view" })]
    public class DefaultAppService : PasteApeartAppService
    {

        private DefaultHelper _defaultHelper;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="dd"></param>
        public DefaultAppService(DefaultHelper dd)
        {
            _defaultHelper = dd;
        }

        /// <summary>
        /// 映射名字
        /// </summary>
        /// <param name="entityName"></param>
        /// <returns></returns>
        private string MapperEntityName(string entityName)
        {
            return base.DefaultMapperEntityName(entityName);
        }


        #region 以下是具体实现 Version.2025.07.005

        /// <summary>
        /// 获取新增格式
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        [TypeFilter(typeof(RoleAttribute), Arguments = new object[] { "data", "view" })]
        [Route("/api/app/{entityName}/readAddModel", Order = 10)]
        public async Task<VoloModelInfo> ReadAddModel([FromRoute] string entityName)
        {
            entityName = MapperEntityName(entityName);
            // 1. 根据实体名称查找对应的实体类型和 DTO 类型
            var entityType = _defaultHelper.FindEntityType(entityName);
            if (entityType == null)
            {
                throw new PasteCodeException($"找不到对应的实体类型: {entityName}");
            }
            await FilterDataAsync(entityType, null, "add");
            var dtoType = _defaultHelper.FindDtoType(entityName, "AddDto");

            if (dtoType == null)
            {
                throw new PasteCodeException($"找不到对应的 DTO 类型: {entityName}AddDto");
            }

            //new一个出来
            var dto = Activator.CreateInstance(dtoType);

            // 4. 动态读取 DTO 的属性信息
            //var dataModel = DefaultHelper.ReadModelProperties(dto, dtoType);
            //return dataModel;

            return await base.DefaultBuildPropertyInfo("add", dto, dtoType);
        }

        /// <summary>
        /// 获取更新数据
        /// </summary>
        /// <param name="entityName"></param>
        /// <param name="id"></param>
        /// <returns></returns>
        /// <exception cref="PasteCodeException"></exception>
        [HttpGet]
        [TypeFilter(typeof(RoleAttribute), Arguments = new object[] { "data", "view" })]
        [Route("/api/app/{entityName}/{id}/readUpdateModel", Order = 10)]
        public async Task<VoloModelInfo> ReadUpdateModel([FromRoute] string entityName, [FromRoute] string id)
        {
            entityName = MapperEntityName(entityName);
            // 1. 根据实体名称查找对应的实体类型和 DTO 类型
            var entityType = _defaultHelper.FindEntityType(entityName);
            var dtoType = _defaultHelper.FindDtoType(entityName, "UpdateDto");

            if (entityType == null || dtoType == null)
            {
                throw new PasteCodeException($"找不到对应的实体或 DTO 类型: {entityName}");
            }
            //Console.WriteLine($"准备查询对象:{id.ToString()}的数据");//这里有问题,输出有问题 准备查询对象:System.Object的数据
            // 2. 动态查询实体
            //var entity = await _defaultHelper.FindEntityByIdAsync(_dbContext, entityType, id);
            var entity = await _defaultHelper.FindEntityByIdWithIncludeAsync(_dbContext, entityType, id);
            if (entity == null)
            {
                throw new PasteCodeException("查询的信息不存在,无法执行编辑操作!");
            }
            //Console.WriteLine($"get data:{Newtonsoft.Json.JsonConvert.SerializeObject(entity)}");

            await FilterDataAsync(entityType, entity, "update");

            var dto = Activator.CreateInstance(dtoType);
            _defaultHelper.MapProperties(entity, dto, entityType, dtoType);

            // 3. 动态映射实体到 DTO
            //var dto = DefaultHelper.MapEntityToDto(ObjectMapper, entity, entityType, dtoType);

            //构建外表等 Include的如何搞定???
            await _defaultHelper.BuildOuterQuery(_dbContext, dto, dtoType);

            // 4. 动态读取 DTO 的属性信息
            //var dataModel = DefaultHelper.ReadModelProperties(dto, dtoType);
            //return dataModel;
            return await base.DefaultBuildPropertyInfo("update", dto, dtoType);
        }

        /// <summary>
        /// 获取详细
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        [Route("/api/app/{entityName}/{id}/readDetailModel", Order = 10)]
        [TypeFilter(typeof(RoleAttribute), Arguments = new object[] { "data", "view" })]
        public async Task<VoloModelInfo> ReadDetailModel([FromRoute] string entityName, [FromRoute] string id)
        {
            entityName = MapperEntityName(entityName);

            // 1. 根据实体名称查找对应的实体类型和 DTO 类型
            var entityType = _defaultHelper.FindEntityType(entityName);
            var dtoType = _defaultHelper.FindDtoType(entityName, "Dto");

            if (entityType == null || dtoType == null)
            {
                throw new PasteCodeException($"找不到对应的实体或 DTO 类型: {entityName}");
            }

            // 2. 动态查询实体
            var entity = await _defaultHelper.FindEntityByIdWithIncludeAsync(_dbContext, entityType, id);
            if (entity == null)
            {
                throw new PasteCodeException("查询的信息不存在,无法执行编辑操作!");
            }

            await FilterDataAsync(entityType, entity, "detail");
            var dto = Activator.CreateInstance(dtoType);
            _defaultHelper.MapProperties(entity, dto, entityType, dtoType);
            // 3. 动态映射实体到 DTO
            //var dto = DefaultHelper.MapEntityToDto(ObjectMapper, entity, entityType, dtoType);

            //构建外表等 Include的如何搞定???
            await _defaultHelper.BuildOuterQuery(_dbContext, dto, dtoType);

            // 4. 动态读取 DTO 的属性信息
            //var dataModel = DefaultHelper.ReadModelProperties(dto, dtoType);
            //return dataModel;
            return await base.DefaultBuildPropertyInfo("detail", dto, dtoType);

        }

        /// <summary>
        /// 获取列表格式
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        [Route("/api/app/{entityName}/readListModel", Order = 10)]
        [TypeFilter(typeof(RoleAttribute), Arguments = new object[] { "data", "view" })]
        public async Task<VoloModelInfo> ReadListModel([FromRoute] string entityName, string searchName = "")
        {
            return await ReadListQueryModel(entityName, searchName);
        }

        /// <summary>
        /// 读取模型数据
        /// </summary>
        /// <param name="entityName"></param>
        /// <param name="searchName"></param>
        /// <returns></returns>
        /// <exception cref="PasteCodeException"></exception>
        private async Task<VoloModelInfo> ReadListQueryModel(string entityName, string searchName = "")
        {
            entityName = MapperEntityName(entityName);

            Type searchType = null;
            if (String.IsNullOrEmpty(searchName))
            {
                //var extendQuery = "InputQuery" + DefaultHelper.ConvertToPascalCase(entityName);
                searchType = _defaultHelper.FindQueryType(entityName);
                if (searchType == null)
                {
                    searchName = "InputSearchBase";
                    searchType = _defaultHelper.AutoFindType(searchName);
                }
            }
            else
            {
                searchType = _defaultHelper.AutoFindType(searchName);
            }

            if (searchType == null)
            {
                throw new PasteCodeException("没有检索到搜索Model,请确认InputSearchBase这个基础检索Model存在!");
            }
            // 动态查找实体对应的 ListDto 类型
            var listDtoType = _defaultHelper.FindDtoType(entityName, "ListDto");
            // 创建 ListDto 实例
            var listDtoInstance = Activator.CreateInstance(listDtoType);
            // 动态读取 ListDto 的属性信息
            //var listModel = BuilderHelper.AttributeReadModelProperty(listDtoInstance, true);
            //var listModel = DefaultHelper.ReadModelProperties(listDtoInstance, listDtoType, true);
            var listModel = await base.DefaultBuildPropertyInfo("list", listDtoInstance, listDtoType, true);
            if (searchType != null)
            {
                var search_model = Activator.CreateInstance(searchType);
                //var searchModel = BuilderHelper.AttributeReadModelProperty(search_model);
                var searchModel = DefaultHelper.ReadModelProperties(search_model, searchType, true);
                if (searchModel != null)
                {
                    listModel.QueryProperties = searchModel.Properties;
                }
            }
            //}
            return listModel;
        }

        /// <summary>
        /// 获取列表数据
        /// </summary>
        /// <param name="entityName"></param>
        /// <param name="searchName"></param>
        /// <returns></returns>
        /// <exception cref="PasteCodeException"></exception>
        [HttpGet]
        [Route("/api/app/{entityName}/page", Order = 10)]
        [TypeFilter(typeof(RoleAttribute), Arguments = new object[] { "data", "view" })]
        public async Task<dynamic> Page([FromRoute] string entityName, string searchName = "")
        {
            entityName = MapperEntityName(entityName);
            // [FromQuery] InputSearchBase input
            // 1. 根据实体名称查找对应的实体类型和DTO类型
            var entityType = _defaultHelper.FindEntityType(entityName);
            var listDtoType = _defaultHelper.FindDtoType(entityName, "ListDto");

            if (entityType == null || listDtoType == null)
            {
                throw new PasteCodeException($"找不到对应的实体或DTO类型: {entityName}", 404);
            }
            await FilterDataAsync(entityType, null, "page");
            //这里应该要改版,直接利用反射,赋值
            var query_string = base._httpContext.Request.QueryString.ToString();

            Type searchType = null;
            if (String.IsNullOrEmpty(searchName))
            {
                //var extendQuery = "InputQuery" + DefaultHelper.ConvertToPascalCase(entityName);
                searchType = _defaultHelper.FindQueryType(entityName);
                if (searchType == null)
                {
                    searchName = "InputSearchBase";
                    searchType = _defaultHelper.AutoFindType(searchName);
                }
            }
            else
            {
                searchType = _defaultHelper.AutoFindType(searchName);
            }

            if (searchType == null)
            {
                throw new PasteCodeException("没有检索到搜索Model,请确认InputSearchBase这个基础检索Model存在!");
            }
            dynamic pagedto = new ExpandoObject();

            object searchObject = null;
            searchObject = Activator.CreateInstance(searchType);
            var input = _defaultHelper.MapperToQueryModel(query_string, searchType, searchObject);
            if (input.page == 1)
            {
                if (query_string.Contains("request=one"))
                {
                    pagedto.pasteModel = await ReadListQueryModel(entityName, searchName);
                }
            }

            IQueryable query = _defaultHelper.BuildDynamicQuery(_dbContext, entityType, searchType, searchObject);

            if (input.page == 1)
            {
                pagedto.totalCount = await DefaultHelper.ExecuteCountQuery(query, entityType);
            }

            var isIncludeType = _defaultHelper.HasPasteIncludeProperties(entityType);

            if (isIncludeType)
            {
                var includeQuery = _defaultHelper.ApplyAllPasteIncludes(query, entityType);
                if (includeQuery != null)
                {
                    query = includeQuery as IQueryable;
                }
            }
            query = _defaultHelper.ApplyPagingAndSorting(query, entityType, searchType, searchObject);
            List<object> dtos;
            if (isIncludeType)
            {
                dtos = await _defaultHelper.ExecuteProjectionQueryWithIncludes(query, entityType, listDtoType);
            }
            else
            {
                dtos = await _defaultHelper.ExecuteProjectionQuery(query, entityType, listDtoType);
            }
            if (dtos == null) { return null; }
            if (dtos?.Any() == false)
            {
                return null;
            }
            //Console.WriteLine($"line.315 {Newtonsoft.Json.JsonConvert.SerializeObject(dtos)}");
            //查询外表 并实现 这里是简单的外表ID的查询 如果有更复杂的,还需要实现
            await _defaultHelper.BuildOuterData(_dbContext, listDtoType, dtos);
            // 7. 设置结果并返回
            //pagedDto.Items = dtos.Cast<object>().ToList();
            pagedto.items = dtos;

            //计算ExtendBind的数据... ExtendBind=true
            await _defaultHelper.ReadExtendBind(_dbContext, listDtoType, dtos, searchType, searchObject);

            return pagedto;
        }

        /// <summary>
        /// 通用创建方法
        /// </summary>
        /// <param name="entityName"></param>
        /// <returns></returns>
        /// <exception cref="PasteCodeException"></exception>
        [HttpPost]
        [Route("/api/app/{entityName}/item", Order = 10)]
        [TypeFilter(typeof(RoleAttribute), Arguments = new object[] { "data", "add" })]
        public async Task<dynamic> CreateItemAsync([FromRoute] string entityName)
        {
            entityName = MapperEntityName(entityName);
            // 获取实体类型和添加DTO类型
            var entityType = _defaultHelper.FindEntityType(entityName);
            var addDtoType = _defaultHelper.FindDtoType(entityName, "AddDto");

            if (entityType == null || addDtoType == null)
            {
                throw new PasteCodeException($"找不到对应的实体或添加DTO类型: {entityName}", 404);
            }
            using var read = new StreamReader(_httpContext.Request.Body, Encoding.UTF8);
            var inputString = await read.ReadToEndAsync();

            Console.WriteLine(inputString);

            // 反序列化输入数据到添加DTO
            //var addDto = JsonConvert.DeserializeObject(inputString, addDtoType);
            //var addDto = Mapster.TypeAdapter(inputString,addDtoType);
            var addDto = JsonSerializer.Deserialize(inputString, addDtoType, JsonConfig.Options);
            DefaultHelper.ValidateModel(addDto, addDtoType);

            var mutexFind = await _defaultHelper.FilterFirstOrDefaultAsync(_dbContext, entityType, addDtoType, addDto, null);
            if (mutexFind != null && mutexFind != default)
            {
                throw new PasteCodeException("已经有相同的数据了,修改后重试!");
            }
            // 创建实体实例
            var entity = Activator.CreateInstance(entityType);

            // 映射DTO到实体
            _defaultHelper.MapProperties(addDto, entity, addDtoType, entityType);

            //ObjectMapper.Map<UserInfoAddDto,UserInfo>(null,null);

            await DataSetExtendAsync(entityType, entity, "add");
            //下面这个和上面注释的意思一样

            await _defaultHelper.CheckEntityShortData(_dbContext, entityType, entity);

            // 添加到数据库
            var dbSet = _defaultHelper.FindDbSetObject(_dbContext, entityType);
            dbSet.GetType().GetMethod("Add").Invoke(dbSet, new[] { entity });

            // 保存更改
            await _dbContext.SaveChangesAsync();

            var idProperty = _defaultHelper.ReadCurrentProperty(entityType, "Id");
            if (idProperty != null && idProperty != default)
            {
                var idVal = idProperty.GetValue(entity).ToString();

                return await ReadListDtoByIdAsync(entityType, entityName, idVal);
            }
            return 0;
        }

        /// <summary>
        /// 通用更新方法
        /// </summary>
        /// <param name="entityName"></param>
        /// <returns></returns>
        /// <exception cref="PasteCodeException"></exception>
        [HttpPost]
        [Route("/api/app/{entityName}/updateItem", Order = 10)]
        [TypeFilter(typeof(RoleAttribute), Arguments = new object[] { "data", "edit" })]
        public async Task<object> UpdateItemAsync([FromRoute] string entityName)
        {
            entityName = MapperEntityName(entityName);
            // 获取实体类型和更新DTO类型
            var entityType = _defaultHelper.FindEntityType(entityName);
            var updateDtoType = _defaultHelper.FindDtoType(entityName, "UpdateDto");

            if (entityType == null || updateDtoType == null)
            {
                throw new PasteCodeException($"找不到对应的实体或更新DTO类型: {entityName}", 404);
            }

            //可以执行归属校验 entityName entityType

            using var read = new StreamReader(_httpContext.Request.Body, Encoding.UTF8);
            var inputString = await read.ReadToEndAsync();
            // 反序列化输入数据到更新DTO
            //var updateDto = JsonConvert.DeserializeObject(inputString, updateDtoType);
            var updateDto = JsonSerializer.Deserialize(inputString, updateDtoType, JsonConfig.Options);

            // 手动执行模型验证
            DefaultHelper.ValidateModel(updateDto, updateDtoType);

            // 获取ID属性值
            var id = _defaultHelper.GetPropertyValue(updateDto, "Id");
            if (id == null)
            {
                throw new PasteCodeException("更新DTO必须包含Id属性", 400);
            }

            var mutexFind = await _defaultHelper.FilterFirstOrDefaultAsync(_dbContext, entityType, updateDtoType, updateDto, id);
            if (mutexFind != null && mutexFind != default)
            {
                throw new PasteCodeException("已经有相同的数据了,修改后重试!");
            }
            // 查找实体
            var entity = await _defaultHelper.FindEntityByIdAsync(_dbContext, entityType, id);
            if (entity == null)
            {
                throw new PasteCodeException("需要更新的记录不存在", 404);
            }
            await FilterDataAsync(entityType, entity, "update");
            // 映射DTO到实体
            _defaultHelper.MapProperties(updateDto, entity, updateDtoType, entityType);

            await DataSetExtendAsync(entityType, entity, "update");

            await _defaultHelper.CheckEntityShortData(_dbContext, entityType, entity);

            // 保存更改
            await _dbContext.SaveChangesAsync();

            //return id; //旧版本,直接返回ID

            ////反射 XXXListDto 返回给前端 新版本 用于更新table的行数据
            //var listDtoType = _defaultHelper.FindDtoType(entityName, "ListDto");
            //var listDto = Activator.CreateInstance(listDtoType);
            //// xxx 转 xxxListDto
            //_defaultHelper.MapProperties(entity, listDto, entityType, listDtoType);
            //return listDto;
            ////return id;

            return await ReadListDtoByIdAsync(entityType, entityName, id);
        }

        /// <summary>
        /// 用于返回ListDto单项数据
        /// </summary>
        /// <param name="entityName"></param>
        /// <param name="id"></param>
        /// <returns></returns>
        /// <exception cref="PasteCodeException"></exception>
        [Obsolete("Use ReadListDtoByIdAsync")]
        private async Task<object> ReadItemListDtoAsync(string entityName, object id)
        {
            entityName = MapperEntityName(entityName);

            // 1. 根据实体名称查找对应的实体类型和 DTO 类型
            var entityType = _defaultHelper.FindEntityType(entityName);
            var dtoType = _defaultHelper.FindDtoType(entityName, "ListDto");

            if (entityType == null || dtoType == null)
            {
                throw new PasteCodeException($"找不到对应的实体或 DTO 类型: {entityName}");
            }

            // 2. 动态查询实体
            //var entity = await _defaultHelper.FindEntityByIdAsync(_dbContext, entityType, id);
            var entity = await _defaultHelper.FindEntityByIdWithIncludeAsync(_dbContext, entityType, id);
            if (entity == null)
            {
                return null;//throw new PasteCodeException("查询的信息不存在,无法执行编辑操作!");
            }

            //await FilterDataAsync(entityType, entity, "detail");
            var dto = Activator.CreateInstance(dtoType);
            _defaultHelper.MapProperties(entity, dto, entityType, dtoType);
            // 3. 动态映射实体到 DTO
            //var dto = DefaultHelper.MapEntityToDto(ObjectMapper, entity, entityType, dtoType);

            //构建外表等 Include的如何搞定???
            await _defaultHelper.BuildOuterQuery(_dbContext, dto, dtoType);

            // 4. 动态读取 DTO 的属性信息
            //var dataModel = DefaultHelper.ReadModelProperties(dto, dtoType);
            //return dataModel;
            //return await this.DefaultVoloModelPropertyAsync("detail", dto, dtoType);
            return dto;

        }

        /// <summary>
        /// 基于ID获取对象ListDto用于新增或更新后同步到Table的UI中
        /// </summary>
        /// <param name="entityType"></param>
        /// <param name="entityName"></param>
        /// <param name="id"></param>
        /// <returns></returns>
        /// <exception cref="PasteCodeException"></exception>
        private async Task<object> ReadListDtoByIdAsync(Type entityType, string entityName, object id)
        {
            entityName = MapperEntityName(entityName);
            var dtoType = _defaultHelper.FindDtoType(entityName, "ListDto");
            if (entityType == null || dtoType == null)
            {
                throw new PasteCodeException($"找不到对应的实体或 DTO 类型: {entityName}");
            }
            var entity = await _defaultHelper.FindEntityByIdWithIncludeAsync(_dbContext, entityType, id);
            if (entity == null)
            {
                return null;//throw new PasteCodeException("查询的信息不存在,无法执行编辑操作!");
            }
            var dto = Activator.CreateInstance(dtoType);
            _defaultHelper.MapProperties(entity, dto, entityType, dtoType);
            await _defaultHelper.BuildOuterQuery(_dbContext, dto, dtoType);
            return dto;
        }


        /// <summary>
        /// 通用状态更新方法
        /// </summary>
        /// <param name="entityName"></param>
        /// <param name="input"></param>
        /// <returns></returns>
        /// <exception cref="PasteCodeException"></exception>
        [HttpPost]
        [Route("/api/app/{entityName}/updateState", Order = 10)]
        [TypeFilter(typeof(RoleAttribute), Arguments = new object[] { "data", "state" })]
        public async Task<string> UpdateState([FromRoute] string entityName, [FromBody] InputQueryUpdateState input)
        {
            entityName = MapperEntityName(entityName);
            // 获取实体类型
            var entityType = _defaultHelper.FindEntityType(entityName);

            if (entityType == null)
            {
                throw new PasteCodeException($"找不到对应的实体类型: {entityName}", 404);
            }
            if (input.name != "extendBind")
            {
                // 查找实体
                var entity = await _defaultHelper.FindEntityByIdAsync(_dbContext, entityType, input.id);
                if (entity == null)
                {
                    throw new PasteCodeException("没有找到对应的操作对象,无法继续执行", 404);
                }

                await FilterDataAsync(entityType, entity, "state");

                var property = _defaultHelper.GetPropertyThrowException(entityType, input.name);// entityType.GetProperties().Where(x => x.Name == input.name || x.Name == pauseName).FirstOrDefault();

                if (!property.CanWrite)
                {
                    throw new PasteCodeException($"属性 {input.name} 不可写", 400);
                }
                // 处理可空布尔类型
                if (property.PropertyType == typeof(bool?))
                {
                    property.SetValue(entity, input.state ? (bool?)true : (bool?)false);
                }
                else
                {
                    property.SetValue(entity, input.state);
                }
                // 保存更改
                await _dbContext.SaveChangesAsync();
            }
            else
            {
                var listDtoType = _defaultHelper.FindDtoType(entityName, "ListDto");
                if (listDtoType == null || listDtoType == default)
                {
                    throw new PasteCodeException($"没有找到这个实体{entityName}的ListDto数据模型!");
                }
                var property = listDtoType.GetProperty("ExtendBind");
                if (property == null || property == default)
                {
                    throw new PasteCodeException("没有找到这个字段ExtendBind的信息");
                }

                var attrs = property.GetCustomAttributes<PasteExtendBindAttribute>();
                if (attrs?.Any() == false)
                {
                    throw new PasteCodeException($"请为{entityName}ListDto的字段ExtendBind配置PasteExtendBind特性后再试,支持绑定多个!");
                }

                foreach (var attr in attrs)
                {
                    var bindEntity = _defaultHelper.FindEntityType(attr.Args1);
                    if (bindEntity == null || bindEntity == default)
                    {
                        throw new PasteCodeException($"PasteExtendBind的args1:{attr.Args1} 配置错误,没有这样的Entity信息!");
                    }
                    //Console.WriteLine($"准备计算Bind的逻辑... .. .{attr.Args1} {attr.Args2} {attr.Args3} {attr.Args4} ");
                    var args = input.search.ToQuerys();
                    if (args.TryGetValue(attr.Args4, out var grade_id))
                    {
                        var dics = new Dictionary<string, string>();
                        dics.Add(attr.Args3, grade_id);
                        dics.Add(attr.Args2, input.id);

                        var find_bind = await _defaultHelper.FindFirstOrDefaultAsync(_dbContext, bindEntity, dics, default);
                        if (find_bind == null || find_bind == default)
                        {
                            if (input.state)
                            {
                                //新增
                                var bind_entity = Activator.CreateInstance(bindEntity);

                                //为GradeId RoleId赋值
                                foreach (var arg in dics)
                                {
                                    //var arg_pro = bindEntity.GetProperty(arg.Key, BindingFlags.Public | BindingFlags.Instance);
                                    var argPro = _defaultHelper.ReadCurrentProperty(bindEntity, arg.Key);
                                    if (argPro == null || argPro == default)
                                    {
                                        throw new PasteCodeException($"没有在Entity:{attr.Args1} 获取到字段:{arg.Key}");
                                    }
                                    var arg_val = Convert.ChangeType(arg.Value, argPro.PropertyType);
                                    argPro.SetValue(bind_entity, arg_val);
                                }

                                // 添加到数据库
                                var dbSet = _defaultHelper.FindDbSetObject(_dbContext, bindEntity);
                                dbSet.GetType().GetMethod("Add").Invoke(dbSet, new[] { bind_entity });
                                // 保存更改
                                await _dbContext.SaveChangesAsync();
                                //Console.WriteLine("执行Bind的新增逻辑... .. .");
                            }
                            else
                            {
                                //Console.WriteLine("数据不存在,且指令是取消绑定");
                            }
                        }
                        else
                        {
                            if (!input.state)
                            {
                                // 执行删除操作
                                //var dbSet = _defaultHelper.FindDbSetObject(_dbContext, bindEntity);
                                //dbSet.GetType().GetMethod("Remove").Invoke(dbSet, new[] { find_bind });
                                _dbContext.Remove(find_bind);
                                await _dbContext.SaveChangesAsync();
                                //Console.WriteLine("执行Bind的删除逻辑... .. .");
                            }
                            else
                            {
                                //Console.WriteLine("数据存在,且指令是绑定数据");
                            }
                        }
                    }
                }

            }
            return "操作成功";
        }

        /// <summary>
        /// 通用删除 遵照ListDto的PasteDisable特性
        /// </summary>
        /// <param name="entityName"></param>
        /// <param name="id"></param>
        /// <returns></returns>
        /// <exception cref="PasteCodeException"></exception>
        [HttpPost]
        [Route("/api/app/{entityName}/{id}/remove", Order = 10)]
        [TypeFilter(typeof(RoleAttribute), Arguments = new object[] { "data", "del" })]
        public async Task<string> Remove([FromRoute] string entityName, [FromRoute] string id)
        {
            entityName = MapperEntityName(entityName);
            // 获取实体类型
            var entityType = _defaultHelper.FindEntityType(entityName);

            if (entityType == null)
            {
                throw new PasteCodeException($"找不到对应的实体类型: {entityName}", 404);
            }
            #region 是否有标记禁止删除
            var listDtoType = _defaultHelper.FindDtoType(entityName, "ListDto");
            if (listDtoType != null)
            {
                var finds = listDtoType.GetCustomAttributes<PasteDisableAttribute>();
                if (finds?.Any() == true)
                {
                    var find = finds.FirstOrDefault();
                    if (find.Args3 == "del")
                    {
                        throw new PasteCodeException($"实体 {entityName} 不允许删除操作", 403);
                    }
                }
            }
            #endregion

            // 查找实体
            var entity = await _defaultHelper.FindEntityByIdAsync(_dbContext, entityType, id);
            if (entity == null)
            {
                throw new PasteCodeException("需要删除的记录不存在", 404);
            }
            await FilterDataAsync(entityType, entity, "remove");
            // 执行删除操作
            //var dbSet = _defaultHelper.FindDbSetObject(_dbContext, entityType);
            //dbSet.GetType().GetMethod("Remove").Invoke(dbSet, new[] { entity });
            _dbContext.Remove(entity);
            // 保存更改
            await _dbContext.SaveChangesAsync();

            return "删除成功";
        }

        #endregion

        #region 以下是数据过滤和自动赋值模块 2025.07.005
        /// <summary>
        /// 数据校验,判断权限等 需要在基Class定义AuthDataFilterAsync(Type,Entity)
        /// </summary>
        /// <param name="entityType"></param>
        /// <param name="obj"></param>
        /// <param name="action"></param>
        /// <returns></returns>
        private async Task FilterDataAsync(Type entityType, object obj, string action)
        {

            await base.DefaultAuthDataFilterAsync(entityType,obj,action);

            //// 获取基类类型
            //Type baseType = this.GetType().BaseType;

            //// 递归查找所有基类中的方法
            //MethodInfo method = FindMethodInBaseTypes(
            //    baseType,
            //    "DefaultAuthDataFilterAsync",
            //    BindingFlags.NonPublic | BindingFlags.Instance,
            //    new[] { typeof(object), typeof(object), typeof(object) } // 修正参数数量
            //);

            //if (method != null)
            //{
            //    var task = (Task)method.Invoke(this, new object[] { entityType, obj, action });
            //    await task;
            //}
        }

        /// <summary>
        /// 递归查找基类方法的辅助方法
        /// </summary>
        /// <param name="type"></param>
        /// <param name="methodName"></param>
        /// <param name="bindingAttr"></param>
        /// <param name="parameterTypes"></param>
        /// <returns></returns>
        private MethodInfo FindMethodInBaseTypes(Type type, string methodName, BindingFlags bindingAttr, Type[] parameterTypes)
        {
            if (type == null)
            {
                return null;
            }
            //Console.WriteLine($"{type.Name} {type.FullName}");
            // 尝试在当前类型中查找方法
            //var method = type.GetMethod(methodName, bindingAttr, null, parameterTypes, null);
            var method = type.GetMethod(methodName, bindingAttr);

            if (method != null)
                return method;

            // 递归查找父类
            return FindMethodInBaseTypes(type.BaseType, methodName, bindingAttr, parameterTypes);
        }

        /// <summary>
        /// 为Entity赋值,比如赋值UserId等 基类需要定义SetDataExtendAsync(Type,Entity,action)
        /// 一般是一些默认字段输入,比如创建者
        /// </summary>
        /// <param name="entityType"></param>
        /// <param name="obj"></param>
        /// <param name="action">add或update</param>
        /// <returns></returns>
        private async Task DataSetExtendAsync(Type entityType, object obj, string action)
        {
            await base.DefaultSetDataExtendAsync(entityType,obj,action);
            //// 获取基类类型
            //Type baseType = this.GetType().BaseType;
            //MethodInfo method = FindMethodInBaseTypes(
            //    baseType,
            //    "DefaultSetDataExtendAsync",
            //    BindingFlags.NonPublic | BindingFlags.Instance,
            //    new[] { typeof(object), typeof(object), typeof(object) } // 修正参数数量
            //);
            //if (method != null)
            //{
            //    var task = (Task)method.Invoke(this, new object[] { entityType, obj, action });
            //    await task;
            //}
        }

        #endregion


    }

}
​ ​