TJC.Cyclops.Common 2024.11.8.1

dotnet add package TJC.Cyclops.Common --version 2024.11.8.1                
NuGet\Install-Package TJC.Cyclops.Common -Version 2024.11.8.1                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="TJC.Cyclops.Common" Version="2024.11.8.1" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add TJC.Cyclops.Common --version 2024.11.8.1                
#r "nuget: TJC.Cyclops.Common, 2024.11.8.1"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install TJC.Cyclops.Common as a Cake Addin
#addin nuget:?package=TJC.Cyclops.Common&version=2024.11.8.1

// Install TJC.Cyclops.Common as a Cake Tool
#tool nuget:?package=TJC.Cyclops.Common&version=2024.11.8.1                

Cyclops.FrameWork

Cyclops.FrameWork 基于aspnetcore封装的api框架,集成了一线开发的常用设置和基础功能;可以用较少的时间代价,让开发人员将精力更多地集中在业务上。

  • [√] 全局api调用和框架级异常日志,支持Swagger接口文档的查看、调试和代码生成
  • [√] 接口入参校验,Cyclops.FrameWork中的接口参数校验完全基于System.ComponentModel.DataAnnotations,且在此基础上提供了验证数据是否存在ExistAttribute等扩展功能
  • [√] 统一返回值,无论是使用Cyclops.FrameWork中的Result及其子类,或者CSharp中的裸类型都自动返回全局统一值,从框架上避免对接混乱
  • [√] 标准化快捷文件上传、下载和excel的导入、导出,支持MS Azure和阿里OSS
  • [√] 在安全方面集成jwt认证和SafeComparisonFilter防重放攻击,并且支持多租户权限
  • [√] 标准化配置,支持Nacos

NuGet version (SAEA) License

一、配置示例

{
  "HostingOptions": {
    
    "ServiceName": "Cyclops.WebApplication1",
    "Domain": "https://cyclops.yswenli.com/",
    "EnableHealthCheck": true,
    "AppOptions": {
      "Urls": [ "https://127.0.0.1:39654" ],
      "DisableSwagger": false,
      "HideConsoleLog": false,      
      //jwt TokenManagement
      "JWTAuthConfig": {
        "Secret": "base64:HU8MlQQDHfGaQ+k+0q3z4HKJvNQUTjK5uRGodDATyKc=",
        "Issuer": "yswenli.cnblogs.com",
        "Audience": "Cyclops.FrameWork",
        "AccessExpiration": 315576000
      },
      "MaxRequestSize": 134217728, //134217728,文件限制128M
      "UserStaticPath": true,
      "StaticPaths": [ "upload" ],
      //全局禁用防复放校验
      "DisableSafeComparisonFilter": false,
      "SafeComparisonExpired": 5,
      //全局验证码
      "GloabVerifyCode": "9365",
      //是否启用SignalR
      "EnableSignalR": true,
      //SignalR配置
      "SignalROptions": {
        //SignalR hub url
        "HubUrl": "/hubs/common",
        //握手超时时间
        "HandshakeTimeout": 30,
        //心跳间隔时间
        "KeepAliveInterval": 15,
        //空连接超时时间
        "FreeTimeout": 60,
        //每连接并行处理数量
        "ParallelCount": "1",
        //消息包大小
        "MaximumReceiveMessageSize": 32768
      }
    },
    "NacosConfig": {
      "Listeners": [
        {
          "Optional": false,
          "DataId": "Common",
          "Group": "DEFAULT_GROUP"
        },
        {
          "Optional": false,
          "DataId": "OperationService",
          "Group": "DEFAULT_GROUP"
        }
      ],
      "Namespace": "dev",
      "ServerAddresses": [ "http://127.0.0.1:8848" ],
      "UserName": "",
      "Password": "",
      "ConfigUseRpc": false,
      "NamingUseRpc": false
    }
  }
}


AppConfig节点以下的可以与nacos集成 其它各项如下:

