Przeglądaj źródła

集成腾讯APIJSON协议,按协议支持后端库表API0代码,参阅文档https://github.com/Tencent/APIJSON/blob/master/Document.md

chengzhongzhu 3 lat temu
rodzic
commit
094f549fca

+ 6 - 3
Admin.NET/Admin.NET.Application/Admin.NET.Application.csproj

@@ -30,9 +30,12 @@
   </ItemGroup>
 
   <ItemGroup>
-    <None Update="Configuration\App.json">
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </None>
+	  <None Update="Configuration\ApiJson.json">
+		  <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+	  </None>
+	  <None Update="Configuration\App.json">
+		  <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+	  </None>
     <None Update="Configuration\Cache.json">
       <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
     </None>

+ 34 - 0
Admin.NET/Admin.NET.Application/Configuration/ApiJson.json

@@ -0,0 +1,34 @@
+{
+  "$schema": "https://gitee.com/dotnetchina/Furion/raw/net6/schemas/v3/furion-schema.json",
+  // 代码生成配置项-程序集名称集合
+  "ApiJson": {
+    "RoleList": [
+      {
+        "name": "role1", //权限名称 唯一
+        "select": { //查询权限
+          "table": [ "*" ], //可操作的表
+          "column": [ "tb.*" ], //可操作的字段
+          "where": []
+        },
+        "update": { //修改权限
+          "table": [ "moment", "User", "Comment" ],
+          "column": [ "tb.*", "tb.*", "tb.*" ]
+        },
+        "insert": { //添加权限
+          "table": [ "moment", "User", "Comment" ],
+          "column": [ "tb.*", "tb.*", "tb.*" ]
+        },
+        "delete": { //删除权限
+          "table": [ "moment", "User", "Comment" ]
+        }
+      },
+      {
+        "name": "role2",
+        "select": {
+          "table": [ "monent" ],
+          "column": [ "*" ]
+        }
+      }
+    ]
+  }
+}

+ 6 - 5
Admin.NET/Admin.NET.Core/Admin.NET.Core.csproj

@@ -15,22 +15,23 @@
 
   <ItemGroup>
     <PackageReference Include="AngleSharp" Version="1.0.1" />
+    <PackageReference Include="AspectCore.Extensions.Reflection" Version="2.3.0" />
     <PackageReference Include="AspNetCoreRateLimit" Version="5.0.0" />
     <PackageReference Include="DotNetCore.Natasha.CSharp" Version="5.0.2" />
     <PackageReference Include="FluentEmail.Smtp" Version="3.0.2" />
-    <PackageReference Include="Furion.Extras.Authentication.JwtBearer" Version="4.8.6.1" />
-    <PackageReference Include="Furion.Extras.ObjectMapper.Mapster" Version="4.8.6.1" />
-    <PackageReference Include="Furion.Pure" Version="4.8.6.1" />
+    <PackageReference Include="Furion.Extras.Authentication.JwtBearer" Version="4.8.6.2" />
+    <PackageReference Include="Furion.Extras.ObjectMapper.Mapster" Version="4.8.6.2" />
+    <PackageReference Include="Furion.Pure" Version="4.8.6.2" />
     <PackageReference Include="Lazy.Captcha.Core" Version="2.0.1" />
     <PackageReference Include="Magicodes.IE.Excel" Version="2.7.4.2" />
     <PackageReference Include="Magicodes.IE.Pdf" Version="2.7.4.2" />
     <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="6.0.13" />
     <PackageReference Include="NEST" Version="7.17.5" />
-    <PackageReference Include="NewLife.Redis" Version="5.1.2023.203" />
+    <PackageReference Include="NewLife.Redis" Version="5.1.2023.207-beta0755" />
     <PackageReference Include="OnceMi.AspNetCore.OSS" Version="1.1.9" />
     <PackageReference Include="SKIT.FlurlHttpClient.Wechat.Api" Version="2.23.0" />
     <PackageReference Include="SKIT.FlurlHttpClient.Wechat.TenpayV3" Version="2.15.2" />
-    <PackageReference Include="SqlSugarCore" Version="5.1.3.50" />
+    <PackageReference Include="SqlSugarCore" Version="5.1.3.51-preview01" />
     <PackageReference Include="System.Linq.Dynamic.Core" Version="1.2.25" />
     <PackageReference Include="UAParser" Version="3.1.47" />
     <PackageReference Include="Yitter.IdGenerator" Version="1.0.14" />

+ 183 - 0
Admin.NET/Admin.NET.Core/Admin.NET.Core.xml

@@ -3628,6 +3628,16 @@
             ES服务注册
             </summary>
         </member>
+        <member name="T:Admin.NET.Core.ApiJsonOptions">
+            <summary>
+            ApiJson配置选项
+            </summary>
+        </member>
+        <member name="P:Admin.NET.Core.ApiJsonOptions.RoleList">
+            <summary>
+            ApiJson集合RoleList
+            </summary>
+        </member>
         <member name="T:Admin.NET.Core.CacheOptions">
             <summary>
             缓存配置选项
@@ -4021,6 +4031,172 @@
             </summary>
             <returns></returns>
         </member>
