fix: delete desktop release oss objects

This commit is contained in:
2026-06-25 00:40:08 +08:00
parent ed48674ab5
commit febfd65b45
3 changed files with 279 additions and 2 deletions
@@ -61,7 +61,7 @@ const (
)
type DesktopClientReleaseService struct {
releases *repository.DesktopClientReleaseRepository
releases desktopClientReleaseStore
storage objectstorage.Client
audits *AuditService
releaseUploadDir string
@@ -70,6 +70,18 @@ type DesktopClientReleaseService struct {
releaseUploadMu sync.Mutex
}
type desktopClientReleaseStore interface {
List(ctx context.Context, f repository.DesktopClientReleaseFilter) ([]domain.DesktopClientRelease, int64, error)
ListEnabledByChannel(ctx context.Context, channel string) ([]domain.DesktopClientRelease, error)
Create(ctx context.Context, in repository.UpsertDesktopClientReleaseInput) (*domain.DesktopClientRelease, error)
Update(ctx context.Context, id int64, in repository.UpsertDesktopClientReleaseInput) (*domain.DesktopClientRelease, error)
SetEnabled(ctx context.Context, id int64, enabled bool, actorID *int64) (*domain.DesktopClientRelease, error)
GetByID(ctx context.Context, id int64) (*domain.DesktopClientRelease, error)
ListEnabledByTarget(ctx context.Context, target repository.DesktopClientReleaseTarget) ([]domain.DesktopClientRelease, error)
HasObjectReference(ctx context.Context, objectKey string, excludeID int64) (bool, error)
Delete(ctx context.Context, id int64) error
}
func NewDesktopClientReleaseService(
releases *repository.DesktopClientReleaseRepository,
storage objectstorage.Client,
@@ -536,6 +548,9 @@ func (s *DesktopClientReleaseService) Delete(ctx context.Context, actor *Actor,
}
return err
}
if err := s.deleteReleaseObjects(ctx, item); err != nil {
return err
}
if err := s.releases.Delete(ctx, id); err != nil {
if errors.Is(err, repository.ErrDesktopClientReleaseNotFound) {
return response.ErrNotFound(40430, "desktop_client_release_not_found", "客户端版本配置不存在")
@@ -546,6 +561,46 @@ func (s *DesktopClientReleaseService) Delete(ctx context.Context, actor *Actor,
return nil
}
func (s *DesktopClientReleaseService) deleteReleaseObjects(ctx context.Context, item *domain.DesktopClientRelease) error {
objectKeys := desktopClientReleaseOSSObjectKeys(item)
if len(objectKeys) == 0 {
return nil
}
if s.storage == nil {
return response.ErrInternal(50091, "object_storage_unavailable", "object storage is unavailable")
}
if err := s.storage.Validate(); err != nil {
appErr := response.ErrInternal(50091, "object_storage_unavailable", "object storage is unavailable")
appErr.Cause = err
return appErr
}
for _, objectKey := range objectKeys {
referenced, err := s.releases.HasObjectReference(ctx, objectKey, item.ID)
if err != nil {
return err
}
if referenced {
continue
}
exists, err := s.storage.Exists(ctx, objectKey)
if err != nil {
appErr := response.ErrInternal(50097, "desktop_client_release_object_check_failed", "检查客户端版本 OSS 对象失败")
appErr.Cause = err
return appErr
}
if !exists {
continue
}
if err := s.storage.Delete(ctx, objectKey); err != nil {
appErr := response.ErrInternal(50098, "desktop_client_release_object_delete_failed", "删除客户端版本 OSS 对象失败")
appErr.Cause = err
return appErr
}
}
return nil
}
func (s *DesktopClientReleaseService) UploadOSS(ctx context.Context, in DesktopClientReleaseUploadInput) (*DesktopClientReleaseUploadResult, error) {
if s.storage == nil {
return nil, response.ErrInternal(50091, "object_storage_unavailable", "object storage is unavailable")
@@ -1441,6 +1496,34 @@ func itemUpdaterAsset(item *domain.DesktopClientRelease) desktopClientReleaseAss
return itemInstallerAsset(item)
}
func desktopClientReleaseOSSObjectKeys(item *domain.DesktopClientRelease) []string {
if item == nil {
return nil
}
candidates := []desktopClientReleaseAsset{itemInstallerAsset(item)}
if item.UpdaterDownloadSource != nil {
candidates = append(candidates, itemUpdaterAsset(item))
}
seen := map[string]struct{}{}
keys := make([]string, 0, len(candidates))
for _, asset := range candidates {
if stringPointerValue(asset.DownloadSource) != DesktopClientDownloadSourceOSS {
continue
}
objectKey := strings.TrimSpace(stringPointerValue(asset.OSSObjectKey))
if objectKey == "" {
continue
}
if _, ok := seen[objectKey]; ok {
continue
}
seen[objectKey] = struct{}{}
keys = append(keys, objectKey)
}
return keys
}
func (s *DesktopClientReleaseService) resolveDownloadURLResult(item *domain.DesktopClientRelease) (*DesktopClientReleaseDownloadURLResult, error) {
downloadURL, err := s.resolveInstallerDownloadURL(item)
if err != nil {