Преглед изворни кода

👍 !1000 完善APIJSON部分
Merge pull request !1000 from 苏智明/next

zuohuaijun пре 2 година
родитељ
комит
00638ab6a9

+ 4 - 4
Admin.NET/Admin.NET.Application/Configuration/APIJSON.json

@@ -7,16 +7,16 @@
         "RoleName": "Role1", // 权限名称 唯一
         "Select": { // 查询
           "Table": [ "*" ], // 可操作的表
-          "Column": [ "tb.*" ], // 可操作的字段
+          "Column": [ "*" ], // 可操作的字段
           "Filter": []
         },
         "Insert": { // 添加
           "Table": [ "table1", "table2", "table3" ],
-          "Column": [ "tb.*", "tb.*", "tb.*" ]
+          "Column": [ "*", "*", "tb.*" ]
         },
         "Update": { // 修改
           "Table": [ "table1", "table2", "table3" ],
-          "Column": [ "tb.*", "tb.*", "tb.*" ]
+          "Column": [ "*", "tb.*", "tb.*" ]
         },
         "Delete": { // 删除
           "Table": [ "table1", "table2", "table3" ]
@@ -26,7 +26,7 @@
         "RoleName": "Role2",
         "Select": {
           "Table": [ "table1" ],
-          "Column": [ "*" ]
+          "Column": [ "tb.*" ]
         }
       }
     ]

+ 0 - 47
Admin.NET/Admin.NET.Application/Configuration/Logging.json

@@ -1,47 +0,0 @@
-{
-  "$schema": "https://gitee.com/dotnetchina/Furion/raw/v4/schemas/v4/furion-schema.json",
-
-  "Logging": {
-    "LogLevel": {
-      "Default": "Information",
-      "Microsoft.AspNetCore": "Warning",
-      "Microsoft.EntityFrameworkCore": "Information"
-    },
-    "File": {
-      "Enabled": false, // 启用文件日志
-      "FileName": "logs/{0:yyyyMMdd}_{1}.log", // 日志文件
-      "Append": true, // 追加覆盖
-      // "MinimumLevel": "Information", // 日志级别
-      "FileSizeLimitBytes": 10485760, // 10M=10*1024*1024
-      "MaxRollingFiles": 30 // 只保留30个文件
-    },
-    "Database": {
-      "Enabled": true, // 启用数据库日志
-      "MinimumLevel": "Information"
-    },
-    "ElasticSearch": {
-      "Enabled": false, // 启用ES日志
-      "AuthType": "Basic", // ES认证类型,可选 Basic、ApiKey、Base64ApiKey
-      "User": "dilon", // Basic认证的用户名,使用Basic认证类型时必填
-      "Password": "123456", // Basic认证的密码,使用Basic认证类型时必填
-      "ApiId": "", // 使用ApiKey认证类型时必填
-      "ApiKey": "", // 使用ApiKey认证类型时必填
-      "Base64ApiKey": "TmtrOEszNEJuQ0NyaWlydGtROFk6SG1RZ0w3YzBTc2lCanJTYlV3aXNzZw==", // 使用Base64ApiKey认证类型时必填
-      "Fingerprint": "37:08:6A:C6:06:CC:9A:43:CF:ED:25:A2:1C:A4:69:57:90:31:2C:06:CA:61:56:39:6A:9C:46:11:BD:22:51:DA", // ES使用Https时的证书指纹
-      "ServerUris": [ "http://192.168.1.100:9200" ], // 地址
-      "DefaultIndex": "adminnet" // 索引
-    },
-    "Monitor": {
-      "GlobalEnabled": true, // 启用全局拦截日志
-      "IncludeOfMethods": [], // 拦截特定方法,当GlobalEnabled=false有效
-      "ExcludeOfMethods": [], // 排除特定方法,当GlobalEnabled=true有效
-      "BahLogLevel": "Information", // Oops.Oh 和 Oops.Bah 业务日志输出级别
-      "WithReturnValue": true, // 是否包含返回值,默认true
-      "ReturnValueThreshold": 500, // 返回值字符串阈值,默认0全量输出
-      "JsonBehavior": "None", // 是否输出Json,默认None(OnlyJson、All)
-      "JsonIndented": false, // 是否格式化Json
-      "UseUtcTimestamp": false, // 时间格式UTC、LOCAL
-      "ConsoleLog": true // 是否显示控制台日志
-    }
-  }
-}