+        <member name="T:Admin.NET.Core.Service.ApiJson.ApiJsonService">
+            <summary>
+            系统数据库管理服务
+            </summary>
+        </member>
+        <member name="M:Admin.NET.Core.Service.ApiJson.ApiJsonService.Post(Newtonsoft.Json.Linq.JObject)">
+            <summary>
+            ApiJson 统一入口
+            </summary>
+            <param name="jobject"></param>
+            <returns></returns>
+        </member>
+        <member name="T:Admin.NET.Core.Service.ApiJson.FuncList">
+            <summary>
+            自定义方法
+            </summary>
+        </member>
+        <member name="M:Admin.NET.Core.Service.ApiJson.FuncList.Merge(System.Object,System.Object)">
+            <summary>
+            
+            </summary>
+            <param name="a"></param>
+            <param name="b"></param>
+            <returns></returns>
+        </member>
+        <member name="M:Admin.NET.Core.Service.ApiJson.FuncList.MergeObj(System.Object,System.Object)">
+            <summary>
+            
+            </summary>
+            <param name="a"></param>
+            <param name="b"></param>
+            <returns></returns>
+        </member>
+        <member name="M:Admin.NET.Core.Service.ApiJson.FuncList.isContain(System.Object,System.Object)">
+            <summary>
+            
+            </summary>
+            <param name="a"></param>
+            <param name="b"></param>
+            <returns></returns>
+        </member>
+        <member name="M:Admin.NET.Core.Service.ApiJson.IIdentityService.GetUserIdentity">
+            <summary>
+            获取当前用户id
+            </summary>
+            <returns></returns>
+        </member>
+        <member name="M:Admin.NET.Core.Service.ApiJson.IIdentityService.GetUserRoleName">
+            <summary>
+            获取当前用户权限组名称
+            </summary>
+            <returns></returns>
+        </member>
+        <member name="M:Admin.NET.Core.Service.ApiJson.IIdentityService.GetRole">
+            <summary>
+            获取当前用户权限
+            </summary>
+            <returns></returns>
+        </member>
+        <member name="M:Admin.NET.Core.Service.ApiJson.IIdentityService.GetSelectRole(System.String)">
+            <summary>
+            获取当前表的可查询字段
+            </summary>
+            <param name="table"></param>
+            <returns></returns>
+        </member>
+        <member name="M:Admin.NET.Core.Service.ApiJson.StringExtensions.IsValue(System.Object)">
+            <summary>
+            是否有值
+            </summary>
+            <param name="str"></param>
+            <returns></returns>
+        </member>
+        <member name="M:Admin.NET.Core.Service.ApiJson.StringExtensions.GetParamName(System.String)">
+            <summary>
+            
+            </summary>
+            <param name="param"></param>
+            <returns></returns>
+        </member>
+        <member name="T:Admin.NET.Core.Service.ApiJson.SelectTable">
+            <summary>
+            
+            </summary>
+        </member>
+        <member name="M:Admin.NET.Core.Service.ApiJson.SelectTable.#ctor(Admin.NET.Core.Service.ApiJson.IIdentityService,APIJSON.NET.Services.ITableMapper,SqlSugar.ISqlSugarClient)">
+            <summary>
+            
+            </summary>
+            <param name="identityService"></param>
+            <param name="tableMapper"></param>
+            <param name="dbClient"></param>
+        </member>
+        <member name="M:Admin.NET.Core.Service.ApiJson.SelectTable.IsTable(System.String)">
+            <summary>
+            判断表名是否正确
+            </summary>
+            <param name="table"></param>
+            <returns></returns>
+        </member>
+        <member name="M:Admin.NET.Core.Service.ApiJson.SelectTable.IsCol(System.String,System.String)">
+            <summary>
+            判断表的列名是否正确
+            </summary>
+            <param name="table"></param>
+            <param name="col"></param>
+            <returns></returns>
+        </member>
+        <member name="M:Admin.NET.Core.Service.ApiJson.SelectTable.ExecFunc(System.String,System.Object[],System.Type[])">
+            <summary>
+            动态调用方法
+            </summary>
+            <param name="funcname"></param>
+            <param name="param"></param>
+            <param name="types"></param>
+            <returns></returns>
+        </member>
+        <member name="M:Admin.NET.Core.Service.ApiJson.SelectTable.GetTableData(System.String,System.Int32,System.Int32,System.Int32,System.String,Newtonsoft.Json.Linq.JObject)">
+            <summary>
+            
+            </summary>
+            <param name="subtable"></param>
+            <param name="page"></param>
+            <param name="count"></param>
+            <param name="json"></param>
+            <param name="dd"></param>
+            <returns></returns>
+        </member>
+        <member name="M:Admin.NET.Core.Service.ApiJson.SelectTable.GetFirstData(System.String,System.String,Newtonsoft.Json.Linq.JObject)">
+            <summary>
+            
+            </summary>
+            <param name="subtable"></param>
+            <param name="json"></param>
+            <param name="dd"></param>
+            <returns></returns>
+        </member>
+        <member name="M:Admin.NET.Core.Service.ApiJson.SelectTable.Query(System.String)">
+            <summary>
+            解析并查询
+            </summary>
+            <param name="query"></param>
+            <returns></returns>
+        </member>
+        <member name="M:Admin.NET.Core.Service.ApiJson.SelectTable.QuerySingle(Newtonsoft.Json.Linq.JObject,System.String)">
+            <summary>
+            单表查询
+            </summary>
+            <param name="queryObj"></param>
+            <param name="nodeName">返回数据的节点名称  默认为 infos</param>
+            <returns></returns>
+        </member>
+        <member name="M:Admin.NET.Core.Service.ApiJson.SelectTable.ToSql(Newtonsoft.Json.Linq.JObject)">
+            <summary>
+            获取查询语句
+            </summary>
+            <param name="queryObj"></param>
+            <returns></returns>
+        </member>
+        <member name="M:Admin.NET.Core.Service.ApiJson.SelectTable.Query(Newtonsoft.Json.Linq.JObject)">
+            <summary>
+            解析并查询
+            </summary>
+            <param name="query"></param>
+            <returns></returns>
+        </member>
         <member name="T:Admin.NET.Core.Service.LoginInput">
             <summary>
             用户登录参数
@@ -7935,5 +8111,12 @@
             SM工具类
             </summary>
         </member>
+        <member name="M:APIJSON.NET.Services.ITableMapper.GetTableName(System.String)">
+            <summary>
+            表别名获取
+            </summary>
+            <param name="oldname"></param>
+            <returns></returns>
+        </member>
     </members>
 </doc>

+ 21 - 0
Admin.NET/Admin.NET.Core/Option/ApiJsonOptions.cs

@@ -0,0 +1,21 @@
+using Admin.NET.Core.Service.ApiJson;
+
+namespace Admin.NET.Core;
+
+/// <summary>
+/// ApiJson配置选项
+/// </summary>
+public sealed class ApiJsonOptions : IConfigurableOptions
+{
+    /// <summary>
+    /// ApiJson集合RoleList
+    /// </summary>
+    public List<Role> RoleList { get; set; }
+    //public Tablempper Tablempper { get; set; }
+}
+
+//public sealed class Tablempper
+//{
+//    public string User { get; set;}
+//    public string Org { get; set;}
+//}

+ 49 - 0
Admin.NET/Admin.NET.Core/Service/ApiJson/ApiJsonService.cs

@@ -0,0 +1,49 @@
+using APIJSON.NET.Services;
+using Newtonsoft.Json.Linq;
+
+namespace Admin.NET.Core.Service.ApiJson;
+
+/// <summary>
+/// 系统数据库管理服务
+/// </summary>
+[ApiDescriptionSettings(Order = 251)]
+public class ApiJsonService : IDynamicApiController, ITransient
+{
+    private SelectTable selectTable;
+    private readonly ISqlSugarClient _db;
+    private readonly IViewEngine _viewEngine;
+    private readonly CodeGenOptions _codeGenOptions;
+    //private readonly ApiJsnOptions _roles;
+    private readonly IIdentityService _identitySvc;
+    private ITableMapper _tableMapper;
+
+    public ApiJsonService(ISqlSugarClient db,
+        IViewEngine viewEngine,
+        IOptions<CodeGenOptions> codeGenOptions,
+        IOptions<ApiJsonOptions> adaOptions,
+        IIdentityService identityService,
+        ITableMapper tableMapper)
+    {
+        _db = db;
+        _viewEngine = viewEngine;
+        //_codeGenOptions = codeGenOptions.Value;
+        //_roles = roles.Value;
+
+
+        _tableMapper = tableMapper;
+        _identitySvc = identityService;
+        selectTable = new SelectTable(_identitySvc, _tableMapper, _db);
+    }
+
+    /// <summary>
+    /// ApiJson 统一入口
+    /// </summary>
+    /// <param name="jobject"></param>
+    /// <returns></returns>
+    public JObject Post([FromBody] JObject jobject)
+    {
+        JObject resultJobj = new SelectTable(_identitySvc, _tableMapper, _db).Query(jobject);
+        return resultJobj;
+    }
+
+}

+ 44 - 0
Admin.NET/Admin.NET.Core/Service/ApiJson/FuncList.cs

