This commit is contained in:
2025-06-20 17:13:51 +08:00
parent 1b55403cd6
commit fd0345a034
472 changed files with 52560 additions and 77 deletions

View File

@@ -0,0 +1,223 @@
package service
import (
"github.com/cool-team-official/cool-admin-go/cool"
"github.com/cool-team-official/cool-admin-go/modules/base/model"
"github.com/gogf/gf/v2/encoding/gjson"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/net/ghttp"
"github.com/gogf/gf/v2/text/gstr"
)
type BaseOpenService struct {
*cool.Service
}
func NewBaseOpenService() *BaseOpenService {
return &BaseOpenService{
&cool.Service{},
}
}
// AdminEPS 获取eps
func (s *BaseOpenService) AdminEPS(ctx g.Ctx) (result *g.Var, err error) {
c := cool.CacheEPS
result, err = c.GetOrSetFunc(ctx, "adminEPS", func(ctx g.Ctx) (interface{}, error) {
return s.creatAdminEPS(ctx)
}, 0)
return
}
// creatAdminEPS 创建eps
func (s *BaseOpenService) creatAdminEPS(ctx g.Ctx) (adminEPS interface{}, err error) {
var (
baseEpsAdmin = model.NewBaseEpsAdmin()
)
type Api struct {
Module string `json:"module"` // 所属模块名称 例如base
Method string `json:"method"` // 请求方法 例如GET
Path string `json:"path"` // 请求路径 例如:/welcome
Prefix string `json:"prefix"` // 路由前缀 例如:/admin/base/open
Summary string `json:"summary"` // 描述 例如:欢迎页面
Tag string `json:"tag"` // 标签 例如base 好像暂时不用
Dts string `json:"dts"` // 未知 例如:{} 好像暂时不用
}
// type Column struct {
// }
type Module struct {
Api []*Api `json:"api"`
Columns []*cool.ColumnInfo `json:"columns"`
Module string `json:"module"`
Prefix string `json:"prefix"`
}
admineps := make(map[string][]*Module)
// 获取所有路由并更新到数据库表 base_eps_admin
cool.DBM(baseEpsAdmin).Where("1=1").Delete()
routers := g.Server().GetRoutes()
for _, router := range routers {
if router.Type == ghttp.HandlerTypeMiddleware || router.Type == ghttp.HandlerTypeHook {
continue
}
if router.Method == "ALL" {
continue
}
routeSplite := gstr.Split(router.Route, "/")
if len(routeSplite) < 5 {
continue
}
if routeSplite[1] != "admin" {
continue
}
module := routeSplite[2]
method := router.Method
// 获取最后一个元素加前缀 / 为 path
path := "/" + routeSplite[len(routeSplite)-1]
// 获取前面的元素为prefix
prefix := gstr.Join(routeSplite[0:len(routeSplite)-1], "/")
// 获取最后一个元素为summary
summary := routeSplite[len(routeSplite)-1]
cool.DBM(baseEpsAdmin).Insert(&Api{
Module: module,
Method: method,
Path: path,
Prefix: prefix,
Summary: summary,
Tag: "",
Dts: "",
})
}
// 读取数据库表生成eps
// var modules []*Module
items, _ := cool.DBM(baseEpsAdmin).Fields("DISTINCT module,prefix").All()
for _, item := range items {
module := item["module"].String()
prefix := item["prefix"].String()
apis, _ := cool.DBM(baseEpsAdmin).Where("module=? AND prefix=?", module, prefix).All()
var apiList []*Api
for _, api := range apis {
apiList = append(apiList, &Api{
Module: api["module"].String(),
Method: api["method"].String(),
Path: api["path"].String(),
Prefix: api["prefix"].String(),
Summary: api["summary"].String(),
Tag: api["tag"].String(),
Dts: api["dts"].String(),
})
}
admineps[module] = append(admineps[module], &Module{
Api: apiList,
Columns: cool.ModelInfo[prefix],
Module: module,
Prefix: prefix,
})
}
adminEPS = gjson.New(admineps)
return
}
// AdminEPS 获取eps
func (s *BaseOpenService) AppEPS(ctx g.Ctx) (result *g.Var, err error) {
c := cool.CacheEPS
result, err = c.GetOrSetFunc(ctx, "appEPS", func(ctx g.Ctx) (interface{}, error) {
return s.creatAppEPS(ctx)
}, 0)
return
}
// creatAppEPS 创建app eps
func (s *BaseOpenService) creatAppEPS(ctx g.Ctx) (appEPS interface{}, err error) {
var (
baseEpsApp = model.NewBaseEpsApp()
)
type Api struct {
Module string `json:"module"` // 所属模块名称 例如base
Method string `json:"method"` // 请求方法 例如GET
Path string `json:"path"` // 请求路径 例如:/welcome
Prefix string `json:"prefix"` // 路由前缀 例如:/admin/base/open
Summary string `json:"summary"` // 描述 例如:欢迎页面
Tag string `json:"tag"` // 标签 例如base 好像暂时不用
Dts string `json:"dts"` // 未知 例如:{} 好像暂时不用
}
// type Column struct {
// }
type Module struct {
Api []*Api `json:"api"`
Columns []*cool.ColumnInfo `json:"columns"`
Module string `json:"module"`
Prefix string `json:"prefix"`
}
appeps := make(map[string][]*Module)
// 获取所有路由并更新到数据库表 base_eps_admin
cool.DBM(baseEpsApp).Where("1=1").Delete()
routers := g.Server().GetRoutes()
for _, router := range routers {
if router.Type == ghttp.HandlerTypeMiddleware || router.Type == ghttp.HandlerTypeHook {
continue
}
if router.Method == "ALL" {
continue
}
routeSplite := gstr.Split(router.Route, "/")
if len(routeSplite) < 5 {
continue
}
if routeSplite[1] != "app" {
continue
}
module := routeSplite[2]
method := router.Method
// 获取最后一个元素加前缀 / 为 path
path := "/" + routeSplite[len(routeSplite)-1]
// 获取前面的元素为prefix
prefix := gstr.Join(routeSplite[0:len(routeSplite)-1], "/")
// 获取最后一个元素为summary
summary := routeSplite[len(routeSplite)-1]
cool.DBM(baseEpsApp).Insert(&Api{
Module: module,
Method: method,
Path: path,
Prefix: prefix,
Summary: summary,
Tag: "",
Dts: "",
})
}
// 读取数据库表生成eps
// var modules []*Module
items, _ := cool.DBM(baseEpsApp).Fields("DISTINCT module,prefix").All()
for _, item := range items {
module := item["module"].String()
prefix := item["prefix"].String()
apis, _ := cool.DBM(baseEpsApp).Where("module=? AND prefix=?", module, prefix).All()
var apiList []*Api
for _, api := range apis {
apiList = append(apiList, &Api{
Module: api["module"].String(),
Method: api["method"].String(),
Path: api["path"].String(),
Prefix: api["prefix"].String(),
Summary: api["summary"].String(),
Tag: api["tag"].String(),
Dts: api["dts"].String(),
})
}
appeps[module] = append(appeps[module], &Module{
Api: apiList,
Columns: cool.ModelInfo[prefix],
Module: module,
Prefix: prefix,
})
}
appEPS = gjson.New(appeps)
return
}

