first commit
This commit is contained in:
230
internal/handler/admin_handler.go
Normal file
230
internal/handler/admin_handler.go
Normal file
@@ -0,0 +1,230 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"xboard-go/internal/database"
|
||||
"xboard-go/internal/model"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func AdminPortal(c *gin.Context) {
|
||||
// Load settings for the portal
|
||||
var appNameSetting model.Setting
|
||||
database.DB.Where("name = ?", "app_name").First(&appNameSetting)
|
||||
appName := appNameSetting.Value
|
||||
if appName == "" {
|
||||
appName = "XBoard Admin"
|
||||
}
|
||||
|
||||
securePath := c.Param("path")
|
||||
if securePath == "" {
|
||||
securePath = "admin" // fallback
|
||||
}
|
||||
|
||||
html := fmt.Sprintf(`
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>%s - 管理控制台</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;600&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
:root {
|
||||
--bg-deep: #0f172a;
|
||||
--bg-accent: #1e293b;
|
||||
--primary: #6366f1;
|
||||
--secondary: #a855f7;
|
||||
--text-main: #f8fafc;
|
||||
--text-dim: #94a3b8;
|
||||
--glass: rgba(255, 255, 255, 0.03);
|
||||
--glass-border: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
font-family: 'Outfit', sans-serif;
|
||||
}
|
||||
|
||||
body {
|
||||
background: var(--bg-deep);
|
||||
color: var(--text-main);
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* Animated Background Gradients */
|
||||
body::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
width: 150vw;
|
||||
height: 150vh;
|
||||
background: radial-gradient(circle at 30%% 30%%, rgba(99, 102, 241, 0.15), transparent 40%%),
|
||||
radial-gradient(circle at 70%% 70%%, rgba(168, 85, 247, 0.15), transparent 40%%);
|
||||
animation: drift 20s infinite alternate ease-in-out;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
@keyframes drift {
|
||||
from { transform: translate(-10%%, -10%%) rotate(0deg); }
|
||||
to { transform: translate(10%%, 10%%) rotate(5deg); }
|
||||
}
|
||||
|
||||
.container {
|
||||
width: 100%%;
|
||||
max-width: 1000px;
|
||||
padding: 2rem;
|
||||
text-align: center;
|
||||
animation: fadeIn 0.8s ease-out;
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
from { opacity: 0; transform: translateY(20px); }
|
||||
to { opacity: 1; transform: translateY(0); }
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 3rem;
|
||||
font-weight: 600;
|
||||
margin-bottom: 0.5rem;
|
||||
background: linear-gradient(135deg, var(--primary), var(--secondary));
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
}
|
||||
|
||||
p.subtitle {
|
||||
font-size: 1.1rem;
|
||||
color: var(--text-dim);
|
||||
margin-bottom: 3rem;
|
||||
}
|
||||
|
||||
.portal-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
||||
gap: 2rem;
|
||||
}
|
||||
|
||||
.portal-card {
|
||||
background: var(--glass);
|
||||
border: 1px solid var(--glass-border);
|
||||
backdrop-filter: blur(20px);
|
||||
border-radius: 24px;
|
||||
padding: 3rem 2rem;
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
transition: all 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.portal-card::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%%;
|
||||
height: 100%%;
|
||||
background: linear-gradient(135deg, rgba(99, 102, 241, 0.05), rgba(168, 85, 247, 0.05));
|
||||
opacity: 0;
|
||||
transition: opacity 0.4s;
|
||||
}
|
||||
|
||||
.portal-card:hover {
|
||||
transform: translateY(-10px) scale(1.02);
|
||||
border-color: rgba(99, 102, 241, 0.4);
|
||||
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
|
||||
.portal-card:hover::after {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.card-icon {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
background: var(--bg-accent);
|
||||
border-radius: 20px;
|
||||
margin-bottom: 1.5rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 2rem;
|
||||
color: var(--primary);
|
||||
transition: transform 0.4s;
|
||||
}
|
||||
|
||||
.portal-card:hover .card-icon {
|
||||
transform: rotate(-5deg) scale(1.1);
|
||||
}
|
||||
|
||||
.card-title {
|
||||
font-size: 1.5rem;
|
||||
font-weight: 600;
|
||||
margin-bottom: 0.75rem;
|
||||
}
|
||||
|
||||
.card-desc {
|
||||
color: var(--text-dim);
|
||||
font-size: 0.95rem;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.badge {
|
||||
position: absolute;
|
||||
top: 1.5rem;
|
||||
right: 1.5rem;
|
||||
background: var(--primary);
|
||||
font-size: 0.75rem;
|
||||
padding: 0.25rem 0.75rem;
|
||||
border-radius: 100px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
@media (max-width: 600px) {
|
||||
h1 { font-size: 2.2rem; }
|
||||
.portal-grid { grid-template-columns: 1fr; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1>%s</h1>
|
||||
<p class="subtitle">欢迎来到管理中心,请选择进入的功能模块</p>
|
||||
|
||||
<div class="portal-grid">
|
||||
<!-- Admin Dashboard -->
|
||||
<a href="/admin/" class="portal-card">
|
||||
<div class="card-icon">⚙️</div>
|
||||
<div class="card-title">系统管理后台</div>
|
||||
<div class="card-desc">管理用户、套餐、节点及系统全局配置</div>
|
||||
</a>
|
||||
|
||||
<!-- Real-Name Verification -->
|
||||
<a href="/%s/realname" class="portal-card">
|
||||
<div class="badge">插件</div>
|
||||
<div class="card-icon">🆔</div>
|
||||
<div class="card-title">实名验证中心</div>
|
||||
<div class="card-desc">审核用户实名信息,确保站点运营安全</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
`, appName, appName, securePath)
|
||||
|
||||
c.Header("Content-Type", "text/html; charset=utf-8")
|
||||
c.String(http.StatusOK, html)
|
||||
}
|
||||
Reference in New Issue
Block a user