@@ -0,0 +1,44 @@
+using System;
+using System.Linq;
+
+namespace Admin.NET.Core.Service.ApiJson
+{
+    /// <summary>
+    /// 自定义方法
+    /// </summary>
+    public class FuncList
+    {
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="a"></param>
+        /// <param name="b"></param>
+        /// <returns></returns>
+        public string Merge(object a, object b)
+        {
+            return a.ToString() + b.ToString();
+        }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="a"></param>
+        /// <param name="b"></param>
+        /// <returns></returns>
+        public object MergeObj(object a, object b)
+        {
+            return new { a, b };
+        }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="a"></param>
+        /// <param name="b"></param>
+        /// <returns></returns>
+        public bool isContain(object a, object b)
+        {
+            return a.ToString().Split(',').Contains(b);
+        }
+    }
+}

+ 32 - 0
Admin.NET/Admin.NET.Core/Service/ApiJson/IIdentityService.cs

@@ -0,0 +1,32 @@
+using System;
+
+namespace Admin.NET.Core.Service.ApiJson
+{
+    public interface IIdentityService
+    {
+        /// <summary>
+        /// 获取当前用户id
+        /// </summary>
+        /// <returns></returns>
+        string GetUserIdentity();
+        /// <summary>
+        /// 获取当前用户权限组名称
+        /// </summary>
+        /// <returns></returns>
+        string GetUserRoleName();
+        /// <summary>
+        /// 获取当前用户权限
+        /// </summary>
+        /// <returns></returns>
+        Role GetRole();
+        /// <summary>
+        /// 获取当前表的可查询字段
+        /// </summary>
+        /// <param name="table"></param>
+        /// <returns></returns>
+        (bool, string) GetSelectRole(string table);
+
+
+        bool ColIsRole(string col, string[] selectrole);
+    }
+}

+ 12 - 0
Admin.NET/Admin.NET.Core/Service/ApiJson/ITableMapper.cs

@@ -0,0 +1,12 @@
+namespace APIJSON.NET.Services
+{
+    public interface ITableMapper
+    {
+        /// <summary>
+        /// 表别名获取
+        /// </summary>
+        /// <param name="oldname"></param>
+        /// <returns></returns>
+          string GetTableName(string oldname);
+    }
+}

+ 91 - 0
Admin.NET/Admin.NET.Core/Service/ApiJson/IdentityService.cs

@@ -0,0 +1,91 @@
+using System.Security.Claims;
+
+namespace Admin.NET.Core.Service.ApiJson
+{
+    public class IdentityService : IIdentityService
+    {
+        private IHttpContextAccessor _context;
+        private List<Role> _roles;
+
+        public IdentityService(IHttpContextAccessor context, IOptions<ApiJsonOptions> roles)
+        {
+            _context = context ?? throw new ArgumentNullException(nameof(context));
+            //roles = App.GetConfig<List<Role>>("ApiJson:RoleList");
+            _roles = roles.Value.RoleList;
+        }
+        public string GetUserIdentity()
+        {
+            return _context.HttpContext.User.FindFirstValue(ClaimTypes.NameIdentifier);
+        }
+
+        public string GetUserRoleName()
+        {
+            return _context.HttpContext.User.FindFirstValue(ClaimTypes.Role);
+        }
+        public Role GetRole()
+        {
+            var role = new Role();
+            if (string.IsNullOrEmpty(GetUserRoleName()))//没登录默认取第一个
+            {
+                role = _roles.FirstOrDefault();
+
+            }
+            else
+            {
+                role = _roles.FirstOrDefault(it => it.Name.Equals(GetUserRoleName(), StringComparison.CurrentCultureIgnoreCase));
+            }
+            return role;
+        }
+        public (bool, string) GetSelectRole(string table)
+        {
+            var role = GetRole();
+            if (role == null || role.Select == null || role.Select.Table == null)
+            {
+                return (false, $"appsettings.json权限配置不正确!");
+            }
+            string tablerole = role.Select.Table.FirstOrDefault(it => it == "*" || it.Equals(table, StringComparison.CurrentCultureIgnoreCase));
+
+            if (string.IsNullOrEmpty(tablerole))
+            {
+                return (false, $"表名{table}没权限查询!");
+            }
+            int index = Array.IndexOf(role.Select.Table, tablerole);
+            string selectrole = role.Select.Column[index];
+            return (true, selectrole);
+        }
+        public bool ColIsRole(string col, string[] selectrole)
+        {
+            if (selectrole.Contains("*"))
+            {
+                return true;
+            }
+            else
+            {
+                if (col.Contains("(") && col.Contains(")"))
+                {
+                    Regex reg = new Regex(@"\(([^)]*)\)");
+                    Match m = reg.Match(col);
+                    if (selectrole.Contains(m.Result("$1"), StringComparer.CurrentCultureIgnoreCase))
+                    {
+                        return true;
+                    }
+                    else
+                    {
+                        return false;
+                    }
+                }
+                else
+                {
+                    if (selectrole.Contains(col, StringComparer.CurrentCultureIgnoreCase))
+                    {
+                        return true;
+                    }
+                    else
+                    {
+                        return false;
+                    }
+                }
+            }
+        }
+    }
+}

+ 29 - 0
Admin.NET/Admin.NET.Core/Service/ApiJson/Infrastructure/StringExtensions.cs

@@ -0,0 +1,29 @@
+namespace Admin.NET.Core.Service.ApiJson
+{
+    using System;
+    using System.Text.RegularExpressions;
+    public static class StringExtensions
+    {
+       
+        /// <summary>
+        /// 是否有值
+        /// </summary>
+        /// <param name="str"></param>
+        /// <returns></returns>
+        public static bool IsValue(this object str)
+        {
+            return str != null && !string.IsNullOrEmpty(str.ToString());
+        }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="param"></param>
+        /// <returns></returns>
+        public static string GetParamName(this string param)
+        {
+            return param + new Random().Next(1, 100);
+        }
+     
+    }
+}

+ 19 - 0
Admin.NET/Admin.NET.Core/Service/ApiJson/Models/RoleItem.cs

@@ -0,0 +1,19 @@
+namespace Admin.NET.Core.Service.ApiJson
+{
+    public class RoleItem
+    {
+        public string[] Table { get; set; }
+        public string[] Column { get; set; }
+        public string[] Filter { get; set; }
+    }
+    public class Role
+    {
+        public string Name { get; set; }
+        public RoleItem Select { get; set; }
+        public RoleItem Update { get; set; }
+        public RoleItem Insert { get; set; }
+        public RoleItem Delete { get; set; }
+
+    }
+    
+}

+ 839 - 0
Admin.NET/Admin.NET.Core/Service/ApiJson/SelectTable.cs