View File

@@ -0,0 +1,53 @@
package service
import (
"github.com/cool-team-official/cool-admin-go/cool"
"github.com/cool-team-official/cool-admin-go/modules/base/model"
"github.com/gogf/gf/v2/frame/g"
)
type BaseSysConfService struct {
*cool.Service
}
func NewBaseSysConfService() *BaseSysConfService {
return &BaseSysConfService{
&cool.Service{
Model: model.NewBaseSysConf(),
UniqueKey: map[string]string{
"cKey": "配置键不能重复",
},
},
}
}
// UpdateValue 更新配置值
func (s *BaseSysConfService) UpdateValue(cKey, cValue string) error {
m := cool.DBM(s.Model).Where("cKey = ?", cKey)
record, err := m.One()
if err != nil {
return err
}
if record == nil {
_, err = cool.DBM(s.Model).Insert(g.Map{
"cKey": cKey,
"cValue": cValue,
})
} else {
_, err = cool.DBM(s.Model).Where("cKey = ?", cKey).Data(g.Map{"cValue": cValue}).Update()
}
return err
}
// GetValue 获取配置值
func (s *BaseSysConfService) GetValue(cKey string) string {
m := cool.DBM(s.Model).Where("cKey = ?", cKey)
record, err := m.One()
if err != nil {
return ""
}
if record == nil {
return ""
}
return record["cValue"].String()
}

View File

@@ -0,0 +1,78 @@
package service
import (
"github.com/cool-team-official/cool-admin-go/cool"
"github.com/cool-team-official/cool-admin-go/modules/base/model"
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/util/gconv"
)
type BaseSysDepartmentService struct {
*cool.Service
}
// GetByRoleIds 获取部门
func (s *BaseSysDepartmentService) GetByRoleIds(roleIds []string, isAdmin bool) (res []uint) {
var (
result gdb.Result
BaseSysRoleDepartment = model.NewBaseSysRoleDepartment()
)
// 如果roleIds不为空
if len(roleIds) > 0 {
// 如果是超级管理员,则返回所有部门
if isAdmin {
result, _ = cool.DBM(s.Model).Fields("id").All()
for _, v := range result {
vmap := v.Map()
if vmap["id"] != nil {
res = append(res, gconv.Uint(vmap["id"]))
}
}
} else {
// 如果不是超级管理员,则返回角色所在部门
result, _ = cool.DBM(BaseSysRoleDepartment).Where("roleId IN (?)", roleIds).Fields("departmentId").All()
for _, v := range result {
vmap := v.Map()
if vmap["departmentId"] != nil {
res = append(res, gconv.Uint(vmap["departmentId"]))
}
}
}
}
return
}
// Order 排序部门
func (s *BaseSysDepartmentService) Order(ctx g.Ctx) (err error) {
r := g.RequestFromCtx(ctx).GetMap()
type item struct {
Id uint64 `json:"id"`
ParentId *uint64 `json:"parentId,omitempty"`
OrderNum int32 `json:"orderNum"`
}
var data *item
for _, v := range r {
err = gconv.Struct(v, &data)
if err != nil {
continue
}
cool.DBM(s.Model).Where("id = ?", data.Id).Data(data).Update()
}
return
}
// NewBaseSysDepartmentService 创建一个BaseSysDepartmentService实例
func NewBaseSysDepartmentService() *BaseSysDepartmentService {
return &BaseSysDepartmentService{
Service: &cool.Service{
Model: model.NewBaseSysDepartment(),
ListQueryOp: &cool.QueryOp{},
},
}
}