//项目配置
"ProjectOptions": {
  //项目名称
  "Name": "Cyclops",
  //项目描述
  "Version": "Cyclops管理平台",
  //项目logo
  "Logo": "/admin/img/logo.png",
  //底部信息
  "Footer": "Copyright © 2024 yswenli All rights reserved.",
  //主题颜色
  "MainColor": "#11559C",
  //菜单背景颜色
  "MenuBGColor": "#1977DA",
  //欢迎语
  "WelcomeText": "欢迎使用Cyclops管理平台",
  //水印文本
  "Watermark": "Cyclops管理平台"
}
"SnowId": {
  "WorkerId": 1, // 机器码 全局唯一
  "WorkerIdBitLength": 1, // 机器码位长 默认值6,取值范围 [1, 19]
  "SeqBitLength": 6 // 序列数位长 默认值6,取值范围 [3, 21](建议不小于4,值越大性能越高、Id位数也更长)
},
//详细数据库配置见SqlSugar官网(第一个为默认库)
"DbConnectionOptions": {
  "EnableConsoleSql": true, // 启用控制台打印SQL
  "EnableDBLogs": true, // 启用日志入库
  "ConnectionConfigs": [
    {
      "ConfigId": "1300000000001", // 默认库标识-禁止修改
      //"DbType": "SqlServer", // MySql、SqlServer、Sqlite、Oracle、PostgreSQL、Dm、Kdbndp、Oscar、MySqlConnector、Access、OpenGauss、QuestDB、HG、ClickHouse、GBase、Odbc、Custom
      //"ConnectionString": "Data Source=10.10.0.214;Initial Catalog=tjc_dev_cyclopsdb;User Id=testuser;Password=testuser;Encrypt=True;TrustServerCertificate=True;",
      "DbType": "Sqlite",
      "ConnectionString": "Data Source=TJCES.Cyclops.db",
      "DbSettings": {
        "EnableInitDb": true, // 启用库初始化
        "EnableDiffLog": true, // 启用库表差异日志
        "EnableUnderLine": true // 启用驼峰转下划线
      },
      "TableSettings": {
        "EnableInitTable": true, // 启用表初始化
        "EnableIncreTable": false // 启用表增量更新-特性[IncreTable]
      },
      "SeedSettings": {
        "EnableInitSeed": true, // 启用种子初始化
        "EnableIncreSeed": false // 启用种子增量更新-特性[IncreSeed]
      }
    }
    // 日志独立数据库配置
    //,{
    //  "ConfigId": "1300000000002", // 日志库标识-禁止修改
    //  "DbType": "Sqlite",
    //  "ConnectionString": "DataSource=./TJCES.Cyclops.Log.db", // 库连接字符串
    //  "DbSettings": {
    //    "EnableInitDb": true, // 启用库初始化
    //    "EnableDiffLog": false, // 启用库表差异日志
    //    "EnableUnderLine": false // 启用驼峰转下划线
    //  },
    //  "TableSettings": {
    //    "EnableInitTable": true, // 启用表初始化
    //    "EnableIncreTable": false // 启用表增量更新-特性[IncreTable]
    //  },
    //  "SeedSettings": {
    //    "EnableInitSeed": false, // 启用种子初始化
    //    "EnableIncreSeed": false // 启用种子增量更新-特性[IncreSeed]
    //  }
    //}
    //// 其他数据库配置(可以配置多个)
    //,{
    //  "ConfigId": "test", // 库标识
    //  "DbType": "Sqlite", // 库类型
    //  "ConnectionString": "DataSource=./TJCES.Cyclops.Test.db", // 库连接字符串
    //  "DbSettings": {
    //    "EnableInitDb": true, // 启用库初始化
    //    "EnableDiffLog": false, // 启用库表差异日志
    //    "EnableUnderLine": false // 启用驼峰转下划线
    //  },
    //  "TableSettings": {
    //    "EnableInitTable": true, // 启用表初始化
    //    "EnableIncreTable": false // 启用表增量更新-特性[IncreTable]
    //  },
    //  "SeedSettings": {
    //    "EnableInitSeed": true, // 启用种子初始化
    //    "EnableIncreSeed": false // 启用种子增量更新-特性[IncreSeed]
    //  }
    //}
  ]
}
//图形验证码
"CaptchaOptions": {
  "CaptchaType": 2, // 验证码类型0、1、2、3、4、5、6、7、8、9、10、11
  "CodeLength": 4, // 验证码长度, 要放在CaptchaType设置后  当类型为算术表达式时,长度代表操作的个数, 例如2
  "ExpirySeconds": 60, // 验证码过期秒数
  "IgnoreCase": true, // 比较时是否忽略大小写
  "StoreageKeyPrefix": "", // 存储键前缀
  "ImageOption": {
    "Animation": false, // 是否启用动画
    "FontSize": 36, // 字体大小
    "Width": 150, // 验证码宽度
    "Height": 50, // 验证码高度
    "BubbleMinRadius": 5, // 气泡最小半径
    "BubbleMaxRadius": 10, // 气泡最大半径
    "BubbleCount": 3, // 气泡数量
    "BubbleThickness": 1.0, // 气泡边沿厚度
    "InterferenceLineCount": 3, // 干扰线数量
    "FontFamily": "kaiti", // 包含actionj,epilog,fresnel,headache,lexo,prefix,progbot,ransom,robot,scandal,kaiti
    "FrameDelay": 300, // 每帧延迟,Animation=true时有效, 默认300
    "BackgroundColor": "#ffffff", //  格式: rgb, rgba, rrggbb, or rrggbbaa format to match web syntax, 默认#fff
    "ForegroundColors": "", //  颜色格式同BackgroundColor,多个颜色逗号分割,随机选取。不填,空值,则使用默认颜色集
    "Quality": 100, // 图片质量(质量越高图片越大,gif调整无效可能会更大)
    "TextBold": true // 粗体
  },
  "DefaultCode": "9365"
}
//redis配置
"RedisOptions": {
  "SectionName": "Redis",
  "Type": 0,
  "Password": "12321",
  "Masters": "127.0.0.1:6379",
  "Slaves": null,
  "ServiceName": "mymaster",
  "DefaultDatabase": 0,
  "AllowAdmin": true,
  "KeepAlive": 180,
  "ConnectTimeout": 10000,
  "ConnectRetry": 1,
  "BusyRetry": 3,
  "BusyRetryWaitMS": 15000,
  "PoolSize": 1,
  "CommandTimeout": 60000,
  "Extention": null
}
//微信公众号/小程序
"WechatOptions": {
  // 公众号-正式版公众测试号
  "WechatAppId": "",
  "WechatAppSecret": "",
  // 小程序
  "WxOpenAppId": "",
  "WxOpenAppSecret": "",
  //企业微信
  "CorpId": "",
  "AgentId": ,
  "AgentSecret": "",
  "PushToken": "",
  "PushEncodingAESKey": ""
},
// 微信支付
"WechatPayOptions": {
  "AppId": "", // 微信公众平台AppId、开放平台AppId、小程序AppId、企业微信CorpId
  "MerchantId": "", // 商户平台的商户号
  "MerchantV3Secret": "", // 商户平台的APIv3密钥
  "MerchantCertificateSerialNumber": "", // 商户平台的证书序列号
  "MerchantCertificatePrivateKey": "/WxPayCert/apiclient_key.pem", // 商户平台的API证书私钥(apiclient_key.pem文件内容)
  "WechatPayUrl": "/api/sysWechatPay/payCallBack" // 微信支付回调
}
//上传文件
"UploadOptions": {
  "Path": "upload/{yyyy}/{MM}/{dd}", // 文件上传目录
  "MaxSize": 5368709120, // 文件最大限制128M
  "MemoryBufferThreshold": 10485760, // 内存缓冲区大小,65536 64k
  "ExtensionNames": [ ".jpg", ".jpeg", ".png", ".gif", ".bmp", ".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".pdf", ".txt", ".zip", ".rar", ".7z" ],
  "EnableMd5": true, // 启用文件MDF5验证-防止重复上传
  "EnableCloudStorage": false, // 启用云存储
  //ms azure
  //"CloudStorageOptions": {
  //  "Id": "",
  //  "Key": "",
  //  "SupplierType": 2,
  //  "ContainerName": "",
  //  "Endpoint": "core.chinacloudapi.cn",
  //  "TimeOut": 60,
  //  "MaxErrorRetry": 3
  //}
  //阿里云
  "CloudStorageOptions": {
    "Id": "",
    "Key": "",
    "SupplierType": 1,
    "ContainerName": "cyclops",
    //"Endpoint": "oss-cn-shanghai-internal.aliyuncs.com",
    "Endpoint": "oss-cn-shanghai.aliyuncs.com",
    "TimeOut": 60,
    "MaxErrorRetry": 3
  }
}
//短信
"SmsOption": {
  "ZhuTong": {
    "UserName": "",
    "Password": "",
    "Signature": "【Cyclops管理平台】"
  }
}
//直播配置
"LiveOption": {
  "AppId": "",
  "AppSecret": "",
  "Url": "",
  "AuthorizeUrl": "",
  "AuthSecret": null,
  "UserName": null,
  "Password": null,
  "Salt": null
}
//语音转换
"SpeechConfig": {
  "SpeechType": 1,
  "ClientId": "",
  "ClientSecret": ""
}
//电子邮件
"EMailOptions": {
  "EMailClientConfigs": [
    {
      //发送邮件
      "ClientType": 1,
      //服务器
      "Host": "",
      //端口
      "Port": 465,
      //是否启用SSL
      "UseSsl": true,
      //用户名
      "Username": "",
      //密码
      "Password": ""
    }
  ]
}

二、初始化代码示例

public class Program
{
    public static void Main(string args)
    {
        WebApp.OnStarted += WebApp_OnStarted;
        WebApp.OnStopped += WebApp_OnStopped;
        WebApp.RunWebHost<Startup>(args);
    }


    static void WebApp_OnStarted()
    {
        Logger.Info($"{WebApp.ServiceName}应用已启动");
    }


    static void WebApp_OnStopped()
    {
        Logger.Info($"{WebApp.ServiceName}应用已停止");
    }
}
    /// <summary>
    /// Startup
    /// </summary>
    public class Startup : BaseStartup
    {
        /// <summary>
        /// Startup
        /// </summary>
        /// <param name="configuration"></param>
        public Startup(IConfiguration configuration) : base(configuration)
        {

        }
    }

三、控制器示例

继承基类即可

[Route(RouteConst.ROUTE_TEMPLATE_MOBILE)]
public class AuthController : BaseApiController

方法示例

    /// <summary>
    /// Login
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [AllowAnonymous, HttpPost, DisplayName("Login")]
    public async Task<Result> Login([Required(ErrorMessage = "请输入用户名或密码"), FromBody] UserLoginInput input)
    {
        var user = new SysUser();
        return SuccessResult(await CreateToken(user));
    }

    /// <summary>
    /// 获取验证码
    /// </summary>
    /// <returns></returns>
    [AllowAnonymous]
    [SuppressMonitor]
    [DisplayName("获取验证码"), HttpGet]
    public Result GetCaptcha()
    {
        ICaptcha captcha = ServiceProviderUtil.GetRequiredService<ICaptcha>();
        var codeId = YitIdHelper.NextId().ToString();
        var captchas = captcha.Generate(codeId, 180);
        return SuccessResult(new { Id = codeId, Img = captchas.Base64 });
    }

四、集成数据校验

/// <summary>
/// 登录信息
/// </summary>
public class UserLoginInput
{
    /// <summary>
    /// 请输入用户名
    /// </summary>
    [Required(ErrorMessage = "请输入用户名"), Exists("用户名不存在", TableName = "bus_user", ColumnName = "user_name")]
    public string UserName { get; set; }
    /// <summary>
    /// 请输入密码
    /// </summary>
    [Required(ErrorMessage = "请输入密码"), Custom<UserLoginInput>("密码不正确", "Valide")]
    public string Password { get; set; }

    /// <summary>
    /// 验证密码
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    public bool Valide(object? input)
    {
        if (input == null) return false;
        if (input is string password && password == "123456")
        {
            return true;
        }
        return false;

    }
}

五、防重放攻击示例

    /// <summary>
    /// 接口安全参数校验测试
    /// </summary>
    [SafeComparisonFilter]
    public class SafeController : BaseApiController
    {
        /// <summary>
        /// Test
        /// </summary>
        /// <param name="testInfo"></param>
        /// <returns></returns>
        [HttpPost]
        public Result Test([FromBody] TestInfo testInfo)
        {
            return SuccessResult(testInfo);
        }

        /// <summary>
        /// test2
        /// </summary>
        /// <returns></returns>
        [HttpGet, AllowAnonymous, NoSafeComparisonFilter]
        public Result Test2()
        {
            return SuccessResult();
        }
    }

六、文件上传下载Excel导入导出示例

   public class FileAdminController : BaseApiController
   {
       /// <summary>
       /// 导入
       /// </summary>
       /// <returns></returns>
       [HttpPost]
       [NoLoginAuth, AllowAnonymous]
       public Result Import(IFormCollection collection)
       {
           var data = collection.SaveAsDataTable();
           return SuccessResult(data);
       }


       /// <summary>
       /// 导出
       /// </summary>
       /// <returns></returns>
       [HttpPost]
       [NoLoginAuth, AllowAnonymous]
       public IActionResult Export()
       {
           return _env.Download("export.png");
       }

       /// <summary>
       /// 导出数据文件
       /// </summary>
       /// <returns></returns>
       [HttpGet]
       [NoLoginAuth, AllowAnonymous]
       public IActionResult ExportFile([FromQuery] bool isExcel = false)
       {
           var fileName = "export.xlsx";
           if (!isExcel)
           {
               fileName = "export.csv";
           }
           var dt = new DataTable();
           //return _env.ExportFile(dt, fileName);
           return Export(dt, fileName);
       }


       /// <summary>
       /// 导出数据文件
       /// </summary>
       /// <returns></returns>
       [HttpGet]
       [NoLoginAuth, AllowAnonymous]
       public IActionResult ExportDataFile([FromQuery] bool isExcel = false)
       {
           var fileName = "export.xlsx";
           if (!isExcel)
           {
               fileName = "export.csv";
           }
           var list = new List<BusUser>
           {
               new BusUser()
               {
                   Id = 1,
                   UserName = "张三"
               }
           };
           //return _env.ExportFile(list, fileName);
           return Export(list, fileName);
       }



       /// <summary>
       /// 测试上传文件大小
       /// </summary>
       /// <returns></returns>
       [HttpPost]
       public async Task<IActionResult> UploadFile(IFormCollection form)
       {
           var fileStream = await form.SaveAsStreamsAsync();

           return fileStream.First().Value.Download("test.jpg");
       }

       /// <summary>
       /// 测试限制上传文件大小
       /// </summary>
       /// <param name="form"></param>
       /// <returns></returns>

       [HttpPost, RequestSizeLimit(2 * 1024 * 1024)]
       public async Task<IActionResult> UploadFileByLimit(IFormCollection form)
       {
           var fileStream = await form.SaveAsStreamsAsync();

           return fileStream.First().Value.Download("test.jpg");
       }

       /// <summary>
       /// 测试不限制上传文件大小
       /// </summary>
       /// <param name="form"></param>
       /// <returns></returns>

       [HttpPost, DisableRequestSizeLimit]
       public async Task<IActionResult> UploadFileByNonLimit(IFormCollection form)
       {
           var fileStream = await form.SaveAsStreamsAsync();

           return fileStream.First().Value.Download("test.jpg");
       }       

      /// <summary>
      /// 示例获取流
      /// </summary>
      /// <returns></returns>
      [HttpGet]
      public async Task<Stream> GetStream()
      {
          var ms = new MemoryStream(RandomUtil.GetBytes(1024));
          return await Task.FromResult(ms);
      }

      /// <summary>
      /// 示例获取字节数组
      /// </summary>
      /// <returns></returns>
      [HttpGet]
      public async Task<byte> GetBytes()
      {
          return await Task.FromResult(RandomUtil.GetBytes(1024));
      }
   }

七、支持非api接口内容

        /// <summary>
        /// 返回指定内容结果
        /// </summary>
        /// <param name="controller"></param>
        /// <param name="text"></param>
        /// <param name="contentType"></param>
        /// <param name="statusCode"></param>
        /// <returns></returns>
        public async Task<IActionResult> ContentAsync(string text, string contentType = "text/plain", int statusCode = 200)
        {
            var contentResult = new ContentResult()
            {
                Content = text,
                ContentType = contentType,
                StatusCode = statusCode
            };
            return await Task.FromResult(contentResult);
        }

        /// <summary>
        /// 返回空结果
        /// </summary>
        /// <param name="controller"></param>
        /// <returns></returns>
        public async Task<IActionResult> EmptyAsync()
        {
            return await Task.FromResult(new EmptyResult());
        }

        /// <summary>
        /// 返回下载结果
        /// </summary>
        /// <param name="controller"></param>
        /// <param name="fileContent">下载时的文件名称</param>
        /// <param name="fileContent">内容字节数组</param>
        /// <param name="contentType">内容mime类型</param>
        /// <returns></returns>
        public async Task<IActionResult> DownloadAsync(string fileDownloadName,
            byte fileContent,
            string contentType)
        {
            return await Task.FromResult(new FileContentResult(fileContent, contentType) { FileDownloadName = fileDownloadName });
        }

        /// <summary>
        /// 返回下载结果
        /// </summary>
        /// <param name="controller"></param>
        /// <param name="fileName">内容文件地址</param>
        /// <param name="contentType">内容mime类型</param>
        /// <returns></returns>
        public async Task<IActionResult> DownloadAsync(string fileName,
            string contentType)
        {
            return await Task.FromResult(new VirtualFileResult(fileName, contentType)
            {
                EnableRangeProcessing = true,
                FileDownloadName = PathUtil.GetFileName(fileName)
            });
        }
        /// <summary>
        /// 返回流结果
        /// </summary>
        /// <param name="controller"></param>
        /// <param name="fileDownloadName"></param>
        /// <param name="fileStream"></param>
        /// <param name="contentType"></param>
        /// <returns></returns>
        public async Task<IActionResult> DownloadAsync(string fileDownloadName,
            Stream fileStream,
            string contentType
            )
        {
            return await Task.FromResult(new FileStreamResult(fileStream, contentType)
            {
                EnableRangeProcessing = true,
                FileDownloadName = fileDownloadName
            });
        }
        /// <summary>
        /// 返回跳转结果
        /// </summary>
        /// <param name="controller"></param>
        /// <param name="url"></param>
        /// <returns></returns>
        public async Task<IActionResult> RedirectAsync(string url)
        {
            return await Task.FromResult(new RedirectResult(url));
        }
Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (13)

Showing the top 5 NuGet packages that depend on TJC.Cyclops.Common:

Package Downloads
TJC.Cyclops.Orm

企服版框架中数据库操作相关处理项目

TJC.Cyclops.LogLib

企服版框架集成日志核心

TJC.Cyclops.Web.Core

企服版框架中api核心功能项目

TJC.Cyclops.Wechat

企服版框架中微信对接相关业务核心项目

TJC.Cyclops.Lives

企服版框架中直播SDK

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
2024.11.8.1 45 11/8/2024
2024.11.6.1 91 11/6/2024
2024.11.5.1 127 11/5/2024
2024.11.1.1 65 11/1/2024
2024.10.29.2 142 10/29/2024
2024.10.29.1 147 10/29/2024
2024.10.28.1 126 10/28/2024
2024.10.25.1 138 10/25/2024
2024.10.24.1 127 10/24/2024
2024.10.21.1 150 10/21/2024
2024.10.18.2 165 10/18/2024
2024.10.18.1 173 10/18/2024
2024.10.16.1 154 10/16/2024
2024.10.12.1 139 10/12/2024
2024.10.11.1 144 10/11/2024
2024.10.10.1 149 10/10/2024
2024.10.9.1 151 10/9/2024
2024.10.8.1 150 10/8/2024
2024.9.26.1 215 9/26/2024
2024.9.25.1 155 9/25/2024
2024.9.23.4 177 9/23/2024
2024.9.23.3 161 9/23/2024
2024.9.23.2 157 9/23/2024
2024.9.23.1 153 9/23/2024
2024.9.19.1 152 9/19/2024
2024.9.14.1 187 9/14/2024
2024.9.10.3 191 9/10/2024
2024.9.10.2 240 9/10/2024
2024.9.10.1 188 9/10/2024
2024.9.5.1 186 9/5/2024
2024.8.22.1 248 8/22/2024
2024.8.21.1 174 8/21/2024
2024.8.19.1 240 8/19/2024
2024.8.15.1 193 8/15/2024
2024.8.14.1 197 8/14/2024
2024.8.13.2 205 8/13/2024
2024.8.13.1 194 8/13/2024
2024.8.12.2 181 8/12/2024
2024.8.12.1 196 8/12/2024
2024.8.9.2 185 8/9/2024
2024.8.9.1 189 8/9/2024
2024.8.7.1 169 8/7/2024
2024.8.6.2 156 8/6/2024
2024.8.6.1 174 8/6/2024
2024.8.5.5 141 8/5/2024
2024.8.5.4 138 8/5/2024
2024.8.5.3 145 8/5/2024
2024.8.5.2 125 8/5/2024
2024.8.5.1 132 8/5/2024
2024.8.2.4 147 8/2/2024
2024.8.2.3 135 8/2/2024
2024.8.2.2 134 8/2/2024
2024.8.2.1 122 8/2/2024
2024.8.1.1 163 8/1/2024
2024.7.31.2 106 7/31/2024
2024.7.31.1 125 7/31/2024
2024.7.25.1 119 7/25/2024
2024.7.17.1 196 7/17/2024
2024.7.12.2 163 7/12/2024
2024.7.12.1 177 7/12/2024
2024.7.11.2 156 7/11/2024
2024.7.11.1 161 7/11/2024
2024.7.10.4 164 7/10/2024
2024.7.10.3 179 7/10/2024
2024.7.10.2 159 7/10/2024
2024.7.10.1 148 7/10/2024
2024.5.29.1 210 5/29/2024
2024.5.28.1 217 5/28/2024
2024.5.15.1 194 5/15/2024
2024.5.13.1 166 5/13/2024
2024.5.11.1 152 5/11/2024
2024.3.15.1 204 3/15/2024
2024.1.9.1 210 1/9/2024
2024.1.4.1 200 1/4/2024
2024.1.2.3 313 1/2/2024
2024.1.2.2 209 1/2/2024
2024.1.2.1 184 1/2/2024
2023.12.29.3 182 12/29/2023
2023.12.29.2 167 12/29/2023
2023.12.29.1 197 12/29/2023
2023.12.28.4 194 12/28/2023
2023.12.28.3 206 12/28/2023
2023.12.28.2 200 12/28/2023
2023.12.28.1 199 12/28/2023
2023.12.27.2 180 12/27/2023
2023.12.27.1 191 12/27/2023
2023.12.26.1 186 12/26/2023
2023.12.25.1 196 12/25/2023
2023.12.22.4 170 12/22/2023
2023.12.22.3 191 12/22/2023
2023.12.22.2 172 12/22/2023
2023.12.22.1 162 12/22/2023
2023.12.21.2 166 12/21/2023
2023.12.21.1 181 12/21/2023
2023.12.20.2 188 12/20/2023
2023.12.20.1 155 12/20/2023
2023.12.14.4 224 12/14/2023
2023.12.14.3 160 12/14/2023
2023.12.14.2 161 12/14/2023
2023.12.14.1 160 12/14/2023
2023.12.13.9 165 12/14/2023
2023.12.13.8 161 12/14/2023
2023.12.13.7 161 12/13/2023
2023.12.13.6 149 12/13/2023
2023.12.13.5 151 12/13/2023
2023.12.13.4 150 12/13/2023
2023.12.13.3 143 12/13/2023
2023.12.13.1 162 12/13/2023
2023.12.13 149 12/13/2023

企服版框架工具类项目