package handler import ( "fmt" "net/http" "os" "runtime" "strings" "u-desk/internal/agent/model" "github.com/labstack/echo/v4" "github.com/shirou/gopsutil/v3/cpu" "github.com/shirou/gopsutil/v3/disk" "github.com/shirou/gopsutil/v3/mem" ) // Ping 健康检查 func (h *Handler) Ping(c echo.Context) error { return c.JSON(http.StatusOK, model.OK(map[string]string{ "status": "ok", })) } // Info 返回 Agent 信息 func (h *Handler) Info(c echo.Context) error { hostname, _ := os.Hostname() return c.JSON(http.StatusOK, model.OK(map[string]interface{}{ "version": "0.1.0", "os": runtime.GOOS, "arch": runtime.GOARCH, "hostname": hostname, })) } // CommonPaths 返回常用系统路径 func (h *Handler) CommonPaths(c echo.Context) error { paths := map[string]string{} home, _ := os.UserHomeDir() if home != "" { paths["home"] = home paths["desktop"] = home + "/Desktop" paths["documents"] = home + "/Documents" paths["downloads"] = home + "/Downloads" } // 根据平台添加盘符/根路径 if runtime.GOOS == "windows" { for _, drive := range "ABCDEFGHIJKLMNOPQRSTUVWXYZ" { _, err := os.Stat(string(drive) + ":\\") if err == nil { paths["drive_"+strings.ToLower(string(drive))] = string(drive) + ":\\" } } } else { paths["root"] = "/" _, err := os.Stat("/home") if err == nil { paths["users"] = "/home" } } return c.JSON(http.StatusOK, model.OK(paths)) } // Drives 返回可用磁盘列表 func (h *Handler) Drives(c echo.Context) error { type DriveInfo struct { Name string `json:"name"` Path string `json:"path"` FsType string `json:"fs_type,omitempty"` Total uint64 `json:"total"` Free uint64 `json:"free"` } var drives []DriveInfo if runtime.GOOS == "windows" { for _, drive := range "ABCDEFGHIJKLMNOPQRSTUVWXYZ" { drivePath := string(drive) + ":\\" if _, err := os.Stat(drivePath); err != nil { continue } drives = append(drives, DriveInfo{ Name: strings.ToLower(string(drive)), Path: drivePath, Total: 0, Free: 0, }) } } else { parts, err := os.ReadDir("/") if err == nil { for _, p := range parts { name := p.Name() if len(name) == 2 && name[0] != '.' && name[1] != '.' && p.IsDir() { // 可能是挂载点 fullPath := "/" + name if stat, err := os.Stat(fullPath); err == nil && stat.IsDir() { drives = append(drives, DriveInfo{ Name: name, Path: fullPath, }) _ = stat } } } } // 至少返回根目录 if len(drives) == 0 { drives = append(drives, DriveInfo{Name: "/", Path: "/"}) } } return c.JSON(http.StatusOK, model.OK(drives)) } // Stats 返回系统资源使用统计(CPU/内存/磁盘) func (h *Handler) Stats(c echo.Context) error { info := make(map[string]interface{}) // CPU if cores, err := cpu.Counts(true); err == nil { info["cpu_cores"] = cores } if percents, err := cpu.Percent(0, false); err == nil && len(percents) > 0 { info["cpu_usage"] = fmt.Sprintf("%.0f%%", percents[0]) } // 内存 if memInfo, err := mem.VirtualMemory(); err == nil { info["mem_total"] = memInfo.Total info["mem_used"] = memInfo.Used info["mem_usage"] = fmt.Sprintf("%.0f%%", memInfo.UsedPercent) } // 磁盘(取根分区) if partitions, err := disk.Partitions(false); err == nil { for _, p := range partitions { if p.Mountpoint == "/" || (runtime.GOOS == "windows" && len(p.Mountpoint) == 3 && p.Mountpoint[1] == ':') { if usage, err := disk.Usage(p.Mountpoint); err == nil { info["disk_total"] = usage.Total info["disk_used"] = usage.Used info["disk_usage"] = fmt.Sprintf("%.0f%%", usage.UsedPercent) } break } } } return c.JSON(http.StatusOK, model.OK(info)) }