Эх сурвалжийг харах

[trunk] merge from develop:2.1.21-preview19

lith 1 жил өмнө
parent
commit
5bc4496341
22 өөрчлөгдсөн 212 нэмэгдсэн , 131 устгасан
  1. 1 1
      dotnet/Gateway/App.Gateway/App.Gateway.csproj
  2. 1 1
      dotnet/Library/Sers/Sers.CL/Ipc/Sers.CL.Ipc.NamedPipe/Sers.CL.Ipc.NamedPipe.csproj
  3. 1 1
      dotnet/Library/Sers/Sers.CL/Socket/Sers.CL.Socket.Iocp/Sers.CL.Socket.Iocp.csproj
  4. 1 1
      dotnet/Library/Sers/Sers.CL/Socket/Sers.CL.Socket.ThreadWait/Sers.CL.Socket.ThreadWait.csproj
  5. 1 1
      dotnet/Library/Sers/Sers.CL/WebSocket/Sers.CL.WebSocket/Sers.CL.WebSocket.csproj
  6. 1 1
      dotnet/Library/Sers/Sers.Core/Sers.Core/Sers.Core.csproj
  7. 10 10
      dotnet/Library/Sers/Sers.Core/Sers.Core/SersLoader/ApiLoader.cs
  8. 71 10
      dotnet/Library/Sers/Sers.Core/Sers.Core/SersLoader/LocalApiNode.cs
  9. 18 10
      dotnet/Library/Sers/Sers.Core/Sers.Core/SersLoader/SsModelBuilder.cs
  10. 1 1
      dotnet/Library/Sers/Sers.Gateway/Sers.Gateway/Sers.Gateway.csproj
  11. 1 1
      dotnet/Library/Sers/Sers.Hardware/Sers.Hardware/Sers.Hardware.csproj
  12. 1 1
      dotnet/Library/Sers/Sers.Serslot/Sers.Serslot/Sers.Serslot.csproj
  13. 1 1
      dotnet/Library/Sers/Sers.ServiceStation/Sers.ServiceStation/Sers.ServiceStation.csproj
  14. 1 1
      dotnet/ServiceCenter/App.Gover.Gateway/App.Gover.Gateway.csproj
  15. 2 2
      dotnet/ServiceCenter/App.Gover.Gateway/wwwroot/_gover_/ApiStation.html
  16. 49 43
      dotnet/ServiceCenter/App.Gover.Gateway/wwwroot/_gover_/Scripts/Sers/sers.ssApiDescToMd.js
  17. 46 40
      dotnet/ServiceCenter/App.Gover.Gateway/wwwroot/_gover_/Scripts/Sers/sers.ssModel.js
  18. 1 1
      dotnet/ServiceCenter/App.ServiceCenter/App.ServiceCenter.csproj
  19. 1 1
      dotnet/ServiceCenter/Sers.ServiceCenter/Sers.Gover/Sers.Gover.csproj
  20. 1 1
      dotnet/ServiceCenter/Sers.ServiceCenter/Sers.ServiceCenter/Sers.ServiceCenter.csproj
  21. 1 1
      dotnet/ServiceStation/Demo/SersLoader/Did.SersLoader.Demo/Did.SersLoader.Demo.csproj
  22. 1 1
      dotnet/ServiceStation/Demo/StressTest/App.Robot.Station/App.Robot.Station.csproj

+ 1 - 1
dotnet/Gateway/App.Gateway/App.Gateway.csproj

@@ -8,7 +8,7 @@
 	<PropertyGroup>
 		<OutputType>Exe</OutputType>
 		<TargetFramework>net6.0</TargetFramework>
-		<Version>2.1.20</Version>
+		<Version>2.1.21-preview19</Version>
 		<PackageProjectUrl>https://github.com/serset/Sers</PackageProjectUrl>
 	</PropertyGroup>
 

+ 1 - 1
dotnet/Library/Sers/Sers.CL/Ipc/Sers.CL.Ipc.NamedPipe/Sers.CL.Ipc.NamedPipe.csproj

@@ -6,7 +6,7 @@
 
 	<PropertyGroup>
 		<TargetFramework>netstandard2.0</TargetFramework>
-		<Version>2.1.20</Version>
+		<Version>2.1.21-preview19</Version>
 	</PropertyGroup>
 
 	<PropertyGroup>

+ 1 - 1
dotnet/Library/Sers/Sers.CL/Socket/Sers.CL.Socket.Iocp/Sers.CL.Socket.Iocp.csproj