View File

@@ -0,0 +1,68 @@
package service
import (
"github.com/cool-team-official/cool-admin-go/cool"
"github.com/cool-team-official/cool-admin-go/modules/base/model"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
"github.com/gogf/gf/v2/util/gconv"
)
type BaseSysLogService struct {
*cool.Service
}
func NewBaseSysLogService() *BaseSysLogService {
return &BaseSysLogService{
&cool.Service{
Model: model.NewBaseSysLog(),
PageQueryOp: &cool.QueryOp{
KeyWordField: []string{"name", "params", "ipAddr"},
Select: "base_sys_log.*,user.name ",
Join: []*cool.JoinOp{
{
Model: model.NewBaseSysUser(),
Alias: "user",
Type: "LeftJoin",
Condition: "user.id = base_sys_log.userID",
},
},
},
},
}
}
// Record 记录日志
func (s *BaseSysLogService) Record(ctx g.Ctx) {
var (
admin = cool.GetAdmin(ctx)
r = g.RequestFromCtx(ctx)
)
baseSysLog := model.NewBaseSysLog()
baseSysLog.UserID = admin.UserId
baseSysLog.Action = r.Method + ":" + r.URL.Path
baseSysLog.IP = r.GetClientIp()
baseSysLog.IPAddr = r.GetClientIp()
baseSysLog.Params = r.GetBodyString()
m := cool.DBM(s.Model)
m.Insert(g.Map{
"userId": baseSysLog.UserID,
"action": baseSysLog.Action,
"ip": baseSysLog.IP,
"ipAddr": baseSysLog.IPAddr,
"params": baseSysLog.Params,
})
}
// Clear 清除日志
func (s *BaseSysLogService) Clear(isAll bool) (err error) {
BaseSysConfService := NewBaseSysConfService()
m := cool.DBM(s.Model)
if isAll {
_, err = m.Delete("1=1")
} else {
keepDays := gconv.Int(BaseSysConfService.GetValue("logKeep"))
_, err = m.Delete("createTime < ?", gtime.Now().AddDate(0, 0, -keepDays).String())
}
return
}

View File

