| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109 |
- // Code scaffolded by goctl. Safe to edit.
- // goctl 1.10.2
- package systemlog
- import (
- "archive/zip"
- "context"
- "fmt"
- "io"
- "net/http"
- "os"
- "path/filepath"
- "udeServer/internal/apierr"
- "udeServer/internal/log"
- "udeServer/internal/svc"
- "udeServer/internal/types"
- "github.com/zeromicro/go-zero/core/logx"
- )
- type LogArchiveDownloadLogic struct {
- logx.Logger
- ctx context.Context
- svcCtx *svc.ServiceContext
- }
- // 归档打包下载(zip)
- func NewLogArchiveDownloadLogic(ctx context.Context, svcCtx *svc.ServiceContext) *LogArchiveDownloadLogic {
- return &LogArchiveDownloadLogic{
- Logger: logx.WithContext(ctx),
- ctx: ctx,
- svcCtx: svcCtx,
- }
- }
- // LogArchiveDownload streams the selected archive files back as one zip.
- // The response is written to w directly (no unified envelope); the handler
- // therefore must not call httpx.OkJsonCtx afterwards.
- func (l *LogArchiveDownloadLogic) LogArchiveDownload(w http.ResponseWriter, req *types.LogArchiveDownloadReq) error {
- if len(req.Ids) == 0 {
- return apierr.BadRequest("ids 不能为空")
- }
- if l.svcCtx.MinioClient == nil {
- return apierr.New(500, "MinIO客户端未加载,无法下载归档(检查t_config的file_*配置)")
- }
- log.RecordDebug(l.ctx, "开始下载Ids:%+v的归档!", req.Ids)
- list, err := l.svcCtx.LogArchiveRecordModel.FindByIds(l.ctx, req.Ids)
- if err != nil {
- log.RecordError(l.ctx, err)
- return apierr.New(500, "查询归档记录失败")
- }
- if len(list) == 0 {
- return apierr.New(404, "归档记录不存在")
- }
- w.Header().Set("Content-Type", "application/zip")
- w.Header().Set("Content-Disposition", "attachment; filename=archives.zip")
- zipWriter := zip.NewWriter(w)
- defer func() {
- _ = zipWriter.Close()
- }()
- for i := range list {
- v := &list[i]
- filePath, err := l.svcCtx.MinioClient.DownloadFile(l.ctx, v.ArchiveFileKey)
- if err != nil || filePath == "" {
- log.RecordError(l.ctx, fmt.Errorf("下载归档文件失败[ID:%d]: %v", v.Id, err))
- return apierr.New(500, "下载归档文件失败")
- }
- if err := copyArchiveIntoZip(zipWriter, filePath, v.ArchiveFileKey); err != nil {
- log.RecordError(l.ctx, err)
- }
- }
- log.RecordDebug(l.ctx, "Ids:%+v的归档下载成功!", req.Ids)
- return nil
- }
- // copyArchiveIntoZip adds one archive file as a zip entry (temp file removed
- // afterwards).
- func copyArchiveIntoZip(zipWriter *zip.Writer, filePath, archiveFileKey string) error {
- // 1.删除临时文件
- defer func() {
- _ = os.Remove(filePath)
- }()
- // 2.打开文件
- file, err := os.Open(filePath)
- if err != nil {
- return fmt.Errorf("打开文件失败[%s]: %w", archiveFileKey, err)
- }
- defer func() {
- _ = file.Close()
- }()
- // 3.文件打包
- zipFileName := filepath.Base(archiveFileKey)
- zipEntryWriter, err := zipWriter.Create(zipFileName)
- if err != nil {
- return fmt.Errorf("创建ZIP条目失败[%s]: %w", archiveFileKey, err)
- }
- if _, err := io.Copy(zipEntryWriter, file); err != nil {
- return fmt.Errorf("写入ZIP条目失败[%s]: %w", archiveFileKey, err)
- }
- return nil
- }
|