用户修改头像、昵称、绑定手机号、获取用户详细信息

This commit is contained in:
chy
2025-06-06 15:48:05 +08:00
parent 01b898163a
commit e40f9987db
12 changed files with 280 additions and 19 deletions

View File

@ -12,6 +12,7 @@ import (
"server/internal/controller/rewardType"
"server/internal/controller/role"
"server/internal/controller/upload"
"server/internal/controller/user"
"server/internal/controller/wx"
"server/internal/middleware"
)
@ -40,6 +41,7 @@ var (
merchant.NewV1(),
rewardType.NewV1(),
feedback.NewV1(),
user.NewV1(),
)
})
})

View File

@ -1,13 +1,7 @@
package consts
// Redis key 前缀
// 用户
const (
// 用户相关
UserCode = "user:code:" // 用户验证码
UserToken = "user:token:" // 用户token
UserInfo = "user:info:" // 用户信息
// 系统相关
SystemConfig = "system:config" // 系统配置
SystemCache = "system:cache:" // 系统缓存
UserBindPhoneKey = "user:bindPhone:%d"
UserCodeExpire = 5 * 60
)

View File

@ -0,0 +1,26 @@
package user
import (
"context"
"github.com/gogf/gf/v2/frame/g"
"server/internal/model"
"server/internal/service"
"server/api/user/v1"
)
func (c *ControllerV1) BindPhone(ctx context.Context, req *v1.BindPhoneReq) (res *v1.BindPhoneRes, err error) {
id := g.RequestFromCtx(ctx).GetCtxVar("id").Int64()
out, err := service.User().BindPhone(ctx, &model.UserBindPhoneIn{
PhoneCode: req.Code,
Phone: req.Phone,
Id: id,
})
if err != nil {
return nil, err
}
return &v1.BindPhoneRes{Success: out.Success}, nil
}

View File

@ -0,0 +1,24 @@
package user
import (
"context"
"github.com/gogf/gf/v2/frame/g"
"server/internal/model"
"server/internal/service"
"server/api/user/v1"
)
func (c *ControllerV1) GetPhoneCode(ctx context.Context, req *v1.GetPhoneCodeReq) (res *v1.GetPhoneCodeRes, err error) {
id := g.RequestFromCtx(ctx).GetCtxVar("id").Int64()
out, err := service.User().Code(ctx, &model.GetPhoneCodeIn{
Phone: req.Phone,
Id: id,
})
if err != nil {
return nil, err
}
return &v1.GetPhoneCodeRes{Success: out.Success}, nil
}

View File

@ -0,0 +1,35 @@
package user
import (
"context"
"github.com/gogf/gf/v2/frame/g"
"server/internal/model"
"server/internal/service"
"server/api/user/v1"
)
func (c *ControllerV1) Info(ctx context.Context, req *v1.InfoReq) (res *v1.InfoRes, err error) {
id := g.RequestFromCtx(ctx).GetCtxVar("id").Int64()
out, err := service.User().Info(ctx, &model.UserInfoIn{
OpenId: req.OpenId,
Id: int(id),
})
if err != nil {
return nil, err
}
return &v1.InfoRes{
Avatar: out.Avatar,
Email: out.Email,
Id: int(out.Id),
Nickname: out.Nickname,
PhoneNumber: out.PhoneNumber,
QQPopenId: out.QQPopenId,
RoleId: int(out.RoleId),
Username: out.Username,
WxOpenId: out.WxOpenId,
WxPopenId: out.WxPopenId,
}, nil
}

View File

@ -0,0 +1,24 @@
package user
import (
"context"
"github.com/gogf/gf/v2/frame/g"
"server/internal/model"
"server/internal/service"
"server/api/user/v1"
)
func (c *ControllerV1) Update(ctx context.Context, req *v1.UpdateReq) (res *v1.UpdateRes, err error) {
id := g.RequestFromCtx(ctx).GetCtxVar("id").Int64()
out, err := service.User().Update(ctx, &model.UserUpdateIn{
Id: id,
Nickname: req.Nickname,
Avatar: req.Avatar,
})
if err != nil {
return nil, err
}
return &v1.UpdateRes{Success: out.Success}, nil
}

View File