@@ -0,0 +1,203 @@
package service
import (
"context"
"time"
"github.com/golang-jwt/jwt/v4"
"github.com/cool-team-official/cool-admin-go/cool"
v1 "github.com/cool-team-official/cool-admin-go/modules/base/api/v1"
"github.com/cool-team-official/cool-admin-go/modules/base/config"
"github.com/cool-team-official/cool-admin-go/modules/base/model"
"github.com/gogf/gf/v2/crypto/gmd5"
"github.com/gogf/gf/v2/encoding/gbase64"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/util/gconv"
"github.com/gogf/gf/v2/util/grand"
"github.com/gogf/gf/v2/util/guid"
)
type BaseSysLoginService struct {
*cool.Service
}
type TokenResult struct {
Expire uint `json:"expire"`
Token string `json:"token"`
RefreshExpire uint `json:"refreshExpire"`
RefreshToken string `json:"refreshToken"`
}
// Login 登录
func (s *BaseSysLoginService) Login(ctx context.Context, req *v1.BaseOpenLoginReq) (result *TokenResult, err error) {
var (
captchaId = req.CaptchaId
verifyCode = req.VerifyCode
password = req.Password
username = req.Username
baseSysUser = model.NewBaseSysUser()
)
vcode, _ := cool.CacheManager.Get(ctx, captchaId)
if vcode.String() != verifyCode {
err = gerror.New("验证码错误")
return
}
md5password, _ := gmd5.Encrypt(password)
var user *model.BaseSysUser
cool.DBM(baseSysUser).Where("username=?", username).Where("password=?", md5password).Where("status=?", 1).Scan(&user)
if user == nil {
err = gerror.New("账户或密码不正确~")
return
}
result, err = s.generateTokenByUser(ctx, user)
if err != nil {
return
}
return
}
// Captcha 图形验证码
func (*BaseSysLoginService) Captcha(req *v1.BaseOpenCaptchaReq) (interface{}, error) {
type capchaInfo struct {
CaptchaId string `json:"captchaId"`
Data string `json:"data"`
}
var (
ctx g.Ctx
err error
result = &capchaInfo{}
)
captchaText := grand.Digits(4)
svg := `<svg width="150" height="50" xmlns="http://www.w3.org/2000/svg"><text x="75" y="25" text-anchor="middle" font-size="25" fill="#fff">` + captchaText + `</text></svg>`
svgbase64 := gbase64.EncodeString(svg)
result.Data = `data:image/svg+xml;base64,` + svgbase64
result.CaptchaId = guid.S()
cool.CacheManager.Set(ctx, result.CaptchaId, captchaText, 1800*time.Second)
g.Log().Debug(ctx, "验证码", result.CaptchaId, captchaText)
return result, err
}
// Logout 退出登录
func (*BaseSysLoginService) Logout(ctx context.Context) (err error) {
userId := cool.GetAdmin(ctx).UserId
cool.CacheManager.Remove(ctx, "admin:department:"+gconv.String(userId))
cool.CacheManager.Remove(ctx, "admin:perms:"+gconv.String(userId))
cool.CacheManager.Remove(ctx, "admin:token:"+gconv.String(userId))
cool.CacheManager.Remove(ctx, "admin:token:refresh:"+gconv.String(userId))
return
}
// RefreshToken 刷新token
func (s *BaseSysLoginService) RefreshToken(ctx context.Context, token string) (result *TokenResult, err error) {
tokenClaims, err := jwt.ParseWithClaims(token, &cool.Claims{}, func(token *jwt.Token) (interface{}, error) {
return []byte(config.Config.Jwt.Secret), nil
})
if err != nil {
return
}
claims, ok := tokenClaims.Claims.(*cool.Claims)
if !ok {
err = gerror.New("tokenClaims.Claims.(*Claims) error")
return
}
if !tokenClaims.Valid {
err = gerror.New("tokenClaims.Valid error")
return
}
if !claims.IsRefresh {
err = gerror.New("claims.IsRefresh error")
return
}
if !(claims.UserId > 0) {
err = gerror.New("claims.UserId error")
return
}
var (
user *model.BaseSysUser
baseSysUser = model.NewBaseSysUser()
)
cool.DBM(baseSysUser).Where("id=?", claims.UserId).Where("status=?", 1).Scan(&user)
if user == nil {
err = gerror.New("用户不存在")
return
}
result, err = s.generateTokenByUser(ctx, user)
return
}
// generateToken 生成token
func (*BaseSysLoginService) generateToken(ctx context.Context, user *model.BaseSysUser, roleIds []string, exprire uint, isRefresh bool) (token string) {
err := cool.CacheManager.Set(ctx, "admin:passwordVersion:"+gconv.String(user.ID), gconv.String(user.PasswordV), 0)
if err != nil {
g.Log().Error(ctx, "生成token失败", err)
}
claims := &cool.Claims{
IsRefresh: isRefresh,
RoleIds: roleIds,
Username: user.Username,
UserId: user.ID,
PasswordVersion: user.PasswordV,
RegisteredClaims: jwt.RegisteredClaims{
IssuedAt: jwt.NewNumericDate(time.Now()),
ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Duration(exprire) * time.Second)),
},
}
tokenClaims := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
token, err = tokenClaims.SignedString([]byte(config.Config.Jwt.Secret))
if err != nil {
g.Log().Error(ctx, "生成token失败", err)
}
return
}
// 根据用户生成前端需要的Token信息
func (s *BaseSysLoginService) generateTokenByUser(ctx context.Context, user *model.BaseSysUser) (result *TokenResult, err error) {
var (
baseSysRoleService = NewBaseSysRoleService()
baseSysMenuService = NewBaseSysMenuService()
baseSysDepartmentService = NewBaseSysDepartmentService()
)
// 获取用户角色
roleIds := baseSysRoleService.GetByUser(user.ID)
// 如果没有角色,则报错
if len(roleIds) == 0 {
err = gerror.New("该用户未设置任何角色,无法登录~")
return
}
// 生成token
result = &TokenResult{}
result.Expire = config.Config.Jwt.Token.Expire
result.RefreshExpire = config.Config.Jwt.Token.RefreshExpire
result.Token = s.generateToken(ctx, user, roleIds, result.Expire, false)
result.RefreshToken = s.generateToken(ctx, user, roleIds, result.RefreshExpire, true)
// 将用户相关信息保存到缓存
perms := baseSysMenuService.GetPerms(roleIds)
departments := baseSysDepartmentService.GetByRoleIds(roleIds, user.Username == "admin")
cool.CacheManager.Set(ctx, "admin:department:"+gconv.String(user.ID), departments, 0)
cool.CacheManager.Set(ctx, "admin:perms:"+gconv.String(user.ID), perms, 0)
cool.CacheManager.Set(ctx, "admin:token:"+gconv.String(user.ID), result.Token, 0)
cool.CacheManager.Set(ctx, "admin:token:refresh:"+gconv.String(user.ID), result.RefreshToken, 0)
return
}
// NewBaseSysLoginService 创建一个新的BaseSysLoginService
func NewBaseSysLoginService() *BaseSysLoginService {
return &BaseSysLoginService{}
}

View File

