333 lines
10 KiB
Go
333 lines
10 KiB
Go
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
|
||
}
|