fix: 修复头像审核旧图裂开问题 + CSP 配置修复
- 头像提交审核不再删除旧文件,审核通过后才删除旧头像文件 - 头像审核被拒时删除已上传的新头像文件,保留旧头像 - CSP style-src 移除 nonce 以启用 unsafe-inline(JS 动态样式需要) - CSP script-src 移除 nonce 改用 unsafe-inline + unsafe-eval(Vditor 编辑器和动态样式需要)
This commit is contained in:
@ -57,6 +57,9 @@ func (s *AvatarService) ProcessAvatar(userID uint, file io.Reader, contentType s
|
||||
return "", err
|
||||
}
|
||||
|
||||
// 直接更新场景:删除旧头像文件,仅保留新文件
|
||||
s.CleanOldAvatars(userID)
|
||||
|
||||
user, err := s.userRepo.FindByID(userID)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("用户不存在")
|
||||
@ -134,10 +137,8 @@ func (s *AvatarService) ProcessImage(userID uint, file io.Reader, contentType st
|
||||
return "", fmt.Errorf("创建存储目录失败")
|
||||
}
|
||||
|
||||
// 8. 删除该用户的旧头像,仅保留最新
|
||||
s.cleanOldAvatars(userID)
|
||||
|
||||
// 9. 原子写入:先写临时文件,再 rename 到最终路径
|
||||
// 8. 原子写入:先写临时文件,再 rename 到最终路径
|
||||
// 注意:此处不删除旧头像文件,审核场景下审核通过前旧头像仍需正常显示
|
||||
ts := time.Now().Unix()
|
||||
filename := fmt.Sprintf("%d_%d.webp", userID, ts)
|
||||
tmpPath := filepath.Join(s.storageDir, filename+".tmp")
|
||||
@ -153,8 +154,8 @@ func (s *AvatarService) ProcessImage(userID uint, file io.Reader, contentType st
|
||||
return fmt.Sprintf("/uploads/avatars/%d_%d.webp", userID, ts), nil
|
||||
}
|
||||
|
||||
// cleanOldAvatars 删除指定用户的所有旧头像文件(仅保留最新一次上传)
|
||||
func (s *AvatarService) cleanOldAvatars(userID uint) {
|
||||
// CleanOldAvatars 删除指定用户的所有旧头像文件,调用方负责确保新文件不受影响
|
||||
func (s *AvatarService) CleanOldAvatars(userID uint) {
|
||||
prefix := strconv.FormatUint(uint64(userID), 10) + "_"
|
||||
entries, err := os.ReadDir(s.storageDir)
|
||||
if err != nil {
|
||||
@ -167,6 +168,19 @@ func (s *AvatarService) cleanOldAvatars(userID uint) {
|
||||
}
|
||||
}
|
||||
|
||||
// DeleteAvatarFile 根据头像 URL 删除对应的磁盘文件
|
||||
func (s *AvatarService) DeleteAvatarFile(url string) error {
|
||||
if url == "" {
|
||||
return nil
|
||||
}
|
||||
filename := filepath.Base(url)
|
||||
if filename == "." || filename == "/" {
|
||||
return nil
|
||||
}
|
||||
fullPath := filepath.Join(s.storageDir, filename)
|
||||
return os.Remove(fullPath)
|
||||
}
|
||||
|
||||
// subImage 从原图中裁切指定正方形区域
|
||||
func subImage(img image.Image, x, y, size int) image.Image {
|
||||
cropped := image.NewNRGBA(image.Rect(0, 0, size, size))
|
||||
|
||||
Reference in New Issue
Block a user