189 lines
4.8 KiB
Go
189 lines
4.8 KiB
Go
package controllers
|
|
|
|
import (
|
|
"baihu/internal/constant"
|
|
"baihu/internal/database"
|
|
"baihu/internal/models"
|
|
"baihu/internal/services"
|
|
"baihu/internal/utils"
|
|
"fmt"
|
|
"os"
|
|
"time"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/shirou/gopsutil/v3/process"
|
|
)
|
|
|
|
type SettingsController struct {
|
|
userService *services.UserService
|
|
settingsService *services.SettingsService
|
|
}
|
|
|
|
func NewSettingsController(userService *services.UserService) *SettingsController {
|
|
return &SettingsController{
|
|
userService: userService,
|
|
settingsService: services.NewSettingsService(),
|
|
}
|
|
}
|
|
|
|
// ChangePassword 修改密码
|
|
func (sc *SettingsController) ChangePassword(c *gin.Context) {
|
|
var req struct {
|
|
OldPassword string `json:"old_password" binding:"required"`
|
|
NewPassword string `json:"new_password" binding:"required,min=6"`
|
|
}
|
|
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
utils.BadRequest(c, "参数错误")
|
|
return
|
|
}
|
|
|
|
// 暂时使用固定用户名 admin
|
|
user := sc.userService.GetUserByUsername("admin")
|
|
if user == nil {
|
|
utils.NotFound(c, "用户不存在")
|
|
return
|
|
}
|
|
|
|
if !sc.userService.ValidatePassword(user, req.OldPassword) {
|
|
utils.BadRequest(c, "原密码错误")
|
|
return
|
|
}
|
|
|
|
if err := sc.userService.UpdatePassword(user.ID, req.NewPassword); err != nil {
|
|
utils.ServerError(c, "修改密码失败")
|
|
return
|
|
}
|
|
|
|
utils.SuccessMsg(c, "密码修改成功")
|
|
}
|
|
|
|
// CleanLogs 清理日志
|
|
func (sc *SettingsController) CleanLogs(c *gin.Context) {
|
|
var req struct {
|
|
Days int `json:"days" binding:"required,min=1"`
|
|
}
|
|
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
utils.BadRequest(c, "参数错误")
|
|
return
|
|
}
|
|
|
|
cutoff := time.Now().AddDate(0, 0, -req.Days)
|
|
result := database.DB.Where("created_at < ?", cutoff).Delete(&models.TaskLog{})
|
|
|
|
utils.Success(c, gin.H{
|
|
"deleted": result.RowsAffected,
|
|
})
|
|
}
|
|
|
|
// GetSiteSettings 获取站点设置
|
|
func (sc *SettingsController) GetSiteSettings(c *gin.Context) {
|
|
settings := sc.settingsService.GetSection(constant.SectionSite)
|
|
utils.Success(c, settings)
|
|
}
|
|
|
|
// GetPublicSiteSettings 获取公开的站点设置(无需认证)
|
|
func (sc *SettingsController) GetPublicSiteSettings(c *gin.Context) {
|
|
settings := sc.settingsService.GetSection(constant.SectionSite)
|
|
// 只返回公开信息
|
|
utils.Success(c, gin.H{
|
|
constant.KeyTitle: settings[constant.KeyTitle],
|
|
constant.KeySubtitle: settings[constant.KeySubtitle],
|
|
constant.KeyIcon: settings[constant.KeyIcon],
|
|
})
|
|
}
|
|
|
|
// UpdateSiteSettings 更新站点设置
|
|
func (sc *SettingsController) UpdateSiteSettings(c *gin.Context) {
|
|
var req struct {
|
|
Title string `json:"title"`
|
|
Subtitle string `json:"subtitle"`
|
|
Icon string `json:"icon"`
|
|
PageSize string `json:"page_size"`
|
|
CookieDays string `json:"cookie_days"`
|
|
}
|
|
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
utils.BadRequest(c, "参数错误")
|
|
return
|
|
}
|
|
|
|
values := map[string]string{
|
|
constant.KeyTitle: req.Title,
|
|
constant.KeySubtitle: req.Subtitle,
|
|
constant.KeyIcon: req.Icon,
|
|
constant.KeyPageSize: req.PageSize,
|
|
constant.KeyCookieDays: req.CookieDays,
|
|
}
|
|
|
|
if err := sc.settingsService.SetSection(constant.SectionSite, values); err != nil {
|
|
utils.ServerError(c, "保存失败")
|
|
return
|
|
}
|
|
|
|
utils.SuccessMsg(c, "保存成功")
|
|
}
|
|
|
|
// GetAbout 获取关于信息
|
|
func (sc *SettingsController) GetAbout(c *gin.Context) {
|
|
var taskCount, logCount, envCount int64
|
|
database.DB.Model(&models.Task{}).Count(&taskCount)
|
|
database.DB.Model(&models.TaskLog{}).Count(&logCount)
|
|
database.DB.Model(&models.EnvironmentVariable{}).Count(&envCount)
|
|
|
|
// 内存使用
|
|
memUsage := "N/A"
|
|
if p, err := process.NewProcess(int32(os.Getpid())); err == nil {
|
|
if memInfo, err := p.MemoryInfo(); err == nil {
|
|
memUsage = formatBytes(memInfo.RSS)
|
|
}
|
|
}
|
|
|
|
// 运行时间
|
|
uptime := formatDuration(time.Since(constant.StartTime))
|
|
|
|
utils.Success(c, gin.H{
|
|
"version": constant.Version,
|
|
"build_time": constant.BuildTime,
|
|
"mem_usage": memUsage,
|
|
"uptime": uptime,
|
|
"task_count": taskCount,
|
|
"log_count": logCount,
|
|
"env_count": envCount,
|
|
})
|
|
}
|
|
|
|
// formatBytes 格式化字节数
|
|
func formatBytes(bytes uint64) string {
|
|
const unit = 1024
|
|
if bytes < unit {
|
|
return fmt.Sprintf("%d B", bytes)
|
|
}
|
|
div, exp := uint64(unit), 0
|
|
for n := bytes / unit; n >= unit; n /= unit {
|
|
div *= unit
|
|
exp++
|
|
}
|
|
return fmt.Sprintf("%.1f %cB", float64(bytes)/float64(div), "KMGTPE"[exp])
|
|
}
|
|
|
|
// formatDuration 格式化时间间隔
|
|
func formatDuration(d time.Duration) string {
|
|
days := int(d.Hours()) / 24
|
|
hours := int(d.Hours()) % 24
|
|
minutes := int(d.Minutes()) % 60
|
|
seconds := int(d.Seconds()) % 60
|
|
|
|
if days > 0 {
|
|
return fmt.Sprintf("%d天%d小时%d分钟%d秒", days, hours, minutes, seconds)
|
|
}
|
|
if hours > 0 {
|
|
return fmt.Sprintf("%d小时%d分钟%d秒", hours, minutes, seconds)
|
|
}
|
|
if minutes > 0 {
|
|
return fmt.Sprintf("%d分钟%d秒", minutes, seconds)
|
|
}
|
|
return fmt.Sprintf("%d秒", seconds)
|
|
}
|