package user
import (
"context"
"fmt"
"focus-single/internal/model/do"
"focus-single/internal/service"
"github.com/gogf/gf/v2/crypto/gmd5"
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gctx"
"github.com/gogf/gf/v2/os/gfile"
"github.com/gogf/gf/v2/util/gconv"
"github.com/o1egl/govatar"
"focus-single/internal/consts"
"focus-single/internal/dao"
"focus-single/internal/model"
"focus-single/internal/model/entity"
)
type sUser struct {
avatarUploadPath string // 头像上传路径
avatarUploadUrlPrefix string // 头像上传对应的URL前缀
}
func init() {
user := New()
// 启动时创建头像存储目录
if !gfile.Exists(user.avatarUploadPath) {
if err := gfile.Mkdir(user.avatarUploadPath); err != nil {
g.Log().Fatal(gctx.New(), err)
}
}
service.RegisterUser(user)
}
func New() *sUser {
return &sUser{
avatarUploadPath: g.Cfg().MustGet(gctx.New(), `upload.path`).String() + `/avatar`,
avatarUploadUrlPrefix: `/upload/avatar`,
}
}
// 获得头像上传路径
func (s *sUser) GetAvatarUploadPath() string {
return s.avatarUploadPath
}
// 获得头像上传对应的URL前缀
func (s *sUser) GetAvatarUploadUrlPrefix() string {
return s.avatarUploadUrlPrefix
}
// 执行登录
func (s *sUser) Login(ctx context.Context, in model.UserLoginInput) error {
userEntity, err := s.GetUserByPassportAndPassword(
ctx,
in.Passport,
s.EncryptPassword(in.Passport, in.Password),
)
if err != nil {
return err
}
if userEntity == nil {
return gerror.New(`账号或密码错误`)
}
if err := service.Session().SetUser(ctx, userEntity); err != nil {
return err
}
// 自动更新上线
service.BizCtx().SetUser(ctx, &model.ContextUser{
Id: userEntity.Id,
Passport: userEntity.Passport,
Nickname: userEntity.Nickname,
Avatar: userEntity.Avatar,
})
return nil
}
// 注销
func (s *sUser) Logout(ctx context.Context) error {
return service.Session().RemoveUser(ctx)
}
// 将密码按照内部算法进行加密
func (s *sUser) EncryptPassword(passport, password string) string {
return gmd5.MustEncrypt(passport + password)
}
// 根据账号和密码查询用户信息,一般用于账号密码登录。
// 注意password参数传入的是按照相同加密算法加密过后的密码字符串。
func (s *sUser) GetUserByPassportAndPassword(ctx context.Context, passport, password string) (user *entity.User, err error) {
err = dao.User.Ctx(ctx).Where(g.Map{
dao.User.Columns().Passport: passport,
dao.User.Columns().Password: password,
}).Scan(&user)
return
}
// 检测给定的账号是否唯一
func (s *sUser) CheckPassportUnique(ctx context.Context, passport string) error {
n, err := dao.User.Ctx(ctx).Where(dao.User.Columns().Passport, passport).Count()
if err != nil {
return err
}
if n > 0 {
return gerror.Newf(`账号"%s"已被占用`, passport)
}
return nil
}
// 检测给定的昵称是否唯一
func (s *sUser) CheckNicknameUnique(ctx context.Context, nickname string) error {
n, err := dao.User.Ctx(ctx).Where(dao.User.Columns().Nickname, nickname).Count()
if err != nil {
return err
}
if n > 0 {
return gerror.Newf(`昵称"%s"已被占用`, nickname)
}
return nil
}
// 用户注册。
func (s *sUser) Register(ctx context.Context, in model.UserRegisterInput) error {
return dao.User.Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
var user *entity.User
if err := gconv.Struct(in, &user); err != nil {
return err
}
if err := s.CheckPassportUnique(ctx, user.Passport); err != nil {
return err
}
if err := s.CheckNicknameUnique(ctx, user.Nickname); err != nil {
return err
}
user.Password = s.EncryptPassword(user.Passport, user.Password)
// 自动生成头像
avatarFilePath := fmt.Sprintf(`%s/%s.jpg`, s.avatarUploadPath, user.Passport)
if err := govatar.GenerateFileForUsername(govatar.MALE, user.Passport, avatarFilePath); err != nil {
return gerror.Wrapf(err, `自动创建头像失败`)
}
user.Avatar = fmt.Sprintf(`%s/%s.jpg`, s.avatarUploadUrlPrefix, user.Passport)
_, err := dao.User.Ctx(ctx).Data(user).OmitEmpty().Save()
return err
})
}
// 修改个人密码
func (s *sUser) UpdatePassword(ctx context.Context, in model.UserPasswordInput) error {
return dao.User.Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
oldPassword := s.EncryptPassword(service.BizCtx().Get(ctx).User.Passport, in.OldPassword)
n, err := dao.User.Ctx(ctx).
Where(dao.User.Columns().Password, oldPassword).
Where(dao.User.Columns().Id, service.BizCtx().Get(ctx).User.Id).
Count()
if err != nil {
return err
}
if n == 0 {
return gerror.New(`原始密码错误`)
}
newPassword := s.EncryptPassword(service.BizCtx().Get(ctx).User.Passport, in.NewPassword)
_, err = dao.User.Ctx(ctx).Data(g.Map{
dao.User.Columns().Password: newPassword,
}).Where(dao.User.Columns().Id, service.BizCtx().Get(ctx).User.Id).Update()
return err
})
}
// 获取个人信息
func (s *sUser) GetProfileById(ctx context.Context, userId uint) (out *model.UserGetProfileOutput, err error) {
if err = dao.User.Ctx(ctx).WherePri(userId).Scan(&out); err != nil {
return nil, err
}
// 需要判断nil是否存在,不存在需要判断为空,以防后续nil
if out == nil {
return nil, nil
}
out.Stats, err = s.GetUserStats(ctx, userId)
if err != nil {
return nil, err
}
return
}
// 修改个人资料
func (s *sUser) GetProfile(ctx context.Context) (*model.UserGetProfileOutput, error) {
return s.GetProfileById(ctx, service.BizCtx().Get(ctx).User.Id)
}
func (s *sUser) UpdateAvatar(ctx context.Context, in model.UserUpdateAvatarInput) error {
return dao.User.Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
var (
err error
)
_, err = dao.User.Ctx(ctx).Data(do.User{
Avatar: in.Avatar,
}).Where(do.User{
Id: in.UserId,
}).Update()
return err
})
}
// 修改个人资料
func (s *sUser) UpdateProfile(ctx context.Context, in model.UserUpdateProfileInput) error {
return dao.User.Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
var (
err error
user = service.BizCtx().Get(ctx).User
userId = user.Id
)
n, err := dao.User.Ctx(ctx).
Where(dao.User.Columns().Nickname, in.Nickname).
WhereNot(dao.User.Columns().Id, userId).
Count()
if err != nil {
return err
}
if n > 0 {
return gerror.Newf(`昵称"%s"已被占用`, in.Nickname)
}
_, err = dao.User.Ctx(ctx).OmitEmpty().Data(in).Where(dao.User.Columns().Id, userId).Update()
// 更新登录session Nickname
if err == nil && user.Nickname != in.Nickname {
sessionUser := service.Session().GetUser(ctx)
sessionUser.Nickname = in.Nickname
err = service.Session().SetUser(ctx, sessionUser)
}
return err
})
}
// 禁用指定用户
func (s *sUser) Disable(ctx context.Context, id uint) error {
_, err := dao.User.Ctx(ctx).
Data(dao.User.Columns().Status, consts.UserStatusDisabled).
Where(dao.User.Columns().Id, id).
Update()
return err
}
// 查询用户内容列表及用户信息
func (s *sUser) GetList(ctx context.Context, in model.UserGetContentListInput) (out *model.UserGetListOutput, err error) {
out = &model.UserGetListOutput{}
// 内容列表
out.Content, err = service.Content().GetList(ctx, in.ContentGetListInput)
if err != nil {
return out, err
}
// 用户信息
out.User, err = service.User().GetProfileById(ctx, in.UserId)
if err != nil {
return out, err
}
// 统计信息
out.Stats, err = s.GetUserStats(ctx, in.UserId)
if err != nil {
return out, err
}
return
}
// 消息列表
func (s *sUser) GetMessageList(ctx context.Context, in model.UserGetMessageListInput) (out *model.UserGetMessageListOutput, err error) {
out = &model.UserGetMessageListOutput{
Page: in.Page,
Size: in.Size,
}
var userId = service.BizCtx().Get(ctx).User.Id
// 管理员看所有的
if !s.IsAdmin(ctx, userId) {
i
没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
收起资源包目录
Single_repo_demo_project_using_GoFrame_ (498个子文件)
gf.mwb.bak 33KB
bootstrap.css 193KB
bootstrap.min.css 157KB
index.css 34KB
katex.min.css 22KB
github-markdown.css 13KB
iconfont.css 12KB
demo.css 8KB
common.css 8KB
tango.css 4KB
colorful.css 4KB
ant-design.css 4KB
murphy.css 4KB
pastie.css 4KB
friendly.css 4KB
ant-design.css 4KB
rainbow_dash.css 4KB
lovelace.css 4KB
github.css 4KB
emacs.css 4KB
monokailight.css 4KB
native.css 4KB
manni.css 4KB
pygments.css 4KB
solarized-light.css 4KB
trac.css 4KB
perldoc.css 4KB
xcode.css 3KB
autumn.css 3KB
bw.css 3KB
solarized-dark256.css 3KB
solarized-dark.css 3KB
arduino.css 3KB
paraiso-light.css 3KB
paraiso-dark.css 3KB
vim.css 3KB
dracula.css 3KB
borland.css 3KB
monokai.css 3KB
abap.css 3KB
bootstrap-dialog.css 3KB
fruity.css 3KB
swapoff.css 3KB
algol.css 3KB
rrt.css 3KB
dark.css 2KB
wechat.css 2KB
light.css 2KB
igor.css 2KB
prism.css 2KB
vs.css 2KB
bootstrap-dialog.min.css 2KB
algol_nu.css 2KB
common.css 1KB
focus.db 668KB
Dockerfile 601B
iconfont.eot 13KB
huaji.gif 13KB
.gitattributes 80B
.gitignore 271B
.gitkeep 0B
.gitkeep 0B
.gitkeep 0B
user.go 10KB
content.go 8KB
interact.go 6KB
view.go 6KB
view_buildin.go 5KB
content.go 4KB
profile.go 4KB
category.go 4KB
content.go 4KB
cmd.go 4KB
reply.go 4KB
category.go 3KB
reply.go 3KB
session.go 3KB
content.go 3KB
interact.go 3KB
user.go 3KB
middleware.go 3KB
file.go 3KB
setting.go 3KB
user.go 2KB
content.go 2KB
reply.go 2KB
content.go 2KB
profile.go 2KB
user.go 2KB
user.go 2KB
article.go 2KB
file.go 2KB
ask.go 2KB
captcha.go 2KB
topic.go 2KB
response.go 2KB
content.go 2KB
user.go 1KB
category.go 1KB
reply.go 1KB
共 498 条
- 1
- 2
- 3
- 4
- 5
资源评论
好家伙VCC
- 粉丝: 2197
- 资源: 9145
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- 非常好的SqlServer大量源代码和教程资料100%好用.zip
- 基于Vue的社区拼购商城(毕业设计).zip
- springboot儿童安全知识教育系统
- (解压密码1234)HTML打包EXE 2.0.0 含Webview2内核
- zheshiyige rocketde bao
- 《人工智能及其应用》蔡自兴最新版课后习题参考答案2021
- 基于Vue、Node.js(Express)、MongoDB搭建的个人博客博客&后台管理系统admin,承接毕业设计系统+解决疑难杂症,联系微信zonemeen.zip
- 洗衣店全球市场报告:2023年洗衣机零售额高达934亿元,潜力无限
- springboot儿童安全知识教育系统
- 基于VUE+PHP的高校校友信息管理系统毕业设计.zip
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功