DeployHelper/internal/service/sys_deploy_project_service.go

333 lines
10 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package service
import (
"ego/internal/model"
"ego/internal/serializer"
"ego/internal/types"
"ego/pkg/logger"
"fmt"
"os"
"time"
"github.com/gin-gonic/gin"
"gorm.io/gorm"
)
// SysDeployProjectService 部署项目服务
type SysDeployProjectService struct {
Db *gorm.DB
}
// NewSysDeployProjectService 构建部署项目服务
func NewSysDeployProjectService(db *gorm.DB) *SysDeployProjectService {
return &SysDeployProjectService{
Db: db,
}
}
// Create 创建部署项目记录
func (s *SysDeployProjectService) Create(c *gin.Context) serializer.Response {
var deployProject model.SysDeployProject
if err := c.ShouldBind(&deployProject); err != nil {
logger.Error(c, "参数绑定失败!")
return serializer.ParamErr("参数绑定失败!", err)
}
// 验证必填字段
if deployProject.Domain == "" {
logger.Error(c, "域名不能为空!")
return serializer.ParamErr("域名不能为空!", fmt.Errorf("域名不能为空"))
}
// 检查域名是否已存在
var existingDeployProject model.SysDeployProject
if err := s.Db.Where("domain = ? AND del_flag = ?", deployProject.Domain, "0").First(&existingDeployProject).Error; err == nil {
logger.Error(c, "域名已存在!")
return serializer.ParamErr("域名已存在,请使用其他域名!", fmt.Errorf("域名已存在"))
}
// 生成部署ID
if id, err := SysSequenceServiceBuilder(deployProject.TableName()).GenerateId(); err == nil {
deployProject.DeployId = id
} else {
return serializer.DBErr("序列生成失败!", err)
}
// 设置默认部署路径
deployProject.DeployPath = fmt.Sprintf("/home/%s", deployProject.Domain)
// 设置默认值
now := time.Now()
deployProject.CreateTime = &now
deployProject.Status = model.DeployProjectStatusNormal
deployProject.DeployStatus = model.DeployStatusNotDeployed
deployProject.DelFlag = "0"
// 获取当前用户
if createBy := c.GetString("id"); createBy != "" {
deployProject.CreateBy = createBy
}
// 开始事务处理
tx := s.Db.Begin()
// 创建部署项目记录
if err := tx.Create(&deployProject).Error; err != nil {
tx.Rollback()
logger.Error(c, "创建部署项目记录失败!")
return serializer.DBErr("创建部署项目记录失败!", err)
}
// 如果提供了FileId则更新关联的部署文件记录的ParentId
if deployProject.FileId != "" {
// 检查文件是否存在且属于当前用户
currentUserId := c.GetString("id")
var deployFile model.SysDeployFile
if err := tx.Where("file_id = ? AND del_flag = ? AND create_by = ?",
deployProject.FileId, "0", currentUserId).First(&deployFile).Error; err != nil {
tx.Rollback()
logger.Error(c, "关联的部署文件不存在或无权限访问!")
return serializer.ParamErr("关联的部署文件不存在或无权限访问!", err)
}
// 更新部署文件的ParentId为当前项目的DeployId
if err := tx.Model(&model.SysDeployFile{}).Where("file_id = ?", deployProject.FileId).
Updates(map[string]interface{}{
"parent_id": deployProject.DeployId,
"update_time": time.Now(),
"update_by": currentUserId,
}).Error; err != nil {
tx.Rollback()
logger.Error(c, "更新部署文件关联信息失败!")
return serializer.DBErr("更新部署文件关联信息失败!", err)
}
}
// 提交事务
tx.Commit()
return serializer.Succ("创建部署项目记录成功!", deployProject)
}
// GetByID 根据ID获取部署项目记录
func (s *SysDeployProjectService) GetByID(c *gin.Context) serializer.Response {
// 获取当前用户ID
currentUserId := c.GetString("id")
if currentUserId == "" {
return serializer.ParamErr("用户信息获取失败!", nil)
}
var deployProject model.SysDeployProject
if err := s.Db.Where("deploy_id = ? AND del_flag = ? AND create_by = ?", c.Param("id"), "0", currentUserId).First(&deployProject).Error; err != nil {
logger.Error(c, "获取部署项目记录失败!")
return serializer.DBErr("获取部署项目记录失败!", err)
}
return serializer.Succ("查询成功!", deployProject)
}
// UpdateByID 根据ID更新部署项目记录
func (s *SysDeployProjectService) UpdateByID(c *gin.Context) serializer.Response {
var deployProject model.SysDeployProject
if err := c.ShouldBind(&deployProject); err != nil {
logger.Error(c, "参数绑定失败!")
return serializer.ParamErr("参数绑定失败!", err)
}
id := deployProject.DeployId
if id == "" {
logger.Error(c, "id 不可为空!")
return serializer.ParamErr("id不可为空!", fmt.Errorf("id不可为空"))
}
// 获取当前用户ID
currentUserId := c.GetString("id")
if currentUserId == "" {
return serializer.ParamErr("用户信息获取失败!", nil)
}
// 检查权限:只能更新自己创建的数据
var existingDeployProject model.SysDeployProject
if err := s.Db.Where("deploy_id = ? AND del_flag = ? AND create_by = ?", id, "0", currentUserId).First(&existingDeployProject).Error; err != nil {
logger.Error(c, "部署项目记录不存在或无权限访问!")
return serializer.ParamErr("部署项目记录不存在或无权限访问!", err)
}
// 设置更新时间
now := time.Now()
deployProject.UpdateTime = &now
// 获取当前用户
deployProject.UpdateBy = currentUserId
if err := s.Db.Model(&deployProject).Where("deploy_id = ? AND del_flag = ? AND create_by = ?", id, "0", currentUserId).Updates(&deployProject).Error; err != nil {
logger.Error(c, "更新部署项目记录失败!")
return serializer.DBErr("更新部署项目记录失败!", err)
}
return serializer.Succ("更新部署项目记录成功!", deployProject)
}
// DeleteByID 根据ID删除部署项目记录
func (s *SysDeployProjectService) DeleteByID(c *gin.Context) serializer.Response {
id := c.Param("id")
if id == "" {
logger.Error(c, "id 不可为空!")
return serializer.ParamErr("id不可为空!", fmt.Errorf("id不可为空"))
}
// 获取当前用户ID
currentUserId := c.GetString("id")
if currentUserId == "" {
return serializer.ParamErr("用户信息获取失败!", nil)
}
// 开始事务处理
tx := s.Db.Begin()
// 获取要删除的项目信息
deployProject := model.SysDeployProject{}
if err := tx.Where("deploy_id = ? AND create_by = ?", id, currentUserId).First(&deployProject).Error; err != nil {
tx.Rollback()
logger.Error(c, "获取部署项目记录失败或无权限访问!")
return serializer.DBErr("获取部署项目记录失败或无权限访问!", err)
}
// 删除 /home/:domain 目录
err := os.RemoveAll(deployProject.DeployPath)
if err != nil {
tx.Rollback()
logger.Error(c, "删除部署文件夹失败!")
return serializer.DBErr("删除部署文件夹失败!", err)
}
// 软删除关联的文件记录
fileData := map[string]any{
"del_flag": "1",
"update_time": time.Now(),
"update_by": currentUserId,
}
if err := tx.Model(&model.SysDeployFile{}).Where("parent_id = ?", id).Updates(fileData).Error; err != nil {
tx.Rollback()
logger.Error(c, "删除关联文件记录失败!")
return serializer.DBErr("删除关联文件记录失败!", err)
}
// 软删除项目记录
projectData := map[string]any{
"del_flag": "1",
"update_time": time.Now(),
"update_by": currentUserId,
}
if err := tx.Model(&model.SysDeployProject{}).Where("deploy_id = ? AND create_by = ?", id, currentUserId).Updates(projectData).Error; err != nil {
tx.Rollback()
logger.Error(c, "删除部署项目记录失败!")
return serializer.DBErr("删除部署项目记录失败!", err)
}
// 提交事务
tx.Commit()
return serializer.Succ("删除部署项目记录成功!", nil)
}
// GetByCondition 条件查询部署项目记录
func (s *SysDeployProjectService) 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 deployProjects []model.SysDeployProject
offset := (p.Page - 1) * p.Limit
// 获取当前用户ID
currentUserId := c.GetString("id")
if currentUserId == "" {
return serializer.ParamErr("用户信息获取失败!", nil)
}
// 构建基础查询
db := s.Db.Model(&model.SysDeployProject{})
// 如果有查询条件,添加条件
if queryStr != "" {
db = db.Where(queryStr, args...)
}
// 添加用户权限过滤:只能查询自己创建的数据
db = db.Where("create_by = ?", currentUserId)
// 排序
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(&deployProjects).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": deployProjects,
"page": p.Page,
"limit": p.Limit,
})
}
// UpdateDeployStatus 更新部署状态
func (s *SysDeployProjectService) UpdateDeployStatus(deployId, status, errorMsg string) error {
data := map[string]any{
"deploy_status": status,
"update_time": time.Now(),
}
if status == model.DeployStatusSuccess {
now := time.Now()
data["deploy_time"] = &now
}
if errorMsg != "" {
data["error_msg"] = errorMsg
}
return s.Db.Model(&model.SysDeployProject{}).Where("deploy_id = ?", deployId).Updates(data).Error
}
// UpdateAccessInfo 更新访问信息
func (s *SysDeployProjectService) UpdateAccessInfo(deployId string) error {
now := time.Now()
return s.Db.Model(&model.SysDeployProject{}).
Where("deploy_id = ?", deployId).
Updates(map[string]any{
"last_access_time": &now,
"access_count": gorm.Expr("access_count + 1"),
}).Error
}
// GetByDomain 根据域名获取部署项目记录
func (s *SysDeployProjectService) GetByDomain(domain string) (*model.SysDeployProject, error) {
var deployProject model.SysDeployProject
err := s.Db.Where("domain = ? AND status = ? AND del_flag = ?",
domain, model.DeployProjectStatusNormal, "0").First(&deployProject).Error
if err != nil {
return nil, err
}
return &deployProject, nil
}