修复个人中心问题
This commit is contained in:
@@ -16,6 +16,7 @@ import (
|
||||
"server/services"
|
||||
|
||||
"github.com/beego/beego/v2/client/orm"
|
||||
"github.com/beego/beego/v2/core/logs"
|
||||
beego "github.com/beego/beego/v2/server/web"
|
||||
)
|
||||
|
||||
@@ -908,16 +909,139 @@ func (c *BackendFileController) BatchDeleteFilesPermanently() {
|
||||
_ = c.ServeJSON()
|
||||
}
|
||||
|
||||
// UploadAvatar POST /backend/uploadavatar(占位)
|
||||
func (c *BackendFileController) UploadAvatar() {
|
||||
c.Data["json"] = map[string]interface{}{"code": 501, "msg": "上传头像暂未实现"}
|
||||
_ = c.ServeJSON()
|
||||
// avatarUploadMaxMB 头像大小上限:头像场景 2MB 足够
|
||||
const avatarUploadMaxMB = 2
|
||||
const avatarUploadMaxBytes = avatarUploadMaxMB * 1024 * 1024
|
||||
|
||||
// avatarAllowedExts 头像允许的图片格式
|
||||
var avatarAllowedExts = map[string]bool{
|
||||
"jpg": true, "jpeg": true, "png": true, "gif": true, "webp": true, "bmp": true,
|
||||
}
|
||||
|
||||
// UpdateAvatar POST /backend/uploadavatar/:id(占位)
|
||||
// UploadAvatar POST /backend/uploadavatar
|
||||
// 上传并设置「当前登录用户」头像:
|
||||
// 复用文件存储链路(Stage → 查重 → Commit → 落文件表),
|
||||
// 并把最终 URL 写入 yz_auth_identity.avatar 供认证中心 userinfo 下发。
|
||||
func (c *BackendFileController) UploadAvatar() {
|
||||
claims, err := c.backendClaims()
|
||||
if err != nil {
|
||||
c.jsonErr(401, 401, err.Error())
|
||||
return
|
||||
}
|
||||
if err := c.Ctx.Request.ParseMultipartForm(avatarUploadMaxBytes); err != nil {
|
||||
c.jsonErr(400, 400, "解析上传失败: "+err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
fh, header, err := c.GetFile("file")
|
||||
if err != nil || fh == nil {
|
||||
c.jsonErr(400, 400, "请选择要上传的头像")
|
||||
return
|
||||
}
|
||||
defer fh.Close()
|
||||
|
||||
if header != nil && header.Size > avatarUploadMaxBytes {
|
||||
c.jsonErr(400, 400, fmt.Sprintf("头像大小不能超过%dMB", avatarUploadMaxMB))
|
||||
return
|
||||
}
|
||||
ext := strings.ToLower(services.FileExt(header.Filename))
|
||||
if !avatarAllowedExts[ext] {
|
||||
c.jsonErr(400, 400, "头像仅支持 jpg / png / gif / webp 格式")
|
||||
return
|
||||
}
|
||||
|
||||
storageService, err := services.GetStorageService()
|
||||
if err != nil {
|
||||
c.jsonErr(500, 500, "获取存储服务失败: "+err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
staged, err := storageService.Stage(fh, header)
|
||||
if err != nil {
|
||||
c.jsonErr(500, 500, "读取上传文件失败: "+err.Error())
|
||||
return
|
||||
}
|
||||
committed := false
|
||||
defer func() {
|
||||
// 去重命中或出错时清理临时文件,避免产生垃圾
|
||||
if !committed && staged != nil {
|
||||
_ = storageService.Discard(staged)
|
||||
}
|
||||
}()
|
||||
|
||||
tid := c.effectiveTid(claims)
|
||||
// 头像固定归入「我的个人文件」目录:既不会混进租户共享文件列表,
|
||||
// 又能让本人在文件管理里找到自己上传过的头像。
|
||||
tuid := uint64(claims.UserID)
|
||||
upCtx := services.UploadContext{Source: services.SourceBackend, Tid: tid, Tuid: tuid}
|
||||
|
||||
// 同一张图重复上传:直接复用已有文件,不再占一份空间
|
||||
if exist, e := services.FindDuplicate(services.SourceBackend, upCtx.Scope(), tid, tuid, staged.MD5); e == nil && exist != nil {
|
||||
c.saveAvatarAndReply(claims.UserID, exist.Src, exist.Name)
|
||||
return
|
||||
}
|
||||
|
||||
result, err := storageService.Commit(staged, upCtx)
|
||||
if err != nil {
|
||||
c.jsonErr(500, 500, "上传头像失败: "+err.Error())
|
||||
return
|
||||
}
|
||||
committed = true
|
||||
|
||||
// 文件台账落库失败不阻断头像设置(头像可用优先)
|
||||
if _, e := services.CreateFileRecord(services.FileUploadParams{
|
||||
Source: services.SourceBackend,
|
||||
Scope: upCtx.Scope(),
|
||||
Tid: tid,
|
||||
Tuid: tuid,
|
||||
Uid: uint64(claims.UserID),
|
||||
Name: header.Filename,
|
||||
Ext: ext,
|
||||
Size: uint64(result.Size),
|
||||
Src: result.URL,
|
||||
ObjectKey: result.Key,
|
||||
Storage: storageService.Type(),
|
||||
MD5: result.MD5,
|
||||
}); e != nil {
|
||||
logs.Warn("[avatar] 头像文件落库失败: %v", e)
|
||||
}
|
||||
|
||||
c.saveAvatarAndReply(claims.UserID, result.URL, header.Filename)
|
||||
}
|
||||
|
||||
// saveAvatarAndReply 写入身份头像并返回结果
|
||||
func (c *BackendFileController) saveAvatarAndReply(identityID int, url, name string) {
|
||||
if err := services.UpdateIdentityAvatar(uint64(identityID), url); err != nil {
|
||||
c.jsonErr(500, 500, "保存头像失败: "+err.Error())
|
||||
return
|
||||
}
|
||||
c.jsonOK(map[string]interface{}{"url": url, "name": name})
|
||||
}
|
||||
|
||||
// UpdateAvatar POST /backend/uploadavatar/:id
|
||||
// 兼容旧调用:把指定文件的地址设为当前登录用户头像(不重新上传文件)。
|
||||
func (c *BackendFileController) UpdateAvatar() {
|
||||
c.Data["json"] = map[string]interface{}{"code": 501, "msg": "更新头像暂未实现"}
|
||||
_ = c.ServeJSON()
|
||||
claims, err := c.backendClaims()
|
||||
if err != nil {
|
||||
c.jsonErr(401, 401, err.Error())
|
||||
return
|
||||
}
|
||||
idStr := c.Ctx.Input.Param(":id")
|
||||
id, err := strconv.ParseUint(idStr, 10, 64)
|
||||
if err != nil || id == 0 {
|
||||
c.jsonErr(400, 400, "无效的文件ID")
|
||||
return
|
||||
}
|
||||
var f models.SystemFile
|
||||
if err := models.Orm.QueryTable(new(models.SystemFile)).
|
||||
Filter("id", id).
|
||||
Filter("tid", c.effectiveTid(claims)).
|
||||
Filter("delete_time__isnull", true).
|
||||
One(&f); err != nil {
|
||||
c.jsonErr(404, 404, "文件不存在")
|
||||
return
|
||||
}
|
||||
c.saveAvatarAndReply(claims.UserID, f.Src, f.Name)
|
||||
}
|
||||
|
||||
// BatchMoveFiles POST /backend/batchMoveFiles
|
||||
|
||||
Reference in New Issue
Block a user