support user role attachment
This commit is contained in:
1
common/structure/sex.go
Normal file
1
common/structure/sex.go
Normal file
@@ -0,0 +1 @@
|
|||||||
|
package structure
|
||||||
@@ -40,10 +40,10 @@ func (m *Migration20230131_165134CreateSysDictionary) table() interface{} {
|
|||||||
type SysDictionary struct {
|
type SysDictionary struct {
|
||||||
gorm.Model
|
gorm.Model
|
||||||
|
|
||||||
Name string `gorm:"column:name;comment:字典名(中)"` // 字典名(中)
|
Name string `gorm:"comment:字典名(中)"` // 字典名(中)
|
||||||
Type string `gorm:"column:type;comment:字典名(英)"` // 字典名(英)
|
Alias string `gorm:"comment:字典名(英)"` // 字典名(英)
|
||||||
Status *bool `gorm:"column:status;comment:状态"` // 状态
|
Status bool `gorm:"comment:状态"` // 状态
|
||||||
Desc string `gorm:"column:desc;comment:描述"` // 描述
|
Description string `gorm:"comment:描述"` // 描述
|
||||||
}
|
}
|
||||||
|
|
||||||
return SysDictionary{}
|
return SysDictionary{}
|
||||||
|
|||||||
@@ -40,11 +40,11 @@ func (m *Migration20230131_165218CreateSysDictionaryDetail) table() interface{}
|
|||||||
type SysDictionaryDetail struct {
|
type SysDictionaryDetail struct {
|
||||||
gorm.Model
|
gorm.Model
|
||||||
|
|
||||||
Label string `gorm:"column:label;comment:展示值"` // 展示值
|
SysDictionaryID int `gorm:"comment:关联标记"`
|
||||||
Value int `gorm:"column:value;comment:字典值"` // 字典值
|
Label string `gorm:"comment:展示值"`
|
||||||
Status *bool `gorm:"column:status;comment:启用状态"` // 启用状态
|
Value string `gorm:"comment:字典值"`
|
||||||
Sort int `gorm:"column:sort;comment:排序标记"` // 排序标记
|
Status bool `gorm:"comment:启用状态"`
|
||||||
SysDictionaryID int `gorm:"column:sys_dictionary_id;comment:关联标记"` // 关联标记
|
Weight int `gorm:"comment:排序权重"`
|
||||||
}
|
}
|
||||||
|
|
||||||
return SysDictionaryDetail{}
|
return SysDictionaryDetail{}
|
||||||
|
|||||||
@@ -19,9 +19,9 @@ type SysDictionary struct {
|
|||||||
UpdatedAt time.Time `gorm:"column:updated_at;type:datetime(3)" json:"updated_at"`
|
UpdatedAt time.Time `gorm:"column:updated_at;type:datetime(3)" json:"updated_at"`
|
||||||
DeletedAt gorm.DeletedAt `gorm:"column:deleted_at;type:datetime(3)" json:"deleted_at"`
|
DeletedAt gorm.DeletedAt `gorm:"column:deleted_at;type:datetime(3)" json:"deleted_at"`
|
||||||
Name string `gorm:"column:name;type:varchar(191)" json:"name"` // 字典名(中)
|
Name string `gorm:"column:name;type:varchar(191)" json:"name"` // 字典名(中)
|
||||||
Type string `gorm:"column:type;type:varchar(191)" json:"type"` // 字典名(英)
|
Alias_ string `gorm:"column:alias;type:varchar(191)" json:"alias"` // 字典名(英)
|
||||||
Status bool `gorm:"column:status;type:tinyint(1)" json:"status"` // 状态
|
Status bool `gorm:"column:status;type:tinyint(1)" json:"status"` // 状态
|
||||||
Desc string `gorm:"column:desc;type:varchar(191)" json:"desc"` // 描述
|
Description string `gorm:"column:description;type:varchar(191)" json:"description"` // 描述
|
||||||
}
|
}
|
||||||
|
|
||||||
// TableName SysDictionary's table name
|
// TableName SysDictionary's table name
|
||||||
|
|||||||
@@ -18,11 +18,11 @@ type SysDictionaryDetail struct {
|
|||||||
CreatedAt time.Time `gorm:"column:created_at;type:datetime(3)" json:"created_at"`
|
CreatedAt time.Time `gorm:"column:created_at;type:datetime(3)" json:"created_at"`
|
||||||
UpdatedAt time.Time `gorm:"column:updated_at;type:datetime(3)" json:"updated_at"`
|
UpdatedAt time.Time `gorm:"column:updated_at;type:datetime(3)" json:"updated_at"`
|
||||||
DeletedAt gorm.DeletedAt `gorm:"column:deleted_at;type:datetime(3)" json:"deleted_at"`
|
DeletedAt gorm.DeletedAt `gorm:"column:deleted_at;type:datetime(3)" json:"deleted_at"`
|
||||||
Label string `gorm:"column:label;type:varchar(191)" json:"label"` // 展示值
|
|
||||||
Value int64 `gorm:"column:value;type:bigint(20)" json:"value"` // 字典值
|
|
||||||
Status bool `gorm:"column:status;type:tinyint(1)" json:"status"` // 启用状态
|
|
||||||
Sort int64 `gorm:"column:sort;type:bigint(20)" json:"sort"` // 排序标记
|
|
||||||
SysDictionaryID int64 `gorm:"column:sys_dictionary_id;type:bigint(20)" json:"sys_dictionary_id"` // 关联标记
|
SysDictionaryID int64 `gorm:"column:sys_dictionary_id;type:bigint(20)" json:"sys_dictionary_id"` // 关联标记
|
||||||
|
Label string `gorm:"column:label;type:varchar(191)" json:"label"` // 展示值
|
||||||
|
Value string `gorm:"column:value;type:varchar(191)" json:"value"` // 字典值
|
||||||
|
Status bool `gorm:"column:status;type:tinyint(1)" json:"status"` // 启用状态
|
||||||
|
Weight int64 `gorm:"column:weight;type:bigint(20)" json:"weight"` // 排序权重
|
||||||
}
|
}
|
||||||
|
|
||||||
// TableName SysDictionaryDetail's table name
|
// TableName SysDictionaryDetail's table name
|
||||||
|
|||||||
@@ -32,9 +32,9 @@ func newSysDictionary(db *gorm.DB, opts ...gen.DOOption) sysDictionary {
|
|||||||
_sysDictionary.UpdatedAt = field.NewTime(tableName, "updated_at")
|
_sysDictionary.UpdatedAt = field.NewTime(tableName, "updated_at")
|
||||||
_sysDictionary.DeletedAt = field.NewField(tableName, "deleted_at")
|
_sysDictionary.DeletedAt = field.NewField(tableName, "deleted_at")
|
||||||
_sysDictionary.Name = field.NewString(tableName, "name")
|
_sysDictionary.Name = field.NewString(tableName, "name")
|
||||||
_sysDictionary.Type = field.NewString(tableName, "type")
|
_sysDictionary.Alias_ = field.NewString(tableName, "alias")
|
||||||
_sysDictionary.Status = field.NewBool(tableName, "status")
|
_sysDictionary.Status = field.NewBool(tableName, "status")
|
||||||
_sysDictionary.Desc = field.NewString(tableName, "desc")
|
_sysDictionary.Description = field.NewString(tableName, "description")
|
||||||
|
|
||||||
_sysDictionary.fillFieldMap()
|
_sysDictionary.fillFieldMap()
|
||||||
|
|
||||||
@@ -50,9 +50,9 @@ type sysDictionary struct {
|
|||||||
UpdatedAt field.Time
|
UpdatedAt field.Time
|
||||||
DeletedAt field.Field
|
DeletedAt field.Field
|
||||||
Name field.String // 字典名(中)
|
Name field.String // 字典名(中)
|
||||||
Type field.String // 字典名(英)
|
Alias_ field.String // 字典名(英)
|
||||||
Status field.Bool // 状态
|
Status field.Bool // 状态
|
||||||
Desc field.String // 描述
|
Description field.String // 描述
|
||||||
|
|
||||||
fieldMap map[string]field.Expr
|
fieldMap map[string]field.Expr
|
||||||
}
|
}
|
||||||
@@ -74,9 +74,9 @@ func (s *sysDictionary) updateTableName(table string) *sysDictionary {
|
|||||||
s.UpdatedAt = field.NewTime(table, "updated_at")
|
s.UpdatedAt = field.NewTime(table, "updated_at")
|
||||||
s.DeletedAt = field.NewField(table, "deleted_at")
|
s.DeletedAt = field.NewField(table, "deleted_at")
|
||||||
s.Name = field.NewString(table, "name")
|
s.Name = field.NewString(table, "name")
|
||||||
s.Type = field.NewString(table, "type")
|
s.Alias_ = field.NewString(table, "alias")
|
||||||
s.Status = field.NewBool(table, "status")
|
s.Status = field.NewBool(table, "status")
|
||||||
s.Desc = field.NewString(table, "desc")
|
s.Description = field.NewString(table, "description")
|
||||||
|
|
||||||
s.fillFieldMap()
|
s.fillFieldMap()
|
||||||
|
|
||||||
@@ -107,9 +107,9 @@ func (s *sysDictionary) fillFieldMap() {
|
|||||||
s.fieldMap["updated_at"] = s.UpdatedAt
|
s.fieldMap["updated_at"] = s.UpdatedAt
|
||||||
s.fieldMap["deleted_at"] = s.DeletedAt
|
s.fieldMap["deleted_at"] = s.DeletedAt
|
||||||
s.fieldMap["name"] = s.Name
|
s.fieldMap["name"] = s.Name
|
||||||
s.fieldMap["type"] = s.Type
|
s.fieldMap["alias"] = s.Alias_
|
||||||
s.fieldMap["status"] = s.Status
|
s.fieldMap["status"] = s.Status
|
||||||
s.fieldMap["desc"] = s.Desc
|
s.fieldMap["description"] = s.Description
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s sysDictionary) clone(db *gorm.DB) sysDictionary {
|
func (s sysDictionary) clone(db *gorm.DB) sysDictionary {
|
||||||
|
|||||||
@@ -31,11 +31,11 @@ func newSysDictionaryDetail(db *gorm.DB, opts ...gen.DOOption) sysDictionaryDeta
|
|||||||
_sysDictionaryDetail.CreatedAt = field.NewTime(tableName, "created_at")
|
_sysDictionaryDetail.CreatedAt = field.NewTime(tableName, "created_at")
|
||||||
_sysDictionaryDetail.UpdatedAt = field.NewTime(tableName, "updated_at")
|
_sysDictionaryDetail.UpdatedAt = field.NewTime(tableName, "updated_at")
|
||||||
_sysDictionaryDetail.DeletedAt = field.NewField(tableName, "deleted_at")
|
_sysDictionaryDetail.DeletedAt = field.NewField(tableName, "deleted_at")
|
||||||
_sysDictionaryDetail.Label = field.NewString(tableName, "label")
|
|
||||||
_sysDictionaryDetail.Value = field.NewInt64(tableName, "value")
|
|
||||||
_sysDictionaryDetail.Status = field.NewBool(tableName, "status")
|
|
||||||
_sysDictionaryDetail.Sort = field.NewInt64(tableName, "sort")
|
|
||||||
_sysDictionaryDetail.SysDictionaryID = field.NewInt64(tableName, "sys_dictionary_id")
|
_sysDictionaryDetail.SysDictionaryID = field.NewInt64(tableName, "sys_dictionary_id")
|
||||||
|
_sysDictionaryDetail.Label = field.NewString(tableName, "label")
|
||||||
|
_sysDictionaryDetail.Value = field.NewString(tableName, "value")
|
||||||
|
_sysDictionaryDetail.Status = field.NewBool(tableName, "status")
|
||||||
|
_sysDictionaryDetail.Weight = field.NewInt64(tableName, "weight")
|
||||||
|
|
||||||
_sysDictionaryDetail.fillFieldMap()
|
_sysDictionaryDetail.fillFieldMap()
|
||||||
|
|
||||||
@@ -50,11 +50,11 @@ type sysDictionaryDetail struct {
|
|||||||
CreatedAt field.Time
|
CreatedAt field.Time
|
||||||
UpdatedAt field.Time
|
UpdatedAt field.Time
|
||||||
DeletedAt field.Field
|
DeletedAt field.Field
|
||||||
Label field.String // 展示值
|
|
||||||
Value field.Int64 // 字典值
|
|
||||||
Status field.Bool // 启用状态
|
|
||||||
Sort field.Int64 // 排序标记
|
|
||||||
SysDictionaryID field.Int64 // 关联标记
|
SysDictionaryID field.Int64 // 关联标记
|
||||||
|
Label field.String // 展示值
|
||||||
|
Value field.String // 字典值
|
||||||
|
Status field.Bool // 启用状态
|
||||||
|
Weight field.Int64 // 排序权重
|
||||||
|
|
||||||
fieldMap map[string]field.Expr
|
fieldMap map[string]field.Expr
|
||||||
}
|
}
|
||||||
@@ -75,11 +75,11 @@ func (s *sysDictionaryDetail) updateTableName(table string) *sysDictionaryDetail
|
|||||||
s.CreatedAt = field.NewTime(table, "created_at")
|
s.CreatedAt = field.NewTime(table, "created_at")
|
||||||
s.UpdatedAt = field.NewTime(table, "updated_at")
|
s.UpdatedAt = field.NewTime(table, "updated_at")
|
||||||
s.DeletedAt = field.NewField(table, "deleted_at")
|
s.DeletedAt = field.NewField(table, "deleted_at")
|
||||||
s.Label = field.NewString(table, "label")
|
|
||||||
s.Value = field.NewInt64(table, "value")
|
|
||||||
s.Status = field.NewBool(table, "status")
|
|
||||||
s.Sort = field.NewInt64(table, "sort")
|
|
||||||
s.SysDictionaryID = field.NewInt64(table, "sys_dictionary_id")
|
s.SysDictionaryID = field.NewInt64(table, "sys_dictionary_id")
|
||||||
|
s.Label = field.NewString(table, "label")
|
||||||
|
s.Value = field.NewString(table, "value")
|
||||||
|
s.Status = field.NewBool(table, "status")
|
||||||
|
s.Weight = field.NewInt64(table, "weight")
|
||||||
|
|
||||||
s.fillFieldMap()
|
s.fillFieldMap()
|
||||||
|
|
||||||
@@ -109,11 +109,11 @@ func (s *sysDictionaryDetail) fillFieldMap() {
|
|||||||
s.fieldMap["created_at"] = s.CreatedAt
|
s.fieldMap["created_at"] = s.CreatedAt
|
||||||
s.fieldMap["updated_at"] = s.UpdatedAt
|
s.fieldMap["updated_at"] = s.UpdatedAt
|
||||||
s.fieldMap["deleted_at"] = s.DeletedAt
|
s.fieldMap["deleted_at"] = s.DeletedAt
|
||||||
|
s.fieldMap["sys_dictionary_id"] = s.SysDictionaryID
|
||||||
s.fieldMap["label"] = s.Label
|
s.fieldMap["label"] = s.Label
|
||||||
s.fieldMap["value"] = s.Value
|
s.fieldMap["value"] = s.Value
|
||||||
s.fieldMap["status"] = s.Status
|
s.fieldMap["status"] = s.Status
|
||||||
s.fieldMap["sort"] = s.Sort
|
s.fieldMap["weight"] = s.Weight
|
||||||
s.fieldMap["sys_dictionary_id"] = s.SysDictionaryID
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s sysDictionaryDetail) clone(db *gorm.DB) sysDictionaryDetail {
|
func (s sysDictionaryDetail) clone(db *gorm.DB) sysDictionaryDetail {
|
||||||
|
|||||||
@@ -18,6 +18,10 @@ func init() {
|
|||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := container.Container.Provide(controller.NewUserController); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
if err := container.Container.Provide(controller.NewPermissionController); err != nil {
|
if err := container.Container.Provide(controller.NewPermissionController); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
@@ -27,11 +31,24 @@ func init() {
|
|||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := container.Container.Provide(service.NewUserService); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
// dao
|
// dao
|
||||||
if err := container.Container.Provide(dao.NewRoleDao); err != nil {
|
if err := container.Container.Provide(dao.NewRoleDao); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := container.Container.Provide(dao.NewUserDao); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := container.Container.Provide(dao.NewUserRoleDao); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// routes
|
||||||
if err := container.Container.Provide(routes.NewRoute, dig.Group("route")); err != nil {
|
if err := container.Container.Provide(routes.NewRoute, dig.Group("route")); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|||||||
23
modules/auth/controller/user.go
Executable file
23
modules/auth/controller/user.go
Executable file
@@ -0,0 +1,23 @@
|
|||||||
|
package controller
|
||||||
|
|
||||||
|
import (
|
||||||
|
"atom/providers/config"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
type UserController interface {
|
||||||
|
GetName(*gin.Context) (string, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type userControllerImpl struct {
|
||||||
|
conf *config.Config
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewUserController(conf *config.Config) UserController {
|
||||||
|
return &userControllerImpl{conf: conf}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *userControllerImpl) GetName(ctx *gin.Context) (string, error) {
|
||||||
|
return "User",nil
|
||||||
|
}
|
||||||
31
modules/auth/dao/user.go
Executable file
31
modules/auth/dao/user.go
Executable file
@@ -0,0 +1,31 @@
|
|||||||
|
package dao
|
||||||
|
|
||||||
|
import (
|
||||||
|
"atom/database/models"
|
||||||
|
"atom/database/query"
|
||||||
|
"context"
|
||||||
|
)
|
||||||
|
|
||||||
|
type UserDao interface {
|
||||||
|
Create(context.Context, *models.User) (*models.User, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type userDaoImpl struct {
|
||||||
|
query *query.Query
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewUserDao(query *query.Query) UserDao {
|
||||||
|
return &userDaoImpl{query: query}
|
||||||
|
}
|
||||||
|
func (dao *userDaoImpl) FindByID(ctx context.Context, id uint64) (*models.User, error) {
|
||||||
|
user := dao.query.User
|
||||||
|
return user.WithContext(ctx).Where(user.ID.Eq(id)).First()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (dao *userDaoImpl) Create(ctx context.Context, model *models.User) (*models.User, error) {
|
||||||
|
user := dao.query.User
|
||||||
|
if err := user.WithContext(ctx).Create(model); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return model, nil
|
||||||
|
}
|
||||||
51
modules/auth/dao/user_role.go
Executable file
51
modules/auth/dao/user_role.go
Executable file
@@ -0,0 +1,51 @@
|
|||||||
|
package dao
|
||||||
|
|
||||||
|
import (
|
||||||
|
"atom/database/models"
|
||||||
|
"atom/database/query"
|
||||||
|
"context"
|
||||||
|
)
|
||||||
|
|
||||||
|
type UserRoleDao interface {
|
||||||
|
Exists(context.Context, int) bool
|
||||||
|
Create(context.Context, int, int) error
|
||||||
|
Update(context.Context, int, int) error
|
||||||
|
Delete(context.Context, int, int) error
|
||||||
|
}
|
||||||
|
|
||||||
|
type userRoleDaoImpl struct {
|
||||||
|
query *query.Query
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewUserRoleDao(query *query.Query) UserRoleDao {
|
||||||
|
return &userRoleDaoImpl{query: query}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (dao *userRoleDaoImpl) Exists(ctx context.Context, userID int) bool {
|
||||||
|
userRole := dao.query.UserRole
|
||||||
|
count, _ := userRole.WithContext(ctx).Where(userRole.UserID.Eq(uint64(userID))).Count()
|
||||||
|
return count > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (dao *userRoleDaoImpl) Create(ctx context.Context, userID, roleID int) error {
|
||||||
|
userRole := dao.query.UserRole
|
||||||
|
return userRole.WithContext(ctx).Create(&models.UserRole{
|
||||||
|
UserID: uint64(userID),
|
||||||
|
RoleID: uint64(roleID),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (dao *userRoleDaoImpl) Update(ctx context.Context, userID, roleID int) error {
|
||||||
|
userRole := dao.query.UserRole
|
||||||
|
_, err := userRole.WithContext(ctx).Where(userRole.UserID.Eq(uint64(userID))).Update(userRole.RoleID, roleID)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (dao *userRoleDaoImpl) Delete(ctx context.Context, userID, roleID int) error {
|
||||||
|
userRole := dao.query.UserRole
|
||||||
|
_, err := userRole.WithContext(ctx).
|
||||||
|
Where(userRole.UserID.Eq(uint64(userID))).
|
||||||
|
Where(userRole.RoleID.Eq(uint64(roleID))).
|
||||||
|
Delete()
|
||||||
|
return err
|
||||||
|
}
|
||||||
79
modules/auth/dao/user_role_test.go
Executable file
79
modules/auth/dao/user_role_test.go
Executable file
@@ -0,0 +1,79 @@
|
|||||||
|
package dao
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"log"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
// 这里的依赖需要被导入,否则会报错
|
||||||
|
"atom/container"
|
||||||
|
"atom/database/models"
|
||||||
|
"atom/database/query"
|
||||||
|
_ "atom/providers"
|
||||||
|
"atom/utils"
|
||||||
|
|
||||||
|
"github.com/brianvoe/gofakeit/v6"
|
||||||
|
. "github.com/smartystreets/goconvey/convey"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/suite"
|
||||||
|
"go.uber.org/dig"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
type UserRoleInjectParams struct {
|
||||||
|
dig.In
|
||||||
|
|
||||||
|
DB *gorm.DB
|
||||||
|
Dao UserRoleDao
|
||||||
|
Query *query.Query
|
||||||
|
Faker *gofakeit.Faker
|
||||||
|
}
|
||||||
|
|
||||||
|
type UserRoleSuite struct {
|
||||||
|
suite.Suite
|
||||||
|
UserRoleInjectParams
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
if err := container.Container.Provide(NewUserRoleDao); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_UserRoleSuite(t *testing.T) {
|
||||||
|
err := container.Container.Invoke(func(p UserRoleInjectParams) {
|
||||||
|
s := &UserRoleSuite{}
|
||||||
|
s.UserRoleInjectParams = p
|
||||||
|
|
||||||
|
suite.Run(t, s)
|
||||||
|
})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *UserRoleSuite) BeforeTest(suiteName, testName string) {
|
||||||
|
utils.TruncateTable(s.DB, s.Query.UserRole.TableName())
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *UserRoleSuite) Test_GetByUserID() {
|
||||||
|
Convey("Test_GetByUserID", s.T(), func() {
|
||||||
|
Reset(func() {
|
||||||
|
s.BeforeTest("_", "Test_GetByUserID")
|
||||||
|
})
|
||||||
|
|
||||||
|
Convey("not exists", func() {
|
||||||
|
has := s.Dao.Exists(context.Background(), 1)
|
||||||
|
So(has, ShouldBeFalse)
|
||||||
|
})
|
||||||
|
|
||||||
|
Convey("exists", func() {
|
||||||
|
_ = s.Query.UserRole.WithContext(context.Background()).Create(&models.UserRole{
|
||||||
|
UserID: 1,
|
||||||
|
RoleID: 1,
|
||||||
|
})
|
||||||
|
|
||||||
|
has := s.Dao.Exists(context.Background(), 1)
|
||||||
|
So(has, ShouldBeTrue)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
93
modules/auth/dao/user_test.go
Executable file
93
modules/auth/dao/user_test.go
Executable file
@@ -0,0 +1,93 @@
|
|||||||
|
package dao
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"log"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
// 这里的依赖需要被导入,否则会报错
|
||||||
|
"atom/container"
|
||||||
|
"atom/database/models"
|
||||||
|
"atom/database/query"
|
||||||
|
_ "atom/providers"
|
||||||
|
"atom/utils"
|
||||||
|
|
||||||
|
"github.com/brianvoe/gofakeit/v6"
|
||||||
|
. "github.com/smartystreets/goconvey/convey"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/suite"
|
||||||
|
"go.uber.org/dig"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
type UserInjectParams struct {
|
||||||
|
dig.In
|
||||||
|
|
||||||
|
DB *gorm.DB
|
||||||
|
Dao UserDao
|
||||||
|
Query *query.Query
|
||||||
|
Faker *gofakeit.Faker
|
||||||
|
}
|
||||||
|
|
||||||
|
type UserSuite struct {
|
||||||
|
suite.Suite
|
||||||
|
UserInjectParams
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
if err := container.Container.Provide(NewUserDao); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_UserSuite(t *testing.T) {
|
||||||
|
err := container.Container.Invoke(func(p UserInjectParams) {
|
||||||
|
s := &UserSuite{}
|
||||||
|
s.UserInjectParams = p
|
||||||
|
|
||||||
|
suite.Run(t, s)
|
||||||
|
})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *UserSuite) BeforeTest(suiteName, testName string) {
|
||||||
|
log.Println("BeforeTest: ", testName)
|
||||||
|
|
||||||
|
utils.TruncateTable(s.DB, s.Query.User.TableName())
|
||||||
|
|
||||||
|
switch testName {
|
||||||
|
case "":
|
||||||
|
log.Println("BeforeTest: insert test data")
|
||||||
|
_, _ = s.Dao.Create(context.Background(), &models.User{
|
||||||
|
UUID: s.Faker.UUID(),
|
||||||
|
Username: s.Faker.Username(),
|
||||||
|
Password: s.Faker.Password(true, true, true, true, false, 16),
|
||||||
|
Nickname: s.Faker.Name(),
|
||||||
|
Avatar: s.Faker.ImageURL(100, 100),
|
||||||
|
RoleID: 0,
|
||||||
|
Phone: s.Faker.Phone(),
|
||||||
|
Email: s.Faker.Email(),
|
||||||
|
Status: s.Faker.RandomString([]string{"enable", "disabled"}),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *UserSuite) Test_Create() {
|
||||||
|
Convey("Test_Create", s.T(), func() {
|
||||||
|
Convey("create", func() {
|
||||||
|
model, err := s.Dao.Create(context.Background(), &models.User{
|
||||||
|
UUID: s.Faker.UUID(),
|
||||||
|
Username: s.Faker.Username(),
|
||||||
|
Password: s.Faker.Password(true, true, true, true, false, 16),
|
||||||
|
Nickname: s.Faker.Name(),
|
||||||
|
Avatar: s.Faker.ImageURL(100, 100),
|
||||||
|
RoleID: 0,
|
||||||
|
Phone: s.Faker.Phone(),
|
||||||
|
Email: s.Faker.Email(),
|
||||||
|
Status: s.Faker.RandomString([]string{"enable", "disabled"}),
|
||||||
|
})
|
||||||
|
So(err, ShouldBeNil)
|
||||||
|
So(model.ID, ShouldEqual, 1)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
39
modules/auth/service/user.go
Executable file
39
modules/auth/service/user.go
Executable file
@@ -0,0 +1,39 @@
|
|||||||
|
package service
|
||||||
|
|
||||||
|
import (
|
||||||
|
"atom/modules/auth/dao"
|
||||||
|
"context"
|
||||||
|
)
|
||||||
|
|
||||||
|
type UserService interface {
|
||||||
|
AttachRole(context.Context, int, int) error
|
||||||
|
}
|
||||||
|
|
||||||
|
type userService struct {
|
||||||
|
userRoleDao dao.UserRoleDao
|
||||||
|
userDao dao.UserDao
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewUserService(
|
||||||
|
userRoleDao dao.UserRoleDao,
|
||||||
|
userDao dao.UserDao,
|
||||||
|
) UserService {
|
||||||
|
return &userService{
|
||||||
|
userRoleDao: userRoleDao,
|
||||||
|
userDao: userDao,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (svc *userService) AttachRole(ctx context.Context, userID, roleID int) error {
|
||||||
|
if svc.userRoleDao.Exists(ctx, userID) {
|
||||||
|
return svc.userRoleDao.Update(ctx, userID, roleID)
|
||||||
|
}
|
||||||
|
return svc.userRoleDao.Create(ctx, userID, roleID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (svc *userService) DetachRole(ctx context.Context, userID, roleID int) error {
|
||||||
|
if !svc.userRoleDao.Exists(ctx, userID) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return svc.userRoleDao.Delete(ctx, userID, roleID)
|
||||||
|
}
|
||||||
119
providers/dictionary/dict.go
Normal file
119
providers/dictionary/dict.go
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
package dictionary
|
||||||
|
|
||||||
|
import (
|
||||||
|
"atom/container"
|
||||||
|
"atom/database/query"
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"log"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Dict struct {
|
||||||
|
dict map[uint64]*DictInfo
|
||||||
|
dictItems []*DictInfo
|
||||||
|
mapAlias map[string]uint64
|
||||||
|
query *query.Query
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
if err := container.Container.Provide(NewDictionary); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewDictionary(query *query.Query) (*Dict, error) {
|
||||||
|
dict := &Dict{
|
||||||
|
query: query,
|
||||||
|
dict: make(map[uint64]*DictInfo),
|
||||||
|
dictItems: []*DictInfo{},
|
||||||
|
mapAlias: make(map[string]uint64),
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := dict.Load(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return dict, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (dict *Dict) Load() error {
|
||||||
|
ctx, _ := context.WithTimeout(context.Background(), time.Second*5)
|
||||||
|
dictTable := dict.query.SysDictionary
|
||||||
|
items, err := dictTable.WithContext(ctx).Where(dictTable.Status.Is(true)).Find()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
ids := []uint64{}
|
||||||
|
for _, item := range items {
|
||||||
|
ids = append(ids, item.ID)
|
||||||
|
dict.mapAlias[item.Alias_] = item.ID
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx, _ = context.WithTimeout(context.Background(), time.Second*5)
|
||||||
|
dictDetailTable := dict.query.SysDictionaryDetail
|
||||||
|
dictItems, err := dictDetailTable.WithContext(ctx).
|
||||||
|
Where(dictDetailTable.Status.Is(true)).
|
||||||
|
Where(dictDetailTable.ID.In(ids...)).
|
||||||
|
Order(dictDetailTable.Weight.Desc()).
|
||||||
|
Find()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
idItems := make(map[uint64][]*DictItem)
|
||||||
|
for _, dictItem := range dictItems {
|
||||||
|
id := uint64(dictItem.SysDictionaryID)
|
||||||
|
idItems[id] = append(idItems[id], &DictItem{
|
||||||
|
Label: dictItem.Label,
|
||||||
|
Value: dictItem.Value,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
for _, item := range items {
|
||||||
|
info := &DictInfo{
|
||||||
|
ID: item.ID,
|
||||||
|
Name: item.Name,
|
||||||
|
Alias: item.Alias_,
|
||||||
|
Description: item.Description,
|
||||||
|
Items: idItems[item.ID],
|
||||||
|
}
|
||||||
|
dict.dictItems = append(dict.dictItems, info)
|
||||||
|
dict.dict[item.ID] = info
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetLabelByValue
|
||||||
|
func (dict *Dict) GetLabelByValue(alias, value string) (string, error) {
|
||||||
|
items, err := dict.GetItems(alias)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, item := range items {
|
||||||
|
if item.Value == value {
|
||||||
|
return item.Label, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "", errors.New("dict item not exists")
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetLabelByValue
|
||||||
|
func (dict *Dict) GetItems(alias string) ([]*DictItem, error) {
|
||||||
|
dictID, ok := dict.mapAlias[alias]
|
||||||
|
if !ok {
|
||||||
|
return nil, errors.New("dict not exists")
|
||||||
|
}
|
||||||
|
|
||||||
|
dictItem, ok := dict.dict[dictID]
|
||||||
|
if !ok {
|
||||||
|
return nil, errors.New("dict not exists")
|
||||||
|
}
|
||||||
|
return dictItem.Items, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (dict *Dict) All(alias string) []*DictInfo {
|
||||||
|
return dict.dictItems
|
||||||
|
}
|
||||||
14
providers/dictionary/info.go
Normal file
14
providers/dictionary/info.go
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
package dictionary
|
||||||
|
|
||||||
|
type DictInfo struct {
|
||||||
|
ID uint64
|
||||||
|
Name string
|
||||||
|
Alias string
|
||||||
|
Description string
|
||||||
|
Items []*DictItem
|
||||||
|
}
|
||||||
|
|
||||||
|
type DictItem struct {
|
||||||
|
Label string
|
||||||
|
Value string
|
||||||
|
}
|
||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
_ "atom/providers/captcha/driver"
|
_ "atom/providers/captcha/driver"
|
||||||
_ "atom/providers/config"
|
_ "atom/providers/config"
|
||||||
_ "atom/providers/database"
|
_ "atom/providers/database"
|
||||||
|
_ "atom/providers/dictionary"
|
||||||
_ "atom/providers/faker"
|
_ "atom/providers/faker"
|
||||||
_ "atom/providers/http"
|
_ "atom/providers/http"
|
||||||
_ "atom/providers/jwt"
|
_ "atom/providers/jwt"
|
||||||
|
|||||||
Reference in New Issue
Block a user