+ 6 - 4
Admin.NET/Admin.NET.Core/Extension/ObjectExtension.cs

@@ -252,15 +252,17 @@ public static partial class ObjectExtension
     }
 
     /// <summary>
-    /// 判断是否有值
+    /// 是否有值
     /// </summary>
-    /// <param name="obj"></param>
+    /// <param name="str"></param>
     /// <returns></returns>
-    public static bool IsNullOrEmpty(this object obj)
+    public static bool HasValue(this object str)
     {
-        return obj == null || string.IsNullOrEmpty(obj.ToString());
+        return str != null && !string.IsNullOrEmpty(str.ToString());
     }
 
+
+
     /// <summary>
     /// 字符串掩码
     /// </summary>

+ 186 - 4
Admin.NET/Admin.NET.Core/Service/APIJSON/APIJSONService.cs

@@ -2,7 +2,9 @@
 //
 // 此源代码遵循位于源代码树根目录中的 LICENSE 文件的许可证
 
+using Newtonsoft.Json;
 using Newtonsoft.Json.Linq;
+using OBS.Model;
 
 namespace Admin.NET.Core.Service;
 
@@ -15,6 +17,7 @@ public class APIJSONService : IDynamicApiController, ITransient
     private readonly ISqlSugarClient _db;
     private readonly IdentityService _identityService;
     private readonly TableMapper _tableMapper;
+    private readonly SelectTable _selectTable;
 
     public APIJSONService(ISqlSugarClient db,
         IdentityService identityService,
@@ -23,16 +26,195 @@ public class APIJSONService : IDynamicApiController, ITransient
         _db = db;
         _tableMapper = tableMapper;
         _identityService = identityService;
+        _selectTable = new SelectTable(_identityService, _tableMapper, _db);
     }
 
     /// <summary>
-    /// 统一入口
+    /// 统一查询入口
     /// </summary>
     /// <param name="jobject"></param>
-    /// <remarks>参数:{"[]":{"SYS_LOG_OP":{}}}</remarks>
+    /// <remarks>参数:{"[]":{"SYSLOGOP":{}}}</remarks>
     /// <returns></returns>