@@ -6,7 +6,7 @@
 
 	<PropertyGroup>
 		<TargetFramework>netstandard2.0</TargetFramework>
-		<Version>2.1.20</Version>
+		<Version>2.1.21-preview19</Version>
 	</PropertyGroup>
 
 	<PropertyGroup>

+ 1 - 1
dotnet/Library/Sers/Sers.CL/Socket/Sers.CL.Socket.ThreadWait/Sers.CL.Socket.ThreadWait.csproj

@@ -6,7 +6,7 @@
 
 	<PropertyGroup>
 		<TargetFramework>netstandard2.0</TargetFramework>
-		<Version>2.1.20</Version>
+		<Version>2.1.21-preview19</Version>
 	</PropertyGroup>
 
 	<PropertyGroup>

+ 1 - 1
dotnet/Library/Sers/Sers.CL/WebSocket/Sers.CL.WebSocket/Sers.CL.WebSocket.csproj

@@ -6,7 +6,7 @@
 
 	<PropertyGroup>
 		<TargetFramework>netstandard2.0</TargetFramework>
-		<Version>2.1.20</Version>
+		<Version>2.1.21-preview19</Version>
 	</PropertyGroup>
 
 	<PropertyGroup>

+ 1 - 1
dotnet/Library/Sers/Sers.Core/Sers.Core/Sers.Core.csproj

@@ -7,7 +7,7 @@
 
     <PropertyGroup>
         <TargetFramework>netstandard2.0</TargetFramework>
-        <Version>2.1.20</Version>
+        <Version>2.1.21-preview19</Version>
     </PropertyGroup>
 
     <PropertyGroup>

+ 10 - 10
dotnet/Library/Sers/Sers.Core/Sers.Core/SersLoader/ApiLoader.cs

@@ -85,7 +85,7 @@ namespace Sers.SersLoader
             #endregion
 
 
-            #region (x.2)LoadSubscriber            
+            #region (x.2)LoadSubscriber
             Core.Module.PubSub.Controller.SubscriberLoader.LoadSubscriber(config.assembly);
             #endregion
 
@@ -109,15 +109,15 @@ namespace Sers.SersLoader
                 var types = LoadControllers(config);
 
 