@@ -0,0 +1,839 @@
+namespace Admin.NET.Core.Service.ApiJson
+{
+    using APIJSON.NET.Services;
+    using AspectCore.Extensions.Reflection;
+    using Newtonsoft.Json.Linq;
+    using SqlSugar;
+    using System;
+    using System.Collections.Generic;
+    using System.Dynamic;
+    using System.Linq;
+    using System.Text.RegularExpressions;
+
+    /// <summary>
+    /// 
+    /// </summary>
+    public class SelectTable
+    {
+        private readonly IIdentityService _identitySvc;
+        private readonly ITableMapper _tableMapper;
+        private readonly ISqlSugarClient db;
+
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="identityService"></param>
+        /// <param name="tableMapper"></param>
+        /// <param name="dbClient"></param>
+        public SelectTable(IIdentityService identityService, ITableMapper tableMapper, ISqlSugarClient dbClient)
+        {
+            _identitySvc = identityService;
+            _tableMapper = tableMapper;
+            db = dbClient;
+        }
+        /// <summary>
+        /// 判断表名是否正确
+        /// </summary>
+        /// <param name="table"></param>
+        /// <returns></returns>
+        public bool IsTable(string table)
+        {
+            return db.DbMaintenance.GetTableInfoList().Any(it => it.Name.Equals(table, StringComparison.CurrentCultureIgnoreCase));
+        }
+        /// <summary>
+        /// 判断表的列名是否正确
+        /// </summary>
+        /// <param name="table"></param>
+        /// <param name="col"></param>
+        /// <returns></returns>
+        public bool IsCol(string table, string col)
+        {
+            return db.DbMaintenance.GetColumnInfosByTableName(table).Any(it => it.DbColumnName.Equals(col, StringComparison.CurrentCultureIgnoreCase));
+        }
+        /// <summary>
+        /// 动态调用方法
+        /// </summary>
+        /// <param name="funcname"></param>
+        /// <param name="param"></param>
+        /// <param name="types"></param>
+        /// <returns></returns>
+        public object ExecFunc(string funcname, object[] param, Type[] types)
+        {
+            var method = typeof(FuncList).GetMethod(funcname);
+
+            var reflector = method.GetReflector();
+            var result = reflector.Invoke(new FuncList(), param);
+            return result;
+        }
+
+        private string ToSql(string subtable, int page, int count, int query, string json)
+        {
+            JObject values = JObject.Parse(json);
+            page = values["page"] == null ? page : int.Parse(values["page"].ToString());
+            count = values["count"] == null ? count : int.Parse(values["count"].ToString());
+            query = values["query"] == null ? query : int.Parse(values["query"].ToString());
+            values.Remove("page");
+            values.Remove("count");
+            subtable = _tableMapper.GetTableName(subtable);
+            var tb = sugarQueryable(subtable, "*", values,null);
+            var xx= tb.Skip((page - 1) * count).Take(10).ToSql();
+            return xx.Key;
+        }
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="subtable"></param>
+        /// <param name="page"></param>
+        /// <param name="count"></param>
+        /// <param name="json"></param>
+        /// <param name="dd"></param>
+        /// <returns></returns>
+        public Tuple<dynamic, int> GetTableData(string subtable, int page, int count, int query, string json, JObject dd)
+        {
+
+            var role = _identitySvc.GetSelectRole(subtable);
+            if (!role.Item1)//没有权限返回异常
+            {
+                throw new Exception(role.Item2);
+            }
+            string selectrole = role.Item2;
+            subtable = _tableMapper.GetTableName(subtable);
+
+            JObject values = JObject.Parse(json);
+            page = values["page"] == null ? page : int.Parse(values["page"].ToString());
+            count = values["count"] == null ? count : int.Parse(values["count"].ToString());
+            query = values["query"] == null ? query : int.Parse(values["query"].ToString());
+            values.Remove("page");
+            values.Remove("count");
+            var tb = sugarQueryable(subtable, selectrole, values, dd);
+            if (query == 1)//1-总数
+                return new Tuple<dynamic, int>(new List<object>(), tb.Count());
+            else
+            {
+                if (count > 0)
+                {
+                    int total = 0;
+                    if (query == 0)//0-对象
+                        return new Tuple<dynamic, int>(tb.ToPageList(page, count), total);
+                    else
+                        //2-以上全部
+                        return new Tuple<dynamic, int>(tb.ToPageList(page, count, ref total), total);
+
+                }
+                else
+                {
+                    if (query == 0)
+                        return new Tuple<dynamic, int>(tb.ToList(), 0);
+                    else
+                        return new Tuple<dynamic, int>(tb.ToList(), tb.Count());
+                }
+            }
+        }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="subtable"></param>
+        /// <param name="json"></param>
+        /// <param name="dd"></param>
+        /// <returns></returns>
+        public dynamic GetFirstData(string subtable, string json, JObject dd)
+        {
+
+            var role = _identitySvc.GetSelectRole(subtable);
+            if (!role.Item1)//没有权限返回异常
+            {
+                throw new Exception(role.Item2);
+            }
+            string selectrole = role.Item2;
+            subtable = _tableMapper.GetTableName(subtable);
+            JObject values = JObject.Parse(json);
+            values.Remove("page");
+            values.Remove("count");
+            var tb = sugarQueryable(subtable, selectrole, values, dd).First();
+            var dic = (IDictionary<string, object>)tb;
+            foreach (var item in values.Properties().Where(it => it.Name.EndsWith("()")))
+            {
+                if (item.Value.IsValue())
+                {
+                    string func = item.Value.ToString().Substring(0, item.Value.ToString().IndexOf("("));
+                    string param = item.Value.ToString().Substring(item.Value.ToString().IndexOf("(") + 1).TrimEnd(')');
+                    var types = new List<Type>();
+                    var paramss = new List<object>();
+                    foreach (var va in param.Split(','))
+                    {
+                        types.Add(typeof(object));
+                        paramss.Add(tb.Where(it => it.Key.Equals(va)).Select(i => i.Value));
+                    }
+                    dic[item.Name] = ExecFunc(func, paramss.ToArray(), types.ToArray());
+                }
+            }
+
+            return tb;
+
+        }
+
+        /// <summary>
+        /// 解析并查询
+        /// </summary>
+        /// <param name="query"></param>
+        /// <returns></returns>
+        public JObject Query(string queryJson)
+        {
+            JObject resultObj = new JObject();
+
+            try
+            {
+                JObject queryJobj = JObject.Parse(queryJson);
+                resultObj = Query(queryJobj);
+            }
+            catch (Exception ex)
+            {
+                resultObj.Add("code", "500");
+                resultObj.Add("msg", ex.Message);
+            }
+
+            return resultObj;
+        }
+
+        /// <summary>
+        /// 单表查询
+        /// </summary>
+        /// <param name="queryObj"></param>
+        /// <param name="nodeName">返回数据的节点名称  默认为 infos</param>
+        /// <returns></returns>
+        public JObject QuerySingle(JObject queryObj, string nodeName = "infos")
+        {
+            JObject resultObj = new JObject();
+            resultObj.Add("code", "200");
+            resultObj.Add("msg", "success");
+            try
+            {
+                int total = 0;
+                foreach (var item in queryObj)
+                {
+                    string key = item.Key.Trim();
+
+                    if (key.EndsWith("[]"))
+                    {
+                        total = QuerySingleList(resultObj, item, nodeName);
+                    }
+                    else if (key.Equals("func"))
+                    {
+                        ExecFunc(resultObj, item);
+                    }
+                    else if (key.Equals("total@"))
+                    {
+                        resultObj.Add("total", total);
+                    }
+                }
+            }
+            catch (Exception ex)
+            {
+                resultObj["code"] = "500";
+                resultObj["msg"] = ex.Message;
+            }
+            return resultObj;
+        }
+
+        /// <summary>
+        /// 获取查询语句
+        /// </summary>
+        /// <param name="queryObj"></param>
+        /// <returns></returns>
+        public string ToSql(JObject queryObj)
+        {
+            foreach (var item in queryObj)
+            {
+                string key = item.Key.Trim();
+
+                if (key.EndsWith("[]"))
+                {
+                    return  ToSql(item);
+                }
+            }
+            return string.Empty;
+        }
+
+        /// <summary>
+        /// 解析并查询
+        /// </summary>
+        /// <param name="query"></param>
+        /// <returns></returns>
+        public JObject Query(JObject queryObj)
+        {
+            JObject resultObj = new JObject();
+            resultObj.Add("code", "200");
+            resultObj.Add("msg", "success");
+            try
+            {
+                int total = 0;
+                foreach (var item in queryObj)
+                {
+                    string key = item.Key.Trim();
+
+                    if (key.Equals("[]"))
+                    {
+                        total = QueryMoreList(resultObj, item);
+                    }
+                    else if (key.EndsWith("[]"))
+                    {
+                        total = QuerySingleList(resultObj, item);
+                    }
+                    else if (key.Equals("func"))
+                    {
+                        ExecFunc(resultObj, item);
+                    }
+                    else if (key.Equals("total@"))
+                    {
+                        resultObj.Add("total", total);
+                    }
+                    else
+                    {
+                        var template = GetFirstData(key, item.Value.ToString(), resultObj);
+                        if (template != null)
+                        {
+                            resultObj.Add(key, JToken.FromObject(template));
+                        }
+                    }
+                }
+            }
+            catch (Exception ex)
+            {
+                resultObj["code"] = "500";
+                resultObj["msg"] = ex.Message;
+            }
+            return resultObj;
+        }
+
+        //单表查询,返回的数据在指定的NodeName节点
+        private int QuerySingleList(JObject resultObj, KeyValuePair<string, JToken> item, string nodeName)
+        {
+            string key = item.Key.Trim();
+            var jb = JObject.Parse(item.Value.ToString());
+            int page = jb["page"] == null ? 0 : int.Parse(jb["page"].ToString());
+            int count = jb["count"] == null ? 10 : int.Parse(jb["count"].ToString());
+            int query = jb["query"] == null ? 0 : int.Parse(jb["query"].ToString());
+            int total = 0;
+
+            jb.Remove("page"); jb.Remove("count"); jb.Remove("query");
+
+            var htt = new JArray();
+            foreach (var t in jb)
+            {
+                var datas = GetTableData(t.Key, page, count, query, t.Value.ToString(), null);
+                if (query > 0)
+                {
+                    total = datas.Item2;
+                }
+                foreach (var data in datas.Item1)
+                {
+                    htt.Add(JToken.FromObject(data));
+                }
+            }
+
+            if (!string.IsNullOrEmpty(nodeName))
+            {
+                resultObj.Add(nodeName, htt);
+            }
+            else
+                resultObj.Add(key, htt);
+            return total;
+        }
+
+        private string ToSql(KeyValuePair<string, JToken> item)
+        {
+            string key = item.Key.Trim();
+            var jb = JObject.Parse(item.Value.ToString());
+            int page = jb["page"] == null ? 0 : int.Parse(jb["page"].ToString());
+            int count = jb["count"] == null ? 10 : int.Parse(jb["count"].ToString());
+            int query = jb["query"] == null ? 0 : int.Parse(jb["query"].ToString());
+
+            jb.Remove("page"); jb.Remove("count"); jb.Remove("query");
+            var htt = new JArray();
+            foreach (var t in jb)
+            {
+                return ToSql(t.Key, page, count, query, t.Value.ToString());
+            }
+
+            return string.Empty;
+        }
+        //单表查询
+        private int QuerySingleList(JObject resultObj, KeyValuePair<string, JToken> item)
+        {
+            string key = item.Key.Trim();
+            return QuerySingleList(resultObj, item, key);
+        }
+
+        //多列表查询
+        private int QueryMoreList(JObject resultObj, KeyValuePair<string, JToken> item)
+        {
+            int total = 0;
+
+            var jb = JObject.Parse(item.Value.ToString());
+            var page = jb["page"] == null ? 0 : int.Parse(jb["page"].ToString());
+            var count = jb["count"] == null ? 10 : int.Parse(jb["count"].ToString());
+            var query = jb["query"] == null ? 0 : int.Parse(jb["query"].ToString());
+            jb.Remove("page"); jb.Remove("count"); jb.Remove("query");
+            var htt = new JArray();
+            List<string> tables = new List<string>(), where = new List<string>();
+            foreach (var t in jb)
+            {
+                tables.Add(t.Key); where.Add(t.Value.ToString());
+            }
+            if (tables.Count > 0)
+            {
+                string table = tables[0];
+                var temp = GetTableData(table, page, count, query, where[0], null);
+                if (query > 0)
+                {
+                    total = temp.Item2;
+                }
+
+                foreach (var dd in temp.Item1)
+                {
+                    var zht = new JObject();
+                    zht.Add(table, JToken.FromObject(dd));
+                    for (int i = 1; i < tables.Count; i++)
+                    {
+                        string subtable = tables[i];
+                        if (subtable.EndsWith("[]"))
+                        {
+                            subtable = subtable.TrimEnd("[]".ToCharArray());
+                            var jbb = JObject.Parse(where[i]);
+                            page = jbb["page"] == null ? 0 : int.Parse(jbb["page"].ToString());
+                            count = jbb["count"] == null ? 0 : int.Parse(jbb["count"].ToString());
+
+                            var lt = new JArray();
+                            foreach (var d in GetTableData(subtable, page, count, query, jbb[subtable].ToString(), zht).Item1)
+                            {
+                                lt.Add(JToken.FromObject(d));
+                            }
+                            zht.Add(tables[i], lt);
+                        }
+                        else
+                        {
+                            var ddf = GetFirstData(subtable, where[i].ToString(), zht);
+                            if (ddf != null)
+                            {
+                                zht.Add(subtable, JToken.FromObject(ddf));
+
+                            }
+                        }
+                    }
+                    htt.Add(zht);
+                }
+
+            }
+            if (query != 1)
+            {
+                resultObj.Add("[]", htt);
+            }
+
+            return total;
+        }
+
+        private void ExecFunc(JObject resultObj, KeyValuePair<string, JToken> item)
+        {
+            JObject jb = JObject.Parse(item.Value.ToString());
+            Type type = typeof(FuncList);
+
+            var dataJObj = new JObject();
+            foreach (var f in jb)
+            {
+                var types = new List<Type>();
+                var param = new List<object>();
+                foreach (var va in JArray.Parse(f.Value.ToString()))
+                {
+                    types.Add(typeof(object));
+                    param.Add(va);
+                }
+                dataJObj.Add(f.Key, JToken.FromObject(ExecFunc(f.Key, param.ToArray(), types.ToArray())));
+            }
+            resultObj.Add("func", dataJObj);
+        }
+
+        private ISugarQueryable<ExpandoObject> sugarQueryable(string subtable, string selectrole, JObject values, JObject dd)
+        {
+            if (!IsTable(subtable))
+            {
+                throw new Exception($"表名{subtable}不正确!");
+            }
+            var tb = db.Queryable(subtable, "tb");
+
+
+            if (values["@column"].IsValue())
+            {
+                ProcessColumn(subtable, selectrole, values, tb);
+            }
+            else
+            {
+                tb.Select(selectrole);
+            }
+
+            List<IConditionalModel> conModels = new List<IConditionalModel>();
+            if (values["identity"].IsValue())
+            {
+                conModels.Add(new ConditionalModel() { FieldName = values["identity"].ToString(), ConditionalType = ConditionalType.Equal, FieldValue = _identitySvc.GetUserIdentity() });
+            }
+            foreach (var va in values)
+            {
+                string vakey = va.Key.Trim();
+                string fieldValue = va.Value.ToString();
+
+                if (vakey.EndsWith("$"))//模糊查询
+                {
+                    FuzzyQuery(subtable, conModels, va);
+                }
+                else if (vakey.EndsWith("{}"))//逻辑运算
+                {
+                    ConditionQuery(subtable, conModels, va);
+                }
+                else if (vakey.EndsWith("%"))//bwtween查询
+                {
+                    ConditionBetween(subtable, conModels, va);
+                }
+                else if (vakey.EndsWith("@") && dd != null) // 关联上一个table
+                {
+                    string[] str = fieldValue.Split('/');
+                    string value = string.Empty;
+                    if (str.Length == 3)
+                    {
+                        value = dd[str[1]][str[2]].ToString();
+                    }
+                    else if (str.Length == 2)
+                    {
+                        value = dd[str[0]][str[1]].ToString();
+                    }
+
+                    conModels.Add(new ConditionalModel() { FieldName = vakey.TrimEnd('@'), ConditionalType = ConditionalType.Equal, FieldValue = value });
+
+                }
+                else if (IsCol(subtable, vakey)) //其他where条件
+                {
+                    conModels.Add(new ConditionalModel() { FieldName = vakey, ConditionalType = ConditionalType.Equal, FieldValue = fieldValue });
+                }
+            }
+            tb.Where(conModels);
+
+            //排序
+            ProcessOrder(subtable, values, tb);
+
+            //分组
+            PrccessGroup(subtable, values, tb);
+
+            //Having
+            ProcessHaving(values, tb);
+            return tb;
+        }
+
+        //处理字段重命名 "@column":"toId:parentId",对应SQL是toId AS parentId,将查询的字段toId变为parentId返回
+        private void ProcessColumn(string subtable, string selectrole, JObject values, ISugarQueryable<ExpandoObject> tb)
+        {
+            var str = new System.Text.StringBuilder(100);
+            foreach (var item in values["@column"].ToString().Split(','))
+            {
+                string[] ziduan = item.Split(':');
+                string colName = ziduan[0];
+                var ma = new Regex(@"\((\w+)\)").Match(colName);
+                //处理max,min这样的函数
+                if (ma.Success && ma.Groups.Count > 1)
+                {
+                    colName = ma.Groups[1].Value;
+                }
+
+                //判断列表是否有权限  sum(1),sum(*),Count(1)这样的值直接有效
+                if (colName == "*" || int.TryParse(colName, out int colNumber) || (IsCol(subtable, colName) && _identitySvc.ColIsRole(colName, selectrole.Split(','))))
+                {
+                    if (ziduan.Length > 1)
+                    {
+                        if (ziduan[1].Length > 20)
+                        {
+                            throw new Exception("别名不能超过20个字符");
+                        }
+                        str.Append(ziduan[0] + " as " + ReplaceSQLChar(ziduan[1]) + ",");
+                    }
+                    else
+                        str.Append(ziduan[0] + ",");
+
+                }
+            }
+            if (string.IsNullOrEmpty(str.ToString()))
+            {
+                throw new Exception($"表名{subtable}没有可查询的字段!");
+            }
+            tb.Select(str.ToString().TrimEnd(','));
+        }
+
+        // "@having":"function0(...)?value0;function1(...)?value1;function2(...)?value2...",
+        // SQL函数条件,一般和 @group一起用,函数一般在 @column里声明
+        private void ProcessHaving(JObject values, ISugarQueryable<ExpandoObject> tb)
+        {
+            if (values["@having"].IsValue())
+            {
+                List<IConditionalModel> hw = new List<IConditionalModel>();
+                List<string> havingItems = new List<string>();
+                if (values["@having"].HasValues)
+                {
+                    havingItems = values["@having"].Select(p => p.ToString()).ToList();
+                }
+                else
+                {
+                    havingItems.Add(values["@having"].ToString());
+                }
+                foreach (var item in havingItems)
+                {
+                    string and = item.ToString();
+                    var model = new ConditionalModel();
+                    if (and.Contains(">="))
+                    {
+                        model.FieldName = and.Split(new string[] { ">=" }, StringSplitOptions.RemoveEmptyEntries)[0];
+                        model.ConditionalType = ConditionalType.GreaterThanOrEqual;
+                        model.FieldValue = and.Split(new string[] { ">=" }, StringSplitOptions.RemoveEmptyEntries)[1];
+                    }
+                    else if (and.Contains("<="))
+                    {
+
+                        model.FieldName = and.Split(new string[] { "<=" }, StringSplitOptions.RemoveEmptyEntries)[0];
+                        model.ConditionalType = ConditionalType.LessThanOrEqual;
+                        model.FieldValue = and.Split(new string[] { "<=" }, StringSplitOptions.RemoveEmptyEntries)[1];
+                    }
+                    else if (and.Contains(">"))
+                    {
+                        model.FieldName = and.Split(new string[] { ">" }, StringSplitOptions.RemoveEmptyEntries)[0];
+                        model.ConditionalType = ConditionalType.GreaterThan;
+                        model.FieldValue = and.Split(new string[] { ">" }, StringSplitOptions.RemoveEmptyEntries)[1];
+                    }
+                    else if (and.Contains("<"))
+                    {
+                        model.FieldName = and.Split(new string[] { "<" }, StringSplitOptions.RemoveEmptyEntries)[0];
+                        model.ConditionalType = ConditionalType.LessThan;
+                        model.FieldValue = and.Split(new string[] { "<" }, StringSplitOptions.RemoveEmptyEntries)[1];
+                    }
+                    else if (and.Contains("!="))
+                    {
+                        model.FieldName = and.Split(new string[] { "!=" }, StringSplitOptions.RemoveEmptyEntries)[0];
+                        model.ConditionalType = ConditionalType.NoEqual;
+                        model.FieldValue = and.Split(new string[] { "!=" }, StringSplitOptions.RemoveEmptyEntries)[1];
+                    }
+                    else if (and.Contains("="))
+                    {
+                        model.FieldName = and.Split(new string[] { "=" }, StringSplitOptions.RemoveEmptyEntries)[0];
+                        model.ConditionalType = ConditionalType.Equal;
+                        model.FieldValue = and.Split(new string[] { "=" }, StringSplitOptions.RemoveEmptyEntries)[1];
+                    }
+                    hw.Add(model);
+                }
+               
+              
+                tb.Having(string.Join(",", havingItems));
+            }
+        }
+
+        //"@group":"column0,column1...",分组方式。如果 @column里声明了Table的id,则id也必须在 @group中声明;其它情况下必须满足至少一个条件:
+        //1.分组的key在 @column里声明
+        //2.Table主键在 @group中声明
+        private void PrccessGroup(string subtable, JObject values, ISugarQueryable<ExpandoObject> tb)
+        {
+            if (values["@group"].IsValue())
+            {
+                var str = new System.Text.StringBuilder(100);
+                foreach (var and in values["@group"].ToString().Split(','))
+                {
+                    if (IsCol(subtable, and))
+                    {
+                        str.Append(and + ",");
+                    }
+                }
+                tb.GroupBy(str.ToString().TrimEnd(','));
+            }
+        }
+
+        //处理排序 "@order":"name-,id"查询按 name降序、id默认顺序 排序的User数组
+        private void ProcessOrder(string subtable, JObject values, ISugarQueryable<ExpandoObject> tb)
+        {
+            if (values["@order"].IsValue())
+            {
+                foreach (var item in values["@order"].ToString().Split(','))
+                {
+                    string col = item.Replace("-", "").Replace("+", "");
+                    if (IsCol(subtable, col))
+                    {
+                        if (item.EndsWith("-"))
+                        {
+                            tb.OrderBy($"{col} desc");
+                        }
+                        else if (item.EndsWith("+"))
+                        {
+                            tb.OrderBy($"{col} asc");
+                        }
+                        else
+                        {
+                            tb.OrderBy($"{col}");
+                        }
+                    }
+                }
+            }
+        }
+
+        //条件查询 "key{}":"条件0,条件1...",条件为任意SQL比较表达式字符串,非Number类型必须用''包含条件的值,如'a'
+        //&, |, ! 逻辑运算符,对应数据库 SQL 中的 AND, OR, NOT。 
+        //   横或纵与:同一字段的值内条件默认 | 或连接,不同字段的条件默认 & 与连接。 
+        //   ① & 可用于"key&{}":"条件"等 
+        //   ② | 可用于"key|{}":"条件", "key|{}":[] 等,一般可省略 
+        //   ③ ! 可单独使用,如"key!":Object,也可像&,|一样配合其他功能符使用
+        private void ConditionQuery(string subtable, List<IConditionalModel> conModels, KeyValuePair<string, JToken> va)
+        {
+            string vakey = va.Key.Trim();
+            string field = vakey.TrimEnd("{}".ToCharArray());
+            if (va.Value.HasValues)
+            {
+                List<string> inValues = new List<string>();
+                foreach (var cm in va.Value)
+                {
+                    inValues.Add(cm.ToString());
+                }
+
+                conModels.Add(new ConditionalModel() { FieldName = field, ConditionalType = field.EndsWith("!") ? ConditionalType.NotIn : ConditionalType.In, FieldValue = string.Join(",", inValues) });
+
+            }
+            else
+            {
+                var ddt = new List<KeyValuePair<WhereType, ConditionalModel>>();
+                foreach (var and in va.Value.ToString().Split(','))
+                {
+                    var model = new ConditionalModel();
+                    model.FieldName = field.TrimEnd("&".ToCharArray());//处理&()的查询方式
+                    if (and.StartsWith(">="))
+                    {
+                        model.ConditionalType = ConditionalType.GreaterThanOrEqual;
+                        model.FieldValue = and.TrimStart(">=".ToCharArray());
+                    }
+                    else if (and.StartsWith("<="))
+                    {
+
+                        model.ConditionalType = ConditionalType.LessThanOrEqual;
+                        model.FieldValue = and.TrimStart("<=".ToCharArray());
+                    }
+                    else if (and.StartsWith(">"))
+                    {
+                        model.ConditionalType = ConditionalType.GreaterThan;
+                        model.FieldValue = and.TrimStart('>');
+                    }
+                    else if (and.StartsWith("<"))
+                    {
+                        model.ConditionalType = ConditionalType.LessThan;
+                        model.FieldValue = and.TrimStart('<');
+                    }
+                    ddt.Add(new KeyValuePair<WhereType, ConditionalModel>((field.EndsWith("&") ? WhereType.And : WhereType.Or), model));
+                }
+                conModels.Add(new ConditionalCollections() { ConditionalList = ddt });
+            }
+        }
+
+        //"key%":"start,end" => "key%":["start,end"],其中 start 和 end 都只能为 Boolean, Number, String 中的一种,如 "2017-01-01,2019-01-01" ,["1,90000", "82001,100000"] ,可用于连续范围内的筛选
+        private void ConditionBetween(string subtable, List<IConditionalModel> conModels, KeyValuePair<string, JToken> va)
+        {
+            string vakey = va.Key.Trim();
+            string field = vakey.TrimEnd("%".ToCharArray());
+            List<string> inValues = new List<string>();
+
+            if (va.Value.HasValues)
+            {
+                foreach (var cm in va.Value)
+                {
+                    inValues.Add(cm.ToString());
+                }
+            }
+            else
+            {
+                inValues.Add(va.Value.ToString());
+            }
+            for (var i = 0; i < inValues.Count; i++)
+            {
+                var fileds = inValues[i].Split(',');
+                if (fileds.Length == 2)
+                {
+                    var ddt = new List<KeyValuePair<WhereType, ConditionalModel>>();
+
+                    var leftCondition = new ConditionalModel()
+                    {
+                        FieldName = field,
+                        ConditionalType = ConditionalType.GreaterThanOrEqual,
+                        FieldValue = fileds[0]
+                    };
+                    ddt.Add(new KeyValuePair<WhereType, ConditionalModel>(i == 0 ? WhereType.And : WhereType.Or, leftCondition));
+                    var rightCondition = new ConditionalModel()
+                    {
+                        FieldName = field,
+                        ConditionalType = ConditionalType.LessThanOrEqual,
+                        FieldValue = fileds[1]
+                    };
+                    ddt.Add(new KeyValuePair<WhereType, ConditionalModel>(WhereType.And, rightCondition));
+
+                    conModels.Add(new ConditionalCollections() { ConditionalList = ddt });
+                }
+            }
+        }
+
+        //模糊搜索	"key$":"SQL搜索表达式" => "key$":["SQL搜索表达式"],任意SQL搜索表达式字符串,如 %key%(包含key), key%(以key开始), %k%e%y%(包含字母k,e,y) 等,%表示任意字符
+        private void FuzzyQuery(string subtable, List<IConditionalModel> conModels, KeyValuePair<string, JToken> va)
+        {
+            string vakey = va.Key.Trim();
+            string fieldValue = va.Value.ToString();
+            var conditionalType = ConditionalType.Like;
+            if (IsCol(subtable, vakey.TrimEnd('$')))
+            {
+                //支持三种like查询
+                if (fieldValue.StartsWith("%") && fieldValue.EndsWith("%"))
+                {
+                    conditionalType = ConditionalType.Like;
+                }
+                else if (fieldValue.StartsWith("%"))
+                {
+                    conditionalType = ConditionalType.LikeRight;
+                }
+                else if (fieldValue.EndsWith("%"))
+                {
+                    conditionalType = ConditionalType.LikeLeft;
+                }
+                conModels.Add(new ConditionalModel() { FieldName = vakey.TrimEnd('$'), ConditionalType = conditionalType, FieldValue = fieldValue.TrimEnd("%".ToArray()).TrimStart("%".ToArray()) });
+            }
+        }
+
+        public string ReplaceSQLChar(string str)
+        {
+            if (str == String.Empty)
+                return String.Empty;
+            str = str.Replace("'", "");
+            str = str.Replace(";", "");
+            str = str.Replace(",", "");
+            str = str.Replace("?", "");
+            str = str.Replace("<", "");
+            str = str.Replace(">", "");
+            str = str.Replace("(", "");
+            str = str.Replace(")", "");
+            str = str.Replace("@", "");
+            str = str.Replace("=", "");
+            str = str.Replace("+", "");
+            str = str.Replace("*", "");
+            str = str.Replace("&", "");
+            str = str.Replace("#", "");
+            str = str.Replace("%", "");
+            str = str.Replace("$", "");
+            str = str.Replace("\"", "");
+
+            //删除与数据库相关的词
+            str = Regex.Replace(str, "delete from", "", RegexOptions.IgnoreCase);
+            str = Regex.Replace(str, "drop table", "", RegexOptions.IgnoreCase);
+            str = Regex.Replace(str, "truncate", "", RegexOptions.IgnoreCase);
+            str = Regex.Replace(str, "xp_cmdshell", "", RegexOptions.IgnoreCase);
+            str = Regex.Replace(str, "exec master", "", RegexOptions.IgnoreCase);
+            str = Regex.Replace(str, "net localgroup administrators", "", RegexOptions.IgnoreCase);
+            str = Regex.Replace(str, "net user", "", RegexOptions.IgnoreCase);
+            str = Regex.Replace(str, "-", "", RegexOptions.IgnoreCase);
+            str = Regex.Replace(str, "truncate", "", RegexOptions.IgnoreCase);
+            return str;
+        }
+    }
+}

