2025-12-19 17:05:09 +08:00
|
|
|
|
package product
|
|
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
|
"archive/zip"
|
|
|
|
|
|
"context"
|
|
|
|
|
|
"fmt"
|
|
|
|
|
|
"io"
|
|
|
|
|
|
"os"
|
|
|
|
|
|
"path/filepath"
|
|
|
|
|
|
"strings"
|
|
|
|
|
|
"time"
|
|
|
|
|
|
|
|
|
|
|
|
"go.uber.org/zap"
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
// UIComponentFileService UI组件文件服务接口
|
|
|
|
|
|
type UIComponentFileService interface {
|
|
|
|
|
|
// 上传并解压UI组件文件
|
|
|
|
|
|
UploadAndExtract(ctx context.Context, componentID, componentCode string, file io.Reader, filename string) error
|
|
|
|
|
|
|
|
|
|
|
|
// 批量上传UI组件文件(支持文件夹结构)
|
|
|
|
|
|
UploadMultipleFiles(ctx context.Context, componentID, componentCode string, files []io.Reader, filenames []string, paths []string) error
|
|
|
|
|
|
|
|
|
|
|
|
// 根据组件编码创建文件夹
|
|
|
|
|
|
CreateFolderByCode(componentCode string) (string, error)
|
|
|
|
|
|
|
|
|
|
|
|
// 删除组件文件夹
|
|
|
|
|
|
DeleteFolder(folderPath string) error
|
|
|
|
|
|
|
|
|
|
|
|
// 检查文件夹是否存在
|
|
|
|
|
|
FolderExists(folderPath string) bool
|
|
|
|
|
|
|
|
|
|
|
|
// 获取文件夹内容
|
|
|
|
|
|
GetFolderContent(folderPath string) ([]FileInfo, error)
|
2025-12-23 15:04:53 +08:00
|
|
|
|
|
|
|
|
|
|
// 根据组件编码和上传时间智能删除组件相关文件
|
|
|
|
|
|
DeleteFilesByComponentCode(componentCode string, uploadTime *time.Time) error
|
2025-12-19 17:05:09 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// FileInfo 文件信息
|
|
|
|
|
|
type FileInfo struct {
|
|
|
|
|
|
Name string `json:"name"`
|
|
|
|
|
|
Path string `json:"path"`
|
|
|
|
|
|
Size int64 `json:"size"`
|
|
|
|
|
|
Type string `json:"type"` // "file" or "folder"
|
|
|
|
|
|
Modified time.Time `json:"modified"`
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// UIComponentFileServiceImpl UI组件文件服务实现
|
|
|
|
|
|
type UIComponentFileServiceImpl struct {
|
|
|
|
|
|
basePath string
|
|
|
|
|
|
logger *zap.Logger
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// NewUIComponentFileService 创建UI组件文件服务
|
|
|
|
|
|
func NewUIComponentFileService(basePath string, logger *zap.Logger) UIComponentFileService {
|
|
|
|
|
|
// 确保基础路径存在
|
|
|
|
|
|
if err := os.MkdirAll(basePath, 0755); err != nil {
|
|
|
|
|
|
logger.Error("创建基础存储目录失败", zap.Error(err), zap.String("path", basePath))
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return &UIComponentFileServiceImpl{
|
|
|
|
|
|
basePath: basePath,
|
|
|
|
|
|
logger: logger,
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// UploadAndExtract 上传并解压UI组件文件
|
|
|
|
|
|
func (s *UIComponentFileServiceImpl) UploadAndExtract(ctx context.Context, componentID, componentCode string, file io.Reader, filename string) error {
|
|
|
|
|
|
// 直接使用基础路径作为文件夹路径,不再创建组件编码子文件夹
|
|
|
|
|
|
folderPath := s.basePath
|
|
|
|
|
|
|
|
|
|
|
|
// 确保基础目录存在
|
|
|
|
|
|
if err := os.MkdirAll(folderPath, 0755); err != nil {
|
|
|
|
|
|
return fmt.Errorf("创建基础目录失败: %w", err)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 保存上传的文件
|
|
|
|
|
|
filePath := filepath.Join(folderPath, filename)
|
|
|
|
|
|
savedFile, err := os.Create(filePath)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return fmt.Errorf("创建文件失败: %w", err)
|
|
|
|
|
|
}
|
|
|
|
|
|
defer savedFile.Close()
|
|
|
|
|
|
|
|
|
|
|
|
// 复制文件内容
|
|
|
|
|
|
if _, err := io.Copy(savedFile, file); err != nil {
|
|
|
|
|
|
// 删除部分写入的文件
|
|
|
|
|
|
_ = os.Remove(filePath)
|
|
|
|
|
|
return fmt.Errorf("保存文件失败: %w", err)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 仅对ZIP文件执行解压逻辑
|
|
|
|
|
|
if strings.HasSuffix(strings.ToLower(filename), ".zip") {
|
|
|
|
|
|
// 解压文件到基础目录
|
|
|
|
|
|
if err := s.extractZipFile(filePath, folderPath); err != nil {
|
|
|
|
|
|
// 删除ZIP文件
|
|
|
|
|
|
_ = os.Remove(filePath)
|
|
|
|
|
|
return fmt.Errorf("解压文件失败: %w", err)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 删除ZIP文件
|
|
|
|
|
|
_ = os.Remove(filePath)
|
|
|
|
|
|
|
|
|
|
|
|
s.logger.Info("UI组件文件上传并解压成功",
|
|
|
|
|
|
zap.String("componentID", componentID),
|
|
|
|
|
|
zap.String("componentCode", componentCode),
|
|
|
|
|
|
zap.String("folderPath", folderPath))
|
|
|
|
|
|
} else {
|
|
|
|
|
|
s.logger.Info("UI组件文件上传成功(未解压)",
|
|
|
|
|
|
zap.String("componentID", componentID),
|
|
|
|
|
|
zap.String("componentCode", componentCode),
|
|
|
|
|
|
zap.String("filePath", filePath))
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// UploadMultipleFiles 批量上传UI组件文件(支持文件夹结构)
|
|
|
|
|
|
func (s *UIComponentFileServiceImpl) UploadMultipleFiles(ctx context.Context, componentID, componentCode string, files []io.Reader, filenames []string, paths []string) error {
|
|
|
|
|
|
// 直接使用基础路径作为文件夹路径,不再创建组件编码子文件夹
|
|
|
|
|
|
folderPath := s.basePath
|
|
|
|
|
|
|
|
|
|
|
|
// 确保基础目录存在
|
|
|
|
|
|
if err := os.MkdirAll(folderPath, 0755); err != nil {
|
|
|
|
|
|
return fmt.Errorf("创建基础目录失败: %w", err)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 处理每个文件
|
|
|
|
|
|
for i, file := range files {
|
|
|
|
|
|
filename := filenames[i]
|
|
|
|
|
|
path := paths[i]
|
|
|
|
|
|
|
|
|
|
|
|
// 如果有路径信息,创建对应的子文件夹
|
|
|
|
|
|
if path != "" && path != filename {
|
|
|
|
|
|
// 获取文件所在目录
|
|
|
|
|
|
dir := filepath.Dir(path)
|
|
|
|
|
|
if dir != "." {
|
|
|
|
|
|
// 创建子文件夹
|
|
|
|
|
|
subDirPath := filepath.Join(folderPath, dir)
|
|
|
|
|
|
if err := os.MkdirAll(subDirPath, 0755); err != nil {
|
|
|
|
|
|
return fmt.Errorf("创建子文件夹失败: %w", err)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 确定文件保存路径
|
|
|
|
|
|
var filePath string
|
|
|
|
|
|
if path != "" && path != filename {
|
|
|
|
|
|
// 有路径信息,使用完整路径
|
|
|
|
|
|
filePath = filepath.Join(folderPath, path)
|
|
|
|
|
|
} else {
|
|
|
|
|
|
// 没有路径信息,直接保存在根目录
|
|
|
|
|
|
filePath = filepath.Join(folderPath, filename)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 保存上传的文件
|
|
|
|
|
|
savedFile, err := os.Create(filePath)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return fmt.Errorf("创建文件失败: %w", err)
|
|
|
|
|
|
}
|
|
|
|
|
|
defer savedFile.Close()
|
|
|
|
|
|
|
|
|
|
|
|
// 复制文件内容
|
|
|
|
|
|
if _, err := io.Copy(savedFile, file); err != nil {
|
|
|
|
|
|
// 删除部分写入的文件
|
|
|
|
|
|
_ = os.Remove(filePath)
|
|
|
|
|
|
return fmt.Errorf("保存文件失败: %w", err)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 对ZIP文件执行解压逻辑
|
|
|
|
|
|
if strings.HasSuffix(strings.ToLower(filename), ".zip") {
|
|
|
|
|
|
// 确定解压目录
|
|
|
|
|
|
var extractDir string
|
|
|
|
|
|
if path != "" && path != filename {
|
|
|
|
|
|
// 有路径信息,解压到对应目录
|
|
|
|
|
|
dir := filepath.Dir(path)
|
|
|
|
|
|
if dir != "." {
|
|
|
|
|
|
extractDir = filepath.Join(folderPath, dir)
|
|
|
|
|
|
} else {
|
|
|
|
|
|
extractDir = folderPath
|
|
|
|
|
|
}
|
|
|
|
|
|
} else {
|
|
|
|
|
|
// 没有路径信息,解压到根目录
|
|
|
|
|
|
extractDir = folderPath
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 解压文件
|
|
|
|
|
|
if err := s.extractZipFile(filePath, extractDir); err != nil {
|
|
|
|
|
|
// 删除ZIP文件
|
|
|
|
|
|
_ = os.Remove(filePath)
|
|
|
|
|
|
return fmt.Errorf("解压文件失败: %w", err)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 删除ZIP文件
|
|
|
|
|
|
_ = os.Remove(filePath)
|
|
|
|
|
|
|
|
|
|
|
|
s.logger.Info("UI组件文件上传并解压成功",
|
|
|
|
|
|
zap.String("componentID", componentID),
|
|
|
|
|
|
zap.String("componentCode", componentCode),
|
|
|
|
|
|
zap.String("filePath", filePath),
|
|
|
|
|
|
zap.String("extractDir", extractDir))
|
|
|
|
|
|
} else {
|
|
|
|
|
|
s.logger.Info("UI组件文件上传成功(未解压)",
|
|
|
|
|
|
zap.String("componentID", componentID),
|
|
|
|
|
|
zap.String("componentCode", componentCode),
|
|
|
|
|
|
zap.String("filePath", filePath))
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// CreateFolderByCode 根据组件编码创建文件夹
|
|
|
|
|
|
func (s *UIComponentFileServiceImpl) CreateFolderByCode(componentCode string) (string, error) {
|
|
|
|
|
|
folderPath := filepath.Join(s.basePath, componentCode)
|
|
|
|
|
|
|
|
|
|
|
|
// 创建文件夹(如果不存在)
|
|
|
|
|
|
if err := os.MkdirAll(folderPath, 0755); err != nil {
|
|
|
|
|
|
return "", fmt.Errorf("创建文件夹失败: %w", err)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return folderPath, nil
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// DeleteFolder 删除组件文件夹
|
|
|
|
|
|
func (s *UIComponentFileServiceImpl) DeleteFolder(folderPath string) error {
|
2025-12-23 17:17:41 +08:00
|
|
|
|
// 记录尝试删除的文件夹路径
|
|
|
|
|
|
s.logger.Info("尝试删除文件夹", zap.String("folderPath", folderPath))
|
|
|
|
|
|
|
|
|
|
|
|
// 获取文件夹信息,用于调试
|
|
|
|
|
|
if info, err := os.Stat(folderPath); err == nil {
|
|
|
|
|
|
s.logger.Info("文件夹信息",
|
|
|
|
|
|
zap.String("folderPath", folderPath),
|
|
|
|
|
|
zap.Bool("isDir", info.IsDir()),
|
|
|
|
|
|
zap.Int64("size", info.Size()),
|
|
|
|
|
|
zap.Time("modTime", info.ModTime()))
|
|
|
|
|
|
} else {
|
|
|
|
|
|
s.logger.Error("获取文件夹信息失败",
|
|
|
|
|
|
zap.Error(err),
|
|
|
|
|
|
zap.String("folderPath", folderPath))
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 检查文件夹是否存在
|
2025-12-19 17:05:09 +08:00
|
|
|
|
if !s.FolderExists(folderPath) {
|
2025-12-23 17:17:41 +08:00
|
|
|
|
s.logger.Info("文件夹不存在", zap.String("folderPath", folderPath))
|
2025-12-19 17:05:09 +08:00
|
|
|
|
return nil // 文件夹不存在,不视为错误
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-23 17:17:41 +08:00
|
|
|
|
// 尝试删除文件夹
|
|
|
|
|
|
s.logger.Info("开始删除文件夹", zap.String("folderPath", folderPath))
|
2025-12-19 17:05:09 +08:00
|
|
|
|
if err := os.RemoveAll(folderPath); err != nil {
|
2025-12-23 17:17:41 +08:00
|
|
|
|
s.logger.Error("删除文件夹失败",
|
|
|
|
|
|
zap.Error(err),
|
|
|
|
|
|
zap.String("folderPath", folderPath))
|
2025-12-19 17:05:09 +08:00
|
|
|
|
return fmt.Errorf("删除文件夹失败: %w", err)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
s.logger.Info("删除组件文件夹成功", zap.String("folderPath", folderPath))
|
|
|
|
|
|
return nil
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// FolderExists 检查文件夹是否存在
|
|
|
|
|
|
func (s *UIComponentFileServiceImpl) FolderExists(folderPath string) bool {
|
|
|
|
|
|
info, err := os.Stat(folderPath)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return false
|
|
|
|
|
|
}
|
|
|
|
|
|
return info.IsDir()
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// GetFolderContent 获取文件夹内容
|
|
|
|
|
|
func (s *UIComponentFileServiceImpl) GetFolderContent(folderPath string) ([]FileInfo, error) {
|
|
|
|
|
|
var files []FileInfo
|
|
|
|
|
|
|
|
|
|
|
|
err := filepath.Walk(folderPath, func(path string, info os.FileInfo, err error) error {
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return err
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 跳过根目录
|
|
|
|
|
|
if path == folderPath {
|
|
|
|
|
|
return nil
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 获取相对路径
|
|
|
|
|
|
relPath, err := filepath.Rel(folderPath, path)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return err
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fileType := "file"
|
|
|
|
|
|
if info.IsDir() {
|
|
|
|
|
|
fileType = "folder"
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
files = append(files, FileInfo{
|
|
|
|
|
|
Name: info.Name(),
|
|
|
|
|
|
Path: relPath,
|
|
|
|
|
|
Size: info.Size(),
|
|
|
|
|
|
Type: fileType,
|
|
|
|
|
|
Modified: info.ModTime(),
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, fmt.Errorf("扫描文件夹失败: %w", err)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return files, nil
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// extractZipFile 解压ZIP文件
|
|
|
|
|
|
func (s *UIComponentFileServiceImpl) extractZipFile(zipPath, destPath string) error {
|
|
|
|
|
|
reader, err := zip.OpenReader(zipPath)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return fmt.Errorf("打开ZIP文件失败: %w", err)
|
|
|
|
|
|
}
|
|
|
|
|
|
defer reader.Close()
|
|
|
|
|
|
|
|
|
|
|
|
for _, file := range reader.File {
|
|
|
|
|
|
path := filepath.Join(destPath, file.Name)
|
|
|
|
|
|
|
|
|
|
|
|
// 防止路径遍历攻击
|
|
|
|
|
|
if !strings.HasPrefix(filepath.Clean(path), filepath.Clean(destPath)+string(os.PathSeparator)) {
|
|
|
|
|
|
return fmt.Errorf("无效的文件路径: %s", file.Name)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if file.FileInfo().IsDir() {
|
|
|
|
|
|
// 创建目录
|
|
|
|
|
|
if err := os.MkdirAll(path, file.Mode()); err != nil {
|
|
|
|
|
|
return fmt.Errorf("创建目录失败: %w", err)
|
|
|
|
|
|
}
|
|
|
|
|
|
continue
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 创建文件
|
|
|
|
|
|
fileReader, err := file.Open()
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return fmt.Errorf("打开ZIP内文件失败: %w", err)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 确保父目录存在
|
|
|
|
|
|
if err := os.MkdirAll(filepath.Dir(path), 0755); err != nil {
|
|
|
|
|
|
fileReader.Close()
|
|
|
|
|
|
return fmt.Errorf("创建父目录失败: %w", err)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
destFile, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, file.Mode())
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
fileReader.Close()
|
|
|
|
|
|
return fmt.Errorf("创建目标文件失败: %w", err)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
_, err = io.Copy(destFile, fileReader)
|
|
|
|
|
|
fileReader.Close()
|
|
|
|
|
|
destFile.Close()
|
|
|
|
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return fmt.Errorf("写入文件失败: %w", err)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
|
}
|
2025-12-23 15:04:53 +08:00
|
|
|
|
|
|
|
|
|
|
// DeleteFilesByComponentCode 根据组件编码和上传时间智能删除组件相关文件
|
|
|
|
|
|
func (s *UIComponentFileServiceImpl) DeleteFilesByComponentCode(componentCode string, uploadTime *time.Time) error {
|
2025-12-23 17:17:41 +08:00
|
|
|
|
// 记录基础路径和组件编码
|
|
|
|
|
|
s.logger.Info("开始删除组件文件",
|
|
|
|
|
|
zap.String("basePath", s.basePath),
|
|
|
|
|
|
zap.String("componentCode", componentCode),
|
|
|
|
|
|
zap.Any("uploadTime", uploadTime))
|
|
|
|
|
|
|
2025-12-23 15:04:53 +08:00
|
|
|
|
// 1. 查找名为组件编码的文件夹
|
|
|
|
|
|
componentDir := filepath.Join(s.basePath, componentCode)
|
2025-12-23 17:17:41 +08:00
|
|
|
|
s.logger.Info("检查组件文件夹", zap.String("componentDir", componentDir))
|
|
|
|
|
|
|
2025-12-23 15:04:53 +08:00
|
|
|
|
if s.FolderExists(componentDir) {
|
2025-12-23 17:17:41 +08:00
|
|
|
|
s.logger.Info("找到组件文件夹,开始删除", zap.String("componentDir", componentDir))
|
2025-12-23 15:04:53 +08:00
|
|
|
|
if err := s.DeleteFolder(componentDir); err != nil {
|
2025-12-23 17:17:41 +08:00
|
|
|
|
s.logger.Error("删除组件文件夹失败",
|
|
|
|
|
|
zap.Error(err),
|
|
|
|
|
|
zap.String("componentCode", componentCode),
|
|
|
|
|
|
zap.String("componentDir", componentDir))
|
2025-12-23 15:04:53 +08:00
|
|
|
|
return fmt.Errorf("删除组件文件夹失败: %w", err)
|
|
|
|
|
|
}
|
|
|
|
|
|
s.logger.Info("成功删除组件文件夹", zap.String("componentCode", componentCode))
|
|
|
|
|
|
return nil
|
2025-12-23 17:17:41 +08:00
|
|
|
|
} else {
|
|
|
|
|
|
s.logger.Info("组件文件夹不存在", zap.String("componentDir", componentDir))
|
2025-12-23 15:04:53 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 2. 查找文件名包含组件编码的文件
|
2025-12-23 17:17:41 +08:00
|
|
|
|
pattern := filepath.Join(s.basePath, "*"+componentCode+"*")
|
|
|
|
|
|
s.logger.Info("查找匹配文件", zap.String("pattern", pattern))
|
|
|
|
|
|
|
|
|
|
|
|
files, err := filepath.Glob(pattern)
|
2025-12-23 15:04:53 +08:00
|
|
|
|
if err != nil {
|
2025-12-23 17:17:41 +08:00
|
|
|
|
s.logger.Error("查找组件文件失败",
|
|
|
|
|
|
zap.Error(err),
|
|
|
|
|
|
zap.String("pattern", pattern))
|
2025-12-23 15:04:53 +08:00
|
|
|
|
return fmt.Errorf("查找组件文件失败: %w", err)
|
|
|
|
|
|
}
|
2025-12-23 17:17:41 +08:00
|
|
|
|
|
|
|
|
|
|
s.logger.Info("找到匹配文件",
|
|
|
|
|
|
zap.Strings("files", files),
|
|
|
|
|
|
zap.Int("count", len(files)))
|
2025-12-23 15:04:53 +08:00
|
|
|
|
|
|
|
|
|
|
// 3. 如果没有上传时间,删除所有匹配的文件
|
|
|
|
|
|
if uploadTime == nil {
|
|
|
|
|
|
for _, file := range files {
|
|
|
|
|
|
if err := os.Remove(file); err != nil {
|
2025-12-23 17:17:41 +08:00
|
|
|
|
s.logger.Error("删除文件失败", zap.String("file", file), zap.Error(err))
|
2025-12-23 15:04:53 +08:00
|
|
|
|
} else {
|
|
|
|
|
|
s.logger.Info("成功删除文件", zap.String("file", file))
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return nil
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 4. 如果有上传时间,根据文件修改时间和上传时间的匹配度来删除文件
|
|
|
|
|
|
var deletedFiles []string
|
|
|
|
|
|
for _, file := range files {
|
|
|
|
|
|
// 获取文件信息
|
|
|
|
|
|
fileInfo, err := os.Stat(file)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
s.logger.Warn("获取文件信息失败", zap.String("file", file), zap.Error(err))
|
|
|
|
|
|
continue
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 计算文件修改时间与上传时间的差异(以秒为单位)
|
|
|
|
|
|
timeDiff := fileInfo.ModTime().Sub(*uploadTime).Seconds()
|
|
|
|
|
|
|
|
|
|
|
|
// 如果时间差在60秒内,认为是最匹配的文件
|
|
|
|
|
|
if timeDiff < 60 && timeDiff > -60 {
|
|
|
|
|
|
if err := os.Remove(file); err != nil {
|
|
|
|
|
|
s.logger.Warn("删除文件失败", zap.String("file", file), zap.Error(err))
|
|
|
|
|
|
} else {
|
|
|
|
|
|
deletedFiles = append(deletedFiles, file)
|
|
|
|
|
|
s.logger.Info("成功删除文件", zap.String("file", file),
|
|
|
|
|
|
zap.Time("uploadTime", *uploadTime),
|
|
|
|
|
|
zap.Time("fileModTime", fileInfo.ModTime()))
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 如果没有找到匹配的文件,记录警告但返回成功
|
|
|
|
|
|
if len(deletedFiles) == 0 && len(files) > 0 {
|
|
|
|
|
|
s.logger.Warn("没有找到匹配时间戳的文件",
|
|
|
|
|
|
zap.String("componentCode", componentCode),
|
|
|
|
|
|
zap.Time("uploadTime", *uploadTime),
|
|
|
|
|
|
zap.Int("foundFiles", len(files)))
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
|
}
|