Merge remote-tracking branch 'origin/master'

# Conflicts:
#	internal/dao/internal/store_desktop_settings.go
#	internal/dao/internal/store_roles.go
#	internal/dao/store_desktop_settings.go
#	internal/dao/store_roles.go
This commit is contained in:
chy
2025-06-13 09:49:03 +08:00
36 changed files with 906 additions and 57 deletions

View File

@ -15,6 +15,7 @@ import (
_ "server/internal/logic/role"
_ "server/internal/logic/store"
_ "server/internal/logic/storeAdmin"
_ "server/internal/logic/storeRole"
_ "server/internal/logic/task"
_ "server/internal/logic/upload"
_ "server/internal/logic/user"

View File

@ -5,8 +5,6 @@ import (
"fmt"
"github.com/gogf/gf/v2/database/gdb"
"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/util/grand"
"server/internal/consts"
"server/internal/dao"
@ -80,13 +78,6 @@ func (s *sMerchantAdmin) Login(ctx context.Context, in *model.MerchantLoginIn) (
out = &model.MerchantLoginOut{
Token: token,
}
go func(ctx context.Context, merchantAdminId int64) {
// 更新商户管理员登录时间
dao.MerchantAdmins.Ctx(ctx).WherePri(merchantAdminId).Update(do.MerchantAdmins{
LastLoginAt: gtime.Now(),
LastLoginIp: ghttp.RequestFromCtx(ctx).RemoteAddr,
})
}(context.Background(), mAdminId)
return
}
func (s *sMerchantAdmin) Info(ctx context.Context, in *model.MerchantAdminInfoIn) (out *model.MerchantAdminInfoOut, err error) {

View File

@ -3,6 +3,7 @@ package store
import (
"context"
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/errors/gerror"
"server/internal/consts"
"server/internal/dao"
"server/internal/model"
@ -152,3 +153,77 @@ func (s *sStore) Info(ctx context.Context, in *model.StoreInfoIn) (out *model.St
// TODO 获取门店信息等相关信息
return
}
func (s *sStore) GetDesktopSetting(ctx context.Context, in *model.StoreGetDesktopSettingIn) (*model.StoreGetDesktopSettingOut, error) {
// 检查门店桌面设置是否存在
exist, err := dao.StoreDesktopSettings.Ctx(ctx).Where(do.StoreDesktopSettings{StoreId: in.StoreId}).Count()
if err != nil {
return nil, gerror.Wrap(ecode.Fail, "查询门店桌面设置出现异常")
}
if exist == 0 {
return &model.StoreGetDesktopSettingOut{}, nil
}
// 查询桌面设置
out := &model.StoreGetDesktopSettingOut{}
err = dao.StoreDesktopSettings.Ctx(ctx).Where(do.StoreDesktopSettings{StoreId: in.StoreId}).Scan(out)
if err != nil {
return nil, gerror.Wrap(ecode.Fail, "查询门店桌面设置出现异常")
}
return out, nil
}
func (s *sStore) SaveDesktopSetting(ctx context.Context, in *model.SaveDesktopSettingIn) (*model.SaveDesktopSettingOut, error) {
out := &model.SaveDesktopSettingOut{}
err := dao.StoreDesktopSettings.Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
// 构建数据,包含所有字段
data := do.StoreDesktopSettings{
Id: in.Id,
StoreId: in.StoreId,
BackgroundUrl: in.BackgroundUrl,
Resolution: in.Resolution,
IsTopWidgetVisible: in.IsTopWidgetVisible,
IsRightWidgetVisible: in.IsRightWidgetVisible,
}
// 检查记录是否存在(基于 store_id
exist, err := dao.StoreDesktopSettings.Ctx(ctx).TX(tx).Where(do.StoreDesktopSettings{StoreId: in.StoreId}).Count()
if err != nil {
return gerror.Wrap(ecode.Fail, "检查门店桌面设置失败")
}
if exist == 0 {
// 新增
result, err := dao.StoreDesktopSettings.Ctx(ctx).TX(tx).Data(data).Insert()
if err != nil {
return gerror.Wrap(ecode.Fail, "新增门店桌面设置失败")
}
id, err := result.LastInsertId()
if err != nil {
return gerror.Wrap(ecode.Fail, "获取新增记录ID失败")
}
out.Id = id
} else {
// 更新(如果提供了 Id则优先使用 Id 作为条件,否则使用 StoreId
updateWhere := do.StoreDesktopSettings{StoreId: in.StoreId}
if in.Id > 0 {
updateWhere = do.StoreDesktopSettings{Id: in.Id}
}
_, err := dao.StoreDesktopSettings.Ctx(ctx).TX(tx).Data(data).Where(updateWhere).Update()
if err != nil {
return gerror.Wrap(ecode.Fail, "更新门店桌面设置失败")
}
id, err := dao.StoreDesktopSettings.Ctx(ctx).TX(tx).Where(updateWhere).Fields(dao.StoreDesktopSettings.Columns().Id).Value()
if err != nil {
return gerror.Wrap(ecode.Fail, "获取更新记录ID失败")
}
out.Id = id.Int64()
}
return nil
})
if err != nil {
return nil, err
}
return out, nil
}

View File

@ -2,6 +2,7 @@ package storeAdmin
import (
"context"
"fmt"
"server/internal/consts"
"server/internal/dao"
"server/internal/model"
@ -92,3 +93,132 @@ func (s *sStoreAdmin) Info(ctx context.Context, in *model.StoreAdminInfoIn) (out
}
return
}
func (s *sStoreAdmin) List(ctx context.Context, in *model.StoreAdminListIn) (out *model.StoreAdminListOut, err error) {
list := make([]model.StoreAdmin, 0)
var total int
if err = dao.StoreAdmins.Ctx(ctx).LeftJoin(
dao.StoreRoles.Table(),
fmt.Sprintf("%s.%s = %s.%s", dao.StoreAdmins.Table(), dao.StoreAdmins.Columns().StoreRoleId, dao.StoreRoles.Table(), dao.StoreRoles.Columns().Id),
).Fields(
fmt.Sprintf("%s.*, %s.name as store_role_name", dao.StoreAdmins.Table(), dao.StoreRoles.Table()),
).Page(in.Page, in.Size).Where(do.StoreAdmins{StoreId: in.StoreId}).ScanAndCount(&list, &total, false); err != nil {
return nil, ecode.Fail.Sub("查询门店管理员失败")
}
return &model.StoreAdminListOut{
List: list,
Total: total,
}, nil
}
func (s *sStoreAdmin) Create(ctx context.Context, in *model.StoreAdminCreateIn) (out *model.CreateOut, err error) {
exist, err := dao.StoreAdmins.Ctx(ctx).Where(do.StoreAdmins{Username: in.Username}).Exist()
if err != nil {
return nil, ecode.Fail.Sub("查询商户管理员失败")
}
if exist {
return nil, ecode.Fail.Sub("该用户名已被注册")
}
passwordHash, err := encrypt.EncryptPassword(in.Password)
if err != nil {
return nil, ecode.Fail.Sub("密码加密失败")
}
count, err := dao.StoreRoles.Ctx(ctx).Where(do.StoreRoles{Id: in.StoreRoleId}).Count()
if err != nil {
return nil, ecode.Fail.Sub("查询角色失败")
}
if count == 0 {
return nil, ecode.Params.Sub("角色不存在")
}
value, err := dao.Roles.Ctx(ctx).Where(do.Roles{Code: consts.StoreRoleCode}).Fields(dao.Roles.Columns().Id).Value()
if err != nil {
return nil, ecode.Fail.Sub("查询角色失败")
}
id, err := dao.StoreAdmins.Ctx(ctx).Data(do.StoreAdmins{
Username: in.Username,
RealName: in.RealName,
PasswordHash: passwordHash,
StoreId: in.StoreId,
Phone: in.Phone,
StoreRoleId: in.StoreRoleId,
Status: consts.StoreAdminEnable,
RoleId: value.Int(),
IsPrimary: false,
}).InsertAndGetId()
if err != nil {
return nil, ecode.Fail.Sub("插入商户管理员数据失败")
}
return &model.CreateOut{
Id: id,
}, nil
}
func (s *sStoreAdmin) Update(ctx context.Context, in *model.StoreAdminUpdateIn) (out *model.UpdateOut, err error) {
exist, err := dao.StoreAdmins.Ctx(ctx).WherePri(in.StoreAdminId).Exist()
if err != nil {
return nil, ecode.Fail.Sub("查询商户管理员失败")
}
if !exist {
return nil, ecode.Params.Sub("该用户不存在")
}
if _, err = dao.StoreAdmins.Ctx(ctx).WherePri(in.StoreAdminId).Data(do.StoreAdmins{
RealName: in.RealName,
Phone: in.Phone,
StoreRoleId: in.StoreRoleId,
}).Update(); err != nil {
return nil, ecode.Fail.Sub("更新商户管理员数据失败")
}
return &model.UpdateOut{
Success: true,
}, nil
}
func (s *sStoreAdmin) EditPassword(ctx context.Context, in *model.StoreAdminEditPasswordIn) (out *model.UpdateOut, err error) {
exist, err := dao.StoreAdmins.Ctx(ctx).WherePri(in.StoreAdminId).Exist()
if err != nil {
return nil, ecode.Fail.Sub("查询商户管理员失败")
}
if !exist {
return nil, ecode.Params.Sub("该用户不存在")
}
value, err := dao.StoreAdmins.Ctx(ctx).WherePri(in.StoreAdminId).Fields(dao.StoreAdmins.Columns().PasswordHash).Value()
if err != nil {
return nil, ecode.Fail.Sub("查询商户管理员失败")
}
if !encrypt.ComparePassword(value.String(), in.Password) {
return nil, ecode.Params.Sub("密码错误")
}
newPassHash, err := encrypt.EncryptPassword(in.Password2)
if err != nil {
return nil, ecode.Fail.Sub("密码加密失败")
}
if _, err = dao.StoreAdmins.Ctx(ctx).WherePri(in.StoreAdminId).Data(do.StoreAdmins{
PasswordHash: newPassHash,
}).Update(); err != nil {
return nil, ecode.Fail.Sub("更新商户管理员数据失败")
}
return &model.UpdateOut{
Success: true,
}, nil
}
func (s *sStoreAdmin) Delete(ctx context.Context, in *model.StoreAdminDeleteIn) (out *model.DeleteOut, err error) {
exist, err := dao.StoreAdmins.Ctx(ctx).WherePri(in.StoreAdminId).Exist()
if err != nil {
return nil, ecode.Fail.Sub("查询商户管理员失败")
}
if !exist {
return nil, ecode.Params.Sub("该用户不存在")
}
value, err := dao.StoreAdmins.Ctx(ctx).WherePri(in.StoreAdminId).Fields(dao.StoreAdmins.Columns().IsPrimary).Value()
if err != nil {
return nil, ecode.Fail.Sub("查询商户管理员失败")
}
if value.Bool() {
return nil, ecode.Params.Sub("该用户为门店管理员,不能删除")
}
if _, err = dao.StoreAdmins.Ctx(ctx).WherePri(in.StoreAdminId).Delete(); err != nil {
return nil, ecode.Fail.Sub("删除商户管理员失败")
}
return &model.DeleteOut{
Success: true,
}, nil
}

View File

@ -0,0 +1,143 @@
package storeRole
import (
"context"
"server/internal/dao"
"server/internal/model"
"server/internal/model/do"
"server/internal/service"
"server/utility/ecode"
)
type sStoreRole struct {
}
func New() service.IStoreRole {
return &sStoreRole{}
}
func init() {
service.RegisterStoreRole(New())
}
func (s *sStoreRole) Create(ctx context.Context, in *model.StoreRoleCreateIn) (out *model.StoreRoleCreateOut, err error) {
out = &model.StoreRoleCreateOut{}
// 检查角色名称是否已存在
exist, err := dao.StoreRoles.Ctx(ctx).Where(do.StoreRoles{
StoreId: in.StoreId,
Name: in.Name,
}).Exist()
if err != nil {
return nil, ecode.Fail.Sub("新增角色查重出现异常")
}
if exist {
return nil, ecode.Params.Sub("该门店下角色名称已存在")
}
// 创建角色
id, err := dao.StoreRoles.Ctx(ctx).InsertAndGetId(do.StoreRoles{
StoreId: in.StoreId,
Name: in.Name,
})
if err != nil {
return nil, ecode.Fail.Sub("创建角色失败")
}
out.Id = id
return out, nil
}
func (s *sStoreRole) Update(ctx context.Context, in *model.StoreRoleUpdateIn) (out *model.StoreRoleUpdateOut, err error) {
out = &model.StoreRoleUpdateOut{}
// 检查角色是否存在
exist, err := dao.StoreRoles.Ctx(ctx).WherePri(in.Id).Exist()
if err != nil {
return nil, ecode.Fail.Sub("查询角色失败")
}
if !exist {
return nil, ecode.Params.Sub("角色不存在")
}
// 检查角色名称是否已存在(排除自身)
exist, err = dao.StoreRoles.Ctx(ctx).
Where(do.StoreRoles{
StoreId: in.StoreID,
Name: in.Name,
}).
WhereNot(dao.StoreRoles.Columns().Id, in.Id).
Exist()
if err != nil {
return nil, ecode.Fail.Sub("查询角色名称失败")
}
if exist {
return nil, ecode.Params.Sub("该门店下角色名称已存在")
}
// 更新角色
if _, err = dao.StoreRoles.Ctx(ctx).
Where(do.StoreRoles{Id: in.Id}).
Update(do.StoreRoles{
Name: in.Name,
}); err != nil {
return nil, ecode.Fail.Sub("更新角色失败")
}
out.Success = true
return out, nil
}
func (s *sStoreRole) Delete(ctx context.Context, in *model.StoreRoleDeleteIn) (out *model.StoreRoleDeleteOut, err error) {
out = &model.StoreRoleDeleteOut{}
// 检查角色是否存在
exist, err := dao.StoreRoles.Ctx(ctx).WherePri(in.Id).Exist()
if err != nil {
return nil, ecode.Fail.Sub("查询角色失败")
}
if !exist {
return nil, ecode.Params.Sub("角色不存在")
}
// 检查是否有管理员使用该角色
count, err := dao.StoreAdmins.Ctx(ctx).Where(do.StoreAdmins{RoleId: in.Id}).Count()
if err != nil {
return nil, ecode.Fail.Sub("查询角色使用情况失败")
}
if count > 0 {
return nil, ecode.Params.Sub("该角色下存在管理员,无法删除")
}
// 软删除角色
if _, err = dao.StoreRoles.Ctx(ctx).
Where(do.StoreRoles{Id: in.Id}).
Delete(); err != nil {
return nil, ecode.Fail.Sub("删除角色失败")
}
out.Success = true
return out, nil
}
func (s *sStoreRole) List(ctx context.Context, in *model.StoreRoleListIn) (out *model.StoreRoleListOut, err error) {
out = &model.StoreRoleListOut{}
// 构建查询条件
orm := dao.StoreRoles.Ctx(ctx)
if in.StoreId > 0 {
orm = orm.Where(do.StoreRoles{StoreId: in.StoreId})
}
// 获取分页数据
list := make([]model.StoreRoleListItem, 0)
var total int
if err = orm.Page(in.Page, in.Size).
OrderDesc(dao.StoreRoles.Columns().Id).
ScanAndCount(&list, &total, false); err != nil {
return nil, ecode.Fail.Sub("查询角色列表失败")
}
out.List = list
out.Total = total
return out, nil
}

View File

@ -63,6 +63,10 @@ func (s *sUser) Login(ctx context.Context, in *model.UserLoginIn) (out *model.Us
return nil, ecode.Fail.Sub("查找用户失败")
}
var userId int64
v, err := dao.Stores.Ctx(ctx).Where(do.Stores{StoreCode: in.StoreCode}).Fields(dao.Stores.Columns().Id).Value()
if err != nil {
return nil, ecode.Fail.Sub("查找门店失败")
}
if !exist {
// 用户不存在,创建新用户
// 生成 username: qy_ + 8位随机字母数字
@ -84,16 +88,17 @@ func (s *sUser) Login(ctx context.Context, in *model.UserLoginIn) (out *model.Us
return nil, ecode.Fail.Sub("加密密码失败")
}
user := &entity.Users{
WxOpenId: in.OpenId,
Username: username,
Nickname: username,
PasswordHash: password,
Avatar: "adssssssssssssss", // FIXME 后续替换成默认头像的 oss 链接
FirstVisitAt: gtime.Now(),
LastLoginAt: gtime.Now(),
WxPopenId: utility.GenerateUserID("WX"),
QqPopenId: utility.GenerateUserID("QQ"),
RoleId: value[dao.Roles.Columns().Id].Int64(),
WxOpenId: in.OpenId,
Username: username,
Nickname: username,
PasswordHash: password,
Avatar: "adssssssssssssss", // FIXME 后续替换成默认头像的 oss 链接
FirstVisitAt: gtime.Now(),
LastLoginAt: gtime.Now(),
WxPopenId: utility.GenerateUserID("WX"),
QqPopenId: utility.GenerateUserID("QQ"),
RoleId: value[dao.Roles.Columns().Id].Int64(),
LastLoginStoreId: v.Int64(),
}
result, err := dao.Users.Ctx(ctx).Insert(user)
if err != nil {
@ -110,7 +115,7 @@ func (s *sUser) Login(ctx context.Context, in *model.UserLoginIn) (out *model.Us
return nil, ecode.Fail.Sub("查找用户失败")
}
userId = user.Id
if _, err := dao.Users.Ctx(ctx).Where(do.Users{Id: userId}).Update(do.Users{LastLoginAt: gtime.Now()}); err != nil {
if _, err := dao.Users.Ctx(ctx).Where(do.Users{Id: userId}).Update(do.Users{LastLoginAt: gtime.Now(), LastLoginStoreId: v.Int64()}); err != nil {
return nil, ecode.Fail.Sub("更新登录时间失败")
}
}
@ -266,15 +271,15 @@ func (s *sUser) UnBoundUrl(ctx context.Context, in *model.UserBoundUrlIn) (out *
func (s *sUser) BoundInfo(ctx context.Context, in *model.UserBoundInfoIn) (out *model.UserBoundInfoOut, err error) {
url, err := gamelife.GetGamelifeClient(ctx).GetBound(ctx, in.PopenId)
if err != nil {
return nil, ecode.Fail.Sub("获取绑定信息失败")
return nil, ecode.Fail.Sub("获取查询用户绑定信息 url 失败")
}
var result model.UserBoundResult
resp, err := resty.New().R().SetResult(&result).Post(url)
if err != nil {
return nil, ecode.Fail.Sub("获取绑定信息失败")
return nil, ecode.Fail.Sub("调用游戏人生接口出现异常")
}
if resp.StatusCode() != 200 {
return nil, ecode.Fail.Sub("获取绑定信息失败")
return nil, ecode.Fail.Sub("调用游戏人生接口失败")
}
return &model.UserBoundInfoOut{