first version

This commit is contained in:
2026-08-16 12:46:15 +08:00
commit 932fce1b9e
40 changed files with 4005 additions and 0 deletions
+35
View File
@@ -0,0 +1,35 @@
/*
* Copyright (c) 2025 SimcuTeam. All rights reserved.
* 移植自 C# 项目 SimApiE:\simcu\simapi-net),遵循 MIT 许可证。
* Controllers/SimApiAuthController:认证相关内置路由。
*/
package simapi.controllers
import soulsoft_web_mvc.annotations.*
import simapi.communications.*
import simapi.helpers.*
/**
* 认证控制器:退出登录。
* 对齐 C# 的 SimApiAuthController。
*/
public class SimApiAuthController <: SimApiBaseController {
private let _auth: SimApiAuth
public init(auth: SimApiAuth) {
this._auth = auth
}
/**
* POST /auth/logout:退出登录(void 自动封装为 SimApiBaseResponse())。
* 对齐 C# LogoutRoute 默认值 /auth/logoutSimApiAuthController.Logout[HttpPost]
* 由 MapControllerRoute(pattern=LogoutRoute) 注册)。
*/
@HttpPost["/auth/logout"]
public func logout(): Unit {
if (let Some(token) <- request.headers.get("Token")) {
_auth.logout(token)
}
}
}
+79
View File
@@ -0,0 +1,79 @@
/*
* Copyright (c) 2025 SimcuTeam. All rights reserved.
* 移植自 C# 项目 SimApiE:\simcu\simapi-net),遵循 MIT 许可证。
* Controllers/SimApiBaseController:基础控制器,所有控制器继承。
* 提供当前登录信息访问(对齐 C# 的 LoginInfo / LoginToken)。
*/
package simapi.controllers
import soulsoft_web_http.*
import soulsoft_web_mvc.core.*
import simapi.communications.*
import simapi.helpers.*
/**
* 基础控制器:所有控制器均继承本控制器。
* 对齐 C# 的 SimApiBaseController[Consumes]/[Produces] JSON + 登录信息)。
*/
public open class SimApiBaseController <: Controller {
/**
* 当前登录信息(需 EnableSimApiAuth;未登录抛 401)。
*/
protected prop loginInfo: SimApiLoginItem {
get() {
if (let Some(item) <- context.items.get("LoginInfo")) {
if (let login: SimApiLoginItem <- item) {
return login
}
}
SimApiError.error(code: 401, message: "需要登录")
SimApiLoginItem("")
}
}
/**
* 当前登录 Token(需 EnableSimApiAuth;未登录抛 401)。
*/
protected prop loginToken: String {
get() {
if (let Some(item) <- context.items.get("LoginToken")) {
if (let token: String <- item) {
return token
}
}
SimApiError.error(code: 401, message: "需要登录")
""
}
}
/**
* 当前登录信息(可选)。
*/
protected func getLogin(): ?SimApiLoginItem {
if (let Some(item) <- context.items.get("LoginInfo")) {
if (let login: SimApiLoginItem <- item) {
return Some(login)
}
}
None
}
/**
* 检查登录状态,未登录抛 401。
*/
protected func requireLogin(): Unit {
match (getLogin()) {
case None => SimApiError.error(code: 401, message: "需要登录")
case _ => ()
}
}
/**
* 绑定当前请求上下文(供 SimApiRequestDelegateFactory 调用;
* Controller.setup 为 protected,此处以 public 方法暴露给框架)。
*/
public func bindRequestContext(context: HttpContext): Unit {
this.setup(context)
}
}
+91
View File
@@ -0,0 +1,91 @@
/*
* Copyright (c) 2025 SimcuTeam. All rights reserved.
* 移植自 C# 项目 SimApiE:\simcu\simapi-net),遵循 MIT 许可证。
* Controllers/SimApiCommonController:通用内置路由。
*/
package simapi.controllers
import std.collection.*
import soulsoft_web_mvc.annotations.*
import simapi.communications.*
import simapi.configurations.*
import simapi.helpers.*
/**
* 通用控制器:错误反馈、WebConfig、用户信息。
* 对齐 C# 的 SimApiCommonController。
* 控制器直接返回 SimApiBaseResponse / SimApiResponse<T>(对齐 C# SimApiBaseResponse<T>)。
*/
public class SimApiCommonController <: SimApiBaseController {
private let _options: SimApiOptions
public init(options: SimApiOptions) {
this._options = options
}
/**
* GET /exception/{code}:错误反馈页面(始终注册)。
* 返回 SimApiBaseResponse(已是响应体,原样输出)。
*/
@HttpGet["exception/{code}"]
public func exceptionHandler(@FromRoute code: Int64): SimApiBaseResponse {
SimApiBaseResponse(code, SimApiBaseResponse.getDefaultMessage(code))
}
/**
* GET/POST /versions:返回 SimApi/App 版本信息(HashMap 由 SimApiResponseFilter 自动封装)。
*/
@HttpGet["versions"]
public func versions(): HashMap<String, Any> {
versionsMap()
}
@HttpPost["versions"]
public func versionsPost(): HashMap<String, Any> {
versionsMap()
}
/**
* POST/GET /config:给前端的自定义信息(含版本)。
* 对齐 C# WebConfigRoute 默认值 /configSimApiCommonController.WebConfig[HttpPost, HttpGet] 无路径,
* 由 MapControllerRoute(pattern=WebConfigRoute) 注册;soulsoft 约定路由不支持 defaults,故用特性路由直接对齐路径)。
*/
@HttpGet["/config"]
public func webConfig(): HashMap<String, Any> {
webConfigMap()
}
@HttpPost["/config"]
public func webConfigPost(): HashMap<String, Any> {
webConfigMap()
}
/**
* POST /user/info:获取已登录用户信息(需登录)。
* 返回 SimApiLoginItem 由 SimApiResponseFilter 自动封装(data 为登录信息对象)。
*/
@HttpPost["/user/info"]
public func userInfo(): SimApiLoginItem {
requireLogin()
loginInfo
}
private func versionsMap(): HashMap<String, Any> {
var map = HashMap<String, Any>()
map["SimApi"] = SimApiUtil.simApiVersion
map["App"] = SimApiUtil.appVersion
map
}
private func webConfigMap(): HashMap<String, Any> {
var map = HashMap<String, Any>()
for ((key, value) in _options.webConfig) {
map[key] = value
}
if (_options.webConfigIncludeVersion) {
map["Versions"] = versionsMap()
}
map
}
}