package service import ( "context" "database/sql" "encoding/json" "fmt" "io" "log" "net/http" "net/http/cookiejar" "net/url" "strings" "blazing/cool" "blazing/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) GetSession(email string, password string) (res *model.BaseSysUser, err error) { m := cool.DBM(s.Model) m.Where("email", email).Where("password", password).Where("status", 1).Scan(&res) if res == nil { err = gerror.New("账户或密码不正确~") return } return } func (s *BaseSysUserService) GetPerson(userId uint32) (res *model.BaseSysUser) { m := cool.DBM(s.Model) m.Where("id", userId).FieldsEx("password").Scan(&res) return } func (s *BaseSysUserService) SetdepartmentId(userId, departmentId uint32) (res *model.BaseSysUser) { m := cool.DBM(s.Model) m.Where("id", userId).Data("departmentId", departmentId).Update() return } func (s *BaseSysUserService) DuihuanFreeGold(userId uint32, gold, free int64) { m := cool.DBM(s.Model).Where("id", userId) m.Data(g.Map{ "goldbean": gdb.Raw("goldbean-" + gconv.String(gold)), "free_gold": gdb.Raw("free_gold+" + gconv.String(free)), }).Update() } func (s *BaseSysUserService) DuihuanGold(userId uint32, gold, free int64) { m := cool.DBM(s.Model).Where("id", userId) m.Data(g.Map{ "goldbean": gdb.Raw("goldbean+" + gconv.String(gold)), "free_gold": gdb.Raw("free_gold-" + gconv.String(free)), }).Update() } func (s *BaseSysUserService) BindQQ(username string, passworid string, qq int64) (err error) { var res *model.BaseSysUser cool.DBM(s.Model).Where("qq", qq).Scan(&res) username = strings.ToLower(username) if res != nil { err = gerror.New("该QQ已绑定其他账号" + gconv.String(res.ID)) return } var res1 *model.BaseSysUser cool.DBM(s.Model).Where("username", username).Scan(&res1) if res1 == nil { return gerror.New("用户未激活") } r, err := s.GetUserInfo(username, passworid) if err != nil { return } if r == nil { err = gerror.New("用户不存在") return } _, err = cool.DBM(s.Model).Where("username", username).Data("qq", qq).Update() if err != nil { return err } return } func (s *BaseSysUserService) UpdateFreeGold(userId uint32, gold int64) { m := cool.DBM(s.Model).Where("id", userId) m.Increment("free_gold", gold) } // 单位是分 func (s *BaseSysUserService) UpdateGold(userId uint32, gold int64) { if cool.Config.ServerInfo.IsVip != 0 { return } m := cool.DBM(s.Model).Where("id", userId) m.Increment("goldbean", gold) } func (s *BaseSysUserService) GetGold(userId uint) (res int64) { var res1 model.BaseSysUser m := cool.DBM(s.Model) m.Where("id", userId).Fields("goldbean").Scan(&res1) return res1.GoldBean } func (s *BaseSysUserService) GetFreeGold(userId uint) (res int64) { var res1 model.BaseSysUser m := cool.DBM(s.Model) m.Where("id", userId).Fields("free_gold").Scan(&res1) return res1.FreeGold } func (s *BaseSysUserService) GetEamil(userId string) (res *model.BaseSysUser) { m := cool.DBM(s.Model) m.Where("email", userId).FieldsEx("password").Scan(&res) return } func (s *BaseSysUserService) GetQQ(userId int64) (res *model.BaseSysUser) { m := cool.DBM(s.Model) m.Where("qq", userId).FieldsEx("password").Scan(&res) 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 := 10001 if userIds.Len() == 1 && found && currentId == superAdminId { err = gerror.New("超级管理员不能删除") return } // 删除超级管理员 userIds.RemoveValue(10001) 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 } func (s *BaseSysUserService) Gen(user UserAttributes) (data interface{}, err error) { var ( m = cool.DBM(s.Model) ) lastInsertId, err := m.Data(user).Data( g.Map{ "username": strings.ToLower(user.Username), "headImg": user.AvatarUrl, "departmentId": 1, }, ).InsertAndGetId() if err != nil { return } data = g.Map{"id": lastInsertId} roleArray := garray.NewArray() roleArray.PushRight(g.Map{ "userId": gconv.Uint(lastInsertId), "roleId": gconv.Uint(13), }) _, err = cool.DBM(model.NewBaseSysUserRole()).Fields("userId,roleId").Insert(roleArray) return } func (s *BaseSysUserService) GetUserInfo(username, password string) (*model.BaseSysUser, error) { // 创建带 Cookie 存储的 HTTP 客户端 jar, err := cookiejar.New(nil) if err != nil { return nil, fmt.Errorf("创建 CookieJar 失败: %w", err) } client := &http.Client{Jar: jar} // 1. POST 获取 token tokenURL := bbsurl + "/api/token" formData := url.Values{} formData.Set("identification", username) formData.Set("password", password) req, err := http.NewRequest("POST", tokenURL, strings.NewReader(formData.Encode())) if err != nil { return nil, fmt.Errorf("创建请求失败: %w", err) } req.Header.Set("Content-Type", "application/x-www-form-urlencoded") resp, err := client.Do(req) if err != nil { return nil, fmt.Errorf("发送请求失败: %w", err) } defer resp.Body.Close() body, err := io.ReadAll(resp.Body) if err != nil { return nil, fmt.Errorf("读取响应失败: %w", err) } // 解析 token var tokenResp TokenResponse err = json.Unmarshal(body, &tokenResp) if err != nil { return nil, fmt.Errorf("解析 token 失败: %w", err) } // 提取 CSRF Token csrfToken := resp.Header.Get("X-CSRF-Token") // 2. GET 获取该用户的详细信息 usersURL := bbsurl + fmt.Sprintf("/api/users/%d", tokenResp.UserID) req2, err := http.NewRequest("GET", usersURL, nil) if err != nil { return nil, fmt.Errorf("创建请求失败: %w", err) } req2.Header.Set("Authentication", tokenResp.Token) req2.Header.Set("X-CSRF-Token", csrfToken) resp2, err := client.Do(req2) if err != nil { return nil, fmt.Errorf("发送请求失败: %w", err) } defer resp2.Body.Close() body2, err := io.ReadAll(resp2.Body) if err != nil { return nil, fmt.Errorf("读取响应失败: %w", err) } // 解析用户信息 var userResp UserResponse err = json.Unmarshal(body2, &userResp) if err != nil { return nil, fmt.Errorf("解析用户信息失败: %w", err) } if !strings.EqualFold(userResp.Data.Attributes.Username, username) { //说明没查找到用户 return nil, gerror.New("账户或密码不正确~") } else { var user *model.BaseSysUser m := cool.DBM(s.Model).Where("username=?", username) m.Scan(&user) if user == nil { s.Gen(userResp.Data.Attributes) m := cool.DBM(s.Model).Where("username=?", username) m.Scan(&user) } else { if *user.Status == 0 { err = gerror.New("账户被封禁~") return nil, err } user.HeadImg = &userResp.Data.Attributes.AvatarUrl var ttt = *user.PasswordV + 1 user.PasswordV = &ttt _, err := m.Save(user) if err != nil { log.Fatal(err) } cool.CacheManager.Set(context.Background(), fmt.Sprintf("admin:passwordVersion:%d", user.ID), ttt, 0) } return user, nil } return nil, nil } // 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()) } if !r.Get("username").IsNil() { reqmap["username"] = strings.ToLower(r.Get("username").String()) } if s.UniqueKey != nil { for k, v := range s.UniqueKey { if reqmap[k] != nil { count, err := cool.DBM(s.Model).Where(k, reqmap[k]).Count() if err != nil { return nil, err } if count > 0 { err = gerror.New(v) return nil, err } } } } lastInsertId, err := m.Data(reqmap).InsertAndGetId() if err != nil { return } data = g.Map{"id": lastInsertId} err = g.DB().Transaction(ctx, func(ctx context.Context, tx gdb.TX) (err error) { if !r.Get("roleIdList").IsNil() { inRoleIdSet := gset.NewFrom(r.Get("roleIdList").Ints()) roleArray := garray.NewArray() inRoleIdSet.Iterator(func(v interface{}) bool { roleArray.PushRight(g.Map{ "userId": gconv.Uint(lastInsertId), "roleId": gconv.Uint(v), }) return true }) _, err = cool.DBM(model.NewBaseSysUserRole()).Fields("userId,roleId").Insert(roleArray) if err != nil { return err } } return }) 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 sql.Result, err error) { var ( admin = cool.GetAdmin(ctx) m = cool.DBM(s.Model) ) r := g.RequestFromCtx(ctx) rMap := r.GetMap() if !r.Get("username").IsNil() { rMap["username"] = strings.ToLower(r.Get("username").String()) } // 如果不传入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 == 10001 && (!r.Get("status").IsNil() && r.Get("status").Int() == 0) { err = gerror.New("禁止禁用超级管理员") return } if s.UniqueKey != nil { for k, v := range s.UniqueKey { if rMap[k] != nil { count, err := cool.DBM(s.Model).Where(k, rMap[k]).WhereNot("id", userId).Count() if err != nil { return nil, err } if count > 0 { err = gerror.New(v) return nil, err } } } } // 如果请求的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") } delete(rMap, "goldbean") 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": "用户名不能重复", "email": "邮箱不能重复", }, PageQueryOp: &cool.QueryOp{ Select: ` base_sys_user.*, STRING_AGG(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{ {"id != ?", g.Slice{"10001"}, true}, //排除管理员 {`("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{"username", "email"}, FieldEQ: []string{"id"}, }, }, } }