@ -2,6 +2,8 @@ package internal
import (
"context"
"fmt"
"github.com/gogf/gf/v2/frame/g"
"server/internal/consts"
"server/internal/dao"
"server/internal/model"
@ -115,21 +117,83 @@ func (s *sUser) Info(ctx context.Context, in *model.UserInfoIn) (out *model.User
return nil, ecode.Fail.Sub("查找用户失败")
}
out = &model.UserInfoOut{
Id: user.Id,
Id: user.Id,
WxOpenId: user.WxOpenId,
Username: user.Username,
Nickname: user.Nickname,
Avatar: user.Avatar,
Email: user.Email,
PhoneNumber: user.PhoneNumber,
WxPopenId: user.WxPopenId,
QQPopenId: user.QqPopenId,
RoleId: user.RoleId,
}
return
return out, nil
}
func (s *sUser) Code(ctx context.Context, in *model.UserCodeIn) (out *model.UserCodeOut, err error) {
return
func (s *sUser) Code(ctx context.Context, in *model.GetPhoneCodeIn) (out *model.GetPhoneCodeOut, err error) {
// TODO 短信平台获取验证码
code := "9999"
// 存入 redis
err = g.Redis().SetEX(ctx, fmt.Sprintf(consts.UserBindPhoneKey, in.Id), code, consts.UserCodeExpire)
if err != nil {
return nil, ecode.Fail.Sub("设置验证码失败")
}
return &model.GetPhoneCodeOut{
Success: true,
}, nil
}
func (s *sUser) Update(ctx context.Context, in *model.UserUpdateIn) (out *model.UpdateOut, err error) {
return
exist, err := dao.Users.Ctx(ctx).Where(do.Users{Id: in.Id}).Exist()
if err != nil {
return nil, ecode.Fail.Sub("该用户不存在")
}
if !exist {
return nil, ecode.Params.Sub("用户不存在")
}
_, err = dao.Users.Ctx(ctx).Where(do.Users{Id: in.Id}).Update(do.Users{
Nickname: in.Nickname,
Avatar: in.Avatar,
})
if err != nil {
return nil, ecode.Fail.Sub("更新用户信息失败")
}
return &model.UpdateOut{
Success: true,
}, nil
}
func (s *sUser) BindPhone(ctx context.Context, in *model.UserBindPhoneIn) (out *model.UpdateOut, err error) {
func (s *sUser) BindPhone(ctx context.Context, in *model.UserBindPhoneIn) (out *model.UserBindPhoneOut, err error) {
// 绑定手机号,需要验证入参和缓存中的验证码时候相同
return
value, err := g.Redis().Get(ctx, fmt.Sprintf(consts.UserBindPhoneKey, in.Id))
if err != nil {
return nil, ecode.Fail.Sub("获取失败")
}
if value.IsEmpty() {
return nil, ecode.Fail.Sub("验证码已过期")
}
if value.String() != in.PhoneCode {
return nil, ecode.Fail.Sub("验证码错误")
}
_, err = dao.Users.Ctx(ctx).Where(do.Users{Id: in.Id}).Update(do.Users{
PhoneNumber: in.Phone,
})
if err != nil {
return nil, ecode.Fail.Sub("绑定手机号失败")
}
return &model.UserBindPhoneOut{
Success: true,
}, nil
}
func (s *sUser) List(ctx context.Context, in *model.UserListIn) (out *model.UserListOut, err error) {

View File

@ -73,10 +73,26 @@ type UserInfoIn struct {
OpenId string
}
type UserInfoOut struct {
Id int64
Id int64
WxOpenId string
Username string
Nickname string
Avatar string
Email string
PhoneNumber string
WxPopenId string
QQPopenId string
RoleId int64
}
type UserBindPhoneIn struct {
Id int64
Phone string
PhoneCode string
}
type UserBindPhoneOut struct {
Success bool
}
type UserListIn struct {
@ -98,3 +114,22 @@ type UserCodeIn struct {
type UserCodeOut struct {
}
type UserUpdateImgIn struct {
Id int64
Nickname string
Avatar string
}
type UserUpdateImgOut struct {
Success bool
}
type GetPhoneCodeIn struct {
Id int64
Phone string
}
type GetPhoneCodeOut struct {
Success bool
}

View File

@ -15,9 +15,9 @@ type (
Login(ctx context.Context, in *model.UserLoginIn) (out *model.UserLoginOut, err error)
WeChatLogin(ctx context.Context, in *model.WeChatLogin) (out *model.WeChatLoginOut, err error)
Info(ctx context.Context, in *model.UserInfoIn) (out *model.UserInfoOut, err error)
Code(ctx context.Context, in *model.UserCodeIn) (out *model.UserCodeOut, err error)
Code(ctx context.Context, in *model.GetPhoneCodeIn) (out *model.GetPhoneCodeOut, err error)
Update(ctx context.Context, in *model.UserUpdateIn) (out *model.UpdateOut, err error)
BindPhone(ctx context.Context, in *model.UserBindPhoneIn) (out *model.UpdateOut, err error)
BindPhone(ctx context.Context, in *model.UserBindPhoneIn) (out *model.UserBindPhoneOut, err error)
List(ctx context.Context, in *model.UserListIn) (out *model.UserListOut, err error)
}
)