+ 26 - 0
Admin.NET/Admin.NET.Core/Service/ApiJson/TableMapper.cs

@@ -0,0 +1,26 @@
+using Microsoft.Extensions.Options;
+using System;
+using System.Collections.Generic;
+
+namespace APIJSON.NET.Services
+{
+    public class TableMapper : ITableMapper
+    {
+        private readonly Dictionary<string, string> _options= new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
+        public TableMapper(IOptions<Dictionary<string, string>> options)
+        {
+            foreach (var item in options.Value)
+            {
+                _options.Add(item.Key, item.Value);
+            }
+        }
+        public string GetTableName(string oldname)
+        {
+            if (_options.ContainsKey(oldname))
+            {
+                return _options[oldname];
+            }
+            return oldname;
+        }
+    }
+}

+ 1 - 0
Admin.NET/Admin.NET.Web.Core/Admin.NET.Web.Core.csproj

@@ -17,6 +17,7 @@
 
   <ItemGroup>
     <ProjectReference Include="..\Admin.NET.Application\Admin.NET.Application.csproj" />
+    <ProjectReference Include="..\Admin.NET.Core\Admin.NET.Core.csproj" />
   </ItemGroup>
 
 </Project>

+ 1 - 0
Admin.NET/Admin.NET.Web.Core/ProjectOptions.cs

