版本预发布

This commit is contained in:
孟帅
2023-02-08 20:29:34 +08:00
parent f11c7c5bf2
commit 2068d05c93
269 changed files with 16122 additions and 12075 deletions

View File

@@ -9,25 +9,26 @@ package admin
import (
"context"
"github.com/gogf/gf/v2/crypto/gmd5"
"github.com/gogf/gf/v2/encoding/gbase64"
"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/net/ghttp"
"github.com/gogf/gf/v2/os/gtime"
"github.com/gogf/gf/v2/text/gstr"
"github.com/gogf/gf/v2/util/gconv"
"github.com/gogf/gf/v2/util/grand"
"hotgo/api/backend/member"
"hotgo/internal/consts"
"hotgo/internal/dao"
"hotgo/internal/library/contexts"
"hotgo/internal/library/hgorm/handler"
"hotgo/internal/library/hgorm/hook"
"hotgo/internal/library/jwt"
"hotgo/internal/library/location"
"hotgo/internal/model"
"hotgo/internal/model/do"
"hotgo/internal/model/entity"
"hotgo/internal/model/input/adminin"
"hotgo/internal/model/input/sysin"
"hotgo/internal/service"
"hotgo/utility/encrypt"
"hotgo/utility/simple"
"hotgo/utility/tree"
"hotgo/utility/validate"
)
@@ -42,7 +43,148 @@ func init() {
service.RegisterAdminMember(NewAdminMember())
}
// UpdateProfile 更新会员资料
// UpdateCash 修改提现信息
func (s *sAdminMember) UpdateCash(ctx context.Context, in adminin.MemberUpdateCashInp) (err error) {
memberId := contexts.Get(ctx).User.Id
if memberId <= 0 {
err = gerror.New("获取用户信息失败!")
return
}
var memberInfo entity.AdminMember
if err = dao.AdminMember.Ctx(ctx).Where("id", memberId).Scan(&memberInfo); err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return
}
if gmd5.MustEncryptString(in.Password+memberInfo.Salt) != memberInfo.PasswordHash {
err = gerror.New("登录密码不正确")
return
}
_, err = dao.AdminMember.Ctx(ctx).
Where("id", memberId).
Data(g.Map{
"cash": adminin.MemberCash{
Name: in.Name,
Account: in.Account,
PayeeCode: in.PayeeCode,
},
}).
Update()
return
}
// UpdateEmail 换绑邮箱
func (s *sAdminMember) UpdateEmail(ctx context.Context, in adminin.MemberUpdateEmailInp) (err error) {
memberId := contexts.Get(ctx).User.Id
if memberId <= 0 {
err = gerror.New("获取用户信息失败!")
return err
}
var memberInfo *entity.AdminMember
if err = dao.AdminMember.Ctx(ctx).Where("id", memberId).Scan(&memberInfo); err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return err
}
if memberInfo == nil {
err = gerror.New("用户信息不存在")
return err
}
if memberInfo.Email == in.Email {
err = gerror.New("新旧邮箱不能一样")
return
}
if !validate.IsEmail(in.Email) {
err = gerror.New("邮箱地址不正确")
return
}
// 存在原绑定号码,需要进行验证
if memberInfo.Email != "" {
err = service.SysEmsLog().VerifyCode(ctx, sysin.VerifyEmsCodeInp{
Event: consts.EmsTemplateBind,
Email: memberInfo.Email,
Code: in.Code,
})
if err != nil {
return err
}
}
update := g.Map{
dao.AdminMember.Columns().Email: in.Email,
}
_, err = dao.AdminMember.Ctx(ctx).Where("id", memberId).Data(update).Update()
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return err
}
return
}
// UpdateMobile 换绑手机号
func (s *sAdminMember) UpdateMobile(ctx context.Context, in adminin.MemberUpdateMobileInp) (err error) {
memberId := contexts.Get(ctx).User.Id
if memberId <= 0 {
err = gerror.New("获取用户信息失败!")
return err
}
var memberInfo *entity.AdminMember
if err = dao.AdminMember.Ctx(ctx).Where("id", memberId).Scan(&memberInfo); err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return err
}
if memberInfo == nil {
err = gerror.New("用户信息不存在")
return err
}
if memberInfo.Mobile == in.Mobile {
err = gerror.New("新旧手机号不能一样")
return
}
if !validate.IsMobile(in.Mobile) {
err = gerror.New("手机号码不正确")
return
}
// 存在原绑定号码,需要进行验证
if memberInfo.Mobile != "" {
err = service.SysSmsLog().VerifyCode(ctx, sysin.VerifyCodeInp{
Event: consts.SmsTemplateBind,
Mobile: memberInfo.Mobile,
Code: in.Code,
})
if err != nil {
return err
}
}
update := g.Map{
dao.AdminMember.Columns().Mobile: in.Mobile,
}
_, err = dao.AdminMember.Ctx(ctx).Where("id", memberId).Data(update).Update()
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return err
}
return
}
// UpdateProfile 更新用户资料
func (s *sAdminMember) UpdateProfile(ctx context.Context, in adminin.MemberUpdateProfileInp) (err error) {
memberId := contexts.Get(ctx).User.Id
if memberId <= 0 {
@@ -50,21 +192,28 @@ func (s *sAdminMember) UpdateProfile(ctx context.Context, in adminin.MemberUpdat
return err
}
var memberInfo entity.AdminMember
var memberInfo *entity.AdminMember
if err = dao.AdminMember.Ctx(ctx).Where("id", memberId).Scan(&memberInfo); err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return err
}
_, err = dao.AdminMember.Ctx(ctx).
Where("id", memberId).
Data(g.Map{
"mobile": in.Mobile,
"email": in.Email,
"real_name": in.Realname,
}).
Update()
if memberInfo == nil {
err = gerror.New("用户信息不存在")
return err
}
update := g.Map{
dao.AdminMember.Columns().Avatar: in.Avatar,
dao.AdminMember.Columns().RealName: in.RealName,
dao.AdminMember.Columns().Qq: in.Qq,
dao.AdminMember.Columns().Birthday: in.Birthday,
dao.AdminMember.Columns().Sex: in.Sex,
dao.AdminMember.Columns().CityId: in.CityId,
dao.AdminMember.Columns().Address: in.Address,
}
_, err = dao.AdminMember.Ctx(ctx).Where("id", memberId).Data(update).Update()
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return err
@@ -104,19 +253,25 @@ func (s *sAdminMember) UpdatePwd(ctx context.Context, in adminin.MemberUpdatePwd
// ResetPwd 重置密码
func (s *sAdminMember) ResetPwd(ctx context.Context, in adminin.MemberResetPwdInp) (err error) {
var (
memberInfo entity.AdminMember
memberInfo *entity.AdminMember
memberId = contexts.GetUserId(ctx)
)
if err = dao.AdminMember.Ctx(ctx).Where("id", in.Id).Scan(&memberInfo); err != nil {
if err = s.FilterAuthModel(ctx, memberId).Where("id", in.Id).Scan(&memberInfo); err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return err
}
if memberInfo == nil {
err = gerror.New("用户信息不存在")
return err
}
if memberInfo.Pid != memberId && !s.VerifySuperId(ctx, memberId) {
err = gerror.New("操作非法")
return err
}
_, err = dao.AdminMember.Ctx(ctx).
_, err = s.FilterAuthModel(ctx, memberId).
Where("id", in.Id).
Data(g.Map{
"password_hash": gmd5.MustEncryptString(in.Password + memberInfo.Salt),
@@ -192,7 +347,7 @@ func (s *sAdminMember) Delete(ctx context.Context, in adminin.MemberDeleteInp) e
return gerror.New("获取用户信息失败!")
}
_, err := dao.AdminMember.Ctx(ctx).Where("id", in.Id).Where("pid", memberId).Delete()
_, err := s.FilterAuthModel(ctx, memberId).Where("id", in.Id).Delete()
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return err
@@ -246,11 +401,7 @@ func (s *sAdminMember) Edit(ctx context.Context, in adminin.MemberEditInp) (err
}
// 权限验证
var mm = dao.AdminMember.Ctx(ctx).Where("id", in.Id)
if !s.VerifySuperId(ctx, opMemberId) {
mm = mm.Where("pid", opMemberId)
}
var mm = s.FilterAuthModel(ctx, opMemberId).Where("id", in.Id)
_, err = mm.Data(in).Update()
if err != nil {
return gerror.Wrap(err, consts.ErrorORM)
@@ -307,7 +458,7 @@ func (s *sAdminMember) MaxSort(ctx context.Context, in adminin.MemberMaxSortInp)
// View 获取信息
func (s *sAdminMember) View(ctx context.Context, in adminin.MemberViewInp) (res *adminin.MemberViewModel, err error) {
if err = dao.AdminMember.Ctx(ctx).Where("id", in.Id).Scan(&res); err != nil {
if err = s.FilterAuthModel(ctx, contexts.GetUserId(ctx)).Hook(hook.MemberInfo).Where("id", in.Id).Scan(&res); err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return nil, err
}
@@ -317,10 +468,9 @@ func (s *sAdminMember) View(ctx context.Context, in adminin.MemberViewInp) (res
// List 获取列表
func (s *sAdminMember) List(ctx context.Context, in adminin.MemberListInp) (list []*adminin.MemberListModel, totalCount int, err error) {
g.Log().Printf(ctx, "in:%#v", in)
mod := dao.AdminMember.Ctx(ctx)
if in.Realname != "" {
mod = mod.WhereLike("real_name", "%"+in.Realname+"%")
mod := s.FilterAuthModel(ctx, contexts.GetUserId(ctx))
if in.RealName != "" {
mod = mod.WhereLike("real_name", "%"+in.RealName+"%")
}
if in.Username != "" {
mod = mod.WhereLike("username", "%"+in.Username+"%")
@@ -349,32 +499,11 @@ func (s *sAdminMember) List(ctx context.Context, in adminin.MemberListInp) (list
return list, totalCount, nil
}
if err = mod.Page(in.Page, in.PerPage).Order("id desc").Scan(&list); err != nil {
if err = mod.Hook(hook.MemberInfo).Page(in.Page, in.PerPage).Order("id desc").Scan(&list); err != nil {
return nil, 0, gerror.Wrap(err, consts.ErrorORM)
}
// 重写树入参
for i := 0; i < len(list); i++ {
// 部门
deptName, err := dao.AdminDept.Ctx(ctx).
Fields("name").
Where("id", list[i].DeptId).
Value()
if err != nil {
return nil, 0, gerror.Wrap(err, consts.ErrorORM)
}
list[i].DeptName = deptName.String()
// 角色
roleName, err := dao.AdminRole.Ctx(ctx).
Fields("name").
Where("id", list[i].RoleId).
Value()
if err != nil {
return nil, 0, gerror.Wrap(err, consts.ErrorORM)
}
list[i].RoleName = roleName.String()
// 岗位
posts, err := dao.AdminMemberPost.Ctx(ctx).
Fields("post_id").
@@ -414,27 +543,43 @@ func (s *sAdminMember) genTree(ctx context.Context, pid int64) (level int, newTr
}
// LoginMemberInfo 获取登录用户信息
func (s *sAdminMember) LoginMemberInfo(ctx context.Context, req *member.InfoReq) (res *adminin.MemberLoginModel, err error) {
identity := contexts.Get(ctx).User
if identity == nil {
func (s *sAdminMember) LoginMemberInfo(ctx context.Context) (res *adminin.LoginMemberInfoModel, err error) {
var memberId = contexts.GetUserId(ctx)
if memberId <= 0 {
err = gerror.New("用户身份异常,请重新登录!")
return
}
permissions, err := service.AdminMenu().LoginPermissions(ctx, identity.Id)
err = dao.AdminMember.Ctx(ctx).
Hook(hook.MemberInfo).
Where("id", memberId).
Scan(&res)
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return
}
res = &adminin.MemberLoginModel{
UserId: identity.Id,
Username: identity.Username,
RealName: identity.RealName,
Avatar: identity.Avatar,
Permissions: permissions,
Token: jwt.GetAuthorization(ghttp.RequestFromCtx(ctx)),
if res == nil {
err = gerror.New("用户不存在!")
return
}
// 细粒度权限
permissions, err := service.AdminMenu().LoginPermissions(ctx, memberId)
if err != nil {
return
}
res.Permissions = permissions
// 登录统计
stat, err := s.MemberLoginStat(ctx, adminin.MemberLoginStatInp{MemberId: memberId})
if err != nil {
return nil, err
}
res.MemberLoginStatModel = stat
res.Mobile = gstr.HideStr(res.Mobile, 40, `*`)
res.Email = gstr.HideStr(res.Email, 40, `*`)
return
}
@@ -443,11 +588,7 @@ func (s *sAdminMember) Login(ctx context.Context, in adminin.MemberLoginInp) (re
var (
roleInfo *entity.AdminRole
memberInfo *entity.AdminMember
identity *model.Identity
timestamp = gtime.Timestamp()
expires = g.Cfg().MustGet(ctx, "jwt.expires", 1).Int64()
exp = gconv.Int64(timestamp) + expires
lastIp = location.GetClientIp(ghttp.RequestFromCtx(ctx))
)
err = dao.AdminMember.Ctx(ctx).Where("username", in.Username).Scan(&memberInfo)
@@ -465,18 +606,13 @@ func (s *sAdminMember) Login(ctx context.Context, in adminin.MemberLoginInp) (re
return
}
// 解密密码
password, err := gbase64.Decode([]byte(in.Password))
err = simple.CheckPassword(in.Password, memberInfo.Salt, memberInfo.PasswordHash)
if err != nil {
return nil, err
}
password, err = encrypt.AesECBDecrypt(password, consts.RequestEncryptKey)
if err != nil {
return nil, err
return
}
if memberInfo.PasswordHash != gmd5.MustEncryptString(string(password)+memberInfo.Salt) {
err = gerror.New("用户密码不正确")
if memberInfo.Status != consts.StatusEnabled {
err = gerror.New("账号已被禁用")
return
}
@@ -494,27 +630,24 @@ func (s *sAdminMember) Login(ctx context.Context, in adminin.MemberLoginInp) (re
}
if roleInfo.Status != consts.StatusEnabled {
err = gerror.New("角色权限已被禁用")
err = gerror.New("角色已被禁用")
return
}
identity = &model.Identity{
Id: memberInfo.Id,
Pid: memberInfo.Pid,
DeptId: memberInfo.DeptId,
RoleId: roleInfo.Id,
RoleKey: roleInfo.Key,
Username: memberInfo.Username,
RealName: memberInfo.RealName,
Avatar: memberInfo.Avatar,
Email: memberInfo.Email,
Mobile: memberInfo.Mobile,
VisitCount: memberInfo.VisitCount,
LastTime: memberInfo.LastTime,
LastIp: lastIp,
Exp: exp,
Expires: expires,
App: consts.AppAdmin,
identity := &model.Identity{
Id: memberInfo.Id,
Pid: memberInfo.Pid,
DeptId: memberInfo.DeptId,
RoleId: roleInfo.Id,
RoleKey: roleInfo.Key,
Username: memberInfo.Username,
RealName: memberInfo.RealName,
Avatar: memberInfo.Avatar,
Email: memberInfo.Email,
Mobile: memberInfo.Mobile,
Exp: gtime.Timestamp() + expires,
Expires: expires,
App: consts.AppAdmin,
}
token, err := jwt.GenerateLoginToken(ctx, identity, false)
@@ -524,14 +657,10 @@ func (s *sAdminMember) Login(ctx context.Context, in adminin.MemberLoginInp) (re
}
// 更新登录信息
_, err = dao.AdminMember.Ctx(ctx).Data(do.AdminMember{
AuthKey: gmd5.MustEncryptString(token),
VisitCount: memberInfo.VisitCount + 1,
LastTime: timestamp,
LastIp: lastIp,
}).Where(do.AdminMember{
Id: memberInfo.Id,
}).Update()
_, err = dao.AdminMember.Ctx(ctx).
Data(do.AdminMember{AuthKey: gmd5.MustEncryptString(token)}).
Where(do.AdminMember{Id: memberInfo.Id}).
Update()
if err != nil {
err = gerror.New(err.Error())
@@ -539,17 +668,15 @@ func (s *sAdminMember) Login(ctx context.Context, in adminin.MemberLoginInp) (re
}
res = &adminin.MemberLoginModel{
UserId: identity.Id,
Username: identity.Username,
RealName: identity.RealName,
Avatar: identity.Avatar,
Token: token,
Id: identity.Id,
Token: token,
Expires: expires,
}
return res, nil
}
// RoleMemberList 获取角色下的会员列表
// RoleMemberList 获取角色下的用户列表
func (s *sAdminMember) RoleMemberList(ctx context.Context, in adminin.RoleMemberListInp) (list []*adminin.MemberListModel, totalCount int, err error) {
mod := dao.AdminMember.Ctx(ctx)
if in.Role > 0 {
@@ -594,7 +721,7 @@ func (s *sAdminMember) Status(ctx context.Context, in adminin.MemberStatusInp) (
// 修改
in.UpdatedAt = gtime.Now()
_, err = dao.AdminMember.Ctx(ctx).Where("id", in.Id).Data("status", in.Status).Update()
_, err = s.FilterAuthModel(ctx, contexts.GetUserId(ctx)).Where("id", in.Id).Data("status", in.Status).Update()
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return err
@@ -603,7 +730,7 @@ func (s *sAdminMember) Status(ctx context.Context, in adminin.MemberStatusInp) (
return nil
}
// GetIdByCode 通过邀请码获取会员ID
// GetIdByCode 通过邀请码获取用户ID
func (s *sAdminMember) GetIdByCode(ctx context.Context, in adminin.GetIdByCodeInp) (res *adminin.GetIdByCodeModel, err error) {
if err = dao.AdminMember.Ctx(ctx).
Fields("invite_code").
@@ -615,3 +742,53 @@ func (s *sAdminMember) GetIdByCode(ctx context.Context, in adminin.GetIdByCodeIn
return res, nil
}
// Select 获取可选的用户选项
func (s *sAdminMember) Select(ctx context.Context, in adminin.MemberSelectInp) (res []*adminin.MemberSelectModel, err error) {
err = dao.AdminMember.Ctx(ctx).
Fields("id as value,real_name as label,username,avatar").
Handler(handler.FilterAuthWithField("id")).
Scan(&res)
if err != nil {
return nil, gerror.Wrap(err, consts.ErrorORM)
}
return res, nil
}
func (s *sAdminMember) FilterAuthModel(ctx context.Context, memberId int64) *gdb.Model {
m := dao.AdminMember.Ctx(ctx)
if !s.VerifySuperId(ctx, memberId) {
m = m.Where("id <> ?", memberId)
}
return m.Handler(handler.FilterAuthWithField("id"))
}
// MemberLoginStat 用户登录统计
func (s *sAdminMember) MemberLoginStat(ctx context.Context, in adminin.MemberLoginStatInp) (res *adminin.MemberLoginStatModel, err error) {
var models *entity.SysLoginLog
err = dao.SysLoginLog.Ctx(ctx).
Fields("login_at,login_ip").
Where("member_id", in.MemberId).
Where("status", consts.StatusEnabled).
Scan(&models)
if err != nil {
return nil, err
}
res = new(adminin.MemberLoginStatModel)
if models == nil {
return
}
res.LastLoginAt = models.LoginAt
res.LastLoginIp = models.LoginIp
res.LoginCount, err = dao.SysLoginLog.Ctx(ctx).
Where("member_id", in.MemberId).
Where("status", consts.StatusEnabled).Count()
if err != nil {
return nil, err
}
return
}

View File

@@ -39,7 +39,7 @@ func (s *sAdminMemberPost) UpdatePostIds(ctx context.Context, member_id int64, p
PostId: post_ids[i],
})
if err != nil {
err = gerror.Wrap(err, "插入会员岗位失败")
err = gerror.Wrap(err, "插入用户岗位失败")
return err
}
}
@@ -47,7 +47,7 @@ func (s *sAdminMemberPost) UpdatePostIds(ctx context.Context, member_id int64, p
return nil
}
// GetMemberByIds 获取指定会员的岗位ids
// GetMemberByIds 获取指定用户的岗位ids
func (s *sAdminMemberPost) GetMemberByIds(ctx context.Context, member_id int64) (post_ids []int64, err error) {
var list []*entity.AdminMemberPost
err = dao.AdminMemberPost.Ctx(ctx).

View File

@@ -23,6 +23,7 @@ import (
"hotgo/internal/model/entity"
"hotgo/internal/model/input/adminin"
"hotgo/internal/service"
"hotgo/utility/convert"
"hotgo/utility/tree"
)
@@ -369,13 +370,8 @@ func (s *sAdminMenu) GetMenuList(ctx context.Context, memberId int64) (lists rol
return
}
// LoginPermissions 获取登录成功后的细权限
func (s *sAdminMenu) LoginPermissions(ctx context.Context, memberId int64) (lists []*adminin.MemberLoginPermissions, err error) {
// 空跑
lists = append(lists, &adminin.MemberLoginPermissions{
Value: "value",
})
// LoginPermissions 获取登录成功后的细粒度权限
func (s *sAdminMenu) LoginPermissions(ctx context.Context, memberId int64) (lists adminin.MemberLoginPermissions, err error) {
type Permissions struct {
Permissions string `json:"permissions"`
}
@@ -401,17 +397,18 @@ func (s *sAdminMenu) LoginPermissions(ctx context.Context, memberId int64) (list
return lists, err
}
// 无权限
if len(allPermissions) == 0 {
lists = append(lists, "value")
return
}
for _, v := range allPermissions {
for _, p := range gstr.Explode(`,`, v.Permissions) {
lists = append(lists, &adminin.MemberLoginPermissions{
Value: p,
})
lists = append(lists, p)
}
}
lists = convert.UniqueSliceString(lists)
return
}

View File

@@ -8,17 +8,22 @@ package admin
import (
"context"
"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/gtime"
"github.com/gogf/gf/v2/util/gconv"
"hotgo/internal/consts"
"hotgo/internal/dao"
"hotgo/internal/library/contexts"
"hotgo/internal/library/hgorm/handler"
"hotgo/internal/model/entity"
"hotgo/internal/model/input/adminin"
"hotgo/internal/model/input/form"
"hotgo/internal/service"
"hotgo/internal/websocket"
"hotgo/utility/charset"
"hotgo/utility/simple"
"hotgo/utility/validate"
"strings"
)
type sAdminNotice struct{}
@@ -31,9 +36,14 @@ func init() {
service.RegisterAdminNotice(NewAdminNotice())
}
// Model Orm模型
func (s *sAdminNotice) Model(ctx context.Context, option ...*handler.Option) *gdb.Model {
return handler.Model(dao.AdminNotice.Ctx(ctx), option...)
}
// Delete 删除
func (s *sAdminNotice) Delete(ctx context.Context, in adminin.NoticeDeleteInp) error {
_, err := dao.AdminNotice.Ctx(ctx).Where("id", in.Id).Delete()
_, err := s.Model(ctx).Where("id", in.Id).Delete()
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return err
@@ -44,44 +54,64 @@ func (s *sAdminNotice) Delete(ctx context.Context, in adminin.NoticeDeleteInp) e
// Edit 修改/新增
func (s *sAdminNotice) Edit(ctx context.Context, in adminin.NoticeEditInp) (err error) {
var member = contexts.Get(ctx).User
if member == nil {
err = gerror.New("获取用户信息失败!")
return
}
if in.Title == "" {
err = gerror.New("标题不能为空")
return err
return
}
if in.Type == consts.NoticeTypeLetter && len(in.Receiver) == 0 {
err = gerror.New("私信类型必须选择接收人")
return
}
// 检查选项接收人是否合法
if in.Type == consts.NoticeTypeLetter {
count, _ := dao.AdminMember.Ctx(ctx).Handler(handler.FilterAuthWithField("id")).WhereIn("id", in.Receiver).Count()
if count != len(in.Receiver) {
err = gerror.New("接收人不合法")
return
}
in.SenderAvatar = member.Avatar
}
// 修改
in.UpdatedAt = gtime.Now()
if in.Id > 0 {
_, err = dao.AdminNotice.Ctx(ctx).Where("id", in.Id).Data(in).Update()
in.UpdatedBy = member.Id
_, err = s.Model(ctx).Where("id", in.Id).Data(in).Update()
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return err
}
return nil
}
// 新增
in.CreatedBy = member.Id
in.CreatedAt = gtime.Now()
_, err = dao.AdminNotice.Ctx(ctx).Data(in).Insert()
in.Id, err = s.Model(ctx, &handler.Option{FilterAuth: false}).Data(in).InsertAndGetId()
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return err
}
// 推送通知
memberIds := charset.SplitMemberIds(in.Receiver, ",")
response := &websocket.WResponse{
Event: "notice",
Data: in,
}
simple.SafeGo(ctx, func(ctx context.Context) {
if len(memberIds) == 0 {
websocket.SendToAll(response)
} else {
for _, memberId := range memberIds {
websocket.SendToUser(memberId, response)
if in.Type == consts.NoticeTypeLetter {
for _, receiverId := range in.Receiver {
websocket.SendToUser(receiverId, response)
}
} else {
websocket.SendToAll(response)
}
})
@@ -106,8 +136,7 @@ func (s *sAdminNotice) Status(ctx context.Context, in adminin.NoticeStatusInp) (
}
// 修改
in.UpdatedAt = gtime.Now()
_, err = dao.AdminNotice.Ctx(ctx).Where("id", in.Id).Data("status", in.Status).Update()
_, err = s.Model(ctx).Where("id", in.Id).Data("status", in.Status).Update()
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return err
@@ -119,19 +148,17 @@ func (s *sAdminNotice) Status(ctx context.Context, in adminin.NoticeStatusInp) (
// MaxSort 最大排序
func (s *sAdminNotice) MaxSort(ctx context.Context, in adminin.NoticeMaxSortInp) (*adminin.NoticeMaxSortModel, error) {
var res adminin.NoticeMaxSortModel
if in.Id > 0 {
if err := dao.AdminNotice.Ctx(ctx).Where("id", in.Id).Order("sort desc").Scan(&res); err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return nil, err
}
if err := s.Model(ctx).Order("sort desc").Scan(&res); err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return nil, err
}
res.Sort = res.Sort + 10
res.Sort = form.DefaultMaxSort(ctx, res.Sort)
return &res, nil
}
// View 获取指定字典类型信息
func (s *sAdminNotice) View(ctx context.Context, in adminin.NoticeViewInp) (res *adminin.NoticeViewModel, err error) {
if err = dao.AdminNotice.Ctx(ctx).Where("id", in.Id).Scan(&res); err != nil {
if err = s.Model(ctx).Where("id", in.Id).Scan(&res); err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return nil, err
}
@@ -141,19 +168,26 @@ func (s *sAdminNotice) View(ctx context.Context, in adminin.NoticeViewInp) (res
// List 获取列表
func (s *sAdminNotice) List(ctx context.Context, in adminin.NoticeListInp) (list []*adminin.NoticeListModel, totalCount int, err error) {
mod := dao.AdminNotice.Ctx(ctx)
var memberId = contexts.GetUserId(ctx)
if memberId <= 0 {
err = gerror.New("获取用户信息失败!")
return
}
mod := s.Model(ctx)
// 访问路径
if in.Title != "" {
mod = mod.WhereLike("title", "%"+in.Title+"%")
}
// 模块
if in.Content != "" {
mod = mod.WhereLike("content", "%"+in.Content+"%")
}
// 请求方式
if in.Type > 0 {
mod = mod.Where("type", in.Type)
}
if in.Status > 0 {
mod = mod.Where("status", in.Status)
}
@@ -173,8 +207,291 @@ func (s *sAdminNotice) List(ctx context.Context, in adminin.NoticeListInp) (list
return list, totalCount, err
}
for k, v := range list {
list[k].ReceiveNum = len(strings.Split(v.Reader, ","))
for _, v := range list {
// 接收人头像组
if v.Type == consts.NoticeTypeLetter {
err = dao.AdminMember.Ctx(ctx).
Fields("real_name as name,avatar as src").
WhereIn("id", v.Receiver.Var().Int64s()).
Scan(&v.ReceiverGroup)
if err != nil {
return
}
}
if v.ReceiverGroup == nil || len(v.ReceiverGroup) == 0 {
v.ReceiverGroup = make([]form.AvatarGroup, 0)
}
// 阅读次数
v.ReadCount, err = dao.AdminNoticeRead.Ctx(ctx).Where("notice_id", v.Id).Sum("clicks")
if err != nil {
return
}
}
return list, totalCount, err
}
// PullMessages 拉取未读消息列表
func (s *sAdminNotice) PullMessages(ctx context.Context, in adminin.PullMessagesInp) (res *adminin.PullMessagesModel, err error) {
var memberId = contexts.GetUserId(ctx)
if memberId <= 0 {
err = gerror.New("获取用户信息失败!")
return
}
messageIds, err := s.messageIds(ctx, memberId)
if err != nil {
return
}
res = new(adminin.PullMessagesModel)
unread, err := s.UnreadCount(ctx, adminin.NoticeUnreadCountInp{MemberId: memberId, MessageIds: messageIds})
if err != nil {
return
}
if unread != nil {
res.NoticeUnreadCountModel = unread
}
if err = s.Model(ctx).WhereIn("id", messageIds).Limit(in.Limit).Order("id desc").Scan(&res.List); err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return
}
for _, v := range res.List {
count, _ := dao.AdminNoticeRead.Ctx(ctx).Where("notice_id", v.Id).Where("member_id", memberId).Count()
if count > 0 {
v.IsRead = true
}
if v.Type == consts.NoticeTypeLetter {
val, err := dao.AdminMember.Ctx(ctx).Fields("avatar").Where("id", v.CreatedBy).Value()
if err == nil {
v.SenderAvatar = val.String()
}
}
}
return
}
// UnreadCount 获取所有类型消息的未读数量
func (s *sAdminNotice) UnreadCount(ctx context.Context, in adminin.NoticeUnreadCountInp) (res *adminin.NoticeUnreadCountModel, err error) {
if in.MemberId <= 0 {
if in.MemberId = contexts.GetUserId(ctx); in.MemberId <= 0 {
err = gerror.New("获取用户信息失败!")
return
}
}
if len(in.MessageIds) == 0 {
in.MessageIds, err = s.messageIds(ctx, in.MemberId)
if err != nil {
return
}
if len(in.MessageIds) == 0 {
return
}
}
stat := func(t int) (count int) {
all, err := dao.AdminNotice.Ctx(ctx).As("nr").
Where("type =? and id IN(?)", t, in.MessageIds).
Count()
if err != nil {
g.Log().Infof(ctx, "UnreadCount stat err:%+v", err)
return
}
if all == 0 {
return
}
read, err := dao.AdminNoticeRead.Ctx(ctx).As("nr").
LeftJoin("admin_notice n", "nr.notice_id=n.id").
Where("n.type = ? and n.id IN(?)", t, in.MessageIds).
Where("nr.member_id", in.MemberId).
Count()
if err != nil {
g.Log().Infof(ctx, "UnreadCount stat2 err:%+v", err)
return
}
count = all - read
return
}
res = new(adminin.NoticeUnreadCountModel)
res.NotifyCount = stat(consts.NoticeTypeNotify)
res.NoticeCount = stat(consts.NoticeTypeNotice)
res.LetterCount = stat(consts.NoticeTypeLetter)
return
}
// messageIds 获取我的消息所有的消息ID
func (s *sAdminNotice) messageIds(ctx context.Context, memberId int64) (ids []int64, err error) {
mod := s.Model(ctx, &handler.Option{FilterAuth: false}).
Fields("id").
Where("status", consts.StatusEnabled).
Where("(`type` IN(?) OR (`type` = ? and JSON_CONTAINS(`receiver`,'"+gconv.String(memberId)+"')))",
[]int{consts.NoticeTypeNotify, consts.NoticeTypeNotice}, consts.NoticeTypeLetter,
)
array, err := mod.Array()
if err != nil {
return nil, err
}
for _, v := range array {
ids = append(ids, v.Int64())
}
return
}
// UpRead 更新已读
func (s *sAdminNotice) UpRead(ctx context.Context, in adminin.NoticeUpReadInp) (err error) {
var (
data *entity.AdminNotice
memberId = contexts.GetUserId(ctx)
)
if memberId <= 0 {
err = gerror.New("获取用户信息失败!")
return
}
if err = dao.AdminNotice.Ctx(ctx).Where("id", in.Id).Scan(&data); err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return err
}
if data == nil {
return gerror.New("公告不存在")
}
return s.updatedReadClicks(ctx, in.Id, memberId)
}
// ReadAll 已读全部
func (s *sAdminNotice) ReadAll(ctx context.Context, in adminin.NoticeReadAllInp) (err error) {
var memberId = contexts.GetUserId(ctx)
if memberId <= 0 {
err = gerror.New("获取用户信息失败!")
return
}
allMessageIds, err := s.messageIds(ctx, memberId)
if err != nil {
return
}
if len(allMessageIds) == 0 {
return
}
array, err := dao.AdminNotice.Ctx(ctx).
Fields("id").
Where("type = ? and id IN(?)", in.Type, allMessageIds).
Array()
if err != nil {
return
}
var messageIds []int64
for _, v := range array {
messageIds = append(messageIds, v.Int64())
}
array, err = dao.AdminNoticeRead.Ctx(ctx).As("nr").
Fields("nr.notice_id").
LeftJoin("admin_notice n", "nr.notice_id=n.id").
Where("n.type = ? and n.id IN(?)", in.Type, messageIds).
Where("nr.member_id", memberId).
Array()
if err != nil {
return
}
var readIds []int64
for _, v := range array {
readIds = append(readIds, v.Int64())
}
for _, messageId := range messageIds {
if !validate.InSliceInt64(readIds, messageId) {
if err = s.updatedReadClicks(ctx, messageId, memberId); err != nil {
return
}
}
}
return
}
// updatedReadClicks 更新公告已读次数
func (s *sAdminNotice) updatedReadClicks(ctx context.Context, noticeId, memberId int64) (err error) {
var (
models *entity.AdminNoticeRead
)
err = dao.AdminNoticeRead.Ctx(ctx).
Where(dao.AdminNoticeRead.Columns().NoticeId, noticeId).
Where(dao.AdminNoticeRead.Columns().MemberId, memberId).
Scan(&models)
if err != nil {
return
}
if models == nil {
_, err = dao.AdminNoticeRead.Ctx(ctx).Data(entity.AdminNoticeRead{NoticeId: noticeId, MemberId: memberId}).Insert()
return
}
_, err = dao.AdminNoticeRead.Ctx(ctx).Where(dao.AdminNoticeRead.Columns().Id, models.Id).Increment("clicks", 1)
return
}
// MessageList 我的消息列表
func (s *sAdminNotice) MessageList(ctx context.Context, in adminin.NoticeMessageListInp) (list []*adminin.NoticeMessageListModel, totalCount int, err error) {
var memberId = contexts.GetUserId(ctx)
if memberId <= 0 {
err = gerror.New("获取用户信息失败!")
return
}
allMessageIds, err := s.messageIds(ctx, memberId)
if err != nil {
return
}
if len(allMessageIds) == 0 {
return
}
mod := s.Model(ctx, &handler.Option{FilterAuth: false}).WhereIn("id", allMessageIds).Where("type", in.Type)
totalCount, err = mod.Count()
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return list, totalCount, err
}
if totalCount == 0 {
return list, totalCount, nil
}
if err = mod.Page(in.Page, in.PerPage).Order("id desc").Scan(&list); err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return list, totalCount, err
}
for _, v := range list {
count, _ := dao.AdminNoticeRead.Ctx(ctx).Where("notice_id", v.Id).Where("member_id", memberId).Count()
if count > 0 {
v.IsRead = true
}
if v.Type == consts.NoticeTypeLetter {
val, err := dao.AdminMember.Ctx(ctx).Fields("avatar").Where("id", v.CreatedBy).Value()
if err == nil {
v.SenderAvatar = val.String()
}
}
}
return list, totalCount, err
}

View File

@@ -27,6 +27,7 @@ import (
"hotgo/utility/convert"
"hotgo/utility/tree"
"sort"
"strconv"
)
type sAdminRole struct{}
@@ -60,7 +61,7 @@ func (s *sAdminRole) Verify(ctx context.Context, path, method string) bool {
}
ok, err := casbin.Enforcer.Enforce(user.RoleKey, path, method)
if err != nil {
g.Log().Warningf(ctx, "admin Verify Enforce err:%v", err)
g.Log().Warningf(ctx, "admin Verify Enforce err:%+v", err)
return false
}
@@ -86,6 +87,12 @@ func (s *sAdminRole) List(ctx context.Context, in adminin.RoleListInp) (list []g
return list, totalCount, err
}
for _, v := range models {
v.Label = v.Name
v.Value = v.Id
v.Key = strconv.FormatInt(v.Id, 10)
}
return tree.GenTree(gconv.SliceMap(models)), totalCount, err
}
@@ -104,7 +111,7 @@ func (s *sAdminRole) GetName(ctx context.Context, RoleId int64) (name string, er
return roleName.String(), nil
}
// GetMemberList 获取指定会员的岗位列表
// GetMemberList 获取指定用户的岗位列表
func (s *sAdminRole) GetMemberList(ctx context.Context, RoleId int64) (list []*adminin.RoleListModel, err error) {
err = dao.AdminRole.Ctx(ctx).
Where("id", RoleId).

View File

@@ -18,6 +18,7 @@ import (
"hotgo/internal/dao"
"hotgo/internal/library/contexts"
"hotgo/internal/library/hgorm"
"hotgo/internal/library/hgorm/handler"
"hotgo/internal/model/input/adminin"
"hotgo/internal/model/input/form"
"hotgo/internal/service"
@@ -37,13 +38,13 @@ func init() {
}
// Model Orm模型
func (s *sAdminTest) Model(ctx context.Context) *gdb.Model {
return dao.Test.Ctx(ctx)
func (s *sAdminTest) Model(ctx context.Context, option ...*handler.Option) *gdb.Model {
return handler.Model(dao.Test.Ctx(ctx), option...)
}
// List 获取列表
func (s *sAdminTest) List(ctx context.Context, in adminin.TestListInp) (list []*adminin.TestListModel, totalCount int, err error) {
mod := dao.Test.Ctx(ctx)
mod := s.Model(ctx)
if in.Title != "" {
mod = mod.WhereLike(dao.Test.Columns().Title, "%"+in.Title+"%")
@@ -98,11 +99,11 @@ func (s *sAdminTest) List(ctx context.Context, in adminin.TestListInp) (list []*
totalCount, err = mod.Clone().Count(1)
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return list, totalCount, err
return
}
if totalCount == 0 {
return list, totalCount, nil
return
}
////关联表select
@@ -113,28 +114,27 @@ func (s *sAdminTest) List(ctx context.Context, in adminin.TestListInp) (list []*
fields, err := hgorm.GenSelect(ctx, adminin.TestListModel{}, dao.Test)
if err != nil {
return nil, 0, err
return
}
if err = mod.Fields(fields).Handler(hgorm.HandlerFilterAuth, hgorm.HandlerForceCache).Page(in.Page, in.PerPage).OrderAsc(dao.Test.Columns().Sort).OrderDesc(dao.Test.Columns().Id).Scan(&list); err != nil {
if err = mod.Fields(fields).Handler(handler.FilterAuth, handler.ForceCache).Page(in.Page, in.PerPage).OrderAsc(dao.Test.Columns().Sort).OrderDesc(dao.Test.Columns().Id).Scan(&list); err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return list, totalCount, err
return
}
return list, totalCount, err
return
}
// Export 导出
func (s *sAdminTest) Export(ctx context.Context, in adminin.TestListInp) (err error) {
list, totalCount, err := s.List(ctx, in)
if err != nil {
return err
return
}
// 字段的排序是依据tags的字段顺序如果你不想使用默认的排序方式可以直接定义 tags = []string{"字段名称", "字段名称2", ...}
tags, err := convert.GetEntityDescTags(adminin.TestExportModel{})
if err != nil {
return err
return
}
var (
@@ -143,10 +143,10 @@ func (s *sAdminTest) Export(ctx context.Context, in adminin.TestListInp) (err er
exports []adminin.TestExportModel
)
err = gconv.Scan(list, &exports)
if err != nil {
return err
if err = gconv.Scan(list, &exports); err != nil {
return
}
if err = excel.ExportByStructs(ctx, tags, exports, fileName, sheetName); err != nil {
return
}
@@ -156,70 +156,51 @@ func (s *sAdminTest) Export(ctx context.Context, in adminin.TestListInp) (err er
// Edit 修改/新增
func (s *sAdminTest) Edit(ctx context.Context, in adminin.TestEditInp) (err error) {
if err = hgorm.IsUnique(ctx, dao.Test, g.Map{dao.Test.Columns().Qq: in.Qq}, "QQ号码已存在请换一个", in.Id); err != nil {
if err != nil {
return err
}
return
}
// 修改
if in.Id > 0 {
in.UpdatedBy = contexts.GetUserId(ctx)
_, err = dao.Test.Ctx(ctx).Where(dao.Test.Columns().Id, in.Id).Data(in).Update()
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return err
}
return nil
_, err = s.Model(ctx).Where(dao.Test.Columns().Id, in.Id).Data(in).Update()
return
}
// 新增
in.CreatedBy = contexts.GetUserId(ctx)
_, err = dao.Test.Ctx(ctx).Data(in).Insert()
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return err
}
return nil
_, err = s.Model(ctx, &handler.Option{FilterAuth: false}).Data(in).Insert()
return
}
// Delete 删除
func (s *sAdminTest) Delete(ctx context.Context, in adminin.TestDeleteInp) (err error) {
_, err = dao.Test.Ctx(ctx).Where(dao.Test.Columns().Id, in.Id).Delete()
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return err
}
return nil
_, err = s.Model(ctx).Where(dao.Test.Columns().Id, in.Id).Delete()
return
}
// Status 更新状态
func (s *sAdminTest) Status(ctx context.Context, in adminin.TestStatusInp) (err error) {
if in.Id <= 0 {
err = gerror.New("ID不能为空")
return err
return
}
if in.Status <= 0 {
err = gerror.New("状态不能为空")
return err
return
}
if !validate.InSliceInt(consts.StatusMap, in.Status) {
err = gerror.New("状态不正确")
return err
return
}
// 修改
_, err = dao.Test.Ctx(ctx).Where(dao.Test.Columns().Id, in.Id).Data(dao.Test.Columns().Status, in.Status).Update()
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return err
}
return nil
_, err = s.Model(ctx).Where(dao.Test.Columns().Id, in.Id).Data(g.Map{
dao.Test.Columns().Status: in.Status,
dao.Test.Columns().UpdatedBy: contexts.GetUserId(ctx),
}).Update()
return
}
// Switch 更新开关状态
@@ -231,36 +212,34 @@ func (s *sAdminTest) Switch(ctx context.Context, in adminin.TestSwitchInp) (err
if !validate.InSliceString(fields, in.Key) {
err = gerror.New("开关键名不在白名单")
return err
return
}
// 修改
_, err = dao.Test.Ctx(ctx).Where(dao.Test.Columns().Id, in.Id).Data(in.Key, in.Value).Update()
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return err
}
return nil
_, err = s.Model(ctx).Where(dao.Test.Columns().Id, in.Id).Data(g.Map{
in.Key: in.Value,
dao.Test.Columns().UpdatedBy: contexts.GetUserId(ctx),
}).Update()
return
}
// MaxSort 最大排序
func (s *sAdminTest) MaxSort(ctx context.Context, in adminin.TestMaxSortInp) (res *adminin.TestMaxSortModel, err error) {
if err = dao.Test.Ctx(ctx).Fields(dao.Test.Columns().Sort).OrderDesc(dao.Test.Columns().Sort).Scan(&res); err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return nil, err
return
}
res.Sort = res.Sort + g.Cfg().MustGet(ctx, "hotgo.admin.maxSortIncrement").Int()
return res, nil
if res == nil {
res = new(adminin.TestMaxSortModel)
}
res.Sort = form.DefaultMaxSort(ctx, res.Sort)
return
}
// View 获取指定字典类型信息
func (s *sAdminTest) View(ctx context.Context, in adminin.TestViewInp) (res *adminin.TestViewModel, err error) {
if err = dao.Test.Ctx(ctx).Where(dao.Test.Columns().Id, in.Id).Scan(&res); err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return nil, err
}
return res, nil
err = s.Model(ctx).Where(dao.Test.Columns().Id, in.Id).Scan(&res)
return
}