package handlers import ( "database/sql" "encoding/json" "net/http" "time" "github.com/gin-gonic/gin" "lan-manager/server/db" "lan-manager/server/middleware" "lan-manager/server/models" ) type ExportHandler struct{} func NewExportHandler() *ExportHandler { return &ExportHandler{} } func (h *ExportHandler) Export(c *gin.Context) { data := map[string]interface{}{} machines := []models.Machine{} if rows, err := db.DB.Query(`SELECT id, hostname, ip, mac, os_type, os_version, notes, ssh_port, ssh_username, ssh_password, is_online, last_ping_at, cpu_info, memory_info, disk_info, uptime, listen_ports, ssh_synced_at, created_at, updated_at FROM machines`); err == nil { defer rows.Close() for rows.Next() { var m models.Machine var lp, ss *time.Time if err := rows.Scan(&m.ID, &m.Hostname, &m.IP, &m.MAC, &m.OsType, &m.OsVersion, &m.Notes, &m.SSHPort, &m.SSHUsername, &m.SSHPassword, &m.IsOnline, &lp, &m.CPUInfo, &m.MemoryInfo, &m.DiskInfo, &m.Uptime, &m.ListenPorts, &ss, &m.CreatedAt, &m.UpdatedAt); err == nil { m.LastPingAt = lp m.SSHSyncedAt = ss machines = append(machines, m) } } } data["machines"] = machines services := []models.Service{} if rows, err := db.DB.Query(`SELECT id, machine_id, name, port, protocol, notes, target_machine_id, target_notes FROM services`); err == nil { defer rows.Close() for rows.Next() { var s models.Service var tm sql.NullInt64 if err := rows.Scan(&s.ID, &s.MachineID, &s.Name, &s.Port, &s.Protocol, &s.Notes, &tm, &s.TargetNotes); err == nil { if tm.Valid { tmid := tm.Int64 s.TargetMachineID = &tmid } services = append(services, s) } } } data["services"] = services relationships := []models.Relationship{} if rows, err := db.DB.Query(`SELECT id, source_machine_id, target_machine_id, relation_type, source_port, target_port, notes FROM relationships`); err == nil { defer rows.Close() for rows.Next() { var r models.Relationship if err := rows.Scan(&r.ID, &r.SourceMachineID, &r.TargetMachineID, &r.RelationType, &r.SourcePort, &r.TargetPort, &r.Notes); err == nil { relationships = append(relationships, r) } } } data["relationships"] = relationships b, _ := json.MarshalIndent(data, "", " ") filename := "lan-manager-backup-" + time.Now().Format("20060102") + ".json" c.Header("Content-Disposition", "attachment; filename="+filename) // 记录导出日志 var entityID int64 = 0 middleware.LogOperation("export", "system", &entityID, "json-export", "", "", c.ClientIP(), middleware.CurrentUser(c)) c.Data(http.StatusOK, "application/json", b) } func (h *ExportHandler) Import(c *gin.Context) { file, _, err := c.Request.FormFile("file") if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } defer file.Close() var data map[string]json.RawMessage if err := json.NewDecoder(file).Decode(&data); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } mode := c.DefaultPostForm("mode", "append") if mode == "overwrite" { _, _ = db.DB.Exec(`DELETE FROM relationships`) _, _ = db.DB.Exec(`DELETE FROM services`) _, _ = db.DB.Exec(`DELETE FROM machines`) } if raw, ok := data["machines"]; ok { var list []models.Machine if err := json.Unmarshal(raw, &list); err == nil { for _, m := range list { _, _ = db.DB.Exec(`INSERT OR IGNORE INTO machines (id, hostname, ip, mac, os_type, os_version, notes, ssh_port, ssh_username, ssh_password, is_online, cpu_info, memory_info, disk_info, uptime, listen_ports) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, m.ID, m.Hostname, m.IP, m.MAC, m.OsType, m.OsVersion, m.Notes, m.SSHPort, m.SSHUsername, m.SSHPassword, 0, m.CPUInfo, m.MemoryInfo, m.DiskInfo, m.Uptime, m.ListenPorts) } } } if raw, ok := data["services"]; ok { var list []models.Service if err := json.Unmarshal(raw, &list); err == nil { for _, s := range list { _, _ = db.DB.Exec(`INSERT OR IGNORE INTO services (id, machine_id, name, port, protocol, notes, target_machine_id, target_notes) VALUES (?, ?, ?, ?, ?, ?, ?, ?)`, s.ID, s.MachineID, s.Name, s.Port, s.Protocol, s.Notes, s.TargetMachineID, s.TargetNotes) } } } if raw, ok := data["relationships"]; ok { var list []models.Relationship if err := json.Unmarshal(raw, &list); err == nil { for _, r := range list { _, _ = db.DB.Exec(`INSERT OR IGNORE INTO relationships (id, source_machine_id, target_machine_id, relation_type, source_port, target_port, notes) VALUES (?, ?, ?, ?, ?, ?, ?)`, r.ID, r.SourceMachineID, r.TargetMachineID, r.RelationType, r.SourcePort, r.TargetPort, r.Notes) } } } middleware.LogOperation("import", "system", nil, "json-import", "", "", c.ClientIP(), middleware.CurrentUser(c)) c.JSON(http.StatusOK, gin.H{"message": "imported"}) }