-    public JObject Post([FromBody] JObject jobject)
+    [HttpPost("get")]
+    public JObject Query([FromBody] JObject jobject)
     {
-        return new SelectTable(_identityService, _tableMapper, _db).Query(jobject);
+        return _selectTable.Query(jobject);
+    }
+
+
+    [HttpPost("get/{table}")]
+    public async Task<JObject> QueryByTable([FromRoute] string table, [FromBody] JObject jobject)
+    {
+
+        JObject ht = new JObject();
+
+        ht.Add(table + "[]", jobject);
+
+        if (jobject["query"] != null && jobject["query"].ToString() != "0" && jobject["total@"] == null)
+        {
+            //自动添加总计数量
+            ht.Add("total@", "");
+        }
+
+        //每页最大1000条数据
+        if (jobject["count"] != null && int.Parse(jobject["count"].ToString()) > 1000)
+        {
+            throw Oops.Bah("count分页数量最大不能超过1000");
+        }
+
+        bool isDebug = (jobject["@debug"] != null && jobject["@debug"].ToString() != "0");
+        jobject.Remove("@debug");
+
+        bool hasTableKey = false;
+        List<string> ignoreConditions = new List<string> { "page", "count", "query" };
+        JObject tableConditions = new JObject();//表的其它查询条件,比如过滤,字段等
+        foreach (var item in jobject)
+        {
+            if (item.Key.Equals(table, StringComparison.CurrentCultureIgnoreCase))
+            {
+                hasTableKey = true;
+                break;
+            }
+            if (!ignoreConditions.Contains(item.Key.ToLower()))
+            {
+                tableConditions.Add(item.Key, item.Value);
+            }
+        }
+
+        foreach (var removeKey in tableConditions)
+        {
+            jobject.Remove(removeKey.Key);
+        }
+
+        if (!hasTableKey)
+        {
+            jobject.Add(table, tableConditions);
+        }
+
+        return Query(ht);
+    }
+    /// <summary>
+    /// 新增
+    /// </summary>
+    /// <param name="tables">表对象或数组,如果没有传id则后端生成id</param>
+    /// <returns></returns>
+    [HttpPost("post")]
+    [UnitOfWork]
+    public JObject Add([FromBody] JObject tables)
+    {
+
+        JObject ht = new JObject();
+        foreach (var table in tables)//遍历不同的表
+        {
+            string talbeName = table.Key.Trim();
+            var role = _identityService.GetRole();
+            if (!role.Insert.Table.Contains(talbeName, StringComparer.CurrentCultureIgnoreCase))
+            {
+                throw Oops.Bah($"没权限添加{talbeName}");
+            }
+            JToken result;
+            //批量插入
+            if (table.Value is JArray)
+            {
+                List<object> ids = new();
+                foreach (var record in table.Value)//遍历同一个表下的不同记录
+                {
+                    var cols = record.ToObject<JObject>();
+                    var id = _selectTable.InsertSingle(talbeName, cols, role);
+                    ids.Add(id);
+                }
+                result = JToken.FromObject(new { id = ids,count=ids.Count });               
+            }
+            //单条插入
+            else
+            {
+                var cols = table.Value.ToObject<JObject>();
+                var id = _selectTable.InsertSingle(talbeName, cols, role);
+                result = JToken.FromObject(new { id });
+            }
+
+            ht.Add(talbeName, result);
+        }
+
+        return ht;
+    }
+    /// <summary>
+    /// 修改,只支持id作为条件
+    /// </summary>
+    /// <param name="tables">支持多表、多id批量更新</param>
+    /// <returns></returns>
+    [HttpPost("put")]
+    [UnitOfWork]
+    public JObject Edit([FromBody] JObject tables)
+    {
+        JObject ht = new JObject();
+
+        foreach (var table in tables)//每个表
+        {
+            string tableName = table.Key.Trim();
+            var role = _identityService.GetRole();
+            int count = _selectTable.UpdateSingleTable(tableName,table.Value,role);
+            ht.Add(tableName, JToken.FromObject(new { count }));
+        }
+
+        return ht;
+    }
+    /// <summary>
+    /// 删除 支持非id条件,支持批量
+    /// </summary>
+    /// <param name="tables"></param>
+    /// <returns></returns>
+    [HttpPost("delete")]
+    [UnitOfWork]
+    public JObject Delete([FromBody] JObject tables)
+    {
+        JObject ht = new JObject();
+        var role = _identityService.GetRole();
+        foreach (var table in tables)//遍历表
+        {
+            string talbeName = table.Key.Trim();
+            var value = JObject.Parse(table.Value.ToString());
+
+            if (role.Delete == null || role.Delete.Table == null)
+            {
+                throw Oops.Bah("delete权限未配置");
+            }
+            if (!role.Delete.Table.Contains(talbeName, StringComparer.CurrentCultureIgnoreCase))
+            {
+                throw Oops.Bah($"没权限删除{talbeName}");
+            }
+            //if (!value.ContainsKey("id"))
+            //{
+            //    throw Oops.Bah("未传主键id");
+            //}
+
+            var sb = new StringBuilder(100);
+            List<SugarParameter> parameters = new List<SugarParameter>();
+            foreach (var f in value)//每个条件
+            {
+                if (f.Value is JArray)//数组
+                {
+                    sb.Append($"{f.Key} in (@{f.Key}) and ");
+                    var paraArray = FuncList.TransJArrayToSugarPara(f.Value);
+                    parameters.Add(new SugarParameter($"@{f.Key}", paraArray));              
+                }
+                else//单个值
+                {
+                    sb.Append($"{f.Key}=@{f.Key} and ");
+                    parameters.Add(new SugarParameter($"@{f.Key}", FuncList.TransJObjectToSugarPara(f.Value)));
+                }
+
+            }
+            if (!parameters.Any())
+            {
+                throw Oops.Bah("请输入删除条件");
+            }
+            string whereSql = sb.ToString().TrimEnd(" and ");
+            int count = _db.Deleteable<object>().AS(talbeName).Where(whereSql, parameters).ExecuteCommand();//无实体删除
+            value.Add("count", count);//命中数量
+            ht.Add(talbeName, value);
+
+        }
+        return ht;
     }
 }

Разлика између датотеке није приказан због своје велике величине
+ 0 - 0
Admin.NET/Admin.NET.Core/Service/APIJSON/APIJSON接口用例.apifox.json


