2025-08-01 16:38:08 +08:00
|
|
|
|
package service
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"crypto/md5"
|
|
|
|
|
"ego/internal/model"
|
|
|
|
|
"ego/internal/serializer"
|
|
|
|
|
"ego/internal/types"
|
|
|
|
|
"ego/pkg/logger"
|
|
|
|
|
"fmt"
|
|
|
|
|
"io"
|
2025-08-01 16:59:47 +08:00
|
|
|
|
"os"
|
|
|
|
|
"path/filepath"
|
2025-08-06 11:38:16 +08:00
|
|
|
|
"strings"
|
2025-08-01 16:38:08 +08:00
|
|
|
|
"time"
|
|
|
|
|
|
|
|
|
|
"github.com/gin-gonic/gin"
|
|
|
|
|
"gorm.io/gorm"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// SysDeployFileService 部署文件服务
|
|
|
|
|
type SysDeployFileService struct {
|
|
|
|
|
Db *gorm.DB
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// NewSysDeployFileService 构建部署文件服务
|
|
|
|
|
func NewSysDeployFileService(db *gorm.DB) *SysDeployFileService {
|
|
|
|
|
return &SysDeployFileService{
|
|
|
|
|
Db: db,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Create 创建部署文件记录
|
|
|
|
|
func (s *SysDeployFileService) Create(c *gin.Context) serializer.Response {
|
2025-08-06 11:38:16 +08:00
|
|
|
|
// 获取上传的文件
|
|
|
|
|
file, err := c.FormFile("file")
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error(c, "获取上传文件失败!")
|
|
|
|
|
return serializer.ParamErr("获取上传文件失败!", err)
|
2025-08-01 16:38:08 +08:00
|
|
|
|
}
|
|
|
|
|
|
2025-08-06 11:38:16 +08:00
|
|
|
|
// 校验文件类型
|
|
|
|
|
if !strings.HasSuffix(strings.ToLower(file.Filename), ".zip") {
|
|
|
|
|
logger.Error(c, "只支持zip格式文件!")
|
|
|
|
|
return serializer.ParamErr("只支持zip格式文件!", nil)
|
2025-08-04 13:16:05 +08:00
|
|
|
|
}
|
|
|
|
|
|
2025-08-06 11:38:16 +08:00
|
|
|
|
// 获取文件名(不包含扩展名)
|
|
|
|
|
filename := strings.TrimSuffix(file.Filename, filepath.Ext(file.Filename))
|
|
|
|
|
var deployFile model.SysDeployFile
|
|
|
|
|
deployFile.FileName = filename
|
2025-08-04 13:16:05 +08:00
|
|
|
|
|
2025-08-06 11:38:16 +08:00
|
|
|
|
// 生成文件ID
|
2025-08-01 16:38:08 +08:00
|
|
|
|
if id, err := SysSequenceServiceBuilder(deployFile.TableName()).GenerateId(); err == nil {
|
2025-08-06 11:38:16 +08:00
|
|
|
|
deployFile.FileId = id
|
2025-08-01 16:38:08 +08:00
|
|
|
|
} else {
|
|
|
|
|
return serializer.DBErr("序列生成失败!", err)
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-06 11:38:16 +08:00
|
|
|
|
// 生成新的文件名:使用文件ID + .zip 后缀
|
|
|
|
|
newFileName := deployFile.FileId + ".zip"
|
|
|
|
|
// 设置文件保存路径
|
|
|
|
|
deployFile.FilePath = filepath.Join("/data", newFileName)
|
|
|
|
|
|
|
|
|
|
// 保存文件到指定路径
|
|
|
|
|
if err := c.SaveUploadedFile(file, deployFile.FilePath); err != nil {
|
|
|
|
|
logger.Error(c, "保存文件失败!")
|
|
|
|
|
return serializer.ParamErr("保存文件失败!", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 打开保存的文件以计算哈希值
|
|
|
|
|
savedFile, err := os.Open(deployFile.FilePath)
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error(c, "打开保存的文件失败!")
|
|
|
|
|
return serializer.ParamErr("打开保存的文件失败!", err)
|
|
|
|
|
}
|
|
|
|
|
defer savedFile.Close()
|
|
|
|
|
|
|
|
|
|
// 计算文件哈希值
|
|
|
|
|
deployFile.FileHash, err = s.CalculateFileHash(savedFile)
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error(c, "计算文件哈希值失败!")
|
|
|
|
|
return serializer.ParamErr("计算文件哈希值失败!", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 获取文件大小(从保存的文件获取更准确)
|
|
|
|
|
fileInfo, err := savedFile.Stat()
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error(c, "获取文件信息失败!")
|
|
|
|
|
return serializer.ParamErr("获取文件信息失败!", err)
|
|
|
|
|
}
|
|
|
|
|
deployFile.FileSize = fileInfo.Size()
|
|
|
|
|
|
2025-08-01 16:38:08 +08:00
|
|
|
|
// 设置默认值
|
|
|
|
|
now := time.Now()
|
|
|
|
|
deployFile.CreateTime = &now
|
2025-08-06 11:38:16 +08:00
|
|
|
|
deployFile.Status = model.FileStatusNotUsed
|
2025-08-01 16:38:08 +08:00
|
|
|
|
deployFile.DelFlag = "0"
|
|
|
|
|
|
|
|
|
|
// 获取当前用户
|
|
|
|
|
if createBy := c.GetString("id"); createBy != "" {
|
|
|
|
|
deployFile.CreateBy = createBy
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if err := s.Db.Create(&deployFile).Error; err != nil {
|
|
|
|
|
logger.Error(c, "创建部署文件记录失败!")
|
|
|
|
|
return serializer.DBErr("创建部署文件记录失败!", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return serializer.Succ("创建部署文件记录成功!", deployFile)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// GetByID 根据ID获取部署文件记录
|
|
|
|
|
func (s *SysDeployFileService) GetByID(c *gin.Context) serializer.Response {
|
2025-08-04 09:55:20 +08:00
|
|
|
|
// 获取当前用户ID
|
|
|
|
|
currentUserId := c.GetString("id")
|
|
|
|
|
if currentUserId == "" {
|
|
|
|
|
return serializer.ParamErr("用户信息获取失败!", nil)
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-01 16:38:08 +08:00
|
|
|
|
var deployFile model.SysDeployFile
|
2025-08-06 11:38:16 +08:00
|
|
|
|
if err := s.Db.Where("file_id = ? AND del_flag = ? AND create_by = ?", c.Param("id"), "0", currentUserId).First(&deployFile).Error; err != nil {
|
2025-08-01 16:38:08 +08:00
|
|
|
|
logger.Error(c, "获取部署文件记录失败!")
|
|
|
|
|
return serializer.DBErr("获取部署文件记录失败!", err)
|
|
|
|
|
}
|
|
|
|
|
return serializer.Succ("查询成功!", deployFile)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// UpdateByID 根据ID更新部署文件记录
|
|
|
|
|
func (s *SysDeployFileService) UpdateByID(c *gin.Context) serializer.Response {
|
|
|
|
|
var deployFile model.SysDeployFile
|
|
|
|
|
if err := c.ShouldBind(&deployFile); err != nil {
|
|
|
|
|
logger.Error(c, "参数绑定失败!")
|
|
|
|
|
return serializer.ParamErr("参数绑定失败!", err)
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-06 11:38:16 +08:00
|
|
|
|
id := deployFile.FileId
|
2025-08-01 16:38:08 +08:00
|
|
|
|
if id == "" {
|
|
|
|
|
logger.Error(c, "id 不可为空!")
|
|
|
|
|
return serializer.ParamErr("id不可为空!", fmt.Errorf("id不可为空"))
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-06 11:38:16 +08:00
|
|
|
|
if deployFile.ParentId == "" {
|
|
|
|
|
logger.Error(c, "项目ID不能为空!")
|
|
|
|
|
return serializer.ParamErr("项目ID不能为空!", fmt.Errorf("项目ID不能为空"))
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-04 09:55:20 +08:00
|
|
|
|
// 获取当前用户ID
|
|
|
|
|
currentUserId := c.GetString("id")
|
|
|
|
|
if currentUserId == "" {
|
|
|
|
|
return serializer.ParamErr("用户信息获取失败!", nil)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 检查权限:只能更新自己创建的数据
|
|
|
|
|
var existingDeployFile model.SysDeployFile
|
2025-08-06 11:38:16 +08:00
|
|
|
|
if err := s.Db.Where("file_id = ? AND del_flag = ? AND create_by = ?", id, "0", currentUserId).First(&existingDeployFile).Error; err != nil {
|
2025-08-04 09:55:20 +08:00
|
|
|
|
logger.Error(c, "部署文件记录不存在或无权限访问!")
|
|
|
|
|
return serializer.ParamErr("部署文件记录不存在或无权限访问!", err)
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-01 16:38:08 +08:00
|
|
|
|
// 设置更新时间
|
|
|
|
|
now := time.Now()
|
|
|
|
|
deployFile.UpdateTime = &now
|
|
|
|
|
|
|
|
|
|
// 获取当前用户
|
2025-08-04 10:10:52 +08:00
|
|
|
|
deployFile.UpdateBy = currentUserId
|
2025-08-01 16:38:08 +08:00
|
|
|
|
|
2025-08-06 11:38:16 +08:00
|
|
|
|
if err := s.Db.Model(&deployFile).Where("file_id = ? AND del_flag = ? AND create_by = ?", id, "0", currentUserId).Updates(&deployFile).Error; err != nil {
|
2025-08-01 16:38:08 +08:00
|
|
|
|
logger.Error(c, "更新部署文件记录失败!")
|
|
|
|
|
return serializer.DBErr("更新部署文件记录失败!", err)
|
|
|
|
|
}
|
|
|
|
|
return serializer.Succ("更新部署文件记录成功!", deployFile)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// DeleteByID 根据ID删除部署文件记录
|
|
|
|
|
func (s *SysDeployFileService) DeleteByID(c *gin.Context) serializer.Response {
|
|
|
|
|
id := c.Param("id")
|
|
|
|
|
if id == "" {
|
|
|
|
|
logger.Error(c, "id 不可为空!")
|
|
|
|
|
return serializer.ParamErr("id不可为空!", fmt.Errorf("id不可为空"))
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-04 09:55:20 +08:00
|
|
|
|
// 获取当前用户ID
|
|
|
|
|
currentUserId := c.GetString("id")
|
|
|
|
|
if currentUserId == "" {
|
|
|
|
|
return serializer.ParamErr("用户信息获取失败!", nil)
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-01 16:38:08 +08:00
|
|
|
|
// 软删除
|
|
|
|
|
data := map[string]any{
|
|
|
|
|
"del_flag": "1",
|
|
|
|
|
"update_time": time.Now(),
|
2025-08-04 09:55:20 +08:00
|
|
|
|
"update_by": currentUserId,
|
2025-08-01 16:38:08 +08:00
|
|
|
|
}
|
|
|
|
|
|
2025-08-01 16:59:47 +08:00
|
|
|
|
// 删除数据库记录
|
2025-08-06 11:38:16 +08:00
|
|
|
|
if err := s.Db.Model(&model.SysDeployFile{}).Where("file_id = ? AND create_by = ?", id, currentUserId).Updates(data).Error; err != nil {
|
2025-08-01 16:38:08 +08:00
|
|
|
|
logger.Error(c, "删除部署文件记录失败!")
|
|
|
|
|
return serializer.DBErr("删除部署文件记录失败!", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return serializer.Succ("删除部署文件记录成功!", nil)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// GetByCondition 条件查询部署文件记录
|
|
|
|
|
func (s *SysDeployFileService) GetByCondition(c *gin.Context) serializer.Response {
|
|
|
|
|
var p types.Params
|
|
|
|
|
if err := c.ShouldBind(&p); err != nil {
|
|
|
|
|
return serializer.ParamErr("参数绑定失败!", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
queryStr, args, err := p.ConvertToGormConditions()
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error(c, "参数绑定失败!")
|
|
|
|
|
return serializer.ParamErr("参数绑定失败!", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var total int64
|
|
|
|
|
var deployFiles []model.SysDeployFile
|
|
|
|
|
offset := (p.Page - 1) * p.Limit
|
|
|
|
|
|
2025-08-04 09:55:20 +08:00
|
|
|
|
// 获取当前用户ID
|
|
|
|
|
currentUserId := c.GetString("id")
|
|
|
|
|
if currentUserId == "" {
|
|
|
|
|
return serializer.ParamErr("用户信息获取失败!", nil)
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-01 16:38:08 +08:00
|
|
|
|
// 构建基础查询
|
|
|
|
|
db := s.Db.Model(&model.SysDeployFile{})
|
|
|
|
|
|
|
|
|
|
// 如果有查询条件,添加条件
|
|
|
|
|
if queryStr != "" {
|
|
|
|
|
db = db.Where(queryStr, args...)
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-04 09:55:20 +08:00
|
|
|
|
// 添加用户权限过滤:只能查询自己创建的数据
|
|
|
|
|
db = db.Where("create_by = ?", currentUserId)
|
|
|
|
|
|
2025-08-01 16:38:08 +08:00
|
|
|
|
// 排序
|
|
|
|
|
if p.Sort != "" {
|
|
|
|
|
db = db.Order(p.Sort)
|
|
|
|
|
} else {
|
|
|
|
|
db = db.Order("create_time DESC")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 执行分页查询
|
|
|
|
|
if err := db.Where("del_flag = ?", "0").Offset(offset).Limit(p.Limit).Find(&deployFiles).Error; err != nil {
|
|
|
|
|
logger.Error(c, "获取部署文件记录失败!")
|
|
|
|
|
return serializer.DBErr("获取部署文件记录失败!", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 执行总数查询
|
|
|
|
|
if err := db.Where("del_flag = ?", "0").Count(&total).Error; err != nil {
|
|
|
|
|
logger.Error(c, "获取部署文件记录总数失败!")
|
|
|
|
|
return serializer.DBErr("获取部署文件记录总数失败!", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return serializer.Succ("查询成功!", gin.H{
|
|
|
|
|
"total": total,
|
|
|
|
|
"items": deployFiles,
|
|
|
|
|
"page": p.Page,
|
|
|
|
|
"limit": p.Limit,
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-06 11:38:16 +08:00
|
|
|
|
// GetByParentID 根据项目ID获取文件列表
|
|
|
|
|
func (s *SysDeployFileService) GetByParentID(c *gin.Context) serializer.Response {
|
|
|
|
|
parentId := c.Param("parentId")
|
|
|
|
|
if parentId == "" {
|
|
|
|
|
logger.Error(c, "项目ID不可为空!")
|
|
|
|
|
return serializer.ParamErr("项目ID不可为空!", fmt.Errorf("项目ID不可为空"))
|
2025-08-01 16:38:08 +08:00
|
|
|
|
}
|
|
|
|
|
|
2025-08-06 11:38:16 +08:00
|
|
|
|
// 获取当前用户ID
|
|
|
|
|
currentUserId := c.GetString("id")
|
|
|
|
|
if currentUserId == "" {
|
|
|
|
|
return serializer.ParamErr("用户信息获取失败!", nil)
|
2025-08-01 16:38:08 +08:00
|
|
|
|
}
|
|
|
|
|
|
2025-08-06 11:38:16 +08:00
|
|
|
|
var deployFiles []model.SysDeployFile
|
|
|
|
|
if err := s.Db.Where("parent_id = ? AND del_flag = ? AND create_by = ?", parentId, "0", currentUserId).
|
|
|
|
|
Order("create_time DESC").Find(&deployFiles).Error; err != nil {
|
|
|
|
|
logger.Error(c, "获取文件列表失败!")
|
|
|
|
|
return serializer.DBErr("获取文件列表失败!", err)
|
2025-08-01 16:38:08 +08:00
|
|
|
|
}
|
|
|
|
|
|
2025-08-06 11:38:16 +08:00
|
|
|
|
return serializer.Succ("查询成功!", deployFiles)
|
2025-08-01 16:38:08 +08:00
|
|
|
|
}
|
|
|
|
|
|
2025-08-06 11:38:16 +08:00
|
|
|
|
// SetActiveFile 设置活跃文件
|
|
|
|
|
func (s *SysDeployFileService) SetActiveFile(c *gin.Context) serializer.Response {
|
|
|
|
|
fileId := c.Param("id")
|
|
|
|
|
if fileId == "" {
|
|
|
|
|
logger.Error(c, "文件ID不可为空!")
|
|
|
|
|
return serializer.ParamErr("文件ID不可为空!", fmt.Errorf("文件ID不可为空"))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 获取当前用户ID
|
|
|
|
|
currentUserId := c.GetString("id")
|
|
|
|
|
if currentUserId == "" {
|
|
|
|
|
return serializer.ParamErr("用户信息获取失败!", nil)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 获取文件信息
|
|
|
|
|
var deployFile model.SysDeployFile
|
|
|
|
|
if err := s.Db.Where("file_id = ? AND del_flag = ? AND create_by = ?", fileId, "0", currentUserId).First(&deployFile).Error; err != nil {
|
|
|
|
|
logger.Error(c, "文件不存在或无权限访问!")
|
|
|
|
|
return serializer.ParamErr("文件不存在或无权限访问!", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 开始事务
|
|
|
|
|
tx := s.Db.Begin()
|
|
|
|
|
|
|
|
|
|
// 将同项目下的其他文件设为未使用状态
|
|
|
|
|
if err := tx.Model(&model.SysDeployFile{}).
|
|
|
|
|
Where("parent_id = ? AND del_flag = ? AND create_by = ?", deployFile.ParentId, "0", currentUserId).
|
2025-08-01 16:38:08 +08:00
|
|
|
|
Updates(map[string]any{
|
2025-08-06 11:38:16 +08:00
|
|
|
|
"status": model.FileStatusNotUsed,
|
|
|
|
|
"update_time": time.Now(),
|
|
|
|
|
"update_by": currentUserId,
|
|
|
|
|
}).Error; err != nil {
|
|
|
|
|
tx.Rollback()
|
|
|
|
|
logger.Error(c, "更新文件状态失败!")
|
|
|
|
|
return serializer.DBErr("更新文件状态失败!", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 将当前文件设为使用中状态
|
|
|
|
|
if err := tx.Model(&model.SysDeployFile{}).
|
|
|
|
|
Where("file_id = ?", fileId).
|
|
|
|
|
Updates(map[string]any{
|
|
|
|
|
"status": model.FileStatusInUse,
|
|
|
|
|
"update_time": time.Now(),
|
|
|
|
|
"update_by": currentUserId,
|
|
|
|
|
}).Error; err != nil {
|
|
|
|
|
tx.Rollback()
|
|
|
|
|
logger.Error(c, "设置活跃文件失败!")
|
|
|
|
|
return serializer.DBErr("设置活跃文件失败!", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tx.Commit()
|
|
|
|
|
return serializer.Succ("设置活跃文件成功!", nil)
|
2025-08-01 16:38:08 +08:00
|
|
|
|
}
|
|
|
|
|
|
2025-08-06 11:38:16 +08:00
|
|
|
|
// GetActiveFileByParentID 根据项目ID获取当前使用中的文件
|
|
|
|
|
func (s *SysDeployFileService) GetActiveFileByParentID(parentId string) (*model.SysDeployFile, error) {
|
2025-08-01 16:38:08 +08:00
|
|
|
|
var deployFile model.SysDeployFile
|
2025-08-06 11:38:16 +08:00
|
|
|
|
err := s.Db.Where("parent_id = ? AND status = ? AND del_flag = ?",
|
|
|
|
|
parentId, model.FileStatusInUse, "0").First(&deployFile).Error
|
2025-08-01 16:38:08 +08:00
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
return &deployFile, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// CalculateFileHash 计算文件哈希值
|
|
|
|
|
func (s *SysDeployFileService) CalculateFileHash(reader io.Reader) (string, error) {
|
|
|
|
|
hash := md5.New()
|
|
|
|
|
if _, err := io.Copy(hash, reader); err != nil {
|
|
|
|
|
return "", err
|
|
|
|
|
}
|
|
|
|
|
return fmt.Sprintf("%x", hash.Sum(nil)), nil
|
|
|
|
|
}
|