-                //(x.2)遍历Controller                
+                //(x.2)遍历Controller
                 foreach (var type in types)
                 {
                     //(x.x.1) 获取 routePrefix
                     List<String> routePrefixs = GetRoutePrefixs(config, type);
 
 
-                    #region (x.x.3) 遍历method 构建apiNodes             
-                    var methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly);             
+                    #region (x.x.3) 遍历method 构建apiNodes
+                    var methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly);
                     foreach (var method in methods)
                     {
                         //(x.x.x.1) sampleApiDesc
@@ -267,7 +267,7 @@ namespace Sers.SersLoader
 
 
         protected virtual ParameterInfo[] MethodInfoGetArgInfos(MethodInfo method)
-        {           
+        {
             return method.GetParameters();
         }
 
@@ -293,10 +293,10 @@ namespace Sers.SersLoader
             apiDesc.description = method.GetCustomAttribute<SsDescriptionAttribute>()?.Value;
 
             //(x.3) rpcValidations from code
-            //apiDesc.rpcValidations = SersValidMng.GetRpcValidationsFromMethod(method);    
+            //apiDesc.rpcValidations = SersValidMng.GetRpcValidationsFromMethod(method);
             apiDesc.rpcVerify2 = RpcVerify2Loader.GetRpcVerify2FromMethod(method);
 
-            //(x.4)ArgType        
+            //(x.4)ArgType
             apiDesc.argType = ssModelBuilder.BuildSsModel_Arg(MethodInfoGetArgInfos(method), xmlComment);
 
             //(x.5)ReturnType
@@ -339,7 +339,7 @@ namespace Sers.SersLoader
             if (null == attrs || attrs.Count() == 0) return null;
 
             #region (x.1)获取 apiDescs
-            
+
             List<SsApiDesc> apiDescs = new List<SsApiDesc>();
 
             foreach (var attr in attrs)
@@ -367,7 +367,7 @@ namespace Sers.SersLoader
                     foreach (var routePrefix in routePrefixs)
                     {
                         //  /{stationName}/{routePrefix}/route
-                        var absRoute = routePrefix + "/" + route;                        
+                        var absRoute = routePrefix + "/" + route;
 
                         var apiDesc = CreateApiDesc();
                         apiDesc.route = absRoute;
@@ -388,7 +388,7 @@ namespace Sers.SersLoader
             //(x.2) apiDescs -> apiNode
             return apiDescs.Select(apiDesc =>
             {
-                IApiNode apiNode = new LocalApiNode(apiDesc, method, apiController_Obj);
+                IApiNode apiNode = LocalApiNode.CreateLocalApiNode(apiDesc, method, apiController_Obj);
                 return apiNode;
             }).ToList();
         }

+ 71 - 10
dotnet/Library/Sers/Sers.Core/Sers.Core/SersLoader/LocalApiNode.cs

@@ -1,6 +1,7 @@
 using System;
 using System.Reflection;
 using System.Runtime.CompilerServices;
+using System.Threading.Tasks;
 
 using Newtonsoft.Json;
 
@@ -13,14 +14,32 @@ using Vit.Extensions.Json_Extensions;
 namespace Sers.SersLoader
 {
     [JsonObject(MemberSerialization.OptIn)]
-    public class LocalApiNode: IApiNode
+    public class LocalApiNode : IApiNode
     {
         [JsonProperty]
         public SsApiDesc apiDesc { get; set; }
 
+        protected DynamicMethodExecutor executor;
 
-        DynamicMethodExecutor executor;
-        public LocalApiNode(SsApiDesc apiDesc,  MethodInfo apiController_Method,Object apiController_Obj)
+        protected MethodInfo apiController_Method;
+        protected Object apiController_Obj;
+
+
+        public static LocalApiNode CreateLocalApiNode(SsApiDesc apiDesc, MethodInfo apiController_Method, Object apiController_Obj)
+        {
+            if (apiController_Method.ReturnType == typeof(Task))
+            {
+                return new AsyncLocalApiNodeWithoutReturn(apiDesc, apiController_Method, apiController_Obj);
+            }
+            else if (apiController_Method.ReturnType.IsGenericType && apiController_Method.ReturnType.GetGenericTypeDefinition() == typeof(Task<>))
+            {
+                return new AsyncLocalApiNode(apiDesc, apiController_Method, apiController_Obj);
+            }
+
+            return new LocalApiNode(apiDesc, apiController_Method, apiController_Obj);
+        }
+
+        protected LocalApiNode(SsApiDesc apiDesc, MethodInfo apiController_Method, Object apiController_Obj)
         {
             this.apiDesc = apiDesc;
             this.apiController_Method = apiController_Method;
@@ -30,7 +49,7 @@ namespace Sers.SersLoader
 
 
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        public /*virtual*/ byte[] Invoke(ArraySegment<byte> arg_OriData)
+        public virtual byte[] Invoke(ArraySegment<byte> arg_OriData)
         {
 
             //(x.1)反序列化 请求参数
@@ -43,15 +62,57 @@ namespace Sers.SersLoader
             //(x.3) 序列化 返回数据
             return returnValue?.SerializeToBytes();
         }
-                          
+    }
 
-        #region apiController        
+    class AsyncLocalApiNode : LocalApiNode
+    {
+        PropertyInfo taskResultProperty;
+        public AsyncLocalApiNode(SsApiDesc apiDesc, MethodInfo apiController_Method, Object apiController_Obj) : base(apiDesc, apiController_Method, apiController_Obj)
+        {
+            taskResultProperty = apiController_Method.ReturnType.GetProperty("Result");
+        }
 
-        //private Type apiController_Type;
-        MethodInfo apiController_Method;
-        Object apiController_Obj;
-        #endregion
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public override byte[] Invoke(ArraySegment<byte> arg_OriData)
+        {
+            //(x.1)反序列化 请求参数
+            var args = apiDesc.argType?.OnDeserialize?.Invoke(arg_OriData);
+
+            //(x.2) Invoke
+            //var returnValue = apiController_Method.Invoke(apiController_Obj, args);
+            var returnValue = executor.Execute(apiController_Obj ?? Activator.CreateInstance(apiController_Method.DeclaringType), args);
 
+            // returnValue is Task<>,so wait it, then get the unwrapped return value
+            returnValue = taskResultProperty.GetValue(returnValue);
 
+            //(x.3) 序列化 返回数据
+            return returnValue?.SerializeToBytes();
+        }
+    }
+
+    class AsyncLocalApiNodeWithoutReturn : LocalApiNode
+    {
+        public AsyncLocalApiNodeWithoutReturn(SsApiDesc apiDesc, MethodInfo apiController_Method, Object apiController_Obj) : base(apiDesc, apiController_Method, apiController_Obj)
+        {
+        }
+
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public override byte[] Invoke(ArraySegment<byte> arg_OriData)
+        {
+
+            //(x.1)反序列化 请求参数
+            var args = apiDesc.argType?.OnDeserialize?.Invoke(arg_OriData);
+
+            //(x.2) Invoke
+            //var returnValue = apiController_Method.Invoke(apiController_Obj, args);
+            var returnValue = executor.Execute(apiController_Obj ?? Activator.CreateInstance(apiController_Method.DeclaringType), args);
+
+            // returnValue is Task,so wait it
+            ((Task)returnValue).GetAwaiter().GetResult();
+            returnValue = null;
+
+            //(x.3) 序列化 返回数据
+            return returnValue?.SerializeToBytes();
+        }
     }
 }

+ 18 - 10
dotnet/Library/Sers/Sers.Core/Sers.Core/SersLoader/SsModelBuilder.cs

@@ -3,6 +3,7 @@ using System.Collections.Generic;
 using System.Data;
 using System.Linq;
 using System.Reflection;
+using System.Threading.Tasks;
 
 using Newtonsoft.Json;
 using Newtonsoft.Json.Linq;
@@ -66,7 +67,7 @@ namespace Sers.SersLoader
 
         #region (x.4)Getter_DefaultValue       
         public static readonly List<Func<Func<Type, System.Attribute>, object>> Getter_DefaultValue = new List<Func<Func<Type, Attribute>, object>>();
-        public static object GeDefaultValueFromAttribute(Func<Type, System.Attribute> GetAttribute) 
+        public static object GeDefaultValueFromAttribute(Func<Type, System.Attribute> GetAttribute)
         {
             foreach (var getter in Getter_DefaultValue)
             {
@@ -90,9 +91,9 @@ namespace Sers.SersLoader
             return null;
         }
         #endregion
- 
 
-        static SsModelBuilder() 
+
+        static SsModelBuilder()
         {
             SsModelBuilder.Getter_Name.Add(GetAttribute =>
             {
@@ -153,6 +154,13 @@ namespace Sers.SersLoader
         #region SsModel
         public SsModel BuildSsModel_Return(MethodInfo methodInfo, Type returnType)
         {
+            if (returnType == typeof(Task))
+            {
+                return new SsModel() { type = "null" };
+            }
+            else if (returnType.IsGenericType && returnType.GetGenericTypeDefinition() == typeof(Task<>))
+                returnType = returnType.GetGenericArguments()[0];
+
             var descType = GetTypeFromAttribute(methodInfo.ReturnParameter.GetCustomAttribute);
             if (descType != null) returnType = descType;
 
@@ -166,7 +174,7 @@ namespace Sers.SersLoader
 
             {
                 model.description = GetDescriptionFromAttribute(methodInfo.ReturnParameter.GetCustomAttribute);
-                model.example = GetExampleFromAttribute(methodInfo.ReturnParameter.GetCustomAttribute);                
+                model.example = GetExampleFromAttribute(methodInfo.ReturnParameter.GetCustomAttribute);
                 model.defaultValue = GeDefaultValueFromAttribute(methodInfo.ReturnParameter.GetCustomAttribute);
             }
             {
@@ -215,7 +223,7 @@ namespace Sers.SersLoader
                 (1 == argInfos.Length && !argInfos[0].ParameterType.TypeIsValueTypeOrStringType() && null == argInfos[0].GetCustomAttribute<SsArgPropertyAttribute>())
             )
             {
-                #region      
+                #region
                 int argCount = argInfos.Length;
                 var argType = argInfos[0].ParameterType;
                 model.OnDeserialize = (bytes) =>
@@ -288,7 +296,7 @@ namespace Sers.SersLoader
         /// <param name="refModels"></param> 
         /// <returns></returns>
         SsModelEntity CreateEntityByParameterInfo(ParameterInfo[] infos, MethodComment comment, List<SsModelEntity> refModels)
-        { 
+        {
             var rootEntity = new SsModelEntity();
             rootEntity.type = "arg";
             rootEntity.mode = "object";
@@ -325,7 +333,7 @@ namespace Sers.SersLoader
 
         SsModelProperty CreateModelProperty(Type propertyType, Func<Type, System.Attribute> GetCustomAttribute, List<SsModelEntity> refModels)
         {
-             
+
             SsModelProperty m = new SsModelProperty();
 
             m.name = GetNameFromAttribute(GetCustomAttribute);
@@ -409,9 +417,9 @@ namespace Sers.SersLoader
                 return null;
             }
             if (typeof(DataTable).IsAssignableFrom(type) || typeof(DataSet).IsAssignableFrom(type) || typeof(DataRow).IsAssignableFrom(type))
-            {               
+            {
                 return null;
-            }             
+            }
             #endregion
 
             #region (x.2)泛型 忽略 Dictionary 等  (List已作为数组处理)
@@ -423,7 +431,7 @@ namespace Sers.SersLoader
                 if (typeof(IDictionary<,>).IsAssignableFrom(genericType))
                 {
                     return null;
-                }             
+                }
             }
             #endregion
 

+ 1 - 1
dotnet/Library/Sers/Sers.Gateway/Sers.Gateway/Sers.Gateway.csproj

@@ -6,7 +6,7 @@
 
 	<PropertyGroup>
 		<TargetFramework>netstandard2.0</TargetFramework>
-		<Version>2.1.20</Version>
+		<Version>2.1.21-preview19</Version>
 	</PropertyGroup>
 
 	<PropertyGroup>

+ 1 - 1
dotnet/Library/Sers/Sers.Hardware/Sers.Hardware/Sers.Hardware.csproj

@@ -6,7 +6,7 @@
 
 	<PropertyGroup>
 		<TargetFramework>netstandard2.0</TargetFramework>
-		<Version>2.1.20</Version>
+		<Version>2.1.21-preview19</Version>
 	</PropertyGroup>
 
 	<PropertyGroup>

+ 1 - 1
dotnet/Library/Sers/Sers.Serslot/Sers.Serslot/Sers.Serslot.csproj

@@ -6,7 +6,7 @@
 
 	<PropertyGroup>
     <TargetFramework>netstandard2.0</TargetFramework>
-		<Version>2.1.20</Version>
+		<Version>2.1.21-preview19</Version>
 	</PropertyGroup>
 
 	<PropertyGroup>

+ 1 - 1
dotnet/Library/Sers/Sers.ServiceStation/Sers.ServiceStation/Sers.ServiceStation.csproj

@@ -6,7 +6,7 @@
 
 	<PropertyGroup>
 		<TargetFramework>netstandard2.0</TargetFramework>
-		<Version>2.1.20</Version>
+		<Version>2.1.21-preview19</Version>
 	</PropertyGroup>
 
 	<PropertyGroup>

+ 1 - 1
dotnet/ServiceCenter/App.Gover.Gateway/App.Gover.Gateway.csproj

@@ -8,7 +8,7 @@
 	<PropertyGroup>
 		<OutputType>Exe</OutputType>
 		<TargetFramework>net6.0</TargetFramework>
-		<Version>2.1.20</Version>
+		<Version>2.1.21-preview19</Version>
 		<PackageProjectUrl>https://github.com/serset/Sers</PackageProjectUrl>
 	</PropertyGroup>
 

+ 2 - 2
dotnet/ServiceCenter/App.Gover.Gateway/wwwroot/_gover_/ApiStation.html

@@ -156,11 +156,11 @@
                             }, methods: {
                                 start: function (station) {
                                     sers.apiClient.apiStation_start(station.stationName, function (data) {
-                                        rendStations();
+                                        reloadStations();
                                     });
                                 }, pause: function (station) {
                                     sers.apiClient.apiStation_pause(station.stationName, function (data) {
-                                        rendStations();
+                                        reloadStations();
                                     });
                                 }
                             }

+ 49 - 43
dotnet/ServiceCenter/App.Gover.Gateway/wwwroot/_gover_/Scripts/Sers/sers.ssApiDescToMd.js

@@ -16,16 +16,16 @@
     if (scope[objName]) return;
 
 
-    
 
 
 
- 
-    function mdEncode(str) { return (''+(str || '')).replace('_', '\\_'); }
+
+
+    function mdEncode(str) { return ('' + (str || '')).replace('_', '\\_'); }
 
 
     //apiDescs 为apiDesc数组
-     function ssApiDescsToMd(apiDescs) {
+    function ssApiDescsToMd(apiDescs) {
 
         /*
          apiStations
@@ -57,20 +57,20 @@
             station.push(apiDesc);
         }
 
-	   //(x.2) 排序
-	   var stationArr=[];
-	   for (var stationName in apiStations) {
-            stationArr.push({stationName:stationName,station:apiStations[stationName]});
+        //(x.2) 排序
+        var stationArr = [];
+        for (var stationName in apiStations) {
+            stationArr.push({ stationName: stationName, station: apiStations[stationName] });
         }
-	   stationArr.sort(function (a, b) { return a.stationName < b.stationName ? -1 : 1; });
+        stationArr.sort(function (a, b) { return a.stationName < b.stationName ? -1 : 1; });
+
 
-        
 
         //(x.3) 构建md
         var md = '';
 
         for (var t in stationArr) {
-        	  var item=stationArr[t];
+            var item = stationArr[t];
             md += '\n\n----\n\n## ' + mdEncode(item.stationName);
             md += apiStationToMd(item.station);
         }
@@ -160,14 +160,14 @@ route:  ** {{route}} **\n\n\
             //Return
             item = item.replace(/{{Return_SsModel}}/g, ssModelToMd(apiDesc['returnType']));
             example = sers.ssModel.getExampleBySsModel(apiDesc['returnType']);
-            example = JSON.stringify(example,null,2);
+            example = JSON.stringify(example, null, 2);
             item = item.replace(/{{Return_Example}}/g, example);
 
             //counter
             // "ext": { "counter": { "sumCount": 0, "errorCount": 0 } }
             var counter = '';
             if (apiDesc.ext && apiDesc.ext.counter) {
-                counter = '\[' + apiDesc.ext.counter.sumCount + '\/' + apiDesc.ext.counter.errorCount +'\]';
+                counter = '\[' + apiDesc.ext.counter.sumCount + '\/' + apiDesc.ext.counter.errorCount + '\]';
             }
             item = item.replace(/{{counter}}/g, counter);
 
@@ -176,7 +176,7 @@ route:  ** {{route}} **\n\n\
                 value = 'all';
                 value = apiDesc.extendConfig.httpMethod;
             } catch (e) {
-            }           
+            }
             value = mdEncode(value);
             item = item.replace(/{{httpMethod}}/g, value);
 
@@ -206,29 +206,29 @@ route:  ** {{route}} **\n\n\
         /*
 //SsModel
 {
-	"type":"type1",
-	"mode":"object",
-	"description":"用户手机号"
-	"defaultValue":"",
-	"example":"15000000000",
-	"models":[ {SsModelEntity1} , {SsModelEntity2}  ]
+    "type":"type1",
+    "mode":"object",
+    "description":"用户手机号"
+    "defaultValue":"",
+    "example":"15000000000",
+    "models":[ {SsModelEntity1} , {SsModelEntity2}  ]
 }
 
 //SsModelEntity
 {
-	"type":"type1",
-	"mode":"object",
-	"propertys":[ {SsModelProperty} , {SsModelProperty}  ]
+    "type":"type1",
+    "mode":"object",
+    "propertys":[ {SsModelProperty} , {SsModelProperty}  ]
 }
 
 //SsModelProperty
 {
-	"name":"mobile",
-	"type":"type1",
-	"mode":"object",
-	"description":"用户手机号",
-	"defaultValue":"",
-	"example":"15000000000"
+    "name":"mobile",
+    "type":"type1",
+    "mode":"object",
+    "description":"用户手机号",
+    "defaultValue":"",
+    "example":"15000000000"
 }
 
 
@@ -246,29 +246,28 @@ md:
 └─ accessToken|string|访问令牌||
 
          */
-        
-        if (!ssModel || !ssModel.mode || !ssModel.type ) return '无';
+
+        if (!ssModel || !ssModel.mode || !ssModel.type) return '无';
         //if (!ssModel.models || ssModel.models.length == 0) return '无';
 
         var typeMap = {};
 
         for (var t in ssModel.models) {
-            var m = ssModel.models[t];          
+            var m = ssModel.models[t];
             typeMap[m.type] = m;
         }
 
+        var arg = { md: '' };
 
-        var arg = { md: '' };       
-
-        arg.md += '\n\n名称|类型|说明|example|默认值\n--| --| --| --| --\n';         
+        arg.md += '\n\n名称|类型|说明|example|默认值\n--| --| --| --| --\n';
 
 
         var prefixItem = '&#124;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';
         var prefixItem_Null = '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';
 
-        
 
-        function buildModelEntity(modelEntity, prefix) {            
+
+        function buildModelEntity(modelEntity, prefix) {
 
             var propertys = modelEntity.propertys;
             for (var t in propertys) {
@@ -302,10 +301,10 @@ md:
 
                 //(x.4.1)类型                
                 if (property.mode == 'value') {
-                    type = '<span title="' + property.type + '">' + property.type + '</span>';                    
+                    type = '<span title="' + property.type + '">' + property.type + '</span>';
                 } else {
                     // 为 object 或者 array 
-                    type = '<span title="' + property.type+'">' + property.mode+'</span>';
+                    type = '<span title="' + property.type + '">' + property.mode + '</span>';
                 }
 
 
@@ -315,7 +314,14 @@ md:
                 arg.md += line;
 
 
-                if (childEntity ) {                
+                if (childEntity) {
+                    if (childEntity.mode != 'value') {
+                        if (childEntity.__ssModelToMd_loaded) {
+                            continue;
+                        }
+                        childEntity.__ssModelToMd_loaded = true;
+                    }
+
                     if (typepath.indexOf(property.type) < 0) {
                         typepath.push(property.type);
                         buildModelEntity(childEntity, childPrefix);
@@ -328,10 +334,10 @@ md:
         }
 
         //添加模型信息 实体
-        {  
+        {
 
             var line = '';
-            
+
             var prefix = '';
             //(x.1) prefix
             line += prefix;
@@ -366,7 +372,7 @@ md:
         if (modelEntity) {
             buildModelEntity(modelEntity, prefixItem_Null);
             return arg.md;
-        } else {          
+        } else {
             return arg.md;
         }
         return '' + ssModel.name;

+ 46 - 40
dotnet/ServiceCenter/App.Gover.Gateway/wwwroot/_gover_/Scripts/Sers/sers.ssModel.js

@@ -17,35 +17,35 @@
 
 
     var obj = scope[objName] = {};
-     
+
 
     function getExampleBySsModel(ssModel) {
         /*
 //SsModel
 {
-	"type":"type1",
-	"mode":"object",
-	"description":"用户手机号"
-	"defaultValue":"",
-	"example":"15000000000",
-	"models":[ {SsModelEntity1} , {SsModelEntity2}  ]
+    "type":"type1",
+    "mode":"object",
+    "description":"用户手机号"
+    "defaultValue":"",
+    "example":"15000000000",
+    "models":[ {SsModelEntity1} , {SsModelEntity2}  ]
 }
 
 //SsModelEntity
 {
-	"type":"type1",
-	"mode":"object",
-	"propertys":[ {SsModelProperty} , {SsModelProperty}  ]
+    "type":"type1",
+    "mode":"object",
+    "propertys":[ {SsModelProperty} , {SsModelProperty}  ]
 }
 
 //SsModelProperty
 {
-	"name":"mobile",
-	"type":"type1",
-	"mode":"object",
-	"description":"用户手机号",
-	"defaultValue":"",
-	"example":"15000000000"
+    "name":"mobile",
+    "type":"type1",
+    "mode":"object",
+    "description":"用户手机号",
+    "defaultValue":"",
+    "example":"15000000000"
 }
 
 */
@@ -53,29 +53,28 @@
         //if (!ssModel.models || ssModel.models.length == 0) return {};
 
         //(x.1) mode 为 value
-        if (ssModel.mode == 'value')
-        {
+        if (ssModel.mode == 'value') {
             return parseValue(ssModel.type, ssModel.example);
         }
 
         //(x.2)指定了example,直接返回
         try {
             if ('string' == typeof (ssModel.example) && ssModel.example != '') {
-                return eval('(' + ssModel.example + ')');                 
+                return eval('(' + ssModel.example + ')');
             }
         } catch (e) {
 
         }
 
- 
 
 
 
-    
+
+
         var typeMap = {};
 
         for (var t in ssModel.models) {
-            var m = ssModel.models[t];           
+            var m = ssModel.models[t];
             typeMap[m.type] = m;
         }
 
@@ -89,7 +88,7 @@
         return buildModelEntity(modelEntity);
 
 
-        function buildModelEntity(modelEntity) {       
+        function buildModelEntity(modelEntity) {
 
             //(x.1) mode 为 array
             if (modelEntity.mode == 'array') {
@@ -105,7 +104,7 @@
                 var property = propertys[t];
 
                 var key = property.name;
-                var value = getExampleValueByModelProperty(property);                
+                var value = getExampleValueByModelProperty(property);
 
                 model[key] = value;
             }
@@ -113,7 +112,7 @@
         }
 
         // mode 必须为 "value"
-        function parseValue(type, example) {           
+        function parseValue(type, example) {
             var value = example;
 
             if (type == 'int32' || type == 'int64') {
@@ -122,21 +121,21 @@
                     if (isNaN(value)) value = 1;
                 } catch (e) {
                     value = 1;
-                }               
-            } else if (type == 'float' || type == 'double') {                
+                }
+            } else if (type == 'float' || type == 'double') {
                 try {
                     value = parseFloat(example);
                     if (isNaN(value)) value = 0.1;
                 } catch (e) {
                     value = 0.1;
-                } 
-            } else if (type == 'bool') {                
+                }
+            } else if (type == 'bool') {
                 try {
                     value = Boolean(example);
                     if (value !== true || value !== false) value = true;
                 } catch (e) {
                     value = true;
-                } 
+                }
             } else if (type == 'string') {
                 if (!value) value = '';
             }
@@ -150,8 +149,8 @@
             var example = property.example;
 
             //子模型
-            if (property.mode == 'value') {        
-                value = parseValue(property.type, example);                 
+            if (property.mode == 'value') {
+                value = parseValue(property.type, example);
                 return value;
             }
 
@@ -166,7 +165,7 @@
 
             }
 
-            
+
 
             if (property.mode == 'object') {
 
@@ -174,23 +173,30 @@
                 var childEntity = typeMap[type];
 
                 if (childEntity) {
-                    if (typepath.indexOf(property.type) < 0) {     
+                    if (childEntity.mode != 'value') {
+                        if (childEntity.__getExampleBySsModel_loaded) {
+                            return value;
+                        }
+                        childEntity.__getExampleBySsModel_loaded = true;
+                    }
+
+                    if (typepath.indexOf(property.type) < 0) {
                         typepath.push(property.type);
-                        value = buildModelEntity(childEntity);       
+                        value = buildModelEntity(childEntity);
                         typepath.pop();
-                    }                    
+                    }
                 }
 
             } else if (property.mode == 'array') {
 
                 var type = property.type;
                 var childEntity = typeMap[type];
-               
+
                 if (childEntity) {
                     typepath.push(property.type);
                     try {
-                        var property = childEntity.propertys[0];                       
-                        value = getExampleValueByModelProperty(property);                        
+                        var property = childEntity.propertys[0];
+                        value = getExampleValueByModelProperty(property);
                     } catch (e) {
                     }
                     typepath.pop();
@@ -198,7 +204,7 @@
                 value = [value];
             }
 
-            
+
             return value;
         }
 

+ 1 - 1
dotnet/ServiceCenter/App.ServiceCenter/App.ServiceCenter.csproj

@@ -8,7 +8,7 @@
 	<PropertyGroup>
 		<OutputType>Exe</OutputType>
 		<TargetFramework>net6.0</TargetFramework>
-		<Version>2.1.20</Version>
+		<Version>2.1.21-preview19</Version>
 		<PackageProjectUrl>https://github.com/serset/Sers</PackageProjectUrl>
 	</PropertyGroup>
 

+ 1 - 1
dotnet/ServiceCenter/Sers.ServiceCenter/Sers.Gover/Sers.Gover.csproj

@@ -6,7 +6,7 @@
 
 	<PropertyGroup>
 		<TargetFramework>netstandard2.0</TargetFramework>
-		<Version>2.1.20</Version>
+		<Version>2.1.21-preview19</Version>
 	</PropertyGroup>
 
 	<PropertyGroup>

+ 1 - 1
dotnet/ServiceCenter/Sers.ServiceCenter/Sers.ServiceCenter/Sers.ServiceCenter.csproj

@@ -6,7 +6,7 @@
 
 	<PropertyGroup>
 		<TargetFramework>netstandard2.0</TargetFramework>
-		<Version>2.1.20</Version>
+		<Version>2.1.21-preview19</Version>
 	</PropertyGroup>
 
 	<PropertyGroup>

+ 1 - 1
dotnet/ServiceStation/Demo/SersLoader/Did.SersLoader.Demo/Did.SersLoader.Demo.csproj

@@ -8,7 +8,7 @@
   <PropertyGroup>
     <OutputType>Exe</OutputType>
     <TargetFramework>net6.0</TargetFramework>
-    <Version>2.1.20</Version>
+    <Version>2.1.21-preview19</Version>
     <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
     <Description>https://github.com/serset/Sers</Description>
   </PropertyGroup>

+ 1 - 1
dotnet/ServiceStation/Demo/StressTest/App.Robot.Station/App.Robot.Station.csproj

@@ -9,7 +9,7 @@
 		<OutputType>Exe</OutputType>
 		<TargetFramework>net6.0</TargetFramework>
 		<RunPostBuildEvent>Always</RunPostBuildEvent>
-		<Version>2.1.20</Version>
+		<Version>2.1.21-preview19</Version>
 		<Description>https://github.com/serset/Sers</Description>
 	</PropertyGroup>