@@ -0,0 +1,91 @@
package service
import (
"context"
"github.com/cool-team-official/cool-admin-go/cool"
"github.com/cool-team-official/cool-admin-go/modules/base/model"
"github.com/gogf/gf/v2/container/garray"
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/text/gstr"
"github.com/gogf/gf/v2/util/gconv"
)
type BaseSysMenuService struct {
*cool.Service
}
// GetPerms 获取菜单的权限
func (s *BaseSysMenuService) GetPerms(roleIds []string) []string {
var (
perms []string
result gdb.Result
)
m := cool.DBM(s.Model).As("a")
// 如果roldIds 包含 1 则表示是超级管理员,则返回所有权限
if garray.NewIntArrayFrom(gconv.Ints(roleIds)).Contains(1) {
result, _ = m.Fields("a.perms").All()
} else {
result, _ = m.InnerJoin("base_sys_role_menu b", "a.id=b.menuId").InnerJoin("base_sys_role c", "b.roleId=c.id").Where("c.id IN (?)", roleIds).Fields("a.perms").All()
}
for _, v := range result {
vmap := v.Map()
if vmap["perms"] != nil {
p := gstr.Split(vmap["perms"].(string), ",")
perms = append(perms, p...)
}
}
return perms
}
// GetMenus 获取菜单
func (s *BaseSysMenuService) GetMenus(roleIds []string, isAdmin bool) (result gdb.Result) {
// 屏蔽 base_sys_role_menu.id 防止部分权限的用户登录时菜单渲染错误
m := cool.DBM(s.Model).As("a").Fields("a.*")
if isAdmin {
result, _ = m.Group("a.id").Order("a.orderNum asc").All()
} else {
result, _ = m.InnerJoin("base_sys_role_menu b", "a.id=b.menuId").Where("b.roleId IN (?)", roleIds).Group("a.id").Order("a.orderNum asc").All()
}
return
}
// ModifyAfter 修改后
func (s *BaseSysMenuService) ModifyAfter(ctx context.Context, method string, param g.MapStrAny) (err error) {
if method == "Delete" {
ids := gconv.Ints(param["ids"])
if len(ids) > 0 {
_, err = cool.DBM(s.Model).Where("parentId IN (?)", ids).Delete()
}
return
}
return
}
// ServiceAdd 添加
func (s *BaseSysMenuService) ServiceAdd(ctx context.Context, req *cool.AddReq) (data interface{}, err error) {
r := g.RequestFromCtx(ctx)
rjson, err := r.GetJson()
if err != nil {
return
}
// g.DumpWithType(rjson)
m := cool.DBM(s.Model)
lastInsertId, err := m.Data(rjson).InsertAndGetId()
if err != nil {
return
}
data = g.Map{"id": lastInsertId}
return
}
// NewBaseSysMenuService 创建一个BaseSysMenuService实例
func NewBaseSysMenuService() *BaseSysMenuService {
return &BaseSysMenuService{
&cool.Service{
Model: model.NewBaseSysMenu(),
},
}
}

View File

@@ -0,0 +1,90 @@
package service
import (
"context"
"github.com/cool-team-official/cool-admin-go/cool"
"github.com/cool-team-official/cool-admin-go/modules/base/model"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/text/gstr"
)
type BaseSysParamService struct {
*cool.Service
}
func NewBaseSysParamService() *BaseSysParamService {
return &BaseSysParamService{
&cool.Service{
Model: model.NewBaseSysParam(),
},
// Service: cool.NewService(model.NewBaseSysParam()),
}
}
// HtmlByKey 根据配置参数key获取网页内容(富文本)
func (s *BaseSysParamService) HtmlByKey(key string) string {
var (
html = "<html><body>@content</body></html>"
)
m := cool.DBM(s.Model)
record, err := m.Where("keyName = ?", key).One()
if err != nil {
html = gstr.Replace(html, "@content", err.Error())
return html
}
if record.IsEmpty() {
html = gstr.Replace(html, "@content", "keyName notfound")
return html
}
html = gstr.Replace(html, "@content", record["data"].String())
return html
}
// ModifyAfter 修改后
func (s *BaseSysParamService) ModifyAfter(ctx context.Context, method string, param g.MapStrAny) (err error) {
var (
m = cool.DBM(s.Model)
)
result, err := m.All()
if err != nil {
return
}
for _, v := range result {
key := "param:" + v["keyName"].String()
value := v["data"].String()
err = cool.CacheManager.Set(ctx, key, value, 0)
if err != nil {
return
}
}
return
}
// DataByKey 根据配置参数key获取数据
func (s *BaseSysParamService) DataByKey(ctx context.Context, key string) (data string, err error) {
var (
m = cool.DBM(s.Model)
)
rKey := "param:" + key
dataCache, err := cool.CacheManager.Get(ctx, rKey)
if err != nil {
return
}
if !dataCache.IsEmpty() {
data = dataCache.String()
return
}
record, err := m.Where("keyName = ?", key).One()
if err != nil {
return
}
if record.IsEmpty() {
return
}
data = record["data"].String()
err = cool.CacheManager.Set(ctx, rKey, data, 0)
return
}

