更新前后端代码
This commit is contained in:
@@ -0,0 +1,110 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"filestoragesystem/internal/config"
|
||||
"filestoragesystem/internal/model"
|
||||
"filestoragesystem/internal/repository"
|
||||
"filestoragesystem/pkg/apperr"
|
||||
)
|
||||
|
||||
// ProjectService 项目服务
|
||||
type ProjectService struct {
|
||||
cfg *config.Config
|
||||
projectRepo *repository.ProjectRepo
|
||||
fileRepo *repository.FileRepo
|
||||
settingRepo *repository.SettingRepo
|
||||
opLogRepo *repository.OpLogRepo
|
||||
webhookSvc *WebhookService
|
||||
}
|
||||
|
||||
// Create 创建项目
|
||||
func (s *ProjectService) Create(userID uint, name, description string, storageLimit int64) (*model.Project, error) {
|
||||
if name == "" || len(name) > 100 {
|
||||
return nil, fmt.Errorf("项目名称不能为空且不超过100字符")
|
||||
}
|
||||
if _, err := s.projectRepo.FindByName(userID, name); err == nil {
|
||||
return nil, apperr.ErrProjectExists
|
||||
}
|
||||
if storageLimit <= 0 {
|
||||
storageLimit = 5368709120 // 5GB
|
||||
if v, err := s.settingRepo.GetValue("default_project_limit"); err == nil {
|
||||
var n int64
|
||||
if _, e := fmt.Sscanf(v, "%d", &n); e == nil && n > 0 {
|
||||
storageLimit = n
|
||||
}
|
||||
}
|
||||
}
|
||||
p := &model.Project{
|
||||
UserID: userID, Name: name, Description: description,
|
||||
StorageLimit: storageLimit, Status: 1,
|
||||
}
|
||||
if err := s.projectRepo.Create(p); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return p, nil
|
||||
}
|
||||
|
||||
// List 项目列表,all=true时管理员查看全部
|
||||
func (s *ProjectService) List(userID uint, keyword string, all bool, page, pageSize int) ([]model.Project, int64, error) {
|
||||
return s.projectRepo.List(userID, keyword, all, page, pageSize)
|
||||
}
|
||||
|
||||
// Get 项目详情(所有者或管理员)
|
||||
func (s *ProjectService) Get(userID uint, id uint, isAdmin bool) (*model.Project, error) {
|
||||
p, err := s.projectRepo.FindByID(id)
|
||||
if err != nil {
|
||||
return nil, apperr.ErrNotFound
|
||||
}
|
||||
if !isAdmin && p.UserID != userID {
|
||||
return nil, apperr.ErrForbidden
|
||||
}
|
||||
return p, nil
|
||||
}
|
||||
|
||||
// Update 更新项目
|
||||
func (s *ProjectService) Update(userID uint, id uint, isAdmin bool, name, description string, storageLimit int64) (*model.Project, error) {
|
||||
p, err := s.Get(userID, id, isAdmin)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if name != "" && name != p.Name {
|
||||
if _, err := s.projectRepo.FindByName(userID, name); err == nil {
|
||||
return nil, apperr.ErrProjectExists
|
||||
}
|
||||
p.Name = name
|
||||
}
|
||||
if description != "" {
|
||||
p.Description = description
|
||||
}
|
||||
if storageLimit > 0 {
|
||||
p.StorageLimit = storageLimit
|
||||
}
|
||||
if err := s.projectRepo.Update(p); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return p, nil
|
||||
}
|
||||
|
||||
// Delete 删除项目及其全部文件(硬删除)
|
||||
func (s *ProjectService) Delete(userID uint, id uint, isAdmin bool) error {
|
||||
if _, err := s.Get(userID, id, isAdmin); err != nil {
|
||||
return err
|
||||
}
|
||||
// 删除物理文件
|
||||
files, _ := s.fileRepo.ListByProject(id)
|
||||
seen := make(map[string]bool)
|
||||
for _, f := range files {
|
||||
if f.StoredPath != "" && !seen[f.StoredPath] {
|
||||
seen[f.StoredPath] = true
|
||||
_ = os.Remove(filepath.Join(s.cfg.Storage.Root, f.StoredPath))
|
||||
}
|
||||
}
|
||||
_ = s.fileRepo.DB.Exec("DELETE FROM files WHERE project_id = ?", id).Error
|
||||
_ = s.fileRepo.DB.Exec("DELETE FROM temp_links WHERE file_id IN (SELECT id FROM files WHERE project_id = ?)", id).Error
|
||||
|
||||
return s.projectRepo.Delete(id)
|
||||
}
|
||||
Reference in New Issue
Block a user