@@ -24,6 +24,7 @@ public static class ProjectOptions
         services.AddConfigurableOptions<WechatPayOptions>();
         services.AddConfigurableOptions<PayCallBackOptions>();
         services.AddConfigurableOptions<CodeGenOptions>();
+        services.AddConfigurableOptions<ApiJsonOptions>();
         services.AddConfigurableOptions<EmailOptions>();
         services.AddConfigurableOptions<OAuthOptions>();
         services.AddConfigurableOptions<CryptogramOptions>();

+ 45 - 0
Admin.NET/Admin.NET.Web.Core/Startup.cs

@@ -1,20 +1,27 @@
 using Admin.NET.Core;
 using Admin.NET.Core.Service;
+using Admin.NET.Core.Service.ApiJson;
+using APIJSON.NET.Services;
 using AspNetCoreRateLimit;
 using Furion;
 using Furion.SpecificationDocument;
 using IGeekFan.AspNetCore.Knife4jUI;
 using Microsoft.AspNetCore.Builder;
 using Microsoft.AspNetCore.Hosting;
+using Microsoft.AspNetCore.Http;
 using Microsoft.AspNetCore.HttpOverrides;
+using Microsoft.Extensions.Configuration;
 using Microsoft.Extensions.DependencyInjection;
 using Microsoft.Extensions.Hosting;
 using Microsoft.Extensions.Logging;