View File

@@ -0,0 +1,53 @@
package service
import (
"context"
"github.com/cool-team-official/cool-admin-go/cool"
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/util/gconv"
)
type BaseSysPermsService struct {
}
func NewBaseSysPermsService() *BaseSysPermsService {
return &BaseSysPermsService{}
}
// permmenu 方法
func (c *BaseSysPermsService) Permmenu(ctx context.Context, roleIds []string) (res interface{}) {
type permmenu struct {
Perms []string `json:"perms"`
Menus gdb.Result `json:"menus"`
}
var (
baseSysMenuService = NewBaseSysMenuService()
admin = cool.GetAdmin(ctx)
)
res = &permmenu{
Perms: baseSysMenuService.GetPerms(roleIds),
Menus: baseSysMenuService.GetMenus(admin.RoleIds, admin.UserId == 1),
}
return
}
// refreshPerms(userId)
func (c *BaseSysPermsService) RefreshPerms(ctx context.Context, userId uint) (err error) {
var (
baseSysUserRoleService = NewBaseSysRoleService()
baseSysMenuService = NewBaseSysMenuService()
baseSysDepartmentService = NewBaseSysDepartmentService()
roleIds = baseSysUserRoleService.GetByUser(userId)
perms = baseSysMenuService.GetPerms(roleIds)
)
cool.CacheManager.Set(ctx, "admin:perms:"+gconv.String(userId), perms, 0)
// 更新部门权限
departments := baseSysDepartmentService.GetByRoleIds(roleIds, userId == 1)
cool.CacheManager.Set(ctx, "admin:department:"+gconv.String(userId), departments, 0)
return
}

View File

@@ -0,0 +1,174 @@
package service
import (
"context"
"github.com/cool-team-official/cool-admin-go/cool"
"github.com/cool-team-official/cool-admin-go/modules/base/model"
"github.com/gogf/gf/v2/container/garray"
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/util/gconv"
)
var baseSysUserRole = model.NewBaseSysUserRole()
type BaseSysRoleService struct {
*cool.Service
}
// ModifyAfter modify after
func (s *BaseSysRoleService) ModifyAfter(ctx context.Context, method string, param g.MapStrAny) (err error) {
if param["id"] != nil {
err = s.updatePerms(ctx, gconv.Uint(param["id"]), gconv.SliceUint(param["menuIdList"]), gconv.SliceUint(param["departmentIdList"]))
}
return
}
// updatePerms(roleId, menuIdList?, departmentIds = [])
func (s *BaseSysRoleService) updatePerms(ctx context.Context, roleId uint, menuIdList, departmentIds []uint) (err error) {
// 更新菜单权限
cool.DBM(model.NewBaseSysRoleMenu()).Where("roleId = ?", roleId).Delete()
if len(menuIdList) > 0 {
roleMenuList := make([]g.MapStrAny, len(menuIdList))
for i, menuId := range menuIdList {
roleMenuList[i] = g.MapStrAny{
"roleId": roleId,
"menuId": menuId,
}
}
cool.DBM(model.NewBaseSysRoleMenu()).Data(roleMenuList).Insert()
}
// 更新部门权限
cool.DBM(model.NewBaseSysRoleDepartment()).Where("roleId = ?", roleId).Delete()
if len(departmentIds) > 0 {
roleDepartmentList := make([]g.MapStrAny, len(departmentIds))
for i, departmentId := range departmentIds {
roleDepartmentList[i] = g.MapStrAny{
"roleId": roleId,
"departmentId": departmentId,
}
}
cool.DBM(model.NewBaseSysRoleDepartment()).Data(roleDepartmentList).Insert()
}
// 刷新权限
userRoles, err := cool.DBM(model.NewBaseSysUserRole()).Where("roleId = ?", roleId).All()
if err != nil {
return
}
baseSysPermsService := NewBaseSysPermsService()
for _, v := range userRoles {
vmap := v.Map()
if vmap["userId"] != nil {
baseSysPermsService.RefreshPerms(ctx, gconv.Uint(vmap["userId"]))
}
}
return
}
// GetByUser get array roleId by userId
func (s *BaseSysRoleService) GetByUser(userId uint) []string {
var (
roles []string
)
res, _ := cool.DBM(baseSysUserRole).Where("userId = ?", userId).Array("roleId")
for _, v := range res {
roles = append(roles, gconv.String(v))
}
return roles
}
// BaseSysRoleService Info 方法重构
func (s *BaseSysRoleService) ServiceInfo(ctx context.Context, req *cool.InfoReq) (data interface{}, err error) {
info, err := cool.DBM(s.Model).Where("id = ?", req.Id).One()
if err != nil {
return nil, err
}
if !info.IsEmpty() {
var menus gdb.Result
if req.Id == 1 {
menus, err = cool.DBM(model.NewBaseSysMenu()).All()
if err != nil {
return nil, err
}
} else {
menus, err = cool.DBM(model.NewBaseSysRoleMenu()).Where("roleId = ?", req.Id).All()
if err != nil {
return nil, err
}
}
menuIdList := garray.NewIntArray()
for _, v := range menus {
menuIdList.Append(gconv.Int(v["menuId"]))
}
var departments gdb.Result
if req.Id == 1 {
departments, err = cool.DBM(model.NewBaseSysRoleDepartment()).All()
if err != nil {
return nil, err
}
} else {
departments, err = cool.DBM(model.NewBaseSysRoleDepartment()).Where("roleId = ?", req.Id).All()
if err != nil {
return nil, err
}
}
departmentIdList := garray.NewIntArray()
for _, v := range departments {
departmentIdList.Append(gconv.Int(v["departmentId"]))
}
result := gconv.Map(info)
result["menuIdList"] = menuIdList.Slice()
result["departmentIdList"] = departmentIdList.Slice()
data = result
return
}
data = g.Map{}
return
}
// NewBaseSysRoleService create a new BaseSysRoleService
func NewBaseSysRoleService() *BaseSysRoleService {
return &BaseSysRoleService{
Service: &cool.Service{
Model: model.NewBaseSysRole(),
ListQueryOp: &cool.QueryOp{
Where: func(ctx context.Context) [][]interface{} {
var (
admin = cool.GetAdmin(ctx)
userId = admin.UserId
roleIds = garray.NewIntArrayFromCopy(gconv.Ints(admin.RoleIds))
)
return [][]interface{}{
{"label != ?", g.Slice{"admin"}, true},
{"(userId=? or id in (?))", g.Slice{userId, admin.RoleIds}, !roleIds.Contains(1)},
}
},
},
PageQueryOp: &cool.QueryOp{
KeyWordField: []string{"name", "label"},
AddOrderby: map[string]string{},
Where: func(ctx context.Context) [][]interface{} {
var (
admin = cool.GetAdmin(ctx)
userId = admin.UserId
roleIds = garray.NewIntArrayFromCopy(gconv.Ints(admin.RoleIds))
)
return [][]interface{}{
{"label != ?", g.Slice{"admin"}, true},
{"(userId=? or id in (?))", g.Slice{userId, admin.RoleIds}, !roleIds.Contains(1)},
}
},
},
InsertParam: func(ctx context.Context) map[string]interface{} {
return g.Map{"userId": cool.GetAdmin(ctx).UserId}
},
UniqueKey: map[string]string{
"name": "角色名称不能重复",
"label": "角色标识不能重复",
},
},
}
}

