yunzer_go/server/routers/router.go
2025-11-06 23:32:06 +08:00

325 lines
14 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package routers
import (
"server/controllers"
"server/middleware"
"server/version"
"strings"
beego "github.com/beego/beego/v2/server/web"
"github.com/beego/beego/v2/server/web/context"
)
// 初始化路由
func init() {
// 专门处理OPTIONS预检请求 - 放在最前面
beego.InsertFilter("*", beego.BeforeRouter, func(ctx *context.Context) {
// 设置CORS头
ctx.Output.Header("Access-Control-Allow-Origin", "*")
ctx.Output.Header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, PATCH, OPTIONS")
ctx.Output.Header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization")
ctx.Output.Header("Access-Control-Allow-Credentials", "true")
ctx.Output.Header("Access-Control-Max-Age", "86400")
// 处理OPTIONS预检请求
if ctx.Input.Method() == "OPTIONS" {
ctx.Output.Status = 200
ctx.Output.Body([]byte(""))
return
}
})
// 处理浏览器访问 API 路径的情况 - 在路由之前拦截
beego.InsertFilter("/api/*", beego.BeforeRouter, func(ctx *context.Context) {
// 检查是否是浏览器访问Accept 头包含 text/html
accept := ctx.Input.Header("Accept")
if strings.Contains(accept, "text/html") {
html := `<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>API 服务运行正常</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
padding: 20px;
}
.container {
background: white;
border-radius: 20px;
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
padding: 60px 40px;
max-width: 600px;
width: 100%;
text-align: center;
animation: fadeIn 0.5s ease-in;
}
@keyframes fadeIn {
from {
opacity: 0;
transform: translateY(-20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.success-icon {
width: 80px;
height: 80px;
background: #4CAF50;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
margin: 0 auto 30px;
animation: scaleIn 0.5s ease-out;
}
@keyframes scaleIn {
from {
transform: scale(0);
}
to {
transform: scale(1);
}
}
.success-icon::after {
content: '✓';
color: white;
font-size: 50px;
font-weight: bold;
}
h1 {
color: #333;
font-size: 32px;
margin-bottom: 15px;
font-weight: 600;
}
.status {
color: #4CAF50;
font-size: 18px;
margin-bottom: 30px;
font-weight: 500;
}
.info {
background: #f5f5f5;
border-radius: 10px;
padding: 20px;
margin: 30px 0;
text-align: left;
}
.info-item {
padding: 10px 0;
border-bottom: 1px solid #e0e0e0;
}
.info-item:last-child {
border-bottom: none;
}
.info-label {
color: #666;
font-size: 14px;
margin-bottom: 5px;
}
.info-value {
color: #333;
font-size: 16px;
font-weight: 500;
}
.footer {
margin-top: 30px;
color: #999;
font-size: 14px;
}
</style>
</head>
<body>
<div class="container">
<div class="success-icon"></div>
<h1>API 服务运行正常</h1>
<div class="status">✓ 服务已成功启动并运行中</div>
<div class="info">
<div class="info-item">
<div class="info-label">服务状态</div>
<div class="info-value">运行中</div>
</div>
<div class="info-item">
<div class="info-label">API 版本</div>
<div class="info-value">` + version.Version + `</div>
</div>
<div class="info-item">
<div class="info-label">访问路径</div>
<div class="info-value">` + ctx.Input.URL() + `</div>
</div>
<div class="info-item">
<div class="info-label">请求方法</div>
<div class="info-value">` + ctx.Input.Method() + `</div>
</div>
</div>
<div class="footer">
<p>这是一个 API 服务,请使用 API 客户端或前端应用进行访问</p>
<p style="margin-top: 10px;">如需查看 API 文档,请联系系统管理员</p>
</div>
</div>
</body>
</html>`
ctx.Output.Header("Content-Type", "text/html; charset=utf-8")
ctx.Output.Status = 200
ctx.Output.Body([]byte(html))
return
}
})
// 为除登录、登出和重置密码外的API路由应用JWT中间件
// 这样登录请求就不会被JWT中间件拦截
beego.InsertFilter("/api/*", beego.BeforeRouter, func(ctx *context.Context) {
path := ctx.Input.URL()
// 不需要认证的路径列表
unauthenticatedPaths := []string{"/api/login", "/api/logout", "/api/reset-password",
"/api/program-categories/public", "/api/program-infos/public", "/api/files/public"}
// 检查当前路径是否在不需要认证的列表中
skipAuth := false
for _, p := range unauthenticatedPaths {
if path == p {
skipAuth = true
break
}
}
// 检查是否为公开预览接口(/api/files/public-preview/:id
if strings.HasPrefix(path, "/api/files/public-preview/") {
skipAuth = true
}
if !skipAuth {
middleware.JWTAuthMiddleware()(ctx)
}
})
// 添加主页路由
beego.Router("/", &controllers.MainController{})
// 添加管理员路由
beego.Router("/admin", &controllers.AdminController{})
//用户相关
beego.Router("/api/allUsers", &controllers.UserController{}, "get:GetAllUsers")
beego.Router("/api/user/:id", &controllers.UserController{}, "get:GetUserInfo")
beego.Router("/api/addUser", &controllers.UserController{}, "post:AddUser")
beego.Router("/api/editUser/:id", &controllers.UserController{}, "post:EditUser")
beego.Router("/api/deleteUser/:id", &controllers.UserController{}, "delete:DeleteUser")
beego.Router("/api/changePassword/:id", &controllers.UserController{}, "post:ChangePassword")
beego.Router("/api/reset-password", &controllers.UserController{}, "post:ResetPassword")
beego.Router("/api/tenantUsers/:tenantId", &controllers.UserController{}, "get:GetTenantUsers")
// 员工管理路由
beego.Router("/api/employees", &controllers.EmployeeController{}, "get:GetAllEmployees;post:AddEmployee")
beego.Router("/api/employees/:id", &controllers.EmployeeController{}, "get:GetEmployeeInfo;put:UpdateEmployee;delete:DeleteEmployee")
beego.Router("/api/employees/tenant/:tenantId", &controllers.EmployeeController{}, "get:GetTenantEmployees")
beego.Router("/api/employees/:id/reset-password", &controllers.EmployeeController{}, "post:ResetEmployeePassword")
beego.Router("/api/employees/:id/change-password", &controllers.EmployeeController{}, "post:ChangeEmployeePassword")
// 部门管理路由
beego.Router("/api/departments", &controllers.DepartmentController{}, "post:AddDepartment")
beego.Router("/api/departments/:id", &controllers.DepartmentController{}, "get:GetDepartmentInfo;put:UpdateDepartment;delete:DeleteDepartment")
beego.Router("/api/departments/tenant/:tenantId", &controllers.DepartmentController{}, "get:GetTenantDepartments")
// 职位管理路由
beego.Router("/api/positions", &controllers.PositionController{}, "post:AddPosition")
beego.Router("/api/positions/:id", &controllers.PositionController{}, "get:GetPositionInfo;put:UpdatePosition;delete:DeletePosition")
beego.Router("/api/positions/tenant/:tenantId", &controllers.PositionController{}, "get:GetTenantPositions")
beego.Router("/api/positions/department/:departmentId", &controllers.PositionController{}, "get:GetPositionsByDepartment")
// 认证路由
beego.Router("/api/login", &controllers.AuthController{}, "post:Login")
beego.Router("/api/logout", &controllers.AuthController{}, "post:Logout")
// 手动配置菜单路由以匹配前台的 API 路径
beego.Router("/api/menu", &controllers.MenuController{}, "post:CreateMenu")
beego.Router("/api/menu/:id", &controllers.MenuController{}, "put:UpdateMenu")
beego.Router("/api/menu/:id", &controllers.MenuController{}, "delete:DeleteMenu")
beego.Router("/api/menu/status/:id", &controllers.MenuController{}, "patch:UpdateMenuStatus")
beego.Router("/api/menus/tenant/:roleId", &controllers.MenuController{}, "get:GetTenantMenus")
// 程序分类路由 - 自动映射到 /api/programcategory/*
beego.AutoRouter(&controllers.ProgramCategoryController{})
// 程序信息路由 - 自动映射到 /api/programinfo/*
beego.AutoRouter(&controllers.ProgramInfoController{})
// 文件管理路由 - 手动配置以匹配前端的 /api/files 路径
beego.Router("/api/files", &controllers.FileController{}, "get:GetAllFiles")
beego.Router("/api/files", &controllers.FileController{}, "post:Post")
beego.Router("/api/files/my", &controllers.FileController{}, "get:GetMyFiles")
beego.Router("/api/files/download/:id", &controllers.FileController{}, "get:DownloadFile")
beego.Router("/api/files/preview/:id", &controllers.FileController{}, "get:PreviewFile")
beego.Router("/api/files/public-preview/:id", &controllers.FileController{}, "get:PublicPreviewFile")
beego.Router("/api/files/:id", &controllers.FileController{}, "get:GetFileById")
beego.Router("/api/files/tenant", &controllers.FileController{}, "get:GetFilesByTenant")
beego.Router("/api/files/:id", &controllers.FileController{}, "put:UpdateFile")
beego.Router("/api/files/:id", &controllers.FileController{}, "delete:DeleteFile")
beego.Router("/api/files/search", &controllers.FileController{}, "get:SearchFiles")
beego.Router("/api/files/statistics", &controllers.FileController{}, "get:GetFileStatistics")
// 知识库路由
beego.Router("/api/knowledge/list", &controllers.KnowledgeController{}, "get:List")
beego.Router("/api/knowledge/count", &controllers.KnowledgeController{}, "get:GetCount")
beego.Router("/api/knowledge/detail", &controllers.KnowledgeController{}, "get:Detail")
beego.Router("/api/knowledge/create", &controllers.KnowledgeController{}, "post:Create")
beego.Router("/api/knowledge/update", &controllers.KnowledgeController{}, "post:Update")
beego.Router("/api/knowledge/delete", &controllers.KnowledgeController{}, "post:Delete")
beego.Router("/api/knowledge/categories", &controllers.KnowledgeController{}, "get:GetCategories")
beego.Router("/api/knowledge/tags", &controllers.KnowledgeController{}, "get:GetTags")
beego.Router("/api/knowledge/category/add", &controllers.KnowledgeController{}, "post:AddCategory")
beego.Router("/api/knowledge/tag/add", &controllers.KnowledgeController{}, "post:AddTag")
//租户相关路由
beego.Router("/api/tenant/list", &controllers.TenantController{}, "get:GetAllTenants")
beego.Router("/api/tenant", &controllers.TenantController{}, "post:CreateTenant")
beego.Router("/api/tenant/:id", &controllers.TenantController{}, "put:UpdateTenant")
beego.Router("/api/tenant/:id", &controllers.TenantController{}, "delete:DeleteTenant")
beego.Router("/api/tenant/:id/audit", &controllers.TenantController{}, "post:AuditTenant")
beego.Router("/api/tenant/:id", &controllers.TenantController{}, "get:GetTenantDetail")
// 角色相关路由
beego.Router("/api/roles", &controllers.RoleController{}, "get:GetAllRoles")
beego.Router("/api/roles", &controllers.RoleController{}, "post:CreateRole")
beego.Router("/api/roles/:id", &controllers.RoleController{}, "get:GetRoleById")
beego.Router("/api/roles/tenant/:tenantId", &controllers.RoleController{}, "get:GetRoleByTenantId")
beego.Router("/api/roles/:id", &controllers.RoleController{}, "post:UpdateRole")
beego.Router("/api/roles/:id", &controllers.RoleController{}, "delete:DeleteRole")
// OA基础数据合并接口一次性获取部门、职位、角色
beego.Router("/api/oa/base-data/:tenantId", &controllers.OAController{}, "get:GetOABaseData")
// 权限管理路由
beego.Router("/api/permissions/menus", &controllers.PermissionController{}, "get:GetAllMenuPermissions")
beego.Router("/api/permissions/role/:roleId", &controllers.PermissionController{}, "get:GetRolePermissions")
beego.Router("/api/permissions/role/:roleId", &controllers.PermissionController{}, "post:AssignRolePermissions")
beego.Router("/api/permissions/user", &controllers.PermissionController{}, "get:GetUserPermissions")
beego.Router("/api/permissions/user/menus", &controllers.PermissionController{}, "get:GetUserMenuTree")
beego.Router("/api/permissions/check", &controllers.PermissionController{}, "get:CheckPermission")
// 仪表盘路由
beego.Router("/api/dashboard/platform-stats", &controllers.DashboardController{}, "get:GetPlatformStats")
beego.Router("/api/dashboard/tenant-stats", &controllers.DashboardController{}, "get:GetTenantStats")
// 手动配置特殊路由(无法通过自动路由处理的)
beego.Router("/api/allmenu", &controllers.MenuController{}, "get:GetAllMenus")
beego.Router("/api/program-categories/public", &controllers.ProgramCategoryController{}, "get:GetProgramCategoriesPublic")
beego.Router("/api/program-infos/public", &controllers.ProgramInfoController{}, "get:GetProgramInfosPublic")
beego.Router("/api/files/public", &controllers.FileController{}, "get:GetFilesPublic")
}