diff --git a/.gitignore b/.gitignore index ec8ef60..df32c0f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ target/ -*.cj.macrocall \ No newline at end of file +*.cj.macrocall +.cache/ \ No newline at end of file diff --git a/README.md b/README.md index 32a7fcd..6a471bf 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # SimApi for Cangjie(simapi) -> 仓颉版 SimApi:ASP.NET Core 风格 API 基础框架,移植自 C# 项目 [SimApi](https://github.com/SimcuTeam/simapi-net)(`E:\simcu\simapi-net`)。 +> 仓颉版 SimApi:ASP.NET Core 风格 API 基础框架,移植自 [SimApi](https://github.com/SimcuTeam/simapi-net)。 提供**统一响应格式、异常拦截、Token 认证、缓存、工具集、HTTP 客户端、S3 存储、声明式注解**等 API 基础能力。 @@ -103,7 +103,7 @@ main(args: Array) { simapi-cj/ ├── cjpm.toml # 包配置 ├── src/ -│ ├── SimApiExtensions.cj # 根包入口:SimApiExtensions 静态类(addSimApi / useSimApi + 内置路由 + 响应封装) +│ ├── simapi_extensions.cj # 根包入口:SimApiExtensions 静态类(addSimApi / useSimApi + 内置路由 + 响应封装) │ ├── annotations/ # 声明式注解:@SimApiAuth(鉴权)、@OriginResponse(原样响应)、 │ │ # @SimApiSign(验签)、@AesBody(AES body 解密) │ ├── authsdk/ # 认证中心 SDK:SimApiAuthClient/Center/Iam + 网关中间件 + DTO @@ -114,7 +114,7 @@ simapi-cj/ │ ├── helpers/ # SimApiError, SimApiUtil, SimApiAuth, SimApiCache, SimApiHttpClient, │ │ # SimApiAesUtil(AES-256), SimApiSignChecker(验签), SimApiAesBodyChecker(AES body), │ │ # SimApiStorage(S3/MinIO, 自实现 SigV4), SimApiRequestDelegateFactory, SimApiResultWriter -│ ├── interfaces/ # ISimApiAuthChecker, IBindRequestContext, SimApiSignProviderBase, AesBodyProviderBase +│ ├── interfaces/ # SimApiAuthChecker, BindRequestContext, SimApiSignProviderBase, AesBodyProviderBase │ ├── logger/ # SimApiLogger, SimApiLoggerProvider(彩色日志) │ ├── macros/ # ReadTomlVersion(编译期读版本号) │ ├── middlewares/ # SimApiExceptionMiddleware, SimApiAuthMiddleware, SimApiRequestLogMiddleware @@ -155,12 +155,12 @@ auth.logoutAll("user-001") // 退出全部 - `"localhost:6379"`(基础) - `"localhost:6379,password=xxx"`(带密码) - `"localhost:6379,password=xxx,db=2"`(带密码 + DB 索引) -- **InMemory 模式**:零配置,适合开发/测试;登录态带过期时间(对齐 C# 过期语义),重启后丢失 +- **InMemory 模式**:零配置,适合开发/测试;登录态带过期时间,重启后丢失 - **Token 传参**:Header `Token: ` 或 Query `token=` -### 2.1 声明式鉴权 — @SimApiAuth(对齐 C# [SimApiAuth]) +### 2.1 声明式鉴权 — @SimApiAuth -标注在控制器**方法或类**上,请求派发时自动执行鉴权(未登录 401 → 类型不匹配 403 → 遍历执行 `ISimApiAuthChecker`): +标注在控制器**方法或类**上,请求派发时自动执行鉴权(未登录 401 → 类型不匹配 403 → 遍历执行 `SimApiAuthChecker`): ```cangjie import simcu::simapi.annotations.{SimApiAuth} @@ -174,11 +174,11 @@ public class MyController <: SimApiBaseController { } ``` -> 说明:仓颉注解参数须为编译期常量,`@SimApiAuth` 支持单个类型参数(`@SimApiAuth["admin"]`)或逗号分隔多类型(`@SimApiAuth["admin,user"]`,对齐 C# `type.Split(",")`);空参数表示任意已登录用户。 +> 说明:仓颉注解参数须为编译期常量,`@SimApiAuth` 支持单个类型参数(`@SimApiAuth["admin"]`)或逗号分隔多类型(`@SimApiAuth["admin,user"]`);空参数表示任意已登录用户。 ### 2.2 原样响应 — @OriginResponse -标注后跳过统一响应封装,接口返回什么就输出什么(对齐 C# `[OriginResponse]`): +标注后跳过统一响应封装,接口返回什么就输出什么: ```cangjie import simcu::simapi.annotations.{OriginResponse} @@ -190,7 +190,7 @@ public func raw(): String { } ``` -### 2.3 声明式验签 — @SimApiSign(对齐 C# [SimApiSign]) +### 2.3 声明式验签 — @SimApiSign 标注在控制器**方法或类**上,请求派发时自动验签(appId 提取 → 密钥获取 → timestamp 过期校验 → nonce 去重 → MD5 比对): @@ -210,9 +210,9 @@ public class MySignProvider <: SimApiSignProviderBase { public func signedAction(): String { "ok" } ``` -`SimApiSignProviderBase` 可配置:`appIdName` / `timestampName` / `nonceName` / `signName` / `queryExpires` / `duplicateRequestProtection` / `signFields`(与 C# 一致)。也可手动调用 `SimApiSignChecker.verify(context, provider, cache)`。 +`SimApiSignProviderBase` 可配置:`appIdName` / `timestampName` / `nonceName` / `signName` / `queryExpires` / `duplicateRequestProtection` / `signFields`。也可手动调用 `SimApiSignChecker.verify(context, provider, cache)`。 -### 2.4 声明式 AES body — @AesBody(对齐 C# [AesBody]) +### 2.4 声明式 AES body — @AesBody 标注在**参数**上,请求派发时自动解密 `{"data":"密文"}` body 并反序列化为参数类型: @@ -252,14 +252,14 @@ Key 自动加前缀 `SimApi:Cache:`。 ```cangjie SimApiUtil.cstNow // UTC+8 时间 SimApiUtil.timestampNow // 秒级时间戳 -SimApiUtil.newGuid() // UUID v4(对齐 C# Guid.NewGuid()) +SimApiUtil.newGuid() // UUID v4 SimApiUtil.md5("text") // 32 位十六进制 SimApiUtil.sha1("text") // 40 位 SimApiUtil.base64Encode("text") / base64Decode("...") -SimApiUtil.base64Encode(obj) // 对象 → JSON → Base64(对齐 C# Base64Encode(object)) +SimApiUtil.base64Encode(obj) // 对象 → JSON → Base64 SimApiUtil.json(obj) // 对象 → JSON 字符串(simcu::serialization 反射) SimApiUtil.escapeJson(s) // JSON 字符串转义 -SimApiUtil.fromJson(json) // JSON → T(对齐 C# FromJson,任意类免约束) +SimApiUtil.fromJson(json) // JSON → T(任意类免约束) SimApiUtil.base64DecodeTo(str) // Base64 → JSON → T SimApiUtil.checkCell("13800138000") // 手机号 SimApiUtil.checkEmail("a@b.com") // 邮箱 @@ -267,9 +267,9 @@ SimApiUtil.checkEmail("a@b.com") // 邮箱 > JSON 序列化/反序列化统一走 **simcu::serialization**(`JsonSerializer.Serialize` / `Deserialize`),任意类免标注、免接口约束。 -### 4.1 AES 加解密 — SimApiAesUtil(对齐 C# SimApiAesUtil) +### 4.1 AES 加解密 — SimApiAesUtil -纯仓颉实现 AES-256-CBC + PKCS7(S-box/密钥扩展/轮函数),与 .NET 双向互操作已验证: +纯仓颉实现 AES-256-CBC + PKCS7(S-box/密钥扩展/轮函数),加解密结果跨语言互通已验证: ```cangjie let encrypted = SimApiAesUtil.encrypt("明文", "key字符串") // Base64(随机IV + 密文) @@ -279,7 +279,7 @@ let plain = SimApiAesUtil.decrypt(encrypted, "key字符串") - 密钥:`SHA256(key 字符串)` → 32 字节;IV 每次随机 16 字节前置;输出 `Base64(IV + 密文)` - 供 `SimApiHttpClient.aesQuery` / `aesSignQuery` 使用 -### 4.2 实体基类 — SimApiBaseModel(对齐 C# SimApiBaseModel) +### 4.2 实体基类 — SimApiBaseModel ```cangjie import simcu::simapi.models.* @@ -301,19 +301,19 @@ user.updateTime() // 刷新 _updatedAt ```cangjie let client = SimApiHttpClient(options: SimApiHttpClientOptions()) // 配置 server/appId/appKey -// 返回泛型 T(对齐 .NET SignQuery/AesQuery/AesSignQuery),T 任意类免约束 +// 返回泛型 T(SignQuery/AesQuery/AesSignQuery),T 任意类免约束 let resp1 = client.signQuery("/api/hello", body: "{\"a\":1}") let resp2 = client.aesQuery("/api/data", body: "{\"a\":1}") let resp3 = client.aesSignQuery("/api/data", body: "{\"a\":1}") ``` -签名参数名可配置(`signName / timestampName / nonceName / appIdName / signFields`,对齐 C# 的 virtual 属性)。AES 请求体用 `SimApiOneFieldRequest` 序列化为 `{"data":"密文"}`(对齐 C#)。 +签名参数名可配置(`signName / timestampName / nonceName / appIdName / signFields`)。AES 请求体用 `SimApiOneFieldRequest` 序列化为 `{"data":"密文"}`。 ### 5.1 请求日志 — enableRequestLog -记录每次请求的方法、URL、请求头、请求体、响应状态码、耗时与异常(对齐 C#): +记录每次请求的方法、URL、请求头、请求体、响应状态码、耗时与异常: - 请求体按 **JSON 字段级截断**(仅对超长字符串字段截断,保留结构;非 JSON 整串截断) -- 下游异常**捕获记录后重抛**(对齐 C# ExceptionDispatchInfo) +- 下游异常**捕获记录后重抛** ```cangjie SimApiExtensions.addSimApi(builder) { options => @@ -336,7 +336,7 @@ SimApiExtensions.addSimApi(builder) { options => ### 5.2 日志格式 — SimApiLogger -`enableLogger`(默认 `true`)时自动使用 `SimApiLoggerProvider`,输出格式对齐 C# 原版: +`enableLogger`(默认 `true`)时自动使用 `SimApiLoggerProvider`,输出格式与原版一致: ``` [ 分类 ][ 时间:毫秒 ][ 级别 ] @@ -345,7 +345,7 @@ SimApiExtensions.addSimApi(builder) { options => 按级别着色:Debug 深紫 / Info 深青 / Warn 黄 / Error 红 / Fatal 深红。 -### 5.3 存储 — SimApiStorage(S3/MinIO,对齐 C# SimApiStorage) +### 5.3 存储 — SimApiStorage(S3/MinIO) `enableSimApiStorage = true` 时注册 `SimApiStorage`(Scoped,内部自实现 AWS Signature V4,基于 stdx.net.http,无需 Minio SDK): @@ -371,7 +371,7 @@ SimApiExtensions.addSimApi(builder) { options => | `fullUrl(path)` / `getUrl(path)` | 补全访问 URL(`~/` 前缀依赖请求上下文) | | `getPath(url)` | 从 URL 还原相对路径(去掉 Endpoint/Bucket 或 ServeUrl 前缀) | -> 说明:桶不存在时自动创建(对齐 C# BucketExists + MakeBucket,静态守卫只执行一次); +> 说明:桶不存在时自动创建(静态守卫只执行一次); > 预签名与上传使用 AWS SigV4(HMAC-SHA256 基于 stdx SHA256 自实现),已用 AWS 官方测试向量验证签名正确。 ### 6. 内置路由(UseSimApi 自动注册) @@ -392,21 +392,21 @@ options.configureSimApiRoute { route => } ``` -### 7. 认证后处理 Hook — ISimApiAuthChecker +### 7. 认证后处理 Hook — SimApiAuthChecker 实现后每次认证成功都会调用(配合 `@SimApiAuth` 注解或手动 `requireLogin`): ```cangjie import simcu::simapi.interfaces.* -class MyAuthChecker <: ISimApiAuthChecker { +class MyAuthChecker <: SimApiAuthChecker { public func run(loginItem: SimApiLoginItem, token: String): Unit { // 认证成功后执行 } } ``` -### 8. 认证中心 SDK — AuthSDK(对齐 C# AuthSDK) +### 8. 认证中心 SDK — AuthSDK `enableSimApiAuthGate = true` 时注册 `SimApiAuthClient` / `SimApiAuthCenter` / `SimApiAuthIam` 单例并挂载网关透传中间件: @@ -457,7 +457,7 @@ SimApiExtensions.addSimApi(builder) { options => options.enableCors = true // 全量 CORS options.enableLogger = true // 控制台日志 - // .NET 风格子模块配置回调(对齐 C# ConfigureSimApiXxx) + // 子模块配置回调(ConfigureSimApiXxx) options.configureSimApiRoute { route => route.userInfoRoute = Some("/user/info") // 内置路由自定义路径 route.logoutRoute = Some("/auth/logout") @@ -483,7 +483,7 @@ SimApiExtensions.addSimApi(builder) { options => ## 内置控制器(MVC 写法) -simapi 提供 Spire MVC 控制器(继承 `SimApiBaseController`),`addSimApi` 自动注册内置控制器 + 自动扫描调用者包中的控制器(对齐 C# `Assembly.GetTypes()` 扫描): +simapi 提供 Spire MVC 控制器(继承 `SimApiBaseController`),`addSimApi` 自动注册内置控制器 + 自动扫描调用者包中的控制器: | 控制器 | 路由 | 说明 | |--------|------|------| @@ -514,7 +514,7 @@ public class MyController <: SimApiBaseController { ## 未实现模块(选项占位) -以下 C# 原包功能因仓颉生态暂无对应库(Hangfire/MQTT/Swashbuckle),**选项保留但未实现**: +以下原包功能因仓颉生态暂无对应库(Hangfire/MQTT/Swashbuckle),**选项保留但未实现**: | 选项 | 原功能 | 状态 | |------|--------|------| @@ -522,7 +522,7 @@ public class MyController <: SimApiBaseController { | `enableSynapse` | MQTT 通信 | ❌ 未实现 | | `enableJob` | Hangfire 任务调度 | ❌ 未实现 | -> ✅ 已实现(曾为占位):`enableSimApiStorage`(S3/MinIO,自实现 AWS SigV4)、`enableSimApiAuthGate`(AuthSDK 认证中心)、`SimApiAesUtil`(纯仓颉 AES-256-CBC,与 .NET 双向互操作)、`ISimApiAuthChecker`、`@SimApiSign` / `@AesBody` 声明式注解、内置路由自定义路径。 +> ✅ 已实现(曾为占位):`enableSimApiStorage`(S3/MinIO,自实现 AWS SigV4)、`enableSimApiAuthGate`(AuthSDK 认证中心)、`SimApiAesUtil`(纯仓颉 AES-256-CBC)、`SimApiAuthChecker`、`@SimApiSign` / `@AesBody` 声明式注解、内置路由自定义路径。 --- @@ -530,7 +530,7 @@ public class MyController <: SimApiBaseController { | 依赖 | 用途 | |------|------| -| `soulsoft_web_http / routing / hosting` | Web 框架(ASP.NET Core 仓颉移植版) | +| `soulsoft_web_http / routing / hosting` | Web 框架 | | `soulsoft_extensions_logging` 系列 | 日志 | | `soulsoft_extensions_injection` | 依赖注入 | | `soulsoft_extensions_configuration` | 配置 | diff --git a/cjpm.lock b/cjpm.lock index 2ac6173..fcbad86 100644 --- a/cjpm.lock +++ b/cjpm.lock @@ -3,17 +3,17 @@ version = 0 [requires] soulsoft_extensions_options_configuration = {version = "1.0.20260528"} soulsoft_web_http = {version = "1.0.20260528"} - soulsoft_extensions_logging = {version = "1.0.20260528"} - soulsoft_extensions_options = {version = "1.0.20260528"} - soulsoft_web_routing = {version = "1.0.20260528"} - soulsoft_extensions_logging_console = {version = "1.0.20260528"} - soulsoft_identity_claims = {version = "1.0.20260528"} soulsoft_web_hosting = {version = "1.0.20260528"} + soulsoft_web_routing = {version = "1.0.20260528"} + soulsoft_extensions_logging = {version = "1.0.20260528"} + soulsoft_web_cors = {version = "1.0.20260528"} + soulsoft_extensions_logging_console = {version = "1.0.20260528"} + redis = {version = "1.0.20260627"} + soulsoft_serialization = {version = "1.0.20260528"} + soulsoft_web_mvc = {version = "1.0.20260528"} soulsoft_extensions_logging_configuration = {version = "1.0.20260528"} soulsoft_extensions_hosting = {version = "1.0.20260528"} - soulsoft_web_mvc = {version = "1.0.20260528"} - soulsoft_extensions_configuration = {version = "1.0.20260528"} - redis = {version = "1.0.20260627"} - soulsoft_web_cors = {version = "1.0.20260528"} - soulsoft_serialization = {version = "1.0.20260528"} soulsoft_extensions_injection = {version = "1.0.20260528"} + soulsoft_identity_claims = {version = "1.0.20260528"} + soulsoft_extensions_configuration = {version = "1.0.20260528"} + soulsoft_extensions_options = {version = "1.0.20260528"} diff --git a/cjpm.toml b/cjpm.toml index 8101d1a..a082108 100644 --- a/cjpm.toml +++ b/cjpm.toml @@ -23,7 +23,7 @@ soulsoft_extensions_injection = "1.0.20260528" soulsoft_extensions_options = "1.0.20260528" redis = "1.0.20260627" - "simcu::serialization" = { path = "../simapi-serialization" } + "simcu::serialization" = { path = "../serialization-cj" } [target] [target.x86_64-w64-mingw32] diff --git a/src/annotations/AesBody.cj b/src/annotations/aes_body.cj similarity index 85% rename from src/annotations/AesBody.cj rename to src/annotations/aes_body.cj index d0c3279..3ed32a1 100644 --- a/src/annotations/AesBody.cj +++ b/src/annotations/aes_body.cj @@ -1,7 +1,7 @@ /* * Copyright (c) 2025 SimcuTeam. All rights reserved. - * 移植自 C# 项目 SimApi(E:\simcu\simapi-net),遵循 MIT 许可证。 - * 声明式 AES body 解密注解(对齐 C# SimApi.Attributes.AesBodyAttribute)。 + * 遵循 MIT 许可证。 + * 声明式 AES body 解密注解。 * * 标注在控制器方法参数上,请求派发时(SimApiRequestDelegateFactory)自动解密并反序列化: * - 读取请求体 {"data": "密文"} diff --git a/src/annotations/OriginResponse.cj b/src/annotations/origin_response.cj similarity index 76% rename from src/annotations/OriginResponse.cj rename to src/annotations/origin_response.cj index bf8b460..aee9162 100644 --- a/src/annotations/OriginResponse.cj +++ b/src/annotations/origin_response.cj @@ -1,12 +1,12 @@ /* * Copyright (c) 2025 SimcuTeam. All rights reserved. - * 移植自 C# 项目 SimApi(E:\simcu\simapi-net),遵循 MIT 许可证。 + * 遵循 MIT 许可证。 */ package simcu::simapi.annotations /** - * 原样响应注解(对齐 C# SimApi.Attributes.OriginResponseAttribute)。 + * 原样响应注解。 * * 标注在控制器方法或类上,请求派发时 SimApiRequestDelegateFactory 跳过 * 统一响应封装(SimApiBaseResponse 包装),接口返回什么就输出什么。 diff --git a/src/annotations/SimApiAuth.cj b/src/annotations/simapi_auth.cj similarity index 68% rename from src/annotations/SimApiAuth.cj rename to src/annotations/simapi_auth.cj index 79aa005..13e26b1 100644 --- a/src/annotations/SimApiAuth.cj +++ b/src/annotations/simapi_auth.cj @@ -1,25 +1,25 @@ /* * Copyright (c) 2025 SimcuTeam. All rights reserved. - * 移植自 C# 项目 SimApi(E:\simcu\simapi-net),遵循 MIT 许可证。 + * 遵循 MIT 许可证。 */ package simcu::simapi.annotations /** - * 声明式鉴权注解(对齐 C# SimApi.Attributes.SimApiAuthAttribute)。 + * 声明式鉴权注解。 * * 标注在控制器方法或类上,请求派发时(SimApiRequestDelegateFactory)自动执行鉴权: * - 未登录(无 LoginInfo)→ 401 * - type 非空且登录用户类型不匹配 → 403 - * - 遍历执行所有已注册的 ISimApiAuthChecker + * - 遍历执行所有已注册的 SimApiAuthChecker * * 用法: * @SimApiAuth // 任意已登录用户 * @SimApiAuth["admin"] // 仅 admin 类型 - * @SimApiAuth["admin,user"] // admin 或 user 类型(对齐 C# type.Split(",")) + * @SimApiAuth["admin,user"] // admin 或 user 类型 * * 说明:仓颉注解参数须为编译期常量,String 无法作为 const 值数组元素, - * 故与 C# 的 string[] 不同,这里用逗号分隔字符串对齐 C# 多类型。 + * 故用逗号分隔字符串表示多种类型。 */ @Annotation[target: [MemberFunction, Type]] public class SimApiAuth { diff --git a/src/annotations/SimApiSign.cj b/src/annotations/simapi_sign.cj similarity index 87% rename from src/annotations/SimApiSign.cj rename to src/annotations/simapi_sign.cj index 525ae51..03f6373 100644 --- a/src/annotations/SimApiSign.cj +++ b/src/annotations/simapi_sign.cj @@ -1,7 +1,7 @@ /* * Copyright (c) 2025 SimcuTeam. All rights reserved. - * 移植自 C# 项目 SimApi(E:\simcu\simapi-net),遵循 MIT 许可证。 - * 声明式签名校验注解(对齐 C# SimApi.Attributes.SimApiSignAttribute)。 + * 遵循 MIT 许可证。 + * 声明式签名校验注解。 * * 标注在控制器方法或类上,请求派发时(SimApiRequestDelegateFactory)自动执行验签: * - 提取 appId / timestamp / nonce / sign(Query 优先,其次 Header) diff --git a/src/authsdk/SimApiAuthCenter.cj b/src/authsdk/simapi_auth_center.cj similarity index 86% rename from src/authsdk/SimApiAuthCenter.cj rename to src/authsdk/simapi_auth_center.cj index 0f367d7..fcee48c 100644 --- a/src/authsdk/SimApiAuthCenter.cj +++ b/src/authsdk/simapi_auth_center.cj @@ -1,6 +1,6 @@ /* * Copyright (c) 2025 SimcuTeam. All rights reserved. - * 移植自 C# 项目 SimApi(E:\simcu\simapi-net),遵循 MIT 许可证。 + * 遵循 MIT 许可证。 * AuthSDK/SimApiAuthCenter:认证中心远程 SDK。 */ @@ -16,7 +16,7 @@ import simcu::simapi.communications.* import simcu::simapi.helpers.* /** - * 认证中心远程 SDK(对齐 C# SimApiAuthCenter): + * 认证中心远程 SDK: * 群组 / Profile / 内部应用 / 系统登录 / 安全验证 等接口,走签名请求。 */ public class SimApiAuthCenter { @@ -35,7 +35,7 @@ public class SimApiAuthCenter { // ===== 公共 ===== /** - * 委托 AuthCenter 进行应用签名验证(对齐 C# VerifySign)。 + * 委托 AuthCenter 进行应用签名验证。 */ public func verifySign(appId: String, timestamp: String, nonce: String, sign: String): Unit { let url = "${_client.server}/api/auth/sign/verify?appId=${appId}×tamp=${timestamp}&nonce=${nonce}&sign=${sign}" @@ -55,7 +55,7 @@ public class SimApiAuthCenter { SimApiError.errorWhenFalse(isSuccess(response.status), code: Int64(response.status), message: "HTTP ERROR: ${response.status}") let json = readBodyText(response.body) - let resp = JsonSerializer.Deserialize(json) + let resp = JsonSerializer.deserialize(json) SimApiError.errorWhen(resp.code != 200, code: 400, message: "签名验证失败") } finally { response.close() @@ -104,7 +104,7 @@ public class SimApiAuthCenter { // ===== 群组相关 ===== /** - * 根据 profileId 获取群组列表(对齐 C# GroupRelated)。 + * 根据 profileId 获取群组列表。 */ public func groupRelated(profileId: String): Array { _client.signQuery>("/api/auth/group/related", @@ -112,7 +112,7 @@ public class SimApiAuthCenter { } /** - * 按关键字搜索群组,输入群组 ID 精准搜索(对齐 C# GroupSearch)。 + * 按关键字搜索群组,输入群组 ID 精准搜索。 */ public func groupSearch(keyword: String, skip!: Int64 = 0, take!: Int64 = 20): Array { var body = HashMap() @@ -123,7 +123,7 @@ public class SimApiAuthCenter { } /** - * 使用组 ID 以及组内成员/管理员 profile 获取组的详细树结构(对齐 C# GroupDetail)。 + * 使用组 ID 以及组内成员/管理员 profile 获取组的详细树结构。 */ public func groupDetail(groupId: String, profileId: String): GroupDetailTreeNode { var body = HashMap() @@ -133,7 +133,7 @@ public class SimApiAuthCenter { } /** - * 获取 profile 在本组的所有子组(对齐 C# GroupRelatedIndex)。 + * 获取 profile 在本组的所有子组。 */ public func groupRelatedIndex(groupId: String, profileId: String): Array { var body = HashMap() @@ -146,7 +146,7 @@ public class SimApiAuthCenter { // ===== Profile 相关 ===== /** - * 按关键字搜索用户 Profile(对齐 C# ProfileSearch)。 + * 按关键字搜索用户 Profile。 */ public func profileSearch(keyword: String, skip!: Int64 = 0, take!: Int64 = 20): Array { var body = HashMap() @@ -157,7 +157,7 @@ public class SimApiAuthCenter { } /** - * 通过 id 批量获取用户基本信息(对齐 C# ProfileList)。 + * 通过 id 批量获取用户基本信息。 */ public func profileList(ids: Array): Array { var body = HashMap() @@ -172,7 +172,7 @@ public class SimApiAuthCenter { // ===== AuthGate 内部应用专用 ===== /** - * 获取是否为 App 的拥有者(对齐 C# CheckIsAppOwner,字段为 PascalCase)。 + * 获取是否为 App 的拥有者。 */ public func checkIsAppOwner(profileId: String, applicationId: String): Bool { var body = HashMap() @@ -182,7 +182,7 @@ public class SimApiAuthCenter { } /** - * 根据用户 profileId 和提供的 appIds 获取应用列表(对齐 C# GetAppList,字段为 PascalCase)。 + * 根据用户 profileId 和提供的 appIds 获取应用列表。 */ public func getAppList(profileId: String, appIds: Array): Array { var body = HashMap() @@ -199,7 +199,7 @@ public class SimApiAuthCenter { // ===== 系统登录 ===== /** - * 获取登录授权 CODE(对齐 C# GetLoginCode)。 + * 获取登录授权 CODE。 * @param scene 场景标识。 * @param data 附加数据。 * @param backUrl 回调地址。 @@ -217,12 +217,12 @@ public class SimApiAuthCenter { } /** - * 使用 code 获取登录信息(对齐 C# GetLoginInfo,场景不匹配抛 403003)。 + * 使用 code 获取登录信息。 */ public func getLoginInfo(code: String, scene!: ?String = None): LoginInfoResponse { var body = HashMap() body["code"] = code - // 说明:C# 的 ErrorWhenNull(resp, 400232, "登录信息获取失败") 对应 signQuery 内部 data.getOrThrow() 的 + // 说明:ErrorWhenNull(resp, 400232, "登录信息获取失败") 对应 signQuery 内部 data.getOrThrow() 的 // None 分支;仓颉版 signQuery 返回非空 T(data 缺失即抛异常),故此处无需重复判空。 let resp = _client.signQuery("/api/auth/login/get", body: SimApiUtil.json(Some(body))) SimApiError.errorWhen(resp.scene != scene, code: 403003, message: "登录场景不匹配") @@ -232,7 +232,7 @@ public class SimApiAuthCenter { // ===== 安全验证 ===== /** - * 获取安全验证代码(对齐 C# GetConfirmCode)。 + * 获取安全验证代码。 */ public func getConfirmCode(scene: String, userId: String, data!: ?HashMap = None, backUrl!: ?String = None): GetCodeResponse { @@ -247,7 +247,7 @@ public class SimApiAuthCenter { } /** - * 使用安全验证 code 获取验证结果(对齐 C# Confirm,身份/场景不匹配分别抛 403002/403003)。 + * 使用安全验证 code 获取验证结果。 */ public func confirm(code: String, scene: String, userId!: ?String = None): ConfirmResponse { var body = HashMap() diff --git a/src/authsdk/SimApiAuthCenterMiddleware.cj b/src/authsdk/simapi_auth_center_middleware.cj similarity index 91% rename from src/authsdk/SimApiAuthCenterMiddleware.cj rename to src/authsdk/simapi_auth_center_middleware.cj index c932428..0264bc4 100644 --- a/src/authsdk/SimApiAuthCenterMiddleware.cj +++ b/src/authsdk/simapi_auth_center_middleware.cj @@ -1,6 +1,6 @@ /* * Copyright (c) 2025 SimcuTeam. All rights reserved. - * 移植自 C# 项目 SimApi(E:\simcu\simapi-net),遵循 MIT 许可证。 + * 遵循 MIT 许可证。 * AuthSDK/SimApiAuthCenterMiddleware:网关透传认证中间件。 */ @@ -12,7 +12,7 @@ import simcu::simapi.configurations.* import simcu::simapi.helpers.* /** - * 网关透传认证中间件(对齐 C# SimApiAuthCenterMiddleware): + * 网关透传认证中间件: * 当请求带 X-SimApi-Gate-Auth / X-SimApi-Gate-Time / X-SimApi-Gate-Sign 三头时, * 校验 MD5 签名(appId=..&auth=..&time=..&appKey=..),通过则 Base64 解码登录信息写入 LoginInfo。 */ diff --git a/src/authsdk/SimApiAuthClient.cj b/src/authsdk/simapi_auth_client.cj similarity index 82% rename from src/authsdk/SimApiAuthClient.cj rename to src/authsdk/simapi_auth_client.cj index d5b594e..ae912ca 100644 --- a/src/authsdk/SimApiAuthClient.cj +++ b/src/authsdk/simapi_auth_client.cj @@ -1,6 +1,6 @@ /* * Copyright (c) 2025 SimcuTeam. All rights reserved. - * 移植自 C# 项目 SimApi(E:\simcu\simapi-net),遵循 MIT 许可证。 + * 遵循 MIT 许可证。 * AuthSDK/SimApiAuthClient:认证中心专用签名客户端。 */ @@ -10,7 +10,7 @@ import simcu::simapi.configurations.* import simcu::simapi.helpers.* /** - * 认证中心签名客户端(对齐 C# SimApiAuthClient): + * 认证中心签名客户端: * SimApiHttpClient 子类,凭证(Server/AppId/AppKey)取自 SimApiAuthCenterOptions。 */ public class SimApiAuthClient <: SimApiHttpClient { diff --git a/src/authsdk/SimApiAuthDto.cj b/src/authsdk/simapi_auth_dto.cj similarity index 75% rename from src/authsdk/SimApiAuthDto.cj rename to src/authsdk/simapi_auth_dto.cj index 61c0d4c..9c55b12 100644 --- a/src/authsdk/SimApiAuthDto.cj +++ b/src/authsdk/simapi_auth_dto.cj @@ -1,9 +1,9 @@ /* * Copyright (c) 2025 SimcuTeam. All rights reserved. - * 移植自 C# 项目 SimApi(E:\simcu\simapi-net),遵循 MIT 许可证。 - * AuthSDK 用到的 DTO(对齐 C# SimApiAuthCenterDto / SimApiAuthIamDto)。 + * 遵循 MIT 许可证。 + * AuthSDK 用到的 DTO。 * - * 说明:C# 中这些 DTO 是 SimApiAuthCenterDto / SimApiAuthIamDto 的嵌套类; + * 说明:原版中这些 DTO 是 SimApiAuthCenterDto / SimApiAuthIamDto 的嵌套类; * 仓颉不支持在类体内声明嵌套类(unexpected class declaration in class body), * 故拍平为顶层类,语义与字段保持一致。 * @@ -15,7 +15,7 @@ package simcu::simapi.authsdk import std.collection.* /** - * 应用/Profile 通用项(对齐 C# AppAndProfileItem)。 + * 应用/Profile 通用项。 */ public class AppAndProfileItem { public var id: String = "" @@ -25,8 +25,8 @@ public class AppAndProfileItem { } /** - * 安全确认响应(对齐 C# ConfirmResponse)。 - * data 用 ?HashMap 对齐 C# Dictionary?(任意 JSON 对象)。 + * 安全确认响应。 + * data 用 ?HashMap 表示任意 JSON 对象。 */ public class ConfirmResponse { public var applicationId: String = "" @@ -36,7 +36,7 @@ public class ConfirmResponse { } /** - * 登录信息响应(对齐 C# LoginInfoResponse)。 + * 登录信息响应。 */ public class LoginInfoResponse { public var scene: ?String = None @@ -48,7 +48,7 @@ public class LoginInfoResponse { } /** - * 获取授权码响应(对齐 C# GetCodeResponse)。 + * 获取授权码响应。 */ public class GetCodeResponse { public var code: String = "" @@ -65,7 +65,7 @@ public class GetCodeResponse { } /** - * 群组关联项(对齐 C# GroupRelatedItem)。 + * 群组关联项。 */ public class GroupRelatedItem { public var id: String = "" @@ -78,7 +78,7 @@ public class GroupRelatedItem { } /** - * 群组详情树节点(对齐 C# GroupDetailTreeNode,children 递归)。 + * 群组详情树节点。 */ public class GroupDetailTreeNode { public var id: String = "" @@ -90,7 +90,7 @@ public class GroupDetailTreeNode { } /** - * 权限项(对齐 C# PermissionItem)。 + * 权限项。 */ public class PermissionItem { public var identifier: String = "" diff --git a/src/authsdk/SimApiAuthIam.cj b/src/authsdk/simapi_auth_iam.cj similarity index 84% rename from src/authsdk/SimApiAuthIam.cj rename to src/authsdk/simapi_auth_iam.cj index 3164d1e..ade35f0 100644 --- a/src/authsdk/SimApiAuthIam.cj +++ b/src/authsdk/simapi_auth_iam.cj @@ -1,6 +1,6 @@ /* * Copyright (c) 2025 SimcuTeam. All rights reserved. - * 移植自 C# 项目 SimApi(E:\simcu\simapi-net),遵循 MIT 许可证。 + * 遵循 MIT 许可证。 * AuthSDK/SimApiAuthIam:权限中心远程 SDK。 */ @@ -11,7 +11,7 @@ import simcu::simapi.communications.* import simcu::simapi.helpers.* /** - * 权限中心远程 SDK(对齐 C# SimApiAuthIam): + * 权限中心远程 SDK: * 注册权限点 / 获取权限标识 / 校验权限。 */ public class SimApiAuthIam { @@ -22,7 +22,7 @@ public class SimApiAuthIam { } /** - * 向 IAM 注册权限(对齐 C# RegisterPermissions)。 + * 向 IAM 注册权限。 */ public func registerPermissions(permissions: Array): Unit { // 请求体:{"permissions":[{"identifier":...,"name":...,"group":...,"description":...},...]} @@ -41,7 +41,7 @@ public class SimApiAuthIam { } /** - * 获取拥有的权限标识数组(对齐 C# GetPermissionOwned)。 + * 获取拥有的权限标识数组。 */ public func getPermissionOwned(profileId: String, groupId!: ?String = None): Array { var body = HashMap() @@ -53,7 +53,7 @@ public class SimApiAuthIam { } /** - * 检测 profileId 是否有该权限,无权限抛 403(对齐 C# CheckPermission)。 + * 检测 profileId 是否有该权限,无权限抛 403。 */ public func checkPermission(profileId: String, permission: String, groupId!: ?String = None): Unit { var body = HashMap() diff --git a/src/communications/SimApiBaseRequest.cj b/src/communications/simapi_base_request.cj similarity index 84% rename from src/communications/SimApiBaseRequest.cj rename to src/communications/simapi_base_request.cj index cbd7198..c8cf11b 100644 --- a/src/communications/SimApiBaseRequest.cj +++ b/src/communications/simapi_base_request.cj @@ -1,7 +1,7 @@ /* * Copyright (c) 2025 SimcuTeam. All rights reserved. - * 移植自 C# 项目 SimApi(E:\simcu\simapi-net),遵循 MIT 许可证。 - * 通用请求 DTO(对齐 C# Communications/SimApiBaseRequest.cs)。 + * 遵循 MIT 许可证。 + * 通用请求 DTO。 * * 说明:这些类仅作反序列化目标(FromJson / @FromBody),无参构造由编译器自动提供; * 不声明显式构造器。 diff --git a/src/communications/SimApiBaseResponse.cj b/src/communications/simapi_base_response.cj similarity index 96% rename from src/communications/SimApiBaseResponse.cj rename to src/communications/simapi_base_response.cj index bacd22a..ffbc610 100644 --- a/src/communications/SimApiBaseResponse.cj +++ b/src/communications/simapi_base_response.cj @@ -1,6 +1,6 @@ /* * Copyright (c) 2025 SimcuTeam. All rights reserved. - * 移植自 C# 项目 SimApi(E:\simcu\simapi-net),遵循 MIT 许可证。 + * 遵循 MIT 许可证。 */ package simcu::simapi.communications diff --git a/src/communications/SimApiDataResponse.cj b/src/communications/simapi_data_response.cj similarity index 92% rename from src/communications/SimApiDataResponse.cj rename to src/communications/simapi_data_response.cj index 5df3592..c7fe3ba 100644 --- a/src/communications/SimApiDataResponse.cj +++ b/src/communications/simapi_data_response.cj @@ -1,6 +1,6 @@ /* * Copyright (c) 2025 SimcuTeam. All rights reserved. - * 移植自 C# 项目 SimApi(E:\simcu\simapi-net),遵循 MIT 许可证。 + * 遵循 MIT 许可证。 */ package simcu::simapi.communications diff --git a/src/communications/SimApiLoginItem.cj b/src/communications/simapi_login_item.cj similarity index 88% rename from src/communications/SimApiLoginItem.cj rename to src/communications/simapi_login_item.cj index 2397534..dc95b0d 100644 --- a/src/communications/SimApiLoginItem.cj +++ b/src/communications/simapi_login_item.cj @@ -1,6 +1,6 @@ /* * Copyright (c) 2025 SimcuTeam. All rights reserved. - * 移植自 C# 项目 SimApi(E:\simcu\simapi-net),遵循 MIT 许可证。 + * 遵循 MIT 许可证。 * Communications/SimApiLoginItem:登录信息项。 */ @@ -10,7 +10,6 @@ import std.collection.* /** * 登录信息项:Token 认证通过后注入请求上下文。 - * 对齐 C# SimApiLoginItem(Id / Type / Meta / Extra)。 * * 序列化/反序列化由 simapi_serialization 反射处理(免标注、免约束), * 字段 id/types/meta/extra 全部为受支持类型(String/Array/HashMap)。 diff --git a/src/configurations/SimApiAuthCenterOptions.cj b/src/configurations/simapi_auth_center_options.cj similarity index 76% rename from src/configurations/SimApiAuthCenterOptions.cj rename to src/configurations/simapi_auth_center_options.cj index cd1d49b..a403251 100644 --- a/src/configurations/SimApiAuthCenterOptions.cj +++ b/src/configurations/simapi_auth_center_options.cj @@ -1,13 +1,13 @@ /* * Copyright (c) 2025 SimcuTeam. All rights reserved. - * 移植自 C# 项目 SimApi(E:\simcu\simapi-net),遵循 MIT 许可证。 - * 对齐 C# 的 Configurations/SimApiAuthCenterOptions.cs。 + * 遵循 MIT 许可证。 + * AuthCenter 认证中心选项配置。 */ package simcu::simapi.configurations /** - * 认证中心配置(对齐 C# SimApiAuthCenterOptions)。 + * 认证中心配置。 */ public class SimApiAuthCenterOptions { /** diff --git a/src/configurations/SimApiDocOptions.cj b/src/configurations/simapi_doc_options.cj similarity index 82% rename from src/configurations/SimApiDocOptions.cj rename to src/configurations/simapi_doc_options.cj index 71bc9f9..d83e006 100644 --- a/src/configurations/SimApiDocOptions.cj +++ b/src/configurations/simapi_doc_options.cj @@ -1,7 +1,6 @@ /* * Copyright (c) 2025 SimcuTeam. All rights reserved. - * 移植自 C# 项目 SimApi(E:\simcu\simapi-net),遵循 MIT 许可证。 - * 对齐 C# 的 Configurations/SimApiDocOptions.cs。 + * 遵循 MIT 许可证。 */ package simcu::simapi.configurations @@ -9,7 +8,7 @@ package simcu::simapi.configurations import std.collection.* /** - * 文档组配置(对齐 C# SimApiDocGroupOption)。 + * 文档组配置。 */ public class SimApiDocGroup { public var id: String = "" @@ -26,13 +25,13 @@ public class SimApiDocGroup { } /** - * 文档授权配置(对齐 C# SimApiAuthOption)。 + * 文档授权配置。 * Type 支持 "SimApiAuth"、"ClientCredentials"、"Implicit"、"AuthorizationCode"、"Password"。 */ public class SimApiAuthOption { /** * 认证方式(默认 ["SimApiAuth"])。 - * `type` 是仓颉关键字,用反引号转义以对齐 C# 属性名 Type。 + * `type` 是仓颉关键字,用反引号转义保留属性名。 */ public var `type`: Array = ["SimApiAuth"] @@ -58,7 +57,7 @@ public class SimApiAuthOption { } /** - * 文档相关配置(默认值与 C# 一致)。 + * 文档相关配置(默认值)。 */ public class SimApiDocOptions { /** diff --git a/src/configurations/SimApiExceptionOptions.cj b/src/configurations/simapi_exception_options.cj similarity index 63% rename from src/configurations/SimApiExceptionOptions.cj rename to src/configurations/simapi_exception_options.cj index bd4f368..4c3a3de 100644 --- a/src/configurations/SimApiExceptionOptions.cj +++ b/src/configurations/simapi_exception_options.cj @@ -1,7 +1,7 @@ /* * Copyright (c) 2025 SimcuTeam. All rights reserved. - * 移植自 C# 项目 SimApi(E:\simcu\simapi-net),遵循 MIT 许可证。 - * 对齐 C# 的 Configurations/SimApiExceptionOptions.cs。 + * 遵循 MIT 许可证。 + * 异常处理选项配置。 */ package simcu::simapi.configurations @@ -9,7 +9,7 @@ package simcu::simapi.configurations import std.collection.* /** - * 异常处理相关配置(默认值与 C# 一致)。 + * 异常处理相关配置(默认值)。 */ public class SimApiExceptionOptions { /** diff --git a/src/configurations/SimApiHttpClientOptions.cj b/src/configurations/simapi_http_client_options.cj similarity index 66% rename from src/configurations/SimApiHttpClientOptions.cj rename to src/configurations/simapi_http_client_options.cj index 4d5fac9..86fc6ca 100644 --- a/src/configurations/SimApiHttpClientOptions.cj +++ b/src/configurations/simapi_http_client_options.cj @@ -1,7 +1,7 @@ /* * Copyright (c) 2025 SimcuTeam. All rights reserved. - * 移植自 C# 项目 SimApi(E:\simcu\simapi-net),遵循 MIT 许可证。 - * 对齐 C# 的 Configurations/SimApiHttpClientOptions.cs。 + * 遵循 MIT 许可证。 + * HTTP 客户端选项配置。 */ package simcu::simapi.configurations diff --git a/src/configurations/SimApiJobOptions.cj b/src/configurations/simapi_job_options.cj similarity index 82% rename from src/configurations/SimApiJobOptions.cj rename to src/configurations/simapi_job_options.cj index 9ec4fd0..c6f36c7 100644 --- a/src/configurations/SimApiJobOptions.cj +++ b/src/configurations/simapi_job_options.cj @@ -1,7 +1,7 @@ /* * Copyright (c) 2025 SimcuTeam. All rights reserved. - * 移植自 C# 项目 SimApi(E:\simcu\simapi-net),遵循 MIT 许可证。 - * 对齐 C# 的 Configurations/SimApiJobOptions.cs。 + * 遵循 MIT 许可证。 + * 后台任务选项配置(占位,未实现)。 */ package simcu::simapi.configurations @@ -9,7 +9,7 @@ package simcu::simapi.configurations import std.collection.* /** - * 任务调度服务器配置(对齐 C# SimApiJobServerConfig)。 + * 任务调度服务器配置。 */ public class SimApiJobServer { /** @@ -24,7 +24,7 @@ public class SimApiJobServer { } /** - * 任务调度相关配置(默认值与 C# 一致)。 + * 任务调度相关配置(默认值)。 */ public class SimApiJobOptions { /** diff --git a/src/configurations/SimApiOptions.cj b/src/configurations/simapi_options.cj similarity index 91% rename from src/configurations/SimApiOptions.cj rename to src/configurations/simapi_options.cj index 38244cf..e275f4f 100644 --- a/src/configurations/SimApiOptions.cj +++ b/src/configurations/simapi_options.cj @@ -1,7 +1,6 @@ /* * Copyright (c) 2025 SimcuTeam. All rights reserved. - * 移植自 C# 项目 SimApi(E:\simcu\simapi-net),遵循 MIT 许可证。 - * 对齐 C# 的 Configurations/SimApiOptions.cs。 + * 遵循 MIT 许可证。 */ package simcu::simapi.configurations @@ -9,7 +8,7 @@ package simcu::simapi.configurations import std.collection.* /** - * SimApi 全局配置:对应 C# 的 SimApi.Configurations.SimApiOptions。 + * SimApi 全局配置。 */ public class SimApiOptions { /** @@ -113,7 +112,7 @@ public class SimApiOptions { public var simApiRequestLogOptions = SimApiRequestLogOptions() - // ===== .NET 风格配置回调(对齐 C# ConfigureSimApiXxx(opt => ...)) ===== + // ===== 配置回调 ===== /** * 配置路由选项。 @@ -172,7 +171,7 @@ public class SimApiOptions { } /** - * 配置请求日志选项(对齐 C# ConfigureSimApiRequestLog)。 + * 配置请求日志选项。 * @param configure 请求日志配置回调。 */ public func configureSimApiRequestLog(configure: (SimApiRequestLogOptions) -> Unit): Unit { @@ -180,7 +179,7 @@ public class SimApiOptions { } /** - * 配置认证中心选项(对齐 C# ConfigureSimApiAuthCenter)。 + * 配置认证中心选项。 * @param configure 认证中心配置回调。 */ public func configureSimApiAuthCenter(configure: (SimApiAuthCenterOptions) -> Unit): Unit { diff --git a/src/configurations/SimApiRequestLogOptions.cj b/src/configurations/simapi_request_log_options.cj similarity index 83% rename from src/configurations/SimApiRequestLogOptions.cj rename to src/configurations/simapi_request_log_options.cj index 91a7c7a..3cdb98e 100644 --- a/src/configurations/SimApiRequestLogOptions.cj +++ b/src/configurations/simapi_request_log_options.cj @@ -1,7 +1,6 @@ /* * Copyright (c) 2025 SimcuTeam. All rights reserved. - * 移植自 C# 项目 SimApi(E:\simcu\simapi-net),遵循 MIT 许可证。 - * 对齐 C# 的 Configurations/SimApiRequestLogOptions.cs。 + * 遵循 MIT 许可证。 */ package simcu::simapi.configurations @@ -16,7 +15,7 @@ public class SimApiRequestLogOptions { public var showFullHeader: Bool = false /** - * 是否打印完整的响应体(false 时截断到 200 字符,对齐 C#)。 + * 是否打印完整的响应体(false 时截断到 200 字符)。 */ public var showFullResponse: Bool = false diff --git a/src/configurations/SimApiRouteOptions.cj b/src/configurations/simapi_route_options.cj similarity index 73% rename from src/configurations/SimApiRouteOptions.cj rename to src/configurations/simapi_route_options.cj index 126bde9..830147d 100644 --- a/src/configurations/SimApiRouteOptions.cj +++ b/src/configurations/simapi_route_options.cj @@ -1,13 +1,13 @@ /* * Copyright (c) 2025 SimcuTeam. All rights reserved. - * 移植自 C# 项目 SimApi(E:\simcu\simapi-net),遵循 MIT 许可证。 - * 对齐 C# 的 Configurations/SimApiRouteOptions.cs。 + * 遵循 MIT 许可证。 + * 内置路由选项配置。 */ package simcu::simapi.configurations /** - * 路由相关配置(默认值与 C# 一致)。 + * 路由相关配置(默认值)。 */ public class SimApiRouteOptions { /** diff --git a/src/configurations/SimApiStorageOptions.cj b/src/configurations/simapi_storage_options.cj similarity index 74% rename from src/configurations/SimApiStorageOptions.cj rename to src/configurations/simapi_storage_options.cj index b6b34ff..6a20123 100644 --- a/src/configurations/SimApiStorageOptions.cj +++ b/src/configurations/simapi_storage_options.cj @@ -1,7 +1,7 @@ /* * Copyright (c) 2025 SimcuTeam. All rights reserved. - * 移植自 C# 项目 SimApi(E:\simcu\simapi-net),遵循 MIT 许可证。 - * 对齐 C# 的 Configurations/SimApiStorageOptions.cs。 + * 遵循 MIT 许可证。 + * S3/MinIO 存储选项配置。 */ package simcu::simapi.configurations diff --git a/src/configurations/SimApiSynapseOptions.cj b/src/configurations/simapi_synapse_options.cj similarity index 85% rename from src/configurations/SimApiSynapseOptions.cj rename to src/configurations/simapi_synapse_options.cj index db28130..23bc7c0 100644 --- a/src/configurations/SimApiSynapseOptions.cj +++ b/src/configurations/simapi_synapse_options.cj @@ -1,13 +1,13 @@ /* * Copyright (c) 2025 SimcuTeam. All rights reserved. - * 移植自 C# 项目 SimApi(E:\simcu\simapi-net),遵循 MIT 许可证。 - * 对齐 C# 的 Configurations/SimApiSynapseOptions.cs。 + * 遵循 MIT 许可证。 + * Synapse 通信选项配置(占位,未实现)。 */ package simcu::simapi.configurations /** - * MQTT 通信配置(默认值与 C# 一致)。 + * MQTT 通信配置(默认值)。 */ public class SimApiSynapseOptions { /** diff --git a/src/controllers/SimApiAuthController.cj b/src/controllers/simapi_auth_controller.cj similarity index 72% rename from src/controllers/SimApiAuthController.cj rename to src/controllers/simapi_auth_controller.cj index fb0efb7..05556cc 100644 --- a/src/controllers/SimApiAuthController.cj +++ b/src/controllers/simapi_auth_controller.cj @@ -1,6 +1,6 @@ /* * Copyright (c) 2025 SimcuTeam. All rights reserved. - * 移植自 C# 项目 SimApi(E:\simcu\simapi-net),遵循 MIT 许可证。 + * 遵循 MIT 许可证。 * Controllers/SimApiAuthController:认证相关内置路由。 */ @@ -12,7 +12,6 @@ import simcu::simapi.helpers.* /** * 认证控制器:退出登录。 - * 对齐 C# 的 SimApiAuthController。 */ public class SimApiAuthController <: SimApiBaseController { private let _auth: SimApiAuth @@ -23,8 +22,8 @@ public class SimApiAuthController <: SimApiBaseController { /** * POST /auth/logout:退出登录(void 自动封装为 SimApiBaseResponse())。 - * 对齐 C# LogoutRoute 默认值 /auth/logout(SimApiAuthController.Logout,[HttpPost], - * 由 MapControllerRoute(pattern=LogoutRoute) 注册)。 + * 对应路由 [HttpPost], + * 由 MapControllerRoute(pattern=LogoutRoute) 注册。 */ @HttpPost["/auth/logout"] public func logout(): Unit { diff --git a/src/controllers/SimApiBaseController.cj b/src/controllers/simapi_base_controller.cj similarity index 86% rename from src/controllers/SimApiBaseController.cj rename to src/controllers/simapi_base_controller.cj index 10e3817..fef9a9b 100644 --- a/src/controllers/SimApiBaseController.cj +++ b/src/controllers/simapi_base_controller.cj @@ -1,8 +1,8 @@ /* * Copyright (c) 2025 SimcuTeam. All rights reserved. - * 移植自 C# 项目 SimApi(E:\simcu\simapi-net),遵循 MIT 许可证。 + * 遵循 MIT 许可证。 * Controllers/SimApiBaseController:基础控制器,所有控制器继承。 - * 提供当前登录信息访问(对齐 C# 的 LoginInfo / LoginToken)。 + * 提供当前登录信息访问。 */ package simcu::simapi.controllers @@ -15,9 +15,8 @@ import simcu::simapi.interfaces.* /** * 基础控制器:所有控制器均继承本控制器。 - * 对齐 C# 的 SimApiBaseController([Consumes]/[Produces] JSON + 登录信息)。 */ -public open class SimApiBaseController <: Controller & IBindRequestContext { +public open class SimApiBaseController <: Controller & BindRequestContext { /** * 当前登录信息(需 EnableSimApiAuth;未登录抛 401)。 */ diff --git a/src/controllers/SimApiCommonController.cj b/src/controllers/simapi_common_controller.cj similarity index 81% rename from src/controllers/SimApiCommonController.cj rename to src/controllers/simapi_common_controller.cj index cd8af84..d56028d 100644 --- a/src/controllers/SimApiCommonController.cj +++ b/src/controllers/simapi_common_controller.cj @@ -1,6 +1,6 @@ /* * Copyright (c) 2025 SimcuTeam. All rights reserved. - * 移植自 C# 项目 SimApi(E:\simcu\simapi-net),遵循 MIT 许可证。 + * 遵循 MIT 许可证。 * Controllers/SimApiCommonController:通用内置路由。 */ @@ -14,8 +14,7 @@ import simcu::simapi.helpers.* /** * 通用控制器:错误反馈、WebConfig、用户信息。 - * 对齐 C# 的 SimApiCommonController。 - * 控制器直接返回 SimApiBaseResponse / SimApiResponse(对齐 C# SimApiBaseResponse)。 + * 控制器直接返回 SimApiBaseResponse / SimApiResponse。 */ public class SimApiCommonController <: SimApiBaseController { private let _options: SimApiOptions @@ -26,7 +25,7 @@ public class SimApiCommonController <: SimApiBaseController { /** * GET /exception/{code}:错误反馈页面(始终注册)。 - * 对齐 C# ExceptionHandler:抛 SimApiException,由异常中间件统一输出。 + * 抛 SimApiException,由异常中间件统一输出。 */ @HttpGet["exception/{code}"] public func exceptionHandler(@FromRoute code: Int64): Unit { @@ -35,8 +34,8 @@ public class SimApiCommonController <: SimApiBaseController { /** * POST/GET /config:给前端的自定义信息(含版本)。 - * 对齐 C# WebConfigRoute 默认值 /config(SimApiCommonController.WebConfig,[HttpPost, HttpGet] 无路径, - * 由 MapControllerRoute(pattern=WebConfigRoute) 注册;soulsoft 约定路由不支持 defaults,故用特性路由直接对齐路径)。 + * 对应路由 [HttpPost, HttpGet] 无路径, + * 由 MapControllerRoute(pattern=WebConfigRoute) 注册;soulsoft 约定路由不支持 defaults,故用特性路由直接对齐路径。 */ @HttpGet["/config"] public func webConfig(): HashMap { diff --git a/src/exceptions/SimApiException.cj b/src/exceptions/simapi_exception.cj similarity index 82% rename from src/exceptions/SimApiException.cj rename to src/exceptions/simapi_exception.cj index ffc827f..37507bc 100644 --- a/src/exceptions/SimApiException.cj +++ b/src/exceptions/simapi_exception.cj @@ -1,6 +1,6 @@ /* * Copyright (c) 2025 SimcuTeam. All rights reserved. - * 移植自 C# 项目 SimApi(E:\simcu\simapi-net),遵循 MIT 许可证。 + * 遵循 MIT 许可证。 */ package simcu::simapi.exceptions diff --git a/src/helpers/SimApiAesBodyChecker.cj b/src/helpers/simapi_aes_body_checker.cj similarity index 89% rename from src/helpers/SimApiAesBodyChecker.cj rename to src/helpers/simapi_aes_body_checker.cj index cf38403..c7a67fc 100644 --- a/src/helpers/SimApiAesBodyChecker.cj +++ b/src/helpers/simapi_aes_body_checker.cj @@ -1,6 +1,6 @@ /* * Copyright (c) 2025 SimcuTeam. All rights reserved. - * 移植自 C# 项目 SimApi(E:\simcu\simapi-net),遵循 MIT 许可证。 + * 遵循 MIT 许可证。 */ package simcu::simapi.helpers @@ -14,21 +14,21 @@ import simcu::simapi.exceptions.* import simcu::simapi.interfaces.* /** - * AES body 请求({"data": "密文"},对齐 C# SimApiOneFieldRequest)。 + * AES body 请求({"data": "密文"})。 */ public class AesBodyRequest { public var data: String = "" } /** - * 服务端 AES body 解密校验器(对齐 C# ModelBinders/AesBodyModelBinder)。 + * 服务端 AES body 解密校验器。 * * 仓颉无 ModelBinder 机制,按项目惯例由控制器在方法开头调用: * let jsonStr = SimApiAesBodyChecker.decryptBody(context, provider) - * let request = JsonSerializer.Deserialize(jsonStr) + * let request = JsonSerializer.deserialize(jsonStr) * 或标注 @AesBody 注解自动执行(SimApiRequestDelegateFactory)。 * - * 流程(与 C# 一致): + * 流程: * 1. 读取 body 并反序列化为 {"data": "密文"} * 2. 校验 Data 非空 * 3. 提取 appId(Query/Header) @@ -53,7 +53,7 @@ public class SimApiAesBodyChecker { } // 2. 反序列化 {"data": "密文"} - let req = JsonSerializer.Deserialize(body) + let req = JsonSerializer.deserialize(body) if (req.data.isEmpty()) { SimApiError.error(code: 400, message: "请求体缺少密文Data字段") } diff --git a/src/helpers/SimApiAesUtil.cj b/src/helpers/simapi_aes_util.cj similarity index 98% rename from src/helpers/SimApiAesUtil.cj rename to src/helpers/simapi_aes_util.cj index 3353cac..3e54142 100644 --- a/src/helpers/SimApiAesUtil.cj +++ b/src/helpers/simapi_aes_util.cj @@ -1,6 +1,6 @@ /* * Copyright (c) 2025 SimcuTeam. All rights reserved. - * 移植自 C# 项目 SimApi(E:\simcu\simapi-net),遵循 MIT 许可证。 + * 遵循 MIT 许可证。 */ package simcu::simapi.helpers @@ -11,9 +11,9 @@ import stdx.crypto.digest.* import stdx.encoding.base64.* /** - * AES-256-CBC + PKCS7 加解密工具(对齐 C# SimApiAesUtil)。 + * AES-256-CBC + PKCS7 加解密工具。 * - * 约定(与 C# 完全一致): + * 约定: * - 密钥:SHA256(key 字符串) → 32 字节 * - 模式:AES-256-CBC,PKCS7 填充 * - IV:每次加密随机生成 16 字节,前置在密文前 diff --git a/src/helpers/SimApiAuth.cj b/src/helpers/simapi_auth.cj similarity index 94% rename from src/helpers/SimApiAuth.cj rename to src/helpers/simapi_auth.cj index 698f190..ee30aea 100644 --- a/src/helpers/SimApiAuth.cj +++ b/src/helpers/simapi_auth.cj @@ -1,6 +1,6 @@ /* * Copyright (c) 2025 SimcuTeam. All rights reserved. - * 移植自 C# 项目 SimApi(E:\simcu\simapi-net),遵循 MIT 许可证。 + * 遵循 MIT 许可证。 */ package simcu::simapi.helpers @@ -113,14 +113,14 @@ public class SimApiAuth { let tokenKey = "${tokenCachePrefix}${token}" let json = loginItemJson(loginItem) if (let Some(redis) <- _redis) { - // 保留原过期时间(对齐 C# update 不刷新 TTL):先读旧 TTL,SET 后重新续期 + // 保留原过期时间:先读旧 TTL,SET 后重新续期 let ttl = redis.ttl(tokenKey) redis.set(tokenKey, Blob.fromUtf8(json)) if (ttl > 0) { redis.expire(tokenKey, ttl) } } else { - // 保留原过期时间(对齐 C# update 不刷新 TTL) + // 保留原过期时间 let expireAt = match (_tokenStore.get(token)) { case Some(entry) => entry.expireAt case None => 0 @@ -162,10 +162,10 @@ public class SimApiAuth { } } - /// 解析登录信息;JSON 无效/非对象时返回 None(视为 token 无效,对齐 C# 返回 null) + /// 解析登录信息;JSON 无效/非对象时返回 None(视为 token 无效) private static func parseLoginItemSafe(json: String): ?SimApiLoginItem { try { - Some(JsonSerializer.Deserialize(json)) + Some(JsonSerializer.deserialize(json)) } catch (_: Exception) { None } @@ -253,7 +253,7 @@ public class SimApiAuth { } private static func generateToken(): String { - // 对齐 C#:token = Guid.NewGuid().ToString()(小写、8-4-4-4-12) + // token = Guid.NewGuid().ToString()(小写、8-4-4-4-12) SimApiUtil.newGuid() } @@ -294,7 +294,7 @@ public class SimApiAuth { } private static func loginItemJson(item: SimApiLoginItem): String { - // 统一 JSON 序列化:对齐 .NET JsonSerializer.Serialize(item) - JsonSerializer.Serialize(item) + // 统一 JSON 序列化:JsonSerializer.Serialize(item) + JsonSerializer.serialize(item) } } diff --git a/src/helpers/SimApiCache.cj b/src/helpers/simapi_cache.cj similarity index 91% rename from src/helpers/SimApiCache.cj rename to src/helpers/simapi_cache.cj index 47bd426..94fec4d 100644 --- a/src/helpers/SimApiCache.cj +++ b/src/helpers/simapi_cache.cj @@ -1,6 +1,6 @@ /* * Copyright (c) 2025 SimcuTeam. All rights reserved. - * 移植自 C# 项目 SimApi(E:\simcu\simapi-net),遵循 MIT 许可证。 + * 遵循 MIT 许可证。 */ package simcu::simapi.helpers @@ -28,7 +28,7 @@ private struct CacheEntry { /** * 缓存助手:Key 自动加前缀 "SimApi:Cache:"。 * 存储后端与 SimApiAuth 一致:配置了 Redis 用 Redis(可带密码/DB 索引),否则 InMemory。 - * InMemory 模式同样支持过期(对齐 C# DistributedCache 的过期语义)。 + * InMemory 模式同样支持过期。 */ public class SimApiCache { private static let prefix = "SimApi:Cache:" @@ -100,17 +100,17 @@ public class SimApiCache { } /** - * 获取特定类型缓存(对齐 C# Get:从 JSON 反序列化,使用 simapi_serialization)。 + * 获取特定类型缓存(从 JSON 反序列化,使用 simapi_serialization)。 */ public func get(key: String): ?T { match (getString(key)) { - case Some(json) => Some(JsonSerializer.Deserialize(json)) + case Some(json) => Some(JsonSerializer.deserialize(json)) case None => None } } /** - * 获取 string 类型缓存(对应 C# Get(string);Cangjie 不支持按泛型重载,故拆分为 getString/get)。 + * 获取 string 类型缓存(仓颉不支持按泛型重载,故拆分为 getString/get)。 */ public func getString(key: String): ?String { if (let Some(redis) <- _redis) { diff --git a/src/helpers/SimApiControllerScanner.cj b/src/helpers/simapi_controller_scanner.cj similarity index 89% rename from src/helpers/SimApiControllerScanner.cj rename to src/helpers/simapi_controller_scanner.cj index 26b2c67..904cdb2 100644 --- a/src/helpers/SimApiControllerScanner.cj +++ b/src/helpers/simapi_controller_scanner.cj @@ -1,10 +1,10 @@ /* * Copyright (c) 2025 SimcuTeam. All rights reserved. - * 移植自 C# 项目 SimApi(E:\simcu\simapi-net),遵循 MIT 许可证。 + * 遵循 MIT 许可证。 * Helpers/SimApiControllerScanner:自动发现调用者包中的 MVC 控制器。 * - * 对齐 C# 的控制器发现机制: - * - C# 通过 StackTrace 获取调用程序集,再 Assembly.GetTypes() 扫描所有类型 + * 控制器发现机制: + * - 通过 StackTrace 获取调用程序集,再 Assembly.GetTypes() 扫描所有类型 * - 仓颉版通过 Error.getStackTrace() 获取调用者包名,再 PackageInfo 枚举类型, * 过滤出继承 Controller 的类型(含子包) */ @@ -35,20 +35,19 @@ public class SimApiControllerScanner { } /** - * 扫描调用者包及其所有子包中 ISimApiAuthChecker 的实现类。 - * 对齐 C# AddSimApi 中遍历调用者程序集 AddScoped 注册 checker 的机制。 + * 扫描调用者包及其所有子包中 SimApiAuthChecker 的实现类。 * @return 找到的 checker 实现类型列表(不含抽象类型与接口本身)。 */ public static func scanAuthCheckers(): Array { let callerPackage = getCallerPackage() var result = ArrayList() - collectImplementations(callerPackage, TypeInfo.of(), result) + collectImplementations(callerPackage, TypeInfo.of(), result) result.toArray() } /** * 获取调用者(应用)包名:遍历栈帧,跳过 simapi/soulsoft/std 等框架包, - * 返回第一个应用包的 declaringClass(对齐 C# 通过 StackTrace 找调用程序集)。 + * 返回第一个应用包的 declaringClass。 */ public static func getCallerPackage(): String { try { diff --git a/src/helpers/SimApiError.cj b/src/helpers/simapi_error.cj similarity index 78% rename from src/helpers/SimApiError.cj rename to src/helpers/simapi_error.cj index 84cd2f4..a72ba0d 100644 --- a/src/helpers/SimApiError.cj +++ b/src/helpers/simapi_error.cj @@ -1,8 +1,8 @@ /* * Copyright (c) 2025 SimcuTeam. All rights reserved. - * 移植自 C# 项目 SimApi(E:\simcu\simapi-net),遵循 MIT 许可证。 + * 遵循 MIT 许可证。 * - * 错误抛出:提供「顶层函数」+「SimApiError 类」两种写法(对齐 C# using static SimApi.Helpers.SimApiError)。 + * 错误抛出:提供「顶层函数」+「SimApiError 类」两种写法。 * - 顶层函数:import simcu::simapi.helpers.* 后可直接 error(400) / errorWhen(...),无需前缀 * - SimApiError.error(...):旧写法,保留兼容 */ @@ -11,7 +11,7 @@ package simcu::simapi.helpers import simcu::simapi.exceptions.* -// ===== 顶层函数(推荐用法:直接 error(400),对齐 C# using static) ===== +// ===== 顶层函数(推荐用法:直接 error(400)) ===== /** * 直接抛错。 @@ -47,17 +47,16 @@ public func errorWhenFalse(condition: Bool, code!: Int64 = 400, message!: String } /** - * 给定的可选值为 None 时抛错。 + * 给定的可选值:None 时抛错,否则返回解包后的值。 */ -public func errorWhenNull(condition: ?Any, code!: Int64 = 404, message!: String = ""): Unit { - SimApiError.errorWhenNull(condition, code: code, message: message) +public func errorWhenNone(value: ?T, code!: Int64 = 404, message!: String = ""): T { + SimApiError.errorWhenNone(value, code: code, message: message) } // ===== 兼容门面(旧写法 SimApiError.error(...) 仍可用,内部为真实实现) ===== /** * 错误抛出辅助类:所有业务错误统一通过这里抛出 SimApiException。 - * 对应 C# 的 SimApi.Helpers.SimApiError。 */ public class SimApiError { private init() {} @@ -98,12 +97,12 @@ public class SimApiError { } /** - * 给定的可选值为 None 时抛错。 + * 给定的可选值:None 时抛错,否则返回解包后的值。 */ - public static func errorWhenNull(condition: ?Any, code!: Int64 = 404, message!: String = ""): Unit { - match (condition) { - case None => error(code: code, message: message) - case _ => () + public static func errorWhenNone(value: ?T, code!: Int64 = 404, message!: String = ""): T { + match (value) { + case Some(v) => v + case None => throw SimApiException(code, message: message) } } } diff --git a/src/helpers/SimApiHttpClient.cj b/src/helpers/simapi_http_client.cj similarity index 90% rename from src/helpers/SimApiHttpClient.cj rename to src/helpers/simapi_http_client.cj index aab7b34..f0bbfff 100644 --- a/src/helpers/SimApiHttpClient.cj +++ b/src/helpers/simapi_http_client.cj @@ -1,6 +1,6 @@ /* * Copyright (c) 2025 SimcuTeam. All rights reserved. - * 移植自 C# 项目 SimApi(E:\simcu\simapi-net),遵循 MIT 许可证。 + * 遵循 MIT 许可证。 */ package simcu::simapi.helpers @@ -17,8 +17,8 @@ import simcu::simapi.exceptions.* /** * HTTP 客户端:用于调用其他带签名/AES 的 SimApi 服务。 - * 对齐 C# 的 SimApi.Helpers.SimApiHttpClient: - * - 内部使用 stdx.net.http 的 HttpClient(等价 .NET 的 System.Net.Http.HttpClient) + * 说明: + * - 内部使用 stdx.net.http 的 HttpClient(等价 System.Net.Http.HttpClient) * - 返回泛型 T(反序列化响应 body 的 data 字段),不再返回 String * @param T 响应 data 的数据类型(任意类,simapi_serialization 反射反序列化)。 */ @@ -41,7 +41,7 @@ public open class SimApiHttpClient { /** * 发起签名请求(GET query 签名 + POST body)。 - * 对齐 C# SignQuery:query 串 = SignFields + AppId + timestamp + nonce,整体拼 AppKey 取 MD5 作为 sign。 + * SignQuery:query 串 = SignFields + AppId + timestamp + nonce,整体拼 AppKey 取 MD5 作为 sign。 * @param url 请求路径(相对路径,自动拼接 server)。 * @param body 请求体 JSON 字符串(可选)。 * @param queries 额外查询参数(可选)。 @@ -74,7 +74,7 @@ public open class SimApiHttpClient { /** * 发起 AES 加密请求:body 加密后放入 {"data": "..."} 提交。 - * 对齐 C# AesQuery(SimApiOneFieldRequest { Data = Encrypt(body, AppKey) })。 + * AesQuery:对应 SimApiOneFieldRequest { Data = Encrypt(body, AppKey) }。 * @param url 请求路径(相对路径,自动拼接 server)。 * @param body 请求体 JSON 字符串。 * @return 响应 data 字段反序列化后的 T。 @@ -91,7 +91,6 @@ public open class SimApiHttpClient { /** * 发起 AES 加密 + 签名请求。 - * 对齐 C# AesSignQuery。 * @param url 请求路径(相对路径,自动拼接 server)。 * @param body 请求体 JSON 字符串。 * @param queries 额外查询参数(可选)。 @@ -105,7 +104,7 @@ public open class SimApiHttpClient { /** * 发起 POST 请求并反序列化 SimApiResponse,返回 data 字段。 - * 对齐 C# Query: + * Query: * ErrorWhenFalse(IsSuccessStatusCode) → ReadFromJsonAsync> → ErrorWhen(Code != 200) → return Data。 * 注意:必须 noProxy(),否则会走系统代理(192.168.0.250:8118)导致连接被拒。 * 反序列化使用 simapi_serialization(Deserialize 免约束)。 @@ -128,7 +127,7 @@ public open class SimApiHttpClient { SimApiError.errorWhenFalse(isSuccess(response.status), code: Int64(response.status), message: "HTTP ERROR: ${response.status}") let json = readBodyText(response.body) - let result = JsonSerializer.Deserialize>(json) + let result = JsonSerializer.deserialize>(json) SimApiError.errorWhen(result.code != 200, code: result.code, message: result.message) return result.data.getOrThrow() } finally { @@ -168,12 +167,12 @@ public open class SimApiHttpClient { } private func aesEncrypt(plain: String): String { - // 对齐 C#:SimApiAesUtil.Encrypt(plain, AppKey)(AES-256-CBC + PKCS7,Base64(IV + 密文)) + // SimApiAesUtil.Encrypt(plain, AppKey)(AES-256-CBC + PKCS7,Base64(IV + 密文)) SimApiAesUtil.encrypt(plain, appKey) } private static func generateNonce(): String { - // 对齐 C#:nonce 直接用 Guid.NewGuid() + // nonce 直接用 Guid.NewGuid() SimApiUtil.newGuid() } diff --git a/src/helpers/SimApiRequestDelegateFactory.cj b/src/helpers/simapi_request_delegate_factory.cj similarity index 90% rename from src/helpers/SimApiRequestDelegateFactory.cj rename to src/helpers/simapi_request_delegate_factory.cj index 4b5ce5b..2edd48d 100644 --- a/src/helpers/SimApiRequestDelegateFactory.cj +++ b/src/helpers/simapi_request_delegate_factory.cj @@ -1,8 +1,8 @@ /* * Copyright (c) 2025 SimcuTeam. All rights reserved. - * 移植自 C# 项目 SimApi(E:\simcu\simapi-net),遵循 MIT 许可证。 + * 遵循 MIT 许可证。 * 自定义 IRequestDelegateFactory:在结果派发时自动封装响应, - * 对齐 C# SimApiResponseFilter(IResultFilter)的行为: + * 即 SimApiResponseFilter(IResultFilter)的行为: * - 返回 SimApiBaseResponse 或其子类 → 原样输出 * - 返回 null/void(Unit)→ SimApiBaseResponse()({code:200, message:成功}) * - 返回 String → SimApiResponse(data 为字符串) @@ -35,7 +35,7 @@ import simcu::simapi.interfaces.* /** * 自定义请求委托工厂:接管 soulsoft 的 ControllerRequestDelegateFactory, - * 在结果派发时自动封装响应(对齐 C# SimApiResponseFilter)。 + * 在结果派发时自动封装响应。 */ public class SimApiRequestDelegateFactory <: IRequestDelegateFactory { private let _mvcOptions: MvcOptions @@ -106,7 +106,7 @@ struct SimApiActionInvoker { // Query/Form/Route/Header/Services → soulsoft bound[index] = soulsoftBound[index] } else if (let Some(aes) <- parameter.findAnnotation()) { - // @AesBody → 解密 body 后按参数类型反序列化(对齐 C# AesBodyModelBinder) + // @AesBody → 解密 body 后按参数类型反序列化 bound[index] = bindAesBody(context, parameter, aes) } else { // FromBody → simapi_serialization 按运行时类型反序列化(免 @Serialization 宏) @@ -135,14 +135,14 @@ struct SimApiActionInvoker { SimApiError.error(code: 400, message: "请求体不能为空") } try { - return JsonSerializer.Deserialize(parameter.typeInfo, body) + return JsonSerializer.deserialize(parameter.typeInfo, body) } catch (ex: Exception) { SimApiError.error(code: 400, message: "请求体反序列化失败: ${ex.message}") } () } - /// @AesBody 参数绑定:解密 body 后按参数类型反序列化(对齐 C# AesBodyModelBinder) + /// @AesBody 参数绑定:解密 body 后按参数类型反序列化 private func bindAesBody(context: ActionBindingContext, parameter: ParameterInfo, aes: AesBody): Any { // 1. 从 DI 解析 keyProvider(AesBodyProviderBase 实现) let provider = resolveAesProvider(aes.keyProvider) @@ -150,7 +150,7 @@ struct SimApiActionInvoker { let plain = SimApiAesBodyChecker.decryptBody(context.httpContext, provider) // 3. 按参数类型反序列化明文 JSON try { - return JsonSerializer.Deserialize(parameter.typeInfo, plain) + return JsonSerializer.deserialize(parameter.typeInfo, plain) } catch (ex: Exception) { SimApiError.error(code: 400, message: "AES body 反序列化失败: ${ex.message}") } @@ -176,7 +176,7 @@ struct SimApiActionInvoker { AesBodyProviderBase() } - /// 检查 @SimApiSign 注解并执行验签(对齐 C# SimApiSignAttribute.OnActionExecuting) + /// 检查 @SimApiSign 注解并执行验签 private func checkSimApiSign() { var sign: ?SimApiSign = None for (item in actionDescriptor.endpointMetadata) { @@ -241,8 +241,8 @@ struct SimApiActionInvoker { "" } - /// 检查 @SimApiAuth 注解并执行鉴权(对齐 C# SimApiAuthAttribute.OnActionExecuting): - /// 未登录 401 → 遍历执行 ISimApiAuthChecker → 类型权限 403 + /// 检查 @SimApiAuth 注解并执行鉴权: + /// 未登录 401 → 遍历执行 SimApiAuthChecker → 类型权限 403 private func checkSimApiAuth() { var auth: ?SimApiAuthAttribute = None for (item in actionDescriptor.endpointMetadata) { @@ -265,17 +265,17 @@ struct SimApiActionInvoker { SimApiError.error(code: 401, message: "需要登录") } - // 2. 遍历执行 ISimApiAuthChecker(对齐 C# GetServices():一次解析全部实现) + // 2. 遍历执行 SimApiAuthChecker let token = match (context.items.get("LoginToken")) { case Some(v) => if (let s: String <- v) { s } else { "" } case None => "" } - let checkers = context.services.getAll() + let checkers = context.services.getAll() for (checker in checkers) { checker.run(loginItem, token) } - // 3. 类型权限校验 → 403(对齐 C# Types.Intersect(loginInfo.Type).Any(),支持逗号分隔多类型) + // 3. 类型权限校验 → 403 if (!auth.`type`.isEmpty()) { let requiredTypes = auth.`type`.split(",") var matched = false @@ -312,9 +312,9 @@ struct SimApiActionInvoker { } } - /// 结果派发 + 自动封装(对齐 C# SimApiResponseFilter) + /// 结果派发 + 自动封装 private func dispatchResult(actionResult: Any) { - // @OriginResponse:跳过统一封装,原样输出(对齐 C# OnResultExecuting 遇注解直接 return) + // @OriginResponse:跳过统一封装,原样输出 var originResponse = false for (item in actionDescriptor.endpointMetadata) { if (item is OriginResponse) { @@ -324,7 +324,7 @@ struct SimApiActionInvoker { } if (originResponse) { if (let s: String <- actionResult) { - // String 原样输出文本(对齐 C# string 返回直接写入) + // String 原样输出文本 context.response.contentType = "application/json; charset=utf-8" SimApiResponseWriter.write(context, s) } else { @@ -367,10 +367,10 @@ struct SimApiActionInvoker { } /// 通过 DI 容器实例化控制器,并注入当前 HttpContext - /// (通过 IBindRequestContext 接口而非 SimApiBaseController,避免 helpers↔controllers 循环依赖) + /// (通过 BindRequestContext 接口而非 SimApiBaseController,避免 helpers↔controllers 循环依赖) private func createControllerInstance(): Object { let instance = ActivatorUtilities.createInstance(context.services, actionDescriptor.controllerType) - if (let controller: IBindRequestContext <- instance) { + if (let controller: BindRequestContext <- instance) { controller.bindRequestContext(context) } return instance diff --git a/src/helpers/SimApiResponseFilter.cj b/src/helpers/simapi_response_filter.cj similarity index 82% rename from src/helpers/SimApiResponseFilter.cj rename to src/helpers/simapi_response_filter.cj index a21e372..1e7feff 100644 --- a/src/helpers/SimApiResponseFilter.cj +++ b/src/helpers/simapi_response_filter.cj @@ -1,6 +1,6 @@ /* * Copyright (c) 2025 SimcuTeam. All rights reserved. - * 移植自 C# 项目 SimApi(E:\simcu\simapi-net),遵循 MIT 许可证。 + * 遵循 MIT 许可证。 */ package simcu::simapi.helpers @@ -11,7 +11,7 @@ import simcu::simapi.communications.* /** * 响应封装:对写操作(Unit)返回统一成功响应,对已有 SimApiBaseResponse 透传。 - * 在仓颉版中以中间件形式实现,对应 C# 的 SimApiResponseFilter。 + * 在仓颉版中以中间件形式实现。 */ public class SimApiResponseFilter { @@ -26,7 +26,7 @@ public class SimApiResponseFilter { next(context) if (!context.response.hasStarted) { context.response.contentType = "application/json; charset=utf-8" - SimApiResponseWriter.write(context, JsonSerializer.Serialize(SimApiBaseResponse())) + SimApiResponseWriter.write(context, JsonSerializer.serialize(SimApiBaseResponse())) } } } diff --git a/src/helpers/SimApiResponseWriter.cj b/src/helpers/simapi_response_writer.cj similarity index 86% rename from src/helpers/SimApiResponseWriter.cj rename to src/helpers/simapi_response_writer.cj index c367866..183d036 100644 --- a/src/helpers/SimApiResponseWriter.cj +++ b/src/helpers/simapi_response_writer.cj @@ -1,6 +1,6 @@ /* * Copyright (c) 2025 SimcuTeam. All rights reserved. - * 移植自 C# 项目 SimApi(E:\simcu\simapi-net),遵循 MIT 许可证。 + * 遵循 MIT 许可证。 */ package simcu::simapi.helpers @@ -11,7 +11,7 @@ import soulsoft_web_http.* * 响应写出工具:写出响应体并缓存文本,供请求日志中间件读取。 * * 背景:soulsoft 的 HttpResponse.body 为只写流(read 抛 UnsupportedException), - * 无法像 C# 那样用 MemoryStream 替换 Body 捕获响应内容; + * 无法像原版那样用 MemoryStream 替换 Body 捕获响应内容; * 故在统一写出入口缓存文本,请求日志中间件直接从 context.items 读取。 */ public class SimApiResponseWriter { diff --git a/src/helpers/SimApiResultWriter.cj b/src/helpers/simapi_result_writer.cj similarity index 89% rename from src/helpers/SimApiResultWriter.cj rename to src/helpers/simapi_result_writer.cj index 364148c..a20c982 100644 --- a/src/helpers/SimApiResultWriter.cj +++ b/src/helpers/simapi_result_writer.cj @@ -1,6 +1,6 @@ /* * Copyright (c) 2025 SimcuTeam. All rights reserved. - * 移植自 C# 项目 SimApi(E:\simcu\simapi-net),遵循 MIT 许可证。 + * 遵循 MIT 许可证。 */ package simcu::simapi.helpers @@ -11,7 +11,7 @@ import simcu::serialization.* import simcu::simapi.communications.* /** - * 统一响应封装工具(对齐 C# SimApiResponseFilter 的包装分支)。 + * 统一响应封装工具。 * 供 SimApiRequestDelegateFactory 与内置路由委托复用: * - SimApiBaseResponse(含子类)→ 原样输出 * - String → SimApiResponse(data 为字符串) @@ -45,6 +45,6 @@ public class SimApiResultWriter { /// simapi_serialization 序列化后直接写响应体(经 SimApiResponseWriter 缓存,供请求日志读取) private static func writeJson(context: HttpContext, obj: Any): Unit { context.response.contentType = "application/json; charset=utf-8" - SimApiResponseWriter.write(context, JsonSerializer.Serialize(obj)) + SimApiResponseWriter.write(context, JsonSerializer.serialize(obj)) } } diff --git a/src/helpers/SimApiSignChecker.cj b/src/helpers/simapi_sign_checker.cj similarity index 93% rename from src/helpers/SimApiSignChecker.cj rename to src/helpers/simapi_sign_checker.cj index 29effb4..a299f7e 100644 --- a/src/helpers/SimApiSignChecker.cj +++ b/src/helpers/simapi_sign_checker.cj @@ -1,6 +1,6 @@ /* * Copyright (c) 2025 SimcuTeam. All rights reserved. - * 移植自 C# 项目 SimApi(E:\simcu\simapi-net),遵循 MIT 许可证。 + * 遵循 MIT 许可证。 */ package simcu::simapi.helpers @@ -11,13 +11,13 @@ import simcu::simapi.exceptions.* import simcu::simapi.interfaces.* /** - * 服务端验签校验器(对齐 C# Attributes/SimApiSignAttribute.OnActionExecuting)。 + * 服务端验签校验器。 * * 仓颉无声明式 ActionFilter 机制,按项目惯例(同 requireLogin)由控制器在需要验签的方法开头调用: * SimApiSignChecker.verify(context, provider, cache) * 或标注 @SimApiSign 注解自动执行(SimApiRequestDelegateFactory)。 * - * 校验流程(与 C# 完全一致): + * 校验流程: * 1. 提取 appId(Query/Header) * 2. provider.getKey(appId) 获取密钥 * 3. 提取并解析 timestamp / nonce @@ -111,7 +111,7 @@ public class SimApiSignChecker { } } - /// 从 Query 或 Header 取参数(Query 优先,对齐 C# FirstOrDefault 语义) + /// 从 Query 或 Header 取参数(Query 优先) private static func getParam(context: HttpContext, name: String): ?String { let q = context.request.query.get(name) if (q != None && q != Some("")) { diff --git a/src/helpers/SimApiStorage.cj b/src/helpers/simapi_storage.cj similarity index 94% rename from src/helpers/SimApiStorage.cj rename to src/helpers/simapi_storage.cj index 6c75c44..04132d7 100644 --- a/src/helpers/SimApiStorage.cj +++ b/src/helpers/simapi_storage.cj @@ -1,13 +1,13 @@ /* * Copyright (c) 2025 SimcuTeam. All rights reserved. - * 移植自 C# 项目 SimApi(E:\simcu\simapi-net),遵循 MIT 许可证。 + * 遵循 MIT 许可证。 * Helpers/SimApiStorage:S3/MinIO 兼容存储助手。 * * 仓颉生态暂无 Minio SDK,此处自实现 AWS Signature V4(HMAC-SHA256 基于 stdx SHA256): * - 预签名 URL(PUT 上传 / GET 下载) * - 直接 PUT 上传(对象 + 建桶) * - HEAD 检测桶是否存在 - * 与 C# SimApiStorage(Minio SDK)的公开方法语义对齐: + * 公开方法语义对齐: * GetUploadUrl / GetDownloadUrl / UploadFile / FullUrl / GetUrl / GetPath */ @@ -26,7 +26,7 @@ import soulsoft_web_http.* import simcu::simapi.configurations.* /** - * 上传预签名 URL 响应(对齐 C# record GetUploadUrlResponse(UploadUrl, DownloadUrl, Path))。 + * 上传预签名 URL 响应。 */ public class GetUploadUrlResponse { public var uploadUrl: String = "" @@ -43,12 +43,12 @@ public class GetUploadUrlResponse { } /** - * S3/MinIO 存储助手(对齐 C# Helpers/SimApiStorage)。 + * S3/MinIO 存储助手。 * * 说明: * - 注册为 Scoped 以注入 IHttpContextAccessor(soulsoft DI 禁止 singleton 消费 scoped 服务); - * 桶的检测/创建由静态守卫保证整个进程只执行一次(对齐 C# 构造函数中 BucketExists+MakeBucket)。 - * - fullUrl/getUrl 的 "~/" 分支依赖当前请求上下文(对齐 C# IHttpContextAccessor)。 + * 桶的检测/创建由静态守卫保证整个进程只执行一次。 + * - fullUrl/getUrl 的 "~/" 分支依赖当前请求上下文。 */ public class SimApiStorage { private static var _bucketEnsured: Bool = false @@ -89,12 +89,12 @@ public class SimApiStorage { _useSsl = useSsl _host = host _httpContextAccessor = httpContextAccessor - // 桶不存在则创建(对齐 C# BucketExists + MakeBucket;静态守卫保证只执行一次) + // 桶不存在则创建 ensureBucketOnce() } /** - * 获取上传预签名 URL(对齐 C# GetUploadUrl,默认 7200 秒)。 + * 获取上传预签名 URL。 */ public func getUploadUrl(path: String, expire!: Int64 = 7200): GetUploadUrlResponse { checkPath(path) @@ -104,7 +104,7 @@ public class SimApiStorage { } /** - * 获取下载预签名 URL(对齐 C# GetDownloadUrl,默认 600 秒)。 + * 获取下载预签名 URL。 */ public func getDownloadUrl(path: String, expire!: Int64 = 600): String { checkPath(path) @@ -113,7 +113,7 @@ public class SimApiStorage { } /** - * 直接上传文件(对齐 C# UploadFile;data 为文件字节)。 + * 直接上传文件。 */ public func uploadFile(path: String, data: Array, contentType!: String = "image/png"): Unit { checkPath(path) @@ -122,7 +122,7 @@ public class SimApiStorage { } /** - * 批量删除对象(对齐 C# Minio RemoveObjectsAsync;S3 原生 DeleteObjects 接口: + * 批量删除对象(S3 原生 DeleteObjects 接口: * POST /{bucket}?delete,一次请求删除多个对象,无需逐个删除)。 * @param paths 对象路径数组(每个须以 / 开头)。 */ @@ -143,7 +143,7 @@ public class SimApiStorage { } /** - * 使用 path 获取完整的访问 URL(对齐 C# FullUrl)。 + * 使用 path 获取完整的访问 URL。 */ public func fullUrl(path: ?String): ?String { if (let Some(p) <- path) { @@ -162,7 +162,7 @@ public class SimApiStorage { } /** - * 获取一个 Path 的访问 URL(对齐 C# GetUrl)。 + * 获取一个 Path 的访问 URL。 */ public func getUrl(path: ?String): ?String { if (let Some(p) <- path) { @@ -181,7 +181,7 @@ public class SimApiStorage { } /** - * 从 URL 中获取相对路径(对齐 C# GetPath;去掉 Endpoint/Bucket 或 ServeUrl 前缀)。 + * 从 URL 中获取相对路径。 */ public func getPath(url: ?String): ?String { if (let Some(u) <- url) { diff --git a/src/helpers/SimApiUtil.cj b/src/helpers/simapi_util.cj similarity index 85% rename from src/helpers/SimApiUtil.cj rename to src/helpers/simapi_util.cj index 0311ce2..b2fe2c1 100644 --- a/src/helpers/SimApiUtil.cj +++ b/src/helpers/simapi_util.cj @@ -1,6 +1,6 @@ /* * Copyright (c) 2025 SimcuTeam. All rights reserved. - * 移植自 C# 项目 SimApi(E:\simcu\simapi-net),遵循 MIT 许可证。 + * 遵循 MIT 许可证。 */ package simcu::simapi.helpers @@ -17,7 +17,7 @@ import simcu::simapi.communications.* import simcu::simapi.macros.* /** - * 工具类:对应 C# 的 SimApi.Helpers.SimApiUtil。 + * 工具类。 * 提供时间、哈希、Base64、JSON、校验等常用能力。 */ public class SimApiUtil { @@ -88,7 +88,7 @@ public class SimApiUtil { toHexString(sha.finish()) } - /// 按 .NET Md5/Sha1 的 mode 格式化:x2/x3/x4 → 每个字节 2/3/4 位十六进制 + /// 按 Md5/Sha1 的 mode 格式化:x2/x3/x4 → 每个字节 2/3/4 位十六进制 private static func formatHex(bytes: Array, mode: String): String { if (mode == "x2") { return toHexString(bytes) @@ -134,14 +134,14 @@ public class SimApiUtil { /** * 判断是否是 Email 地址。 - * 说明:.NET 使用 System.Net.Mail.MailAddress 校验,仓颉无等价 API,此处用正则近似。 + * 说明:原版使用 System.Net.Mail.MailAddress 校验,仓颉无等价 API,此处用正则近似。 */ public static func checkEmail(email: String): Bool { Regex("^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}$").matches(email) } /** - * 生成 UUID v4 字符串(对齐 C# Guid.NewGuid().ToString():小写、8-4-4-4-12 连字符格式)。 + * 生成 UUID v4 字符串。 * 仓颉标准库没有 GUID 生成器(stdx 的 GUID 是 stdx.net.http 内部类型), * 此处用随机数自行构造:16 字节随机数 + 版本位(4)+ 变体位(10)。 */ @@ -172,18 +172,18 @@ public class SimApiUtil { } /** - * 将对象序列化为 JSON 字符串(对齐 C# SimApiUtil.Json)。 + * 将对象序列化为 JSON 字符串。 * @param obj 任意对象(None 输出 null)。 */ public static func json(obj: ?Any): String { if (let Some(obj) <- obj) { - return JsonSerializer.Serialize(obj) + return JsonSerializer.serialize(obj) } "null" } /** - * JSON 字符串转义(对齐 C# 内部转义逻辑)。 + * JSON 字符串转义。 * @param s 原始字符串。 * @return 转义后可直接放入 JSON 字符串字面量的内容。 */ @@ -203,17 +203,17 @@ public class SimApiUtil { } /** - * 从 JSON 字符串反序列化为 T(对齐 C# SimApiUtil.FromJson)。 + * 从 JSON 字符串反序列化为 T。 * @param T 目标类型(任意类,无需接口/宏约束)。 * @param jsonString JSON 字符串。 * @return 反序列化结果。 */ public static func fromJson(jsonString: String): T { - JsonSerializer.Deserialize(jsonString) + JsonSerializer.deserialize(jsonString) } /** - * 对象 Base64 编码(对象 → JSON → Base64,对齐 C# Base64Encode(object))。 + * 对象 Base64 编码(对象 → JSON → Base64)。 * @param obj 任意对象(DTO/基础类型/HashMap 等)。 * @return Base64 字符串。 */ @@ -223,7 +223,7 @@ public class SimApiUtil { } /** - * Base64 → JSON → T 反序列化(对齐 C# Base64Decode)。 + * Base64 → JSON → T 反序列化。 * @param T 目标类型(任意类,无需接口/宏约束)。 * @param base64Str Base64 字符串。 * @return 反序列化结果。 @@ -233,7 +233,7 @@ public class SimApiUtil { } /** - * 分页(对齐 C# Paginate 扩展;仓颉无 IQueryable,改为对 Array 切片)。 + * 分页。 */ public static func paginate(list: Array, page: Int64, count: Int64): Array { let p = if (page < 1) { 1 } else { page } @@ -247,5 +247,5 @@ public class SimApiUtil { list[skip..end] } - // 说明:C# 的 XmlDeserialize 依赖 System.Xml.Serialization,仓颉生态无 XML 序列化库,未移植。 + // 说明:XmlDeserialize 依赖 System.Xml.Serialization,仓颉生态无 XML 序列化库,未移植。 } diff --git a/src/interfaces/AesBodyProviderBase.cj b/src/interfaces/aes_body_provider_base.cj similarity index 71% rename from src/interfaces/AesBodyProviderBase.cj rename to src/interfaces/aes_body_provider_base.cj index 24d8bc0..c545cec 100644 --- a/src/interfaces/AesBodyProviderBase.cj +++ b/src/interfaces/aes_body_provider_base.cj @@ -1,10 +1,10 @@ /* * Copyright (c) 2025 SimcuTeam. All rights reserved. - * 移植自 C# 项目 SimApi(E:\simcu\simapi-net),遵循 MIT 许可证。 - * AES body 密钥提供器基类(对齐 C# ModelBinders/AesBodyProviderBase)。 + * 遵循 MIT 许可证。 + * AES body 密钥提供器基类。 * * 说明:本类含配置字段(appIdName),故用 open class 而非 interface - * (Cangjie 接口不能声明字段),与 .NET 抽象类对应。应用继承本类并实现 getKey。 + * (Cangjie 接口不能声明字段),与抽象类对应。应用继承本类并实现 getKey。 */ package simcu::simapi.interfaces diff --git a/src/interfaces/IBindRequestContext.cj b/src/interfaces/bind_request_context.cj similarity index 79% rename from src/interfaces/IBindRequestContext.cj rename to src/interfaces/bind_request_context.cj index 988823b..74df880 100644 --- a/src/interfaces/IBindRequestContext.cj +++ b/src/interfaces/bind_request_context.cj @@ -1,7 +1,7 @@ /* * Copyright (c) 2025 SimcuTeam. All rights reserved. - * 移植自 C# 项目 SimApi(E:\simcu\simapi-net),遵循 MIT 许可证。 - * Interfaces/IBindRequestContext:请求上下文绑定接口。 + * 遵循 MIT 许可证。 + * Interfaces/BindRequestContext:请求上下文绑定接口。 * * 说明:SimApiBaseController 实现本接口,由 SimApiRequestDelegateFactory(simapi.helpers) * 在创建控制器后注入当前 HttpContext。放在 interfaces 包是为了避免 @@ -15,7 +15,7 @@ import soulsoft_web_http.* /** * 请求上下文绑定接口:控制器实现后,框架在派发请求时把当前 HttpContext 注入。 */ -public interface IBindRequestContext { +public interface BindRequestContext { /** * 绑定当前请求上下文。 * @param context 当前请求的 HttpContext。 diff --git a/src/interfaces/ISimApiAuthChecker.cj b/src/interfaces/simapi_auth_checker.cj similarity index 69% rename from src/interfaces/ISimApiAuthChecker.cj rename to src/interfaces/simapi_auth_checker.cj index 41ea4e9..592b4cf 100644 --- a/src/interfaces/ISimApiAuthChecker.cj +++ b/src/interfaces/simapi_auth_checker.cj @@ -1,6 +1,6 @@ /* * Copyright (c) 2025 SimcuTeam. All rights reserved. - * 移植自 C# 项目 SimApi(E:\simcu\simapi-net),遵循 MIT 许可证。 + * 遵循 MIT 许可证。 */ package simcu::simapi.interfaces @@ -9,9 +9,8 @@ import simcu::simapi.communications.* /** * 认证后处理 Hook:实现后每次认证成功都会调用。 - * 对应 C# 的 SimApi.Interfaces.ISimApiAuthChecker。 */ -public interface ISimApiAuthChecker { +public interface SimApiAuthChecker { /** * 认证成功后执行。 * @param loginItem 登录信息。 diff --git a/src/interfaces/SimApiSignProviderBase.cj b/src/interfaces/simapi_sign_provider_base.cj similarity index 82% rename from src/interfaces/SimApiSignProviderBase.cj rename to src/interfaces/simapi_sign_provider_base.cj index 2f9ad22..e3b237f 100644 --- a/src/interfaces/SimApiSignProviderBase.cj +++ b/src/interfaces/simapi_sign_provider_base.cj @@ -1,10 +1,10 @@ /* * Copyright (c) 2025 SimcuTeam. All rights reserved. - * 移植自 C# 项目 SimApi(E:\simcu\simapi-net),遵循 MIT 许可证。 - * 签名提供器基类(对齐 C# ModelBinders/SimApiSignProviderBase)。 + * 遵循 MIT 许可证。 + * 签名提供器基类。 * * 说明:本类含配置字段(appIdName/queryExpires 等),故用 open class 而非 interface - * (Cangjie 接口不能声明字段),与 .NET 抽象类对应。应用继承本类并实现 getKey。 + * (Cangjie 接口不能声明字段),与抽象类对应。应用继承本类并实现 getKey。 */ package simcu::simapi.interfaces diff --git a/src/logger/SimApiLogger.cj b/src/logger/simapi_logger.cj similarity index 91% rename from src/logger/SimApiLogger.cj rename to src/logger/simapi_logger.cj index 9e00635..7dc306a 100644 --- a/src/logger/SimApiLogger.cj +++ b/src/logger/simapi_logger.cj @@ -1,6 +1,6 @@ /* * Copyright (c) 2025 SimcuTeam. All rights reserved. - * 移植自 C# 项目 SimApi(E:\simcu\simapi-net),遵循 MIT 许可证。 + * 遵循 MIT 许可证。 */ package simcu::simapi.logger @@ -11,7 +11,7 @@ import std.time.* import soulsoft_extensions_logging.* /** - * SimApi 日志记录器:输出格式对齐 C# 原版 SimApiLogger。 + * SimApi 日志记录器。 * 格式:`[ 分类 ][ 时间 ][ 级别 ]\n消息\n[异常]` * 按日志级别着色输出。 */ @@ -39,7 +39,7 @@ public class SimApiLogger <: ILogger { sb.append("${ex}\n") } sb.append(resetColor()) - // 对齐 C# Console.WriteLine:message 末尾 \n 之后再补一个 \n,形成空行分隔 + // message 末尾 \n 之后再补一个 \n,形成空行分隔 sb.append("\n") let writer = getStdOut() @@ -52,7 +52,7 @@ public class SimApiLogger <: ILogger { } /** - * 级别名称,对齐 C# 的 LogLevel.ToString()。 + * 级别名称。 */ private static func levelName(logLevel: LogLevel): String { match (logLevel) { @@ -67,7 +67,7 @@ public class SimApiLogger <: ILogger { } /** - * 级别对应 ANSI 前景色(对齐 C# ConsoleColor): + * 级别对应 ANSI 前景色: * Debug→DarkMagenta, Info→DarkCyan, Warn→Yellow, Error→Red, Fatal→DarkRed, 其他→White */ private static func levelColor(logLevel: LogLevel): String { diff --git a/src/macros/ReadTomlVersionMacro.cj b/src/macros/read_toml_version_macro.cj similarity index 100% rename from src/macros/ReadTomlVersionMacro.cj rename to src/macros/read_toml_version_macro.cj diff --git a/src/middlewares/SimApiAuthMiddleware.cj b/src/middlewares/simapi_auth_middleware.cj similarity index 81% rename from src/middlewares/SimApiAuthMiddleware.cj rename to src/middlewares/simapi_auth_middleware.cj index c50f10f..a0ac920 100644 --- a/src/middlewares/SimApiAuthMiddleware.cj +++ b/src/middlewares/simapi_auth_middleware.cj @@ -1,6 +1,6 @@ /* * Copyright (c) 2025 SimcuTeam. All rights reserved. - * 移植自 C# 项目 SimApi(E:\simcu\simapi-net),遵循 MIT 许可证。 + * 遵循 MIT 许可证。 */ package simcu::simapi.middlewares @@ -11,7 +11,6 @@ import simcu::simapi.helpers.* /** * 认证信息获取中间件:从 Header Token 或 Query token 解析登录信息并注入上下文。 - * 对应 C# 的 SimApi.Middlewares.SimApiAuthMiddleware。 */ public class SimApiAuthMiddleware <: IMiddleware { private let _auth: SimApiAuth @@ -21,7 +20,7 @@ public class SimApiAuthMiddleware <: IMiddleware { } /** - * 中间件入口(IMiddleware 风格,对齐 C# UseMiddleware 的 InvokeAsync)。 + * 中间件入口(IMiddleware 风格)。 */ public func invoke(context: HttpContext, next: RequestDelegate): Unit { var token = context.request.headers.get("Token") diff --git a/src/middlewares/SimApiExceptionMiddleware.cj b/src/middlewares/simapi_exception_middleware.cj similarity index 89% rename from src/middlewares/SimApiExceptionMiddleware.cj rename to src/middlewares/simapi_exception_middleware.cj index edd873d..2a5d5f8 100644 --- a/src/middlewares/SimApiExceptionMiddleware.cj +++ b/src/middlewares/simapi_exception_middleware.cj @@ -1,6 +1,6 @@ /* * Copyright (c) 2025 SimcuTeam. All rights reserved. - * 移植自 C# 项目 SimApi(E:\simcu\simapi-net),遵循 MIT 许可证。 + * 遵循 MIT 许可证。 */ package simcu::simapi.middlewares @@ -15,7 +15,6 @@ import simcu::simapi.helpers.* /** * 异常处理中间件:全异常捕获,统一输出 HTTP 200 + JSON 响应。 - * 对应 C# 的 SimApi.Middlewares.SimApiExceptionMiddleware。 */ public class SimApiExceptionMiddleware <: IMiddleware { private let _options: SimApiOptions @@ -27,7 +26,7 @@ public class SimApiExceptionMiddleware <: IMiddleware { } /** - * 中间件入口(IMiddleware 风格,对齐 C# UseMiddleware 的 InvokeAsync)。 + * 中间件入口(IMiddleware 风格)。 */ public func invoke(context: HttpContext, next: RequestDelegate): Unit { try { @@ -71,6 +70,6 @@ public class SimApiExceptionMiddleware <: IMiddleware { } private func responseJson(response: SimApiBaseResponse): String { - JsonSerializer.Serialize(response) + JsonSerializer.serialize(response) } } diff --git a/src/middlewares/SimApiRequestLogMiddleware.cj b/src/middlewares/simapi_request_log_middleware.cj similarity index 86% rename from src/middlewares/SimApiRequestLogMiddleware.cj rename to src/middlewares/simapi_request_log_middleware.cj index c537eba..0f8b983 100644 --- a/src/middlewares/SimApiRequestLogMiddleware.cj +++ b/src/middlewares/simapi_request_log_middleware.cj @@ -1,6 +1,6 @@ /* * Copyright (c) 2025 SimcuTeam. All rights reserved. - * 移植自 C# 项目 SimApi(E:\simcu\simapi-net),遵循 MIT 许可证。 + * 遵循 MIT 许可证。 */ package simcu::simapi.middlewares @@ -17,16 +17,15 @@ import simcu::simapi.helpers.* /** * 请求日志中间件:记录请求方法、URL、请求头、请求体、响应状态码、响应体、耗时与异常。 - * 对应 C# 的 SimApi.Middlewares.SimApiRequestLogMiddleware。 * * 对齐说明: - * - 请求体按 JSON 字段级截断(对齐 C#:仅对超长字符串字段截断,保留结构) - * - 捕获下游异常并记录,随后重抛(对齐 C# ExceptionDispatchInfo + edi.Throw) + * - 请求体按 JSON 字段级截断 + * - 捕获下游异常并记录,随后重抛 * - 响应体:soulsoft HttpResponse.body 只读且不可读回(read 抛 UnsupportedException), - * 无法像 C# 那样用 MemoryStream 替换捕获;改为在各统一写出入口 + * 无法像原版那样用 MemoryStream 替换捕获;改为在各统一写出入口 * (SimApiResponseWriter)缓存响应文本,此处直接读取。 * 响应行格式:*( Response [status] ) => [ N bytes ],随后换行输出响应体结构; - * ShowFullResponse=false 时截断到 200 字符(对齐 C#,长度仍显示完整字节数) + * ShowFullResponse=false 时截断到 200 字符 * - ShowFullUrl=false 时仅显示路径+查询串;ShowRunTime=true 时请求行显示 [POST] (xxxms) */ public class SimApiRequestLogMiddleware <: IMiddleware { @@ -39,7 +38,7 @@ public class SimApiRequestLogMiddleware <: IMiddleware { } /** - * 中间件入口(IMiddleware 风格,对齐 C# UseMiddleware 的 InvokeAsync)。 + * 中间件入口(IMiddleware 风格)。 */ public func invoke(context: HttpContext, next: RequestDelegate): Unit { let start = MonoTime.now() @@ -61,7 +60,7 @@ public class SimApiRequestLogMiddleware <: IMiddleware { sb.append("*( RequestBody ) =>\n") sb.append(readRequestBody(context)) - // 调用下一级,捕获异常以便记录并重抛(对齐 C# ExceptionDispatchInfo) + // 调用下一级,捕获异常以便记录并重抛 var exception: ?Exception = None try { next(context) @@ -96,7 +95,7 @@ public class SimApiRequestLogMiddleware <: IMiddleware { let display = if (_options.simApiRequestLogOptions.showFullResponse) { responseBody } else if (responseBody.size > 200) { - // 对齐 C#:ShowFullResponse=false 时截断到 200 字符(长度仍显示完整字节数) + // ShowFullResponse=false 时截断到 200 字符(长度仍显示完整字节数) responseBody[0..200] + "...(${responseBody.size})" } else { responseBody @@ -114,14 +113,14 @@ public class SimApiRequestLogMiddleware <: IMiddleware { _logger.info(sbHead.toString() + sb.toString()) - // 重抛原异常(对齐 C# edi?.Throw()),由外层 ExceptionMiddleware 处理 + // 重抛原异常,由外层 ExceptionMiddleware 处理 if (let Some(ex) <- exception) { throw ex } } /// 构造完整请求 URL:stdx 服务端请求 URL 只有路径(无 scheme/host),需手动拼接。 - /// 对齐 C# 的 {Scheme}://{Host}{Path}{QueryString};Host 优先取 Host 请求头。 + /// {Scheme}://{Host}{Path}{QueryString};Host 优先取 Host 请求头。 private func buildDisplayUrl(context: HttpContext): String { var sb = StringBuilder() let scheme = context.request.scheme @@ -196,7 +195,7 @@ public class SimApiRequestLogMiddleware <: IMiddleware { } } - /// 请求体截断:JSON 字段级截断(对齐 C#:仅对超长字符串字段截断),非 JSON 则整串截断 + /// 请求体截断:JSON 字段级截断,非 JSON 则整串截断 private func truncateBody(body: String): String { let maxLen = _options.simApiRequestLogOptions.requestStringLogLength if (maxLen <= 0) { @@ -204,7 +203,7 @@ public class SimApiRequestLogMiddleware <: IMiddleware { } try { // 用 simapi_serialization 解析为动态结构,仅截断超长字符串字段(保持结构) - let map = JsonSerializer.Deserialize>(body) + let map = JsonSerializer.deserialize>(body) var sb = StringBuilder() sb.append("{") var first = true diff --git a/src/models/SimApiBaseModel.cj b/src/models/simapi_base_model.cj similarity index 91% rename from src/models/SimApiBaseModel.cj rename to src/models/simapi_base_model.cj index 20d28d5..6d9fa74 100644 --- a/src/models/SimApiBaseModel.cj +++ b/src/models/simapi_base_model.cj @@ -1,6 +1,6 @@ /* * Copyright (c) 2025 SimcuTeam. All rights reserved. - * 移植自 C# 项目 SimApi(E:\simcu\simapi-net),遵循 MIT 许可证。 + * 遵循 MIT 许可证。 */ package simcu::simapi.models @@ -11,7 +11,7 @@ import std.time.* import simcu::simapi.helpers.* /** - * 实体基类(对齐 C# Models/SimApiBaseModel)。 + * 实体基类。 * 提供: * - Id(默认 Guid)、CreatedAt / UpdatedAt(默认当前时间) * - MapData:反射式字段映射(源 → 目标,同名 + 同类型;可忽略字段/白名单) @@ -30,7 +30,7 @@ public open class SimApiBaseModel { /** - * 反射映射:把 source 的同名同类型非忽略字段赋值到 this(对齐 C# MapData(source, mapAll))。 + * 反射映射:把 source 的同名同类型非忽略字段赋值到 this。 * @param source 源对象。 * @param mapAll 为 true 时连忽略字段(Id/CreatedAt/UpdatedAt)也映射。 */ @@ -46,7 +46,7 @@ public open class SimApiBaseModel { } /** - * 反射映射:仅映射白名单字段(对齐 C# MapData(source, mapFields))。 + * 反射映射:仅映射白名单字段。 * @param source 源对象。 * @param mapFields 白名单字段名。 */ @@ -62,7 +62,7 @@ public open class SimApiBaseModel { } /** - * 更新 UpdatedAt 为当前时间(对齐 C# UpdateTime)。 + * 更新 UpdatedAt 为当前时间。 */ public func updateTime(): Unit { let targetProps = collectProps(TypeInfo.of(this)) diff --git a/src/SimApiExtensions.cj b/src/simapi_extensions.cj similarity index 80% rename from src/SimApiExtensions.cj rename to src/simapi_extensions.cj index 4afe46b..865b1a3 100644 --- a/src/SimApiExtensions.cj +++ b/src/simapi_extensions.cj @@ -1,8 +1,8 @@ /* * Copyright (c) 2025 SimcuTeam. All rights reserved. - * 移植自 C# 项目 SimApi(E:\simcu\simapi-net),遵循 MIT 许可证。 + * 遵循 MIT 许可证。 * - * 对齐 .NET:根命名空间 SimApi 下的静态类 SimApiExtensions(AddSimApi + UseSimApi)。 + * 根命名空间 SimApi 下的静态类 SimApiExtensions(AddSimApi + UseSimApi)。 * 本文件同时是 simapi 根包的入口锚点:cjpm 要求 src 根目录至少有一个 .cj 文件, * 否则不会扫描 src 子目录(helpers/controllers/...),整个包将编译为空。 * @@ -44,7 +44,7 @@ import simcu::simapi.logger.* import simcu::simapi.middlewares.* /** - * SimApi 扩展入口(对齐 C# 根命名空间 SimApi 的静态类 SimApiExtensions)。 + * SimApi 扩展入口。 */ public class SimApiExtensions { private init() {} @@ -58,10 +58,10 @@ public class SimApiExtensions { public static func addSimApi(builder: WebHostBuilder, configure: (SimApiOptions) -> Unit): WebHostBuilder { // 自动注册路由(对齐 builder.Services.AddRouting()) builder.services.addRouting() - // 先构造配置,供后续按开关注册服务(对齐 C# AddSimApi 中先读 options 再注册) + // 先构造配置,供后续按开关注册服务 let options = SimApiOptions() configure(options) - // 响应封装(对齐 C# SimApiResponseFilter,受 EnableSimApiResponseFilter 开关控制): + // 响应封装: // 启用时注册自定义 IRequestDelegateFactory 自动封装响应。 // 必须在 addControllers 之前:soulsoft 用 tryAddSingleton 注册,先到先得,不会被覆盖。 // 未启用时使用 soulsoft 默认派发(String→ContentResult / ISerializable→ObjectResult / 其余→204)。 @@ -69,7 +69,7 @@ public class SimApiExtensions { builder.services.addSingleton() } // 自动注册 MVC + 控制器(对齐 builder.Services.AddControllers()) - // 自动扫描调用者包中的 Controller 子类(对齐 C# 的 Assembly.GetTypes() 扫描) + // 自动扫描调用者包中的 Controller 子类 let controllers = SimApiControllerScanner.scan() addControllers(builder.services, controllers) // 注册 SimApi 服务 @@ -87,16 +87,16 @@ public class SimApiExtensions { } /** - * 应用 SimApi 中间件与内置路由(日志输出对齐 C# UseSimApi)。 + * 应用 SimApi 中间件与内置路由(日志输出)。 * @param host 构建完成的主机。 */ public static func useSimApi(host: WebHost): Unit { let options = host.services.getOrThrow() let loggerFactory = host.services.getOrThrow() - // 对齐 C# ILogger:分类名为 SimApiOptions 的全限定名 + // 分类名为 SimApiOptions 的全限定名 let logger = loggerFactory.createLogger() - // ===== 基础信息(对齐 C# UseSimApi(IHost) 开头) ===== + // ===== 基础信息 ===== let now = DateTime.now() logger.info("当前时区: ${now.zoneId}") logger.info("主应用版本: ${SimApiUtil.appVersion}\nSimApi版本: ${SimApiUtil.simApiVersion}") @@ -112,7 +112,7 @@ public class SimApiExtensions { } // SimApiStorage(已实现:addSimApi 中注册 Scoped,桶初始化惰性执行; - // 对齐 C# 的 GetService 预热,但 scoped 服务不能从根解析,故仅输出配置日志) + // 但 scoped 服务不能从根解析,故仅输出配置日志) if (options.enableSimApiStorage) { logger.info("开始配置 SimApiStorage...") } @@ -133,35 +133,35 @@ public class SimApiExtensions { logger.info("开始配置 SimApiJob ...") } - // ===== 中间件与路由(对齐 C# UseSimApi(WebApplication) 的挂载顺序) ===== - // C# 挂载顺序(先挂载 = 外层):ForwardedHeaders(L419) → CORS(L425) → AuthGate(L454) → Auth(L462) + // ===== 中间件与路由 ===== + // 挂载顺序(先挂载 = 外层):ForwardedHeaders(L419) → CORS(L425) → AuthGate(L454) → Auth(L462) // → 内置路由(L465-496) → Swagger(L502) → RequestLog(L519) → Exception(L525) → LowerUrl → Job - // ForwardedHeaders(占位:soulsoft 暂无内置,对齐 C# 最先挂载) + // ForwardedHeaders(占位:soulsoft 暂无内置) if (options.enableForwardHeaders) { logger.info("开始配置ForwardedHeaders...") } - // CORS(对齐 C# builder.UseCors("any")) + // CORS if (options.enableCors) { logger.info("开始配置 Cors全部允许...") host.useCors() } - // AuthGate(对齐 C# UseMiddleware) + // AuthGate if (options.enableSimApiAuthGate) { logger.info("开始配置 SimApiAuthGate...") host.use() } - // 认证中间件(对齐 C# builder.UseMiddleware()) + // 认证中间件 if (options.enableSimApiAuth) { logger.info("开始配置 SimApiAuth...") host.use() } // 内置路由:RouteOptions 自定义路径时真实注册(默认路径已由内置控制器特性路由覆盖, - // 对齐 C# MapControllerRoute 语义;soulsoft 无约定路由 defaults,用 mapGet/mapPost 委托实现) + // 因 soulsoft 无约定路由 defaults,用 mapGet/mapPost 委托实现) let routeOptions = options.simApiRouteOptions if (let Some(route) <- routeOptions.userInfoRoute) { if (route != "/user/info") { @@ -219,18 +219,18 @@ public class SimApiExtensions { logger.info("注册内置Route: WebConfig => ${route}") } - // SimApiDoc(占位,对齐 C# UseSwagger/UseSwaggerUI) + // SimApiDoc(占位:soulsoft 暂无内置 Swagger 文档页) if (options.enableSimApiDoc) { logger.info("开始配置 SimApiDoc...") } - // 请求日志中间件(对齐 C# builder.UseMiddleware()) + // 请求日志中间件 if (options.enableRequestLog) { logger.info("开始配置 SimApiRequestLog...") host.use() } - // 异常中间件最后挂载(最内层,对齐 C# builder.UseMiddleware()) + // 异常中间件最后挂载(最内层) if (options.enableSimApiException) { logger.info("开始配置 SimApiException...") host.use() @@ -247,12 +247,12 @@ public class SimApiExtensions { } // 响应封装(已实现:addSimApi 中按开关注册 SimApiRequestDelegateFactory 自动封装, - // 对齐 C# SimApiResponseFilter;此处仅输出配置日志) + // 此处仅输出配置日志) if (options.enableSimApiResponseFilter) { logger.info("开始配置 SimApiResponseFilter...") } - // 映射控制器端点(对齐 C# UseSimApi 中的 MapControllers) + // 映射控制器端点 let callSiteFactory = host.services.getOrThrow() if (callSiteFactory.isService()) { host.mapControllers() @@ -262,10 +262,10 @@ public class SimApiExtensions { // ===== 私有辅助 ===== private static func addSimApiCore(builder: WebHostBuilder, options: SimApiOptions): WebHostBuilder { - // 注册单例配置(对齐 C# builder.AddSingleton(simApiOptions)) + // 注册单例配置 builder.services.addSingleton(options) // 子配置不单独注册:中间件统一注入 SimApiOptions 后访问其属性 - // (对齐 C# SimApiExceptionMiddleware(..., SimApiOptions simApiOptions) 风格) + // 自定义日志格式(替换默认 console provider) if (options.enableLogger) { @@ -277,20 +277,20 @@ public class SimApiExtensions { } // 中间件无需注册:挂载时由 ActivatorUtilities 从 DI 解析构造参数创建 - // (对齐 C# builder.UseMiddleware(),其中间件由 UseMiddleware 创建) + // 认证(DI 自动注入 SimApiOptions) if (options.enableSimApiAuth) { builder.services.addSingleton() } - // ISimApiAuthChecker 自动扫描注册(对齐 C# AddSimApi 中遍历调用者程序集 AddScoped(ISimApiAuthChecker, type)) - // 扫描调用者包中的实现类,按【接口】注册;执行时用 getAll() 一次解析全部实现, + // SimApiAuthChecker 自动扫描注册 + // 扫描调用者包中的实现类,按【接口】注册;执行时用 getAll() 一次解析全部实现, // 无需在 SimApiOptions 里维护类型列表。 if (options.enableSimApiAuth) { let checkers = SimApiControllerScanner.scanAuthCheckers() for (checkerType in checkers) { - builder.services.addScoped(TypeInfo.of(), checkerType) + builder.services.addScoped(TypeInfo.of(), checkerType) } } @@ -304,22 +304,22 @@ public class SimApiExtensions { builder.services.addSingleton() } - // 存储(S3/MinIO,对齐 C# AddHttpContextAccessor + AddSingleton; + // 存储(S3/MinIO): // 仓颉版注册为 Scoped 以便注入 IHttpContextAccessor(DI 禁止 singleton 消费 scoped), - // 桶初始化由静态守卫保证只执行一次) + // 桶初始化由静态守卫保证只执行一次。 if (options.enableSimApiStorage) { builder.services.addHttpContextAccessor() builder.services.addScoped() } - // AuthGate 认证中心 SDK(对齐 C# 注册 SimApiAuthClient/Center/Iam 单例) + // AuthGate 认证中心 SDK if (options.enableSimApiAuthGate) { builder.services.addSingleton() builder.services.addSingleton() builder.services.addSingleton() } - // CORS(对齐 C# builder.Services.AddCors(policy => policy.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader())) + // CORS if (options.enableCors) { builder.services.addCors { cors => @@ -335,7 +335,7 @@ public class SimApiExtensions { return builder } - /// 注册 MVC 服务,并注册 SimApi 内置控制器 + 用户控制器到 ApplicationPartManager(对齐 .NET AddControllers())。 + /// 注册 MVC 服务,并注册 SimApi 内置控制器 + 用户控制器到 ApplicationPartManager。 private static func addControllers(services: ServiceCollection, controllerTypes: Array): MvcBuilder { // 调用 soulsoft_web_mvc 的无参 addControllers() 注册 MVC 核心服务 let mvc = services.addControllers()