View File

@@ -0,0 +1,238 @@
package service
import (
"context"
"fmt"
"github.com/cool-team-official/cool-admin-go/cool"
"github.com/cool-team-official/cool-admin-go/modules/base/model"
"github.com/gogf/gf/v2/container/garray"
"github.com/gogf/gf/v2/container/gset"
"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/util/gconv"
)
type BaseSysUserService struct {
*cool.Service
}
// Person 方法 返回不带密码的用户信息
func (s *BaseSysUserService) Person(userId uint) (res gdb.Record, err error) {
m := cool.DBM(s.Model)
res, err = m.Where("id = ?", userId).FieldsEx("password").One()
return
}
func (s *BaseSysUserService) ModifyBefore(ctx context.Context, method string, param g.MapStrAny) (err error) {
if method == "Delete" {
// 禁止删除超级管理员
userIds := garray.NewIntArrayFrom(gconv.Ints(param["ids"]))
currentId, found := userIds.Get(0)
superAdminId := 1
if userIds.Len() == 1 && found && currentId == superAdminId {
err = gerror.New("超级管理员不能删除")
return
}
// 删除超级管理员
userIds.RemoveValue(1)
g.RequestFromCtx(ctx).SetParam("ids", userIds.Slice())
}
return
}
func (s *BaseSysUserService) ModifyAfter(ctx context.Context, method string, param g.MapStrAny) (err error) {
if method == "Delete" {
userIds := garray.NewIntArrayFrom(gconv.Ints(param["ids"]))
userIds.RemoveValue(1)
// 删除用户时删除相关数据
cool.DBM(model.NewBaseSysUserRole()).WhereIn("userId", userIds.Slice()).Delete()
}
return
}
// ServiceAdd 方法 添加用户
func (s *BaseSysUserService) ServiceAdd(ctx context.Context, req *cool.AddReq) (data interface{}, err error) {
var (
m = cool.DBM(s.Model)
r = g.RequestFromCtx(ctx)
reqmap = r.GetMap()
)
// 如果reqmap["password"]不为空则对密码进行md5加密
if !r.Get("password").IsNil() {
reqmap["password"] = gmd5.MustEncryptString(r.Get("password").String())
}
lastInsertId, err := m.Data(reqmap).InsertAndGetId()
if err != nil {
return
}
data = g.Map{"id": lastInsertId}
return
}
// ServiceInfo 方法 返回服务信息
func (s *BaseSysUserService) ServiceInfo(ctx g.Ctx, req *cool.InfoReq) (data interface{}, err error) {
result, err := s.Service.ServiceInfo(ctx, req)
if err != nil {
return nil, err
}
if result.(gdb.Record).IsEmpty() {
return nil, nil
}
// g.DumpWithType(result)
resultMap := result.(gdb.Record).Map()
// 获取角色
roleIds, err := cool.DBM(model.NewBaseSysUserRole()).Where("userId = ?", resultMap["id"]).Fields("roleId").Array()
if err != nil {
return nil, err
}
resultMap["roleIdList"] = roleIds
data = resultMap
return
}
// ServiceUpdate 方法 更新用户信息
func (s *BaseSysUserService) ServiceUpdate(ctx context.Context, req *cool.UpdateReq) (data interface{}, err error) {
var (
admin = cool.GetAdmin(ctx)
m = cool.DBM(s.Model)
)
r := g.RequestFromCtx(ctx)
rMap := r.GetMap()
// 如果不传入ID代表更新当前用户
userId := r.Get("id", admin.UserId).Uint()
userInfo, err := m.Where("id = ?", userId).One()
if err != nil {
return
}
if userInfo.IsEmpty() {
err = gerror.New("用户不存在")
return
}
// 禁止禁用超级管理员
if userId == 1 && (!r.Get("status").IsNil() && r.Get("status").Int() == 0) {
err = gerror.New("禁止禁用超级管理员")
return
}
// 如果请求的password不为空并且密码加密后的值有变动说明要修改密码
var rPassword = r.Get("password", "").String()
if rPassword != "" && rPassword != userInfo["password"].String() {
rMap["password"], _ = gmd5.Encrypt(rPassword)
rMap["passwordV"] = userInfo["passwordV"].Int() + 1
cool.CacheManager.Set(ctx, fmt.Sprintf("admin:passwordVersion:%d", userId), rMap["passwordV"], 0)
} else {
delete(rMap, "password")
}
err = g.DB().Transaction(ctx, func(ctx context.Context, tx gdb.TX) (err error) {
roleModel := cool.DBM(model.NewBaseSysUserRole()).TX(tx).Where("userId = ?", userId)
roleIds, err := roleModel.Fields("roleId").Array()
if err != nil {
return
}
// 如果请求参数中不包含roleIdList说明不修改角色信息
if !r.Get("roleIdList").IsNil() {
inRoleIdSet := gset.NewFrom(r.Get("roleIdList").Ints())
roleIdsSet := gset.NewFrom(gconv.Ints(roleIds))
// 如果请求的角色信息未发生变化则跳过更新逻辑
if roleIdsSet.Diff(inRoleIdSet).Size() != 0 || inRoleIdSet.Diff(roleIdsSet).Size() != 0 {
roleArray := garray.NewArray()
inRoleIdSet.Iterator(func(v interface{}) bool {
roleArray.PushRight(g.Map{
"userId": gconv.Uint(userId),
"roleId": gconv.Uint(v),
})
return true
})
_, err = roleModel.Delete()
if err != nil {
return err
}
_, err = roleModel.Fields("userId,roleId").Insert(roleArray)
if err != nil {
return err
}
}
}
_, err = m.TX(tx).Update(rMap)
if err != nil {
return err
}
return
})
return
}
// Move 移动用户部门
func (s *BaseSysUserService) Move(ctx g.Ctx) (err error) {
request := g.RequestFromCtx(ctx)
departmentId := request.Get("departmentId").Int()
userIds := request.Get("userIds").Slice()
_, err = cool.DBM(s.Model).Where("`id` IN(?)", userIds).Data(g.Map{"departmentId": departmentId}).Update()
return
}
// NewBaseSysUserService 创建一个新的BaseSysUserService实例
func NewBaseSysUserService() *BaseSysUserService {
return &BaseSysUserService{
Service: &cool.Service{
Model: model.NewBaseSysUser(),
InfoIgnoreProperty: "password",
UniqueKey: map[string]string{
"username": "用户名不能重复",
},
PageQueryOp: &cool.QueryOp{
Select: "base_sys_user.*,dept.`name` as departmentName,GROUP_CONCAT( role.`name` ) AS `roleName`",
Join: []*cool.JoinOp{
{
Model: model.NewBaseSysDepartment(),
Alias: "dept",
Type: "LeftJoin",
Condition: "`base_sys_user`.`departmentId` = `dept`.`id`",
},
{
Model: model.NewBaseSysUserRole(),
Alias: "user_role",
Type: "LeftJoin",
Condition: "`base_sys_user`.`id` = `user_role`.`userId`",
},
{
Model: model.NewBaseSysRole(),
Alias: "`role`",
Type: "LeftJoin",
Condition: "`role`.`id` = `user_role`.`roleId`",
},
},
Where: func(ctx context.Context) []g.Array {
r := g.RequestFromCtx(ctx).GetMap()
return []g.Array{
{"(departmentId IN (?))", gconv.SliceStr(r["departmentIds"])},
}
},
Extend: func(ctx g.Ctx, m *gdb.Model) *gdb.Model {
return m.Group("`base_sys_user`.`id`")
},
KeyWordField: []string{"name", "username", "nickName"},
},
},
}
}