feat: rename qiniu to oss, add admin upload proxy with thumbnail, add dev-login

- Rename all QINIU_* config/code/docs to OSS_* to match actual Alibaba Cloud OSS
- Refactor upload module from internal/common/qiniu to internal/common/upload
- Add backend proxy upload endpoint (POST /api/admin/marketing/upload) to avoid CORS
- Auto-generate compressed thumbnail (800px, JPEG 80%) on admin image upload
- Add dev-login endpoint (POST /api/v1/auth/dev-login) for H5 debugging
- Add imageutil package for server-side image resizing

Made-with: Cursor
This commit is contained in:
nepiedg
2026-04-04 02:52:16 +08:00
parent aeaf6a04c2
commit 1eab1b99c1
21 changed files with 1023 additions and 191 deletions
@@ -147,6 +147,51 @@ func (s *AuthService) LoginWithCode(ctx context.Context, req LoginRequest) (*Log
return result, nil
}
// DevLogin 开发模式专用:创建或查找测试用户,无需微信授权。
func (s *AuthService) DevLogin(ctx context.Context, miniProgramID uint) (*LoginResult, error) {
if miniProgramID == 0 {
return nil, ErrMiniProgramRequired
}
miniProgram, err := s.miniProgramSvc.GetByID(ctx, miniProgramID)
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, ErrMiniProgramNotFound
}
return nil, fmt.Errorf("load mini program: %w", err)
}
const devOpenID = "dev_test_user"
sessionKey := fmt.Sprintf("dev_session_%d", miniProgramID)
tx := s.db.WithContext(ctx)
var user model.User
err = tx.Where("mini_program_id = ? AND open_id = ?", miniProgramID, devOpenID).First(&user).Error
if errors.Is(err, gorm.ErrRecordNotFound) {
user = model.User{
MiniProgramID: miniProgramID,
OpenID: devOpenID,
NickName: "开发测试用户",
AvatarURL: defaultAvatarURL,
SessionKey: sessionKey,
}
if err := tx.Create(&user).Error; err != nil {
return nil, fmt.Errorf("create dev user: %w", err)
}
} else if err != nil {
return nil, fmt.Errorf("query dev user: %w", err)
} else {
tx.Model(&user).Update("session_key", sessionKey)
user.SessionKey = sessionKey
}
return &LoginResult{
User: &user,
SessionKey: sessionKey,
MiniProgram: miniProgram,
}, nil
}
func (s *AuthService) getSmokeMode(ctx context.Context, uid int) (string, error) {
var profile smokemodel.SmokeUserProfile
err := s.db.WithContext(ctx).