package controllers import ( "errors" "net/url" "strconv" "fwh-toolbox-server/dto" "fwh-toolbox-server/middleware" mongoRepo "fwh-toolbox-server/repositories/mongo" "fwh-toolbox-server/services" "github.com/gofiber/fiber/v2" "go.uber.org/zap" ) // faultRecordOperator 当前操作人:优先显示名,没有时用登录名 func faultRecordOperator(c *fiber.Ctx) string { if name := middleware.AuthGetDisplayName(c); name != "" { return name } return middleware.AuthGetUserName(c) } func faultRecordErr(c *fiber.Ctx, err error) error { if errors.Is(err, services.ErrFaultRecordInvalid) || errors.Is(err, mongoRepo.ErrFaultRecordOpNotFound) { return Fail(c, err.Error()) } return Error(c, err.Error()) } // 查询网关下可操作的设备 // GET /faultRecord/devices?env=&gatewaySn= func GetFaultRecordDevices(c *fiber.Ctx) error { data, err := services.GetFaultRecordSiteDevices(c.Query("env"), c.Query("gatewaySn")) if err != nil { return faultRecordErr(c, err) } return Success(c, data) } // 创建操作 // POST /faultRecord/operations func CreateFaultRecordOperation(c *fiber.Ctx) error { var body dto.FaultRecordCreateOpReq if err := c.BodyParser(&body); err != nil { zap.L().Warn("Invalid request body", zap.String("err", err.Error())) return Fail(c, "Invalid request body") } id, err := services.CreateFaultRecordOperation(c.UserContext(), body, faultRecordOperator(c)) if err != nil { return faultRecordErr(c, err) } return Success(c, fiber.Map{"id": id}) } // 操作历史(所有人共享) // GET /faultRecord/operations?env=&gatewaySn=&kind=&pageNum=&pageSize= func ListFaultRecordOperations(c *fiber.Ctx) error { page, _ := strconv.ParseInt(c.Query("pageNum", "1"), 10, 64) size, _ := strconv.ParseInt(c.Query("pageSize", "20"), 10, 64) if page < 1 || size < 1 || size > 200 { return Fail(c, "invalid pagination") } data, err := services.ListFaultRecordOperations(c.UserContext(), mongoRepo.FaultRecordOpFilter{ Env: c.Query("env"), GatewaySn: c.Query("gatewaySn"), Kind: c.Query("kind"), }, page, size) if err != nil { return faultRecordErr(c, err) } return Success(c, data) } // 操作详情(含原始报文和逐项结果) // GET /faultRecord/operations/:id func GetFaultRecordOperation(c *fiber.Ctx) error { data, err := services.GetFaultRecordOperation(c.UserContext(), c.Params("id")) if err != nil { return faultRecordErr(c, err) } return Success(c, data) } // 取消操作 // POST /faultRecord/operations/:id/cancel func CancelFaultRecordOperation(c *fiber.Ctx) error { if err := services.CancelFaultRecordOperation(c.UserContext(), c.Params("id")); err != nil { return faultRecordErr(c, err) } return Success[any](c, nil) } // 手动重试下载(上传已完成但下载失败时) // POST /faultRecord/operations/:id/retry-download func RetryFaultRecordDownload(c *fiber.Ctx) error { if err := services.RetryFaultRecordDownload(c.UserContext(), c.Params("id"), faultRecordOperator(c)); err != nil { return faultRecordErr(c, err) } return Success[any](c, nil) } // 录波详情(解析后的基本信息、通道和波形) // GET /faultRecord/operations/:id/record func GetFaultRecordRecord(c *fiber.Ctx) error { data, err := services.GetFaultRecordRecord(c.UserContext(), c.Params("id")) if err != nil { return faultRecordErr(c, err) } return Success(c, data) } // 导出录波文件 // GET /faultRecord/operations/:id/export?format=raw|csv func ExportFaultRecordFile(c *fiber.Ctx) error { name, data, err := services.ExportFaultRecordFile(c.UserContext(), c.Params("id"), c.Query("format")) if err != nil { return faultRecordErr(c, err) } c.Set("Content-Disposition", "attachment; filename=\""+name+"\"; filename*=UTF-8''"+url.PathEscape(name)) c.Type("application/octet-stream") return c.Send(data) }