- 实现照片更新功能 (updatePhotoLogic.go) - 支持部分字段更新 (title, description, category_id) - 添加用户权限验证,只能更新自己的照片 - 添加分类存在性验证 - 完善错误处理和响应格式 - 实现照片删除功能 (deletePhotoLogic.go) - 添加用户权限验证,只能删除自己的照片 - 同时删除数据库记录和文件系统文件 - 安全的文件删除处理 - 更新Handler使用统一响应格式 - updatePhotoHandler.go: 使用response.Response统一处理 - deletePhotoHandler.go: 使用response.Response统一处理 - 添加完整API测试用例 (test_photo_crud.http) - 涵盖正常场景和错误场景测试 - 包含权限验证测试 - 更新项目进度 (TASK_PROGRESS.md) - 完成率从8%提升到12% - 更新API接口状态 - 记录技术成果和里程碑
104 lines
2.6 KiB
Go
104 lines
2.6 KiB
Go
package photo
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"time"
|
|
|
|
"photography-backend/internal/model"
|
|
"photography-backend/internal/svc"
|
|
"photography-backend/internal/types"
|
|
"photography-backend/pkg/errorx"
|
|
|
|
"github.com/zeromicro/go-zero/core/logx"
|
|
)
|
|
|
|
type UpdatePhotoLogic struct {
|
|
logx.Logger
|
|
ctx context.Context
|
|
svcCtx *svc.ServiceContext
|
|
}
|
|
|
|
// 更新照片
|
|
func NewUpdatePhotoLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UpdatePhotoLogic {
|
|
return &UpdatePhotoLogic{
|
|
Logger: logx.WithContext(ctx),
|
|
ctx: ctx,
|
|
svcCtx: svcCtx,
|
|
}
|
|
}
|
|
|
|
func (l *UpdatePhotoLogic) UpdatePhoto(req *types.UpdatePhotoRequest) (resp *types.UpdatePhotoResponse, err error) {
|
|
// 1. 获取当前用户ID (从JWT中间件获取)
|
|
userID := l.ctx.Value("userID")
|
|
if userID == nil {
|
|
return nil, errorx.NewWithCode(errorx.AuthError)
|
|
}
|
|
currentUserID := userID.(int64)
|
|
|
|
// 2. 查询照片是否存在
|
|
photo, err := l.svcCtx.PhotoModel.FindOne(l.ctx, req.Id)
|
|
if err != nil {
|
|
if err == model.ErrNotFound {
|
|
return nil, errorx.NewWithCode(errorx.PhotoNotFound)
|
|
}
|
|
logx.Errorf("查询照片失败: %v", err)
|
|
return nil, errorx.NewWithCode(errorx.ServerError)
|
|
}
|
|
|
|
// 3. 检查权限 - 只有照片所有者可以更新
|
|
if photo.UserId != currentUserID {
|
|
return nil, errorx.NewWithCode(errorx.Forbidden)
|
|
}
|
|
|
|
// 4. 验证分类是否存在 (如果要更新分类)
|
|
if req.CategoryId > 0 {
|
|
_, err = l.svcCtx.CategoryModel.FindOne(l.ctx, req.CategoryId)
|
|
if err != nil {
|
|
if err == model.ErrNotFound {
|
|
return nil, errorx.NewWithCode(errorx.CategoryNotFound)
|
|
}
|
|
logx.Errorf("查询分类失败: %v", err)
|
|
return nil, errorx.NewWithCode(errorx.ServerError)
|
|
}
|
|
}
|
|
|
|
// 5. 更新照片信息
|
|
if req.Title != "" {
|
|
photo.Title = req.Title
|
|
}
|
|
if req.Description != "" {
|
|
photo.Description = sql.NullString{String: req.Description, Valid: true}
|
|
}
|
|
if req.CategoryId > 0 {
|
|
photo.CategoryId = req.CategoryId
|
|
}
|
|
photo.UpdatedAt = time.Now()
|
|
|
|
// 6. 保存到数据库
|
|
err = l.svcCtx.PhotoModel.Update(l.ctx, photo)
|
|
if err != nil {
|
|
logx.Errorf("更新照片失败: %v", err)
|
|
return nil, errorx.NewWithCode(errorx.ServerError)
|
|
}
|
|
|
|
// 7. 构造响应
|
|
return &types.UpdatePhotoResponse{
|
|
BaseResponse: types.BaseResponse{
|
|
Code: errorx.Success,
|
|
Message: "照片更新成功",
|
|
},
|
|
Data: types.Photo{
|
|
Id: photo.Id,
|
|
Title: photo.Title,
|
|
Description: photo.Description.String,
|
|
FilePath: photo.FilePath,
|
|
ThumbnailPath: photo.ThumbnailPath,
|
|
UserId: photo.UserId,
|
|
CategoryId: photo.CategoryId,
|
|
CreatedAt: photo.CreatedAt.Unix(),
|
|
UpdatedAt: photo.UpdatedAt.Unix(),
|
|
},
|
|
}, nil
|
|
}
|