+using Microsoft.IdentityModel.Tokens;
+using Microsoft.OpenApi.Models;
 using NewLife.Model;
 using Newtonsoft.Json;
 using Newtonsoft.Json.Serialization;
 using OnceMi.AspNetCore.OSS;
 using System;
+using System.Collections.Generic;
 using System.IO;
 using System.Net;
 using System.Net.Mail;
@@ -181,6 +188,44 @@ public class Startup : AppStartup
 
         // 验证码
         services.AddLazyCaptcha();
+
+        #region ApiJson
+        //services.Configure<List<Role>>(App.GetConfig<List<Role>>("ApiJson:RoleList"));
+        //services.Configure<Dictionary<string, string>>(Configuration.GetSection("tablempper"));
+        //services.Configure<TokenAuthConfiguration>(tokenAuthConfig =>
+        //{
+        //    tokenAuthConfig.SecurityKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(Configuration["Authentication:JwtBearer:SecurityKey"]));
+        //    tokenAuthConfig.Issuer = Configuration["Authentication:JwtBearer:Issuer"];
+        //    tokenAuthConfig.Audience = Configuration["Authentication:JwtBearer:Audience"];
+        //    tokenAuthConfig.SigningCredentials = new SigningCredentials(tokenAuthConfig.SecurityKey, SecurityAlgorithms.HmacSha256);
+        //    tokenAuthConfig.Expiration = TimeSpan.FromDays(1);
+        //});
+        //AuthConfigurer.Configure(services, Configuration);
+
+        //var origins = Configuration.GetSection("CorsUrls").Value.Split(",");
+        //services.AddCors(options => options.AddPolicy(_defaultCorsPolicyName,
+        //   builder =>
+        //   builder.WithOrigins(origins)
+        //     .AllowAnyHeader()
+        //     .AllowAnyMethod().AllowCredentials()
+        //     ));
+        //services.AddControllers()
+        //    .AddNewtonsoftJson(options =>
+        //    {
+        //        options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
+        //        options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";
+        //    }); ;
+        //services.AddSwaggerGen(c =>
+        //{
+        //    c.SwaggerDoc("v1", new OpenApiInfo { Title = "APIJSON.NET", Version = "v1" });
+        //});
+        //services.AddSingleton<DbContext>();
+        services.AddSingleton<SelectTable>();
+        //services.AddSingleton<TokenAuthConfiguration>();
+        services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
+        services.AddTransient<IIdentityService, IdentityService>();
+        services.AddTransient<ITableMapper, TableMapper>();
+        #endregion
     }
 
     public void Configure(IApplicationBuilder app, IWebHostEnvironment env)

+ 1 - 1
Admin.NET/Admin.NET.Web.Entry/appsettings.json

@@ -1,5 +1,5 @@
 {
     "$schema": "https://gitee.com/dotnetchina/Furion/raw/net6/schemas/v3/furion-schema.json",
 
-    "ConfigurationScanDirectories": [ "Configuration", "" ]
+    "ConfigurationScanDirectories": [ "Configuration", "" ]// 扫描配置文件.json的文件夹,配置.json文件在此文件夹下即被扫描合并。
 }