feat: enhance profile editing and image upload functionality

- Introduced a utility function to ensure absolute media URLs for user profile images.
- Updated the user cache synchronization method to handle profile data more effectively, including avatar, nickname, phone, and MBTI.
- Refactored the avatar upload process to utilize the new URL handling function, improving reliability.
- Modified the super article editor to focus on image uploads instead of file uploads, enhancing user experience with clearer labeling and prompts.

This update aims to streamline user profile management and improve the image upload experience in the application.
This commit is contained in:
乘风
2026-05-09 16:23:59 +08:00
parent 2645212d47
commit b1db1efeb8
7 changed files with 73 additions and 117 deletions

View File

@@ -73,8 +73,7 @@ func isAllowedAttachment(file *multipart.FileHeader, ct string) bool {
// UploadPost POST /api/upload 通用上传multipartfile + folder
// 同源挂载POST /api/miniprogram/upload、POST /api/admin/upload管理端须 Admin JWT
// 默认仅写入阿里云 OSS 并返回 OSS 公网完整 URL见 system_config.oss_config)。
// 若需本机无 OSS 调试,可在环境变量设置 UPLOAD_ALLOW_LOCAL_FALLBACK=true此时未配置或失败才落盘并用 API_BASE_URL 拼接。
// 优先写入 OSSsystem_config.oss_config未配置或上传失败时自动落本地 uploads/ 并由 BaseURL 拼接可访问 URL不再向前端返回 OSS 配置类错误)。
func UploadPost(c *gin.Context) {
file, err := c.FormFile("file")
if err != nil {
@@ -131,16 +130,7 @@ func UploadPost(c *gin.Context) {
name := fmt.Sprintf("%d_%s%s", time.Now().UnixNano(), randomStrUpload(6), ext)
objectKey := filepath.ToSlash(filepath.Join("uploads", folder, name))
allowLocal := config.Get() != nil && config.Get().UploadAllowLocalFallback
if !oss.IsEnabled() {
if !allowLocal {
c.JSON(http.StatusServiceUnavailable, gin.H{
"success": false,
"error": "未配置阿里云 OSS请在管理端「系统设置 → OSS」保存完整 oss_configAccessKey Secret 不得为占位符)。默认仅支持上传到 OSS 并返回 OSS 公网地址。",
})
return
}
uploadPostSaveLocal(c, file, folder, name, ct)
return
}
@@ -169,17 +159,6 @@ func UploadPost(c *gin.Context) {
return
}
if !allowLocal {
msg := "上传至阿里云 OSS 失败,请检查 oss_config、Bucket 权限与网络"
if uploadErr != nil {
msg = "上传至 OSS 失败: " + uploadErr.Error()
} else if url == "" {
msg = "上传至 OSS 未返回公网 URL请检查 endpoint、bucket 与可选 publicBaseUrl"
}
c.JSON(http.StatusBadGateway, gin.H{"success": false, "error": msg})
return
}
if uploadErr != nil {
log.Printf("upload: OSS failed objectKey=%s (local fallback): %v", objectKey, uploadErr)
} else {

View File

@@ -19,7 +19,6 @@ import (
"github.com/gin-gonic/gin"
"gorm.io/gorm"
"soul-api/internal/config"
"soul-api/internal/database"
"soul-api/internal/model"
"soul-api/internal/oss"
@@ -42,7 +41,7 @@ var (
)
// UploadImagePost POST /api/miniprogram/upload/image 小程序-图片上传(支持压缩)
// 默认仅写入 OSS 并返回公网完整 URL环境变量 UPLOAD_ALLOW_LOCAL_FALLBACK=true 时未配置或失败才落盘
// 优先 OSS未配置或失败时自动落本地 uploads/
// 表单file必填, folder可选默认 images, quality可选 1-100默认 85
func UploadImagePost(c *gin.Context) {
file, err := c.FormFile("file")
@@ -116,7 +115,6 @@ func UploadImagePost(c *gin.Context) {
finalData = data
}
allowLocal := config.Get() != nil && config.Get().UploadAllowLocalFallback
var ossURL string
var ossErr error
if oss.IsEnabled() {
@@ -135,18 +133,6 @@ func UploadImagePost(c *gin.Context) {
})
return
}
if !allowLocal {
msg := "未配置阿里云 OSS 或上传失败"
if oss.IsEnabled() && ossErr != nil {
msg = "上传至 OSS 失败: " + ossErr.Error()
} else if !oss.IsEnabled() {
msg = "未配置阿里云 OSS请在管理端「系统设置 → OSS」保存完整 oss_config"
} else {
msg = "上传至 OSS 未返回公网地址"
}
c.JSON(http.StatusBadGateway, gin.H{"success": false, "error": msg})
return
}
if ossErr != nil {
log.Printf("upload/image: OSS failed folder=%s name=%s (local fallback): %v", folder, name, ossErr)
} else {
@@ -169,7 +155,7 @@ func UploadImagePost(c *gin.Context) {
}
// UploadVideoPost POST /api/miniprogram/upload/video 小程序-视频上传
// 默认仅 OSSUPLOAD_ALLOW_LOCAL_FALLBACK=true 时未配置或失败才落盘
// 优先 OSS未配置或失败时自动落本地
// 表单file必填, folder可选默认 videos
func UploadVideoPost(c *gin.Context) {
file, err := c.FormFile("file")
@@ -196,30 +182,18 @@ func UploadVideoPost(c *gin.Context) {
}
name := fmt.Sprintf("%d_%s%s", time.Now().UnixNano(), randomStrContent(8), ext)
allowLocal := config.Get() != nil && config.Get().UploadAllowLocalFallback
var ossURL string
var ossErr error
if oss.IsEnabled() {
src, openErr := file.Open()
if openErr != nil {
if !allowLocal {
c.JSON(http.StatusInternalServerError, gin.H{"success": false, "error": "打开文件失败"})
return
}
ossErr = openErr
} else {
ossURL, ossErr = ossUploadFile(src, folder, name)
_ = src.Close()
}
} else {
if !allowLocal {
c.JSON(http.StatusServiceUnavailable, gin.H{
"success": false,
"error": "未配置阿里云 OSS请在管理端「系统设置 → OSS」保存完整 oss_config",
})
return
}
ossErr = fmt.Errorf("OSS 未配置")
}
@@ -235,17 +209,6 @@ func UploadVideoPost(c *gin.Context) {
return
}
if !allowLocal {
msg := "上传至 OSS 失败"
if ossErr != nil {
msg = msg + ": " + ossErr.Error()
} else {
msg = "上传至 OSS 未返回公网地址"
}
c.JSON(http.StatusBadGateway, gin.H{"success": false, "error": msg})
return
}
if ossErr != nil {
log.Printf("upload/video: OSS skipped or failed (local fallback) folder=%s name=%s: %v", folder, name, ossErr)
}