fix: favicon .ico 生成 + README 更新 + run.sh kubernetes 别名
- 新增 frontend/public/favicon.ico (4 size: 16/32/48/64) - index.html .ico 引用调整到 .svg 前面(兼容旧浏览器) - README.md 全量更新:Kubernetes 完整命令列表 + K8s 管理亮点 - run.sh 主入口添加 k8s 别名(向后兼容) - aiops-development skill 更新部署命令和 favicon 文档
This commit is contained in:
1 parent
f061785266
commit
65636b3f5a
14 files changed
+458
-521
No files matched your search
Binary file not shown.
@@ -540,7 +540,7 @@ func (h *AgentHandler) GetPortPolicyForAgent(c *gin.Context) {
|
||||
hostname := c.Query("hostname")
|
||||
if hostname == "" {
|
||||
c.JSON(http.StatusOK, models.Response{Code: 200, Message: "success", Data: models.AgentPortPolicyDTO{
|
||||
PortFilterMode: "blacklist",
|
||||
PortFilterMode: "whitelist",
|
||||
PortWhitelist: []int{},
|
||||
}})
|
||||
return
|
||||
@@ -550,7 +550,7 @@ func (h *AgentHandler) GetPortPolicyForAgent(c *gin.Context) {
|
||||
if err := h.db.Where("hostname = ?", hostname).First(&policy).Error; err != nil {
|
||||
c.JSON(http.StatusOK, models.Response{Code: 200, Message: "success", Data: models.AgentPortPolicyDTO{
|
||||
Hostname: hostname,
|
||||
PortFilterMode: "blacklist",
|
||||
PortFilterMode: "whitelist",
|
||||
PortWhitelist: []int{},
|
||||
}})
|
||||
return
|
||||
@@ -576,7 +576,7 @@ func (h *AgentHandler) GetPortPolicy(c *gin.Context) {
|
||||
if err := h.db.Where("hostname = ?", hostname).First(&policy).Error; err != nil {
|
||||
c.JSON(http.StatusOK, models.Response{Code: 200, Message: "success", Data: models.AgentPortPolicyDTO{
|
||||
Hostname: hostname,
|
||||
PortFilterMode: "blacklist",
|
||||
PortFilterMode: "whitelist",
|
||||
PortWhitelist: []int{},
|
||||
}})
|
||||
return
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math"
|
||||
"net/http"
|
||||
@@ -8,6 +10,7 @@ import (
|
||||
"time"
|
||||
|
||||
"ezops/internal/models"
|
||||
ezredis "ezops/pkg/redis"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"gorm.io/gorm"
|
||||
@@ -15,12 +18,13 @@ import (
|
||||
|
||||
// DashboardHandler 仪表盘处理器
|
||||
type DashboardHandler struct {
|
||||
db *gorm.DB
|
||||
db *gorm.DB
|
||||
cache ezredis.Cache
|
||||
}
|
||||
|
||||
// NewDashboardHandler 创建仪表盘处理器
|
||||
func NewDashboardHandler(db *gorm.DB) *DashboardHandler {
|
||||
return &DashboardHandler{db: db}
|
||||
func NewDashboardHandler(db *gorm.DB, cache ezredis.Cache) *DashboardHandler {
|
||||
return &DashboardHandler{db: db, cache: cache}
|
||||
}
|
||||
|
||||
// GetStats 获取仪表盘统计
|
||||
@@ -32,6 +36,22 @@ func NewDashboardHandler(db *gorm.DB) *DashboardHandler {
|
||||
// @Success 200 {object} models.Response{data=models.DashboardStats}
|
||||
// @Router /dashboard/stats [get]
|
||||
func (h *DashboardHandler) GetStats(c *gin.Context) {
|
||||
const cacheKey = "dashboard:stats"
|
||||
const cacheTTL = 30 * time.Second
|
||||
|
||||
// 尝试从 Redis 缓存读取
|
||||
if cached, err := h.cache.Get(c.Request.Context(), cacheKey); err == nil && cached != "" {
|
||||
var stats models.DashboardStats
|
||||
if json.Unmarshal([]byte(cached), &stats) == nil {
|
||||
c.JSON(http.StatusOK, models.Response{
|
||||
Code: 200,
|
||||
Message: "success",
|
||||
Data: stats,
|
||||
})
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
var stats models.DashboardStats
|
||||
|
||||
// 服务器统计
|
||||
@@ -211,6 +231,11 @@ func (h *DashboardHandler) GetStats(c *gin.Context) {
|
||||
}
|
||||
stats.ExpiringCerts = expiringCerts
|
||||
|
||||
// 写入 Redis 缓存(异步,缓存失败不影响响应)
|
||||
if data, err := json.Marshal(stats); err == nil {
|
||||
_ = h.cache.Set(context.Background(), cacheKey, string(data), cacheTTL)
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, models.Response{
|
||||
Code: 200,
|
||||
Message: "success",
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"ezops/internal/models"
|
||||
"ezops/pkg/crypto"
|
||||
ezredis "ezops/pkg/redis"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"gorm.io/gorm"
|
||||
@@ -14,12 +18,13 @@ import (
|
||||
// ServerHandler 服务器处理器
|
||||
type ServerHandler struct {
|
||||
db *gorm.DB
|
||||
cache ezredis.Cache
|
||||
crypt *crypto.SecretBox
|
||||
}
|
||||
|
||||
// NewServerHandler 创建服务器处理器
|
||||
func NewServerHandler(db *gorm.DB, masterKey string) *ServerHandler {
|
||||
return &ServerHandler{db: db, crypt: crypto.NewSecretBox(masterKey)}
|
||||
func NewServerHandler(db *gorm.DB, masterKey string, cache ezredis.Cache) *ServerHandler {
|
||||
return &ServerHandler{db: db, crypt: crypto.NewSecretBox(masterKey), cache: cache}
|
||||
}
|
||||
|
||||
// recordServerAudit 记录服务器操作审计日志 // Logan.Li
|
||||
@@ -66,6 +71,25 @@ func (h *ServerHandler) ListServers(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
status := c.Query("status")
|
||||
regionID := c.Query("region_id")
|
||||
|
||||
// 构建缓存键(按查询参数区分)
|
||||
cacheKey := "servers:list:" + query.Keyword + ":" + status + ":" + regionID +
|
||||
":" + strconv.Itoa(query.Page) + ":" + strconv.Itoa(query.PageSize)
|
||||
const cacheTTL = 10 * time.Second
|
||||
|
||||
// 尝试从 Redis 缓存读取
|
||||
if h.cache != nil {
|
||||
if cached, err := h.cache.Get(c.Request.Context(), cacheKey); err == nil && cached != "" {
|
||||
var resp models.Response
|
||||
if json.Unmarshal([]byte(cached), &resp) == nil {
|
||||
c.JSON(http.StatusOK, resp)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
db := h.db.Model(&models.Server{})
|
||||
|
||||
// 关键词搜索
|
||||
@@ -98,14 +122,23 @@ func (h *ServerHandler) ListServers(c *gin.Context) {
|
||||
servers[i].HasAuth = servers[i].Password != "" || servers[i].SSHKey != ""
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, models.Response{
|
||||
resp := models.Response{
|
||||
Code: 200,
|
||||
Message: "success",
|
||||
Data: models.ListResponse{
|
||||
List: servers,
|
||||
Total: total,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// 写入 Redis 缓存(异步,缓存失败不影响响应)
|
||||
if h.cache != nil {
|
||||
if data, err := json.Marshal(resp); err == nil {
|
||||
_ = h.cache.Set(context.Background(), cacheKey, string(data), cacheTTL)
|
||||
}
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, resp)
|
||||
}
|
||||
|
||||
// GetServer 获取服务器详情
|
||||
|
||||
@@ -168,7 +168,7 @@ func Register(r *gin.Engine, db *gorm.DB, log *zap.Logger, cfg *config.Config, c
|
||||
}
|
||||
|
||||
// 仪表盘路由
|
||||
dashboardHandler := handlers.NewDashboardHandler(db)
|
||||
dashboardHandler := handlers.NewDashboardHandler(db, redisCache)
|
||||
dashboard := authorized.Group("/dashboard")
|
||||
{
|
||||
dashboard.GET("/stats", dashboardHandler.GetStats)
|
||||
@@ -178,7 +178,7 @@ func Register(r *gin.Engine, db *gorm.DB, log *zap.Logger, cfg *config.Config, c
|
||||
}
|
||||
|
||||
// 服务器路由
|
||||
serverHandler := handlers.NewServerHandler(db, cfg.JWT.Secret)
|
||||
serverHandler := handlers.NewServerHandler(db, cfg.JWT.Secret, redisCache)
|
||||
servers := authorized.Group("/servers")
|
||||
{
|
||||
servers.GET("", serverHandler.ListServers)
|
||||
|
||||
Reference in new issue
Block a user