getAlarmSnapshot.go 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. package jobs
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "fwh-toolbox-server/ext/api/fwh_pro"
  6. "fwh-toolbox-server/logger"
  7. "fwh-toolbox-server/types"
  8. "fwh-toolbox-server/utils/files"
  9. "io"
  10. "net/http"
  11. "os"
  12. "path/filepath"
  13. "go.uber.org/zap"
  14. )
  15. type AlarmSnapshotInfo struct {
  16. Id uint64 `json:"id"`
  17. CodeType int `json:"codeType"` // 作用未知
  18. FileName string `json:"fileName"`
  19. FileUrl string `json:"fileUrl"`
  20. LinkId string `json:"linkId"` // site SN
  21. LogTime string `json:"logTime"` // format YYYY-MM-DD
  22. SerialNumber string `json:"serialNumber"`
  23. StartTime string `json:"startTime"` // format YYYY-MM-DD HH:mm:SS
  24. EndTime string `json:"endTime"` // format YYYY-MM-DD HH:mm:SS
  25. Status int `json:"status"` // 1-完成
  26. CompleteTime string `json:"completeTime"` // format YYYY-MM-DD HH:mm:SS
  27. }
  28. type AlarmSnapshotListResponse = types.FwhPageResponse[AlarmSnapshotInfo]
  29. // 解析
  30. func handleAlarmSnapshot(sn string, logTime string, page int) (uint64, []AlarmSnapshotInfo, error) {
  31. // 查询告警快照数据
  32. resByte, err := fwh_pro.QueryAlarmSnapshotInfo(sn, logTime, page)
  33. if err != nil {
  34. return 0, nil, fmt.Errorf("[handleAlarmSnapshot] %s", err.Error())
  35. }
  36. var alarmSnapshotRes AlarmSnapshotListResponse
  37. // 反序列化(unmarshal)
  38. jsonErr := json.Unmarshal(resByte, &alarmSnapshotRes)
  39. if jsonErr != nil {
  40. return 0, nil, fmt.Errorf("[handleAlarmSnapshot] %s", jsonErr)
  41. }
  42. return alarmSnapshotRes.Total, alarmSnapshotRes.Result, nil
  43. }
  44. // 获取告警快照
  45. // 从FHW后端请求快照文件后,处理并放入数据库
  46. // logTime 格式 YYYY-MM-DD
  47. func GetAlarmSnapshot(sn, logTime string) error {
  48. // 请求快照信息列表
  49. var page int = 1
  50. snapshotList := make([]AlarmSnapshotInfo, 0)
  51. total, dataList, err := handleAlarmSnapshot(sn, logTime, page)
  52. if err != nil {
  53. return fmt.Errorf("[GetAlarmSnapshot] %s", err.Error())
  54. }
  55. snapshotList = append(snapshotList, dataList...)
  56. for uint64(len(snapshotList)) < total {
  57. page = page + 1
  58. _, dataList, err = handleAlarmSnapshot(sn, logTime, page)
  59. if err != nil {
  60. return fmt.Errorf("[GetAlarmSnapshot] %s", err.Error())
  61. }
  62. snapshotList = append(snapshotList, dataList...)
  63. }
  64. // 创建临时目录存储下载和解压数据
  65. tempDir, err := os.MkdirTemp("", "fwhtb-alarmSnapshot-*")
  66. if err != nil {
  67. logger.Std.Printf("创建临时目录失败: %v\n", err)
  68. return err
  69. }
  70. defer os.RemoveAll(tempDir) // 程序结束时清理临时目录
  71. for _, info := range snapshotList {
  72. snapFileName := filepath.Join(tempDir, info.FileName)
  73. // 下载快照文件
  74. if err = files.DownloadFile(info.FileUrl, snapFileName); err != nil {
  75. zap.L().Error("快照文件下载失败。", zap.String("err", err.Error()))
  76. return err
  77. }
  78. // 创建解压目标文件夹
  79. snapDir := filepath.Join(tempDir, fmt.Sprintf("AlarmSnapshot_%d", info.Id))
  80. if err = files.CheckAndCreateDir(snapDir); err != nil {
  81. zap.L().Error("文件夹创建失败", zap.String("err", err.Error()))
  82. return err
  83. }
  84. // 解压包文件
  85. if err = files.AutoExtract(snapFileName, snapDir); err != nil {
  86. zap.L().Error("解压快照包失败", zap.String("err", err.Error()))
  87. return err
  88. }
  89. // 包文件有两个版本:
  90. // 1 - 包中文件内容为字符串,直接读取即可
  91. // 2 - 包中数据为16进制数据,须配合VID/PID表解析
  92. // 判断包类型
  93. // TODO
  94. // 解析文件并写入数据库
  95. }
  96. return nil
  97. }
  98. func downloadAlarmSnapshotFile(url, filepath string) error {
  99. // 发送 HTTP GET 请求
  100. resp, err := http.Get(url)
  101. if err != nil {
  102. return err
  103. }
  104. defer resp.Body.Close()
  105. // 创建本地文件
  106. out, err := os.Create(filepath)
  107. if err != nil {
  108. return err
  109. }
  110. defer out.Close()
  111. // 将响应内容写入文件
  112. _, err = io.Copy(out, resp.Body)
  113. return err
  114. }