更新 update 门户站点界面和后台功能
build-winui / winui (push) Waiting to run

This commit is contained in:
QWQLwToo
2026-06-27 18:09:11 +08:00
parent 2513eb2903
commit 962a2f2143
56 changed files with 4564 additions and 714 deletions
@@ -2,6 +2,7 @@ package db
import (
"fmt"
"strings"
"time"
)
@@ -40,7 +41,7 @@ func (s *Store) DashboardOverview(limit int) (map[string]any, error) {
}
func (s *Store) RecentSourceChecks(limit int) ([]map[string]any, error) {
rows, err := s.query(`SELECT h.id, e.source_id, e.name, h.status, h.latency_ms, h.error, h.checked_at
rows, err := s.query(`SELECT h.id, h.source_db_id, COALESCE(e.source_id, ''), COALESCE(e.name, ''), h.status, h.latency_ms, h.error, h.checked_at
FROM endpoint_health_checks h LEFT JOIN source_endpoints e ON e.id = h.source_db_id
ORDER BY h.checked_at DESC, h.id DESC LIMIT ?`, limit)
if err != nil {
@@ -49,13 +50,19 @@ func (s *Store) RecentSourceChecks(limit int) ([]map[string]any, error) {
defer rows.Close()
items := []map[string]any{}
for rows.Next() {
var id int64
var id, sourceDBID int64
var sourceID, name, status, message, checkedAt string
var latency int
if err := rows.Scan(&id, &sourceID, &name, &status, &latency, &message, &checkedAt); err != nil {
if err := rows.Scan(&id, &sourceDBID, &sourceID, &name, &status, &latency, &message, &checkedAt); err != nil {
return nil, err
}
items = append(items, map[string]any{"id": id, "sourceId": sourceID, "name": name, "status": status, "latencyMs": latency, "error": message, "checkedAt": checkedAt})
if sourceID == "" {
sourceID = fmt.Sprintf("deleted-%d", sourceDBID)
}
if name == "" {
name = fmt.Sprintf("已删除接口 #%d", sourceDBID)
}
items = append(items, map[string]any{"id": id, "sourceDbId": sourceDBID, "sourceId": sourceID, "name": name, "status": status, "latencyMs": latency, "error": message, "checkedAt": checkedAt})
}
return items, rows.Err()
}
@@ -100,6 +107,59 @@ func (s *Store) ListAuditLogs(limit int) ([]AuditLog, error) {
return scanAuditRows(rows)
}
func (s *Store) ListAuditLogsPage(filters AuditFilters) (AuditPage, error) {
page := filters.Page
if page <= 0 {
page = 1
}
perPage := filters.PerPage
if perPage <= 0 {
perPage = 35
}
if perPage > 100 {
perPage = 100
}
where, args := auditWhere(filters)
var total int
if err := s.queryRow(`SELECT COUNT(*) FROM audit_logs`+where, args...).Scan(&total); err != nil {
return AuditPage{}, err
}
offset := (page - 1) * perPage
queryArgs := append(append([]any{}, args...), perPage, offset)
rows, err := s.query(`SELECT id, actor, type, target, message, ip, user_agent, created_at FROM audit_logs`+where+` ORDER BY id DESC LIMIT ? OFFSET ?`, queryArgs...)
if err != nil {
return AuditPage{}, err
}
defer rows.Close()
items, err := scanAuditRows(rows)
if err != nil {
return AuditPage{}, err
}
return AuditPage{Items: items, Total: total, Page: page, PerPage: perPage}, nil
}
func auditWhere(filters AuditFilters) (string, []any) {
clauses := []string{}
args := []any{}
if value := strings.TrimSpace(filters.Type); value != "" {
clauses = append(clauses, "type = ?")
args = append(args, sanitize(value))
}
if value := strings.TrimSpace(filters.Target); value != "" {
clauses = append(clauses, "target = ?")
args = append(args, sanitize(value))
}
if value := strings.TrimSpace(filters.Query); value != "" {
clauses = append(clauses, "(actor LIKE ? OR type LIKE ? OR target LIKE ? OR message LIKE ? OR ip LIKE ?)")
like := "%" + sanitize(value) + "%"
args = append(args, like, like, like, like, like)
}
if len(clauses) == 0 {
return "", args
}
return " WHERE " + strings.Join(clauses, " AND "), args
}
func (s *Store) ListAuditLogsForTarget(target string, limit int) ([]AuditLog, error) {
if limit <= 0 || limit > 200 {
limit = 100