+ 88 - 0
Admin.NET/Admin.NET.Core/Service/APIJSON/FuncList.cs

@@ -2,6 +2,11 @@
 //
 // 此源代码遵循位于源代码树根目录中的 LICENSE 文件的许可证
 
+using NewLife.Reflection;
+using Newtonsoft.Json.Linq;
+using OfficeOpenXml.FormulaParsing.Excel.Functions.Text;
+using Org.BouncyCastle.Asn1.X509.Qualified;
+
 namespace Admin.NET.Core.Service;
 
 /// <summary>
@@ -41,4 +46,87 @@ public class FuncList
     {
         return a.ToString().Split(',').Contains(b);
     }
+   
+
+    /// <summary>
+    /// 根据jtoken的实际类型来转换SugarParameter,避免全转成字符串
+    /// </summary>
+    /// <param name="jToken"></param>
+    /// <returns></returns>
+    public static dynamic TransJObjectToSugarPara(JToken jToken)
+    {
+        JTokenType jTokenType = jToken.Type;
+        return jTokenType switch
+        {
+            JTokenType.Integer => jToken.ToObject(typeof(long)),
+            JTokenType.Float => jToken.ToObject(typeof(decimal)),
+            JTokenType.Boolean => jToken.ToObject(typeof(bool)),
+            JTokenType.Date => jToken.ToObject(typeof(DateTime)),
+            JTokenType.Bytes => jToken.ToObject(typeof(byte)),
+            JTokenType.Guid => jToken.ToObject(typeof(Guid)),
+            JTokenType.TimeSpan => jToken.ToObject(typeof(TimeSpan)),
+            JTokenType.Array => TransJArrayToSugarPara(jToken),
+            _ => jToken
+        };
+    }
+
+    /// <summary>
+    /// 根据jArray的实际类型来转换SugarParameter,避免全转成字符串
+    /// </summary>
+    /// <param name="jToken"></param>
+    /// <returns></returns>
+    public static dynamic TransJArrayToSugarPara(JToken jToken)
+    {
+        if (jToken is not JArray) return jToken;
+        if (jToken.Any())
+        {
+            JTokenType jTokenType = jToken.First().Type;
+            return jTokenType switch
+            {
+                JTokenType.Integer => jToken.ToObject<long[]>(),
+                JTokenType.Float => jToken.ToObject<decimal[]>(),
+                JTokenType.Boolean => jToken.ToObject<bool[]>(),
+                JTokenType.Date => jToken.ToObject<DateTime[]>(),
+                JTokenType.Bytes => jToken.ToObject<byte[]>(),
+                JTokenType.Guid => jToken.ToObject<Guid[]>(),
+                JTokenType.TimeSpan => jToken.ToObject<TimeSpan[]>(),
+                _ => jToken.ToArray()
+            } ;
+        }
+        else return (JArray)jToken;
+
+    }
+
+    /// <summary>
+    /// 获取字符串里的值的真正类型
+    /// </summary>
+    /// <param name="input"></param>
+    /// <returns></returns>
+    public static string GetValueCSharpType(string input)
+    {
+        if (DateTime.TryParse(input, out _))
+        {
+            return "DateTime";
+        }
+        else if (int.TryParse(input, out _))
+        {
+            return "int";
+        }
+        else if (long.TryParse(input, out _))
+        {
+            return "long";
+        }
+        else if (decimal.TryParse(input, out _))
+        {
+            return "decimal";
+        }
+        else if (bool.TryParse(input, out _))
+        {
+            return "bool";
+        }
+        else
+        {
+            return "string";
+        }
+    }
 }

+ 1 - 1
Admin.NET/Admin.NET.Core/Service/APIJSON/IdentityService.cs

@@ -41,7 +41,7 @@ public class IdentityService : ITransient
     /// <returns></returns>
     public APIJSON_Role GetRole()
     {
-        var role = new APIJSON_Role();
+        APIJSON_Role role;
         if (string.IsNullOrEmpty(GetUserRoleName())) // 若没登录默认取第一个
         {
             role = _roles.FirstOrDefault();

Разлика између датотеке није приказан због своје велике величине
+ 393 - 318
Admin.NET/Admin.NET.Core/Service/APIJSON/SelectTable.cs


Неке датотеке нису приказане због велике количине промена