297 lines
8.3 KiB
Go
297 lines
8.3 KiB
Go
package service
|
|
|
|
import (
|
|
"errors"
|
|
"sort"
|
|
|
|
"seeyon-filesystem/config"
|
|
"seeyon-filesystem/dto"
|
|
"seeyon-filesystem/model"
|
|
)
|
|
|
|
// StorageAssignService 存储策略分配服务
|
|
type StorageAssignService struct{}
|
|
|
|
func NewStorageAssignService() *StorageAssignService {
|
|
return &StorageAssignService{}
|
|
}
|
|
|
|
// UserStorageInfo 用户存储策略信息
|
|
type UserStorageInfo struct {
|
|
PolicyID uint64 // 当前使用的策略ID(最高优先级)
|
|
PolicyName string
|
|
PolicyType string
|
|
TotalQuota int64 // 总配额(所有策略叠加)
|
|
UsedStorage int64 // 已用空间
|
|
UsedPercent float64
|
|
AccessMode string
|
|
Assignments []model.StorageAssignment // 所有关联的分配规则
|
|
}
|
|
|
|
// ResolvePolicyID 确定用户上传时应使用的存储策略
|
|
// 优先级: 用户专属 > 角色(按priority排序) > 系统默认
|
|
// 多角色时取优先级最高的策略
|
|
func (s *StorageAssignService) ResolvePolicyID(userID uint64) uint64 {
|
|
assignments := s.getUserAssignments(userID)
|
|
if len(assignments) == 0 {
|
|
return uint64(config.AppConfig.Storage.DefaultPolicyID)
|
|
}
|
|
// 已按priority DESC排序, 取第一个
|
|
return assignments[0].PolicyID
|
|
}
|
|
|
|
// ResolveAccessMode 确定用户的访问模式
|
|
func (s *StorageAssignService) ResolveAccessMode(userID uint64) string {
|
|
assignments := s.getUserAssignments(userID)
|
|
for _, a := range assignments {
|
|
if a.AccessMode != "" {
|
|
return a.AccessMode
|
|
}
|
|
}
|
|
return ""
|
|
}
|
|
|
|
// GetUserStorageInfo 获取用户完整的存储策略信息(含配额叠加)
|
|
func (s *StorageAssignService) GetUserStorageInfo(userID uint64) (*UserStorageInfo, error) {
|
|
assignments := s.getUserAssignments(userID)
|
|
|
|
var user model.User
|
|
config.DB.First(&user, userID)
|
|
|
|
info := &UserStorageInfo{
|
|
UsedStorage: user.UsedStorage,
|
|
Assignments: assignments,
|
|
}
|
|
|
|
if len(assignments) == 0 {
|
|
// 使用默认策略
|
|
info.PolicyID = uint64(config.AppConfig.Storage.DefaultPolicyID)
|
|
info.TotalQuota = user.StorageQuota
|
|
} else {
|
|
// 最高优先级策略
|
|
info.PolicyID = assignments[0].PolicyID
|
|
info.AccessMode = assignments[0].AccessMode
|
|
|
|
// 配额叠加: 所有策略的配额之和
|
|
var totalQuota int64
|
|
for _, a := range assignments {
|
|
if a.StorageQuota > 0 {
|
|
totalQuota += a.StorageQuota
|
|
}
|
|
}
|
|
if totalQuota > 0 {
|
|
info.TotalQuota = totalQuota
|
|
} else {
|
|
info.TotalQuota = user.StorageQuota
|
|
}
|
|
}
|
|
|
|
// 获取策略详情
|
|
var policy model.StoragePolicy
|
|
if config.DB.First(&policy, info.PolicyID).Error == nil {
|
|
info.PolicyName = policy.Name
|
|
info.PolicyType = policy.PolicyType
|
|
}
|
|
|
|
if info.TotalQuota > 0 {
|
|
info.UsedPercent = float64(info.UsedStorage) / float64(info.TotalQuota) * 100
|
|
}
|
|
|
|
return info, nil
|
|
}
|
|
|
|
// getUserAssignments 获取用户的所有存储分配(去重+排序)
|
|
func (s *StorageAssignService) getUserAssignments(userID uint64) []model.StorageAssignment {
|
|
var all []model.StorageAssignment
|
|
|
|
// 1. 用户专属分配
|
|
var userAssigns []model.StorageAssignment
|
|
config.DB.Where("user_id = ? AND status = 1", userID).Find(&userAssigns)
|
|
all = append(all, userAssigns...)
|
|
|
|
// 2. 角色分配(用户所属的所有角色)
|
|
var userRoles []model.UserRole
|
|
config.DB.Where("user_id = ?", userID).Find(&userRoles)
|
|
for _, ur := range userRoles {
|
|
var roleAssigns []model.StorageAssignment
|
|
config.DB.Where("group_id = ? AND status = 1", ur.RoleID).Find(&roleAssigns)
|
|
all = append(all, roleAssigns...)
|
|
}
|
|
|
|
// 3. 系统默认
|
|
if len(all) == 0 {
|
|
var defaultAssign model.StorageAssignment
|
|
config.DB.Where("is_default = 1 AND status = 1").First(&defaultAssign)
|
|
if defaultAssign.ID > 0 {
|
|
all = append(all, defaultAssign)
|
|
}
|
|
}
|
|
|
|
// 去重(按PolicyID)
|
|
seen := make(map[uint64]bool)
|
|
unique := make([]model.StorageAssignment, 0, len(all))
|
|
for _, a := range all {
|
|
if !seen[a.PolicyID] {
|
|
seen[a.PolicyID] = true
|
|
unique = append(unique, a)
|
|
}
|
|
}
|
|
|
|
// 按优先级降序排序
|
|
sort.Slice(unique, func(i, j int) bool {
|
|
return unique[i].Priority > unique[j].Priority
|
|
})
|
|
|
|
return unique
|
|
}
|
|
|
|
// ========== 管理接口 ==========
|
|
|
|
// ListAssignments 获取所有分配规则
|
|
func (s *StorageAssignService) ListAssignments() ([]dto.StorageAssignmentVO, error) {
|
|
var assignments []model.StorageAssignment
|
|
if err := config.DB.Order("is_default DESC, priority DESC, group_id ASC").Find(&assignments).Error; err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
vos := make([]dto.StorageAssignmentVO, 0, len(assignments))
|
|
for _, a := range assignments {
|
|
vo := dto.StorageAssignmentVO{
|
|
ID: a.ID,
|
|
PolicyID: a.PolicyID,
|
|
UserID: a.UserID,
|
|
GroupID: a.GroupID,
|
|
IsDefault: a.IsDefault,
|
|
Priority: a.Priority,
|
|
StorageQuota: a.StorageQuota,
|
|
AccessMode: a.AccessMode,
|
|
Status: a.Status,
|
|
}
|
|
var policy model.StoragePolicy
|
|
if config.DB.First(&policy, a.PolicyID).Error == nil {
|
|
vo.PolicyName = policy.Name
|
|
}
|
|
if a.UserID > 0 {
|
|
var user model.User
|
|
if config.DB.First(&user, a.UserID).Error == nil {
|
|
vo.UserName = user.Nickname
|
|
}
|
|
}
|
|
if a.GroupID > 0 {
|
|
var role model.Role
|
|
if config.DB.First(&role, a.GroupID).Error == nil {
|
|
vo.RoleName = role.DisplayName
|
|
}
|
|
}
|
|
vos = append(vos, vo)
|
|
}
|
|
return vos, nil
|
|
}
|
|
|
|
// SetDefault 设置系统默认存储策略
|
|
func (s *StorageAssignService) SetDefault(policyID uint64) error {
|
|
// 先清除旧的默认
|
|
config.DB.Model(&model.StorageAssignment{}).Where("is_default = 1").Update("is_default", 0)
|
|
|
|
// 查找或创建默认记录
|
|
var existing model.StorageAssignment
|
|
err := config.DB.Where("is_default = 0 AND user_id = 0 AND group_id = 0").First(&existing).Error
|
|
if err == nil {
|
|
// 更新现有记录
|
|
existing.PolicyID = policyID
|
|
existing.IsDefault = 1
|
|
return config.DB.Save(&existing).Error
|
|
}
|
|
|
|
// 创建新记录
|
|
return config.DB.Create(&model.StorageAssignment{
|
|
PolicyID: policyID,
|
|
IsDefault: 1,
|
|
Status: 1,
|
|
}).Error
|
|
}
|
|
|
|
// AssignToRole 为角色分配存储策略(支持多策略)
|
|
func (s *StorageAssignService) AssignToRole(roleID, policyID uint64, quota int64, priority int, accessMode string) error {
|
|
// 检查是否已存在相同分配
|
|
var existing model.StorageAssignment
|
|
err := config.DB.Where("group_id = ? AND policy_id = ?", roleID, policyID).First(&existing).Error
|
|
if err == nil {
|
|
// 更新
|
|
existing.StorageQuota = quota
|
|
existing.Priority = priority
|
|
existing.AccessMode = accessMode
|
|
return config.DB.Save(&existing).Error
|
|
}
|
|
|
|
return config.DB.Create(&model.StorageAssignment{
|
|
GroupID: roleID,
|
|
PolicyID: policyID,
|
|
StorageQuota: quota,
|
|
Priority: priority,
|
|
AccessMode: accessMode,
|
|
Status: 1,
|
|
}).Error
|
|
}
|
|
|
|
// AssignToUser 为用户分配存储策略(覆盖角色策略)
|
|
func (s *StorageAssignService) AssignToUser(userID, policyID uint64, quota int64, accessMode string) error {
|
|
var existing model.StorageAssignment
|
|
err := config.DB.Where("user_id = ?", userID).First(&existing).Error
|
|
if err == nil {
|
|
existing.PolicyID = policyID
|
|
existing.StorageQuota = quota
|
|
existing.AccessMode = accessMode
|
|
return config.DB.Save(&existing).Error
|
|
}
|
|
|
|
return config.DB.Create(&model.StorageAssignment{
|
|
UserID: userID,
|
|
PolicyID: policyID,
|
|
StorageQuota: quota,
|
|
Priority: 100, // 用户专属最高优先级
|
|
AccessMode: accessMode,
|
|
Status: 1,
|
|
}).Error
|
|
}
|
|
|
|
// UpdateAssignment 更新分配规则
|
|
func (s *StorageAssignService) UpdateAssignment(id uint64, policyID uint64, priority *int, quota *int64, accessMode string) error {
|
|
var assignment model.StorageAssignment
|
|
if err := config.DB.First(&assignment, id).Error; err != nil {
|
|
return errors.New("分配规则不存在")
|
|
}
|
|
|
|
updates := make(map[string]interface{})
|
|
if policyID > 0 {
|
|
updates["policy_id"] = policyID
|
|
}
|
|
if priority != nil {
|
|
updates["priority"] = *priority
|
|
}
|
|
if quota != nil {
|
|
updates["storage_quota"] = *quota
|
|
}
|
|
if accessMode != "" {
|
|
updates["access_mode"] = accessMode
|
|
}
|
|
|
|
if len(updates) == 0 {
|
|
return errors.New("没有需要更新的字段")
|
|
}
|
|
|
|
return config.DB.Model(&model.StorageAssignment{}).Where("id = ?", id).Updates(updates).Error
|
|
}
|
|
|
|
// DeleteAssignment 删除分配规则
|
|
func (s *StorageAssignService) DeleteAssignment(id uint64) error {
|
|
var assignment model.StorageAssignment
|
|
if err := config.DB.First(&assignment, id).Error; err != nil {
|
|
return errors.New("分配规则不存在")
|
|
}
|
|
if assignment.IsDefault == 1 {
|
|
return errors.New("不能删除默认分配规则")
|
|
}
|
|
return config.DB.Delete(&model.StorageAssignment{}, id).Error
|
|
}
|