2
This commit is contained in:
30
internal/erpserver/service/v1/common/captcha.go
Normal file
30
internal/erpserver/service/v1/common/captcha.go
Normal file
@@ -0,0 +1,30 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
v1 "management/internal/erpserver/service/v1"
|
||||
|
||||
"github.com/mojocn/base64Captcha"
|
||||
)
|
||||
|
||||
type captchaService struct{}
|
||||
|
||||
var _ v1.CaptchaService = (*captchaService)(nil)
|
||||
|
||||
func NewCaptchaService() *captchaService {
|
||||
return &captchaService{}
|
||||
}
|
||||
|
||||
var captchaStore base64Captcha.Store = base64Captcha.DefaultMemStore
|
||||
|
||||
func (b *captchaService) Generate(height int, width int, length int, maxSkew float64, dotCount int) (id, b64s, answer string, err error) {
|
||||
driver := base64Captcha.NewDriverDigit(height, width, length, maxSkew, dotCount)
|
||||
// driver := base64Captcha.NewDriverString(config.File.Captcha.ImgHeight,
|
||||
// config.File.Captcha.ImgWidth,
|
||||
// 6, 1, keyLong, source, nil, nil, nil)
|
||||
cp := base64Captcha.NewCaptcha(driver, captchaStore)
|
||||
return cp.Generate()
|
||||
}
|
||||
|
||||
func (b *captchaService) Verify(id, answer string, clear bool) bool {
|
||||
return captchaStore.Verify(id, answer, clear)
|
||||
}
|
||||
102
internal/erpserver/service/v1/service.go
Normal file
102
internal/erpserver/service/v1/service.go
Normal file
@@ -0,0 +1,102 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"management/internal/db/model/dto"
|
||||
"management/internal/erpserver/model/form"
|
||||
"management/internal/erpserver/model/system"
|
||||
"management/internal/erpserver/model/view"
|
||||
)
|
||||
|
||||
type CaptchaService interface {
|
||||
Generate(height int, width int, length int, maxSkew float64, dotCount int) (id, b64s, answer string, err error)
|
||||
Verify(id, answer string, clear bool) bool
|
||||
}
|
||||
|
||||
type ConfigService interface {
|
||||
Create(ctx context.Context, obj *system.Config) error
|
||||
Update(ctx context.Context, obj *system.Config) error
|
||||
Get(ctx context.Context, id int32) (*system.Config, error)
|
||||
List(ctx context.Context, q dto.SearchDto) ([]*system.Config, int64, error)
|
||||
Pear(ctx context.Context) (*dto.PearConfig, error)
|
||||
}
|
||||
|
||||
type UserService interface {
|
||||
Create(ctx context.Context, req *form.User) error
|
||||
Update(ctx context.Context, req *form.User) error
|
||||
All(ctx context.Context) ([]*system.User, error)
|
||||
List(ctx context.Context, q dto.SearchDto) ([]*system.User, int64, error)
|
||||
Get(ctx context.Context, id int32) (*system.User, error)
|
||||
|
||||
XmSelect(ctx context.Context) ([]*view.XmSelect, error)
|
||||
Login(ctx context.Context, req *form.Login) error
|
||||
}
|
||||
|
||||
type LoginLogService interface {
|
||||
Create(ctx context.Context, req *system.LoginLog) error
|
||||
List(ctx context.Context, q dto.SearchDto) ([]*system.LoginLog, int64, error)
|
||||
|
||||
LoginLatestTime(ctx context.Context, email string) time.Time
|
||||
LoginCount(ctx context.Context, email string) int64
|
||||
}
|
||||
|
||||
type AuditLogService interface {
|
||||
Create(ctx context.Context, req *system.AuditLog) error
|
||||
List(ctx context.Context, q dto.SearchDto) ([]*system.AuditLog, int64, error)
|
||||
}
|
||||
|
||||
type RoleService interface {
|
||||
Create(ctx context.Context, req *form.Role) error
|
||||
Update(ctx context.Context, req *form.Role) error
|
||||
Get(ctx context.Context, id int32) (*system.Role, error)
|
||||
All(ctx context.Context) ([]*system.Role, error)
|
||||
List(ctx context.Context, q dto.SearchDto) ([]*system.Role, int64, error)
|
||||
RefreshCache(ctx context.Context) error
|
||||
RebuildParentPath(ctx context.Context) error
|
||||
|
||||
Tree(ctx context.Context, id int32) ([]*view.LayuiTree, error)
|
||||
XmSelectTree(ctx context.Context, id int32) ([]*view.XmSelectTree, error)
|
||||
}
|
||||
|
||||
type DepartmentService interface {
|
||||
Create(ctx context.Context, req *form.Department) error
|
||||
Update(ctx context.Context, req *form.Department) error
|
||||
Get(ctx context.Context, id int32) (*system.Department, error)
|
||||
All(ctx context.Context) ([]*system.Department, error)
|
||||
List(ctx context.Context, q dto.SearchDto) ([]*system.Department, int64, error)
|
||||
RefreshCache(ctx context.Context) error
|
||||
RebuildParentPath(ctx context.Context) error
|
||||
|
||||
Tree(ctx context.Context, id int32) ([]*view.LayuiTree, error)
|
||||
XmSelectTree(ctx context.Context, id int32) ([]*view.XmSelectTree, error)
|
||||
}
|
||||
|
||||
type MenuService interface {
|
||||
Create(ctx context.Context, req *system.Menu) error
|
||||
Update(ctx context.Context, req *system.Menu) error
|
||||
Get(ctx context.Context, id int32) (*system.Menu, error)
|
||||
GetByUrl(ctx context.Context, url string) (*system.Menu, error)
|
||||
All(ctx context.Context) ([]*system.Menu, error)
|
||||
ListMenuTree(ctx context.Context) ([]*view.MenuTree, error)
|
||||
ListByRoleID(ctx context.Context, roleID int32) ([]*dto.OwnerMenuDto, error)
|
||||
SetListByRoleID(ctx context.Context, roleID int32) ([]*dto.OwnerMenuDto, error)
|
||||
ListByRoleIDToMap(ctx context.Context, roleID int32) (map[string]*dto.OwnerMenuDto, error)
|
||||
SetListByRoleIDToMap(ctx context.Context, roleID int32) (map[string]*dto.OwnerMenuDto, error)
|
||||
OwerMenus(ctx context.Context, roleID int32) ([]*dto.MenuUIDto, error)
|
||||
SetOwerMenus(ctx context.Context, roleID int32) ([]*dto.MenuUIDto, error)
|
||||
MenuViewData(ctx context.Context, roleID int32) ([]*dto.SetMenuDto, error)
|
||||
SetRoleMenu(ctx context.Context, roleID int32, rms []*system.RoleMenu) error
|
||||
RefreshCache(ctx context.Context) error
|
||||
RebuildParentPath(ctx context.Context) error
|
||||
|
||||
Tree(ctx context.Context, id int32) ([]*view.LayuiTree, error)
|
||||
XmSelectTree(ctx context.Context, id int32) ([]*view.XmSelectTree, error)
|
||||
}
|
||||
|
||||
type RoleMenuService interface {
|
||||
Create(ctx context.Context, req []*system.RoleMenu) error
|
||||
DeleteByRoleID(ctx context.Context, roleID int32) error
|
||||
ListByRoleID(ctx context.Context, roleID int32) ([]*system.RoleMenu, error)
|
||||
}
|
||||
29
internal/erpserver/service/v1/system/audit_log.go
Normal file
29
internal/erpserver/service/v1/system/audit_log.go
Normal file
@@ -0,0 +1,29 @@
|
||||
package system
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"management/internal/db/model/dto"
|
||||
"management/internal/erpserver/model/system"
|
||||
v1 "management/internal/erpserver/service/v1"
|
||||
)
|
||||
|
||||
type auditLogService struct {
|
||||
repo system.AuditLogRepository
|
||||
}
|
||||
|
||||
var _ v1.AuditLogService = (*auditLogService)(nil)
|
||||
|
||||
func NewAuditLogService(repo system.AuditLogRepository) *auditLogService {
|
||||
return &auditLogService{
|
||||
repo: repo,
|
||||
}
|
||||
}
|
||||
|
||||
func (b *auditLogService) Create(ctx context.Context, req *system.AuditLog) error {
|
||||
return b.repo.Create(ctx, req)
|
||||
}
|
||||
|
||||
func (b *auditLogService) List(ctx context.Context, q dto.SearchDto) ([]*system.AuditLog, int64, error) {
|
||||
return b.repo.List(ctx, q)
|
||||
}
|
||||
69
internal/erpserver/service/v1/system/config.go
Normal file
69
internal/erpserver/service/v1/system/config.go
Normal file
@@ -0,0 +1,69 @@
|
||||
package system
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"time"
|
||||
|
||||
"management/internal/db/model/dto"
|
||||
"management/internal/erpserver/model/system"
|
||||
v1 "management/internal/erpserver/service/v1"
|
||||
"management/internal/pkg/know"
|
||||
"management/internal/pkg/know/pearadmin"
|
||||
"management/internal/pkg/redis"
|
||||
)
|
||||
|
||||
type configService struct {
|
||||
repo system.ConfigRepository
|
||||
redis redis.RedisCache
|
||||
}
|
||||
|
||||
var _ v1.ConfigService = (*configService)(nil)
|
||||
|
||||
func NewConfigService(repo system.ConfigRepository, redis redis.RedisCache) *configService {
|
||||
return &configService{
|
||||
repo: repo,
|
||||
redis: redis,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *configService) Create(ctx context.Context, obj *system.Config) error {
|
||||
return s.repo.Create(ctx, obj)
|
||||
}
|
||||
|
||||
func (s *configService) Update(ctx context.Context, obj *system.Config) error {
|
||||
return s.repo.Update(ctx, obj)
|
||||
}
|
||||
|
||||
func (s *configService) Get(ctx context.Context, id int32) (*system.Config, error) {
|
||||
return s.repo.Get(ctx, id)
|
||||
}
|
||||
|
||||
func (s *configService) List(ctx context.Context, q dto.SearchDto) ([]*system.Config, int64, error) {
|
||||
return s.repo.List(ctx, q)
|
||||
}
|
||||
|
||||
func (s *configService) Pear(ctx context.Context) (*dto.PearConfig, error) {
|
||||
// 判断redis是否存储
|
||||
key := know.GetManageKey(ctx, know.PearAdmin)
|
||||
bs, err := s.redis.GetBytes(ctx, key)
|
||||
if err == nil {
|
||||
var res *dto.PearConfig
|
||||
if err := json.Unmarshal(bs, &res); err == nil {
|
||||
return res, nil
|
||||
}
|
||||
}
|
||||
|
||||
conf, err := s.repo.GetByKey(ctx, pearadmin.PearKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var pear dto.PearConfig
|
||||
if err := json.Unmarshal(conf.Value, &pear); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
_ = s.redis.Set(ctx, key, conf.Value, time.Hour*6)
|
||||
return &pear, nil
|
||||
}
|
||||
207
internal/erpserver/service/v1/system/department.go
Normal file
207
internal/erpserver/service/v1/system/department.go
Normal file
@@ -0,0 +1,207 @@
|
||||
package system
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"management/internal/db/model/dto"
|
||||
db "management/internal/db/sqlc"
|
||||
"management/internal/erpserver/model/form"
|
||||
"management/internal/erpserver/model/system"
|
||||
"management/internal/erpserver/model/view"
|
||||
v1 "management/internal/erpserver/service/v1"
|
||||
"management/internal/pkg/convertor"
|
||||
"management/internal/pkg/know"
|
||||
"management/internal/pkg/redis"
|
||||
)
|
||||
|
||||
type departmentService struct {
|
||||
repo system.DepartmentRepository
|
||||
}
|
||||
|
||||
var _ v1.DepartmentService = (*departmentService)(nil)
|
||||
|
||||
func NewDepartmentService(repo system.DepartmentRepository) *departmentService {
|
||||
return &departmentService{
|
||||
repo: repo,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *departmentService) Create(ctx context.Context, req *form.Department) error {
|
||||
parent := &system.Department{
|
||||
ID: 0,
|
||||
ParentID: 0,
|
||||
ParentPath: ",0,",
|
||||
}
|
||||
if *req.ParentID > 0 {
|
||||
var err error
|
||||
parent, err = s.Get(ctx, *req.ParentID)
|
||||
if err != nil {
|
||||
return errors.New("父级节点错误")
|
||||
}
|
||||
}
|
||||
|
||||
var order int32 = 6666
|
||||
if *req.Sort > 0 {
|
||||
order = *req.Sort
|
||||
}
|
||||
|
||||
arg := &system.Department{
|
||||
Name: req.Name,
|
||||
ParentID: parent.ID,
|
||||
ParentPath: convertor.HandleParentPath(fmt.Sprintf("%s,%d,", parent.ParentPath, parent.ID)),
|
||||
Status: *req.Status,
|
||||
Sort: order,
|
||||
CreatedAt: time.Now(),
|
||||
UpdatedAt: time.Now(),
|
||||
}
|
||||
err := s.repo.Create(ctx, arg)
|
||||
if err != nil {
|
||||
if db.IsUniqueViolation(err) {
|
||||
return errors.New("部门已存在")
|
||||
}
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *departmentService) Update(ctx context.Context, req *form.Department) error {
|
||||
parent := &system.Department{
|
||||
ID: 0,
|
||||
ParentID: 0,
|
||||
ParentPath: ",0,",
|
||||
}
|
||||
if *req.ParentID > 0 {
|
||||
var err error
|
||||
parent, err = s.Get(ctx, *req.ParentID)
|
||||
if err != nil {
|
||||
return errors.New("父级节点错误")
|
||||
}
|
||||
}
|
||||
|
||||
depart, err := s.Get(ctx, *req.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var order int32 = 6666
|
||||
if *req.Sort > 0 {
|
||||
order = *req.Sort
|
||||
}
|
||||
|
||||
depart.Name = req.Name
|
||||
depart.ParentID = parent.ID
|
||||
depart.ParentPath = convertor.HandleParentPath(fmt.Sprintf("%s,%d,", parent.ParentPath, parent.ID))
|
||||
depart.Status = *req.Status
|
||||
depart.Sort = order
|
||||
depart.UpdatedAt = time.Now()
|
||||
return s.repo.Update(ctx, depart)
|
||||
}
|
||||
|
||||
func (s *departmentService) Get(ctx context.Context, id int32) (*system.Department, error) {
|
||||
return s.repo.Get(ctx, id)
|
||||
}
|
||||
|
||||
func (s *departmentService) All(ctx context.Context) ([]*system.Department, error) {
|
||||
key := know.GetManageKey(ctx, know.AllDepartments)
|
||||
bs, err := redis.GetBytes(ctx, key)
|
||||
if err == nil {
|
||||
var res []*system.Department
|
||||
if err := json.Unmarshal(bs, &res); err == nil {
|
||||
return res, nil
|
||||
}
|
||||
}
|
||||
|
||||
res, err := s.repo.All(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
bs, err = json.Marshal(res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
_ = redis.Set(ctx, key, bs, time.Hour*6)
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (s *departmentService) List(ctx context.Context, q dto.SearchDto) ([]*system.Department, int64, error) {
|
||||
return s.repo.List(ctx, q)
|
||||
}
|
||||
|
||||
func (s *departmentService) RefreshCache(ctx context.Context) error {
|
||||
key := know.GetManageKey(ctx, know.AllDepartments)
|
||||
res, err := s.All(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
b, err := json.Marshal(res)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_ = redis.Set(ctx, key, b, time.Hour*6)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *departmentService) RebuildParentPath(ctx context.Context) error {
|
||||
return s.repo.RebuildParentPath(ctx)
|
||||
}
|
||||
|
||||
func (s *departmentService) Tree(ctx context.Context, id int32) ([]*view.LayuiTree, error) {
|
||||
all, err := s.All(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.toTree(id, all), nil
|
||||
}
|
||||
|
||||
func (s *departmentService) XmSelectTree(ctx context.Context, id int32) ([]*view.XmSelectTree, error) {
|
||||
all, err := s.All(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.toXmSelectTree(id, all), nil
|
||||
}
|
||||
|
||||
func (s *departmentService) toTree(parentId int32, data []*system.Department) []*view.LayuiTree {
|
||||
var res []*view.LayuiTree
|
||||
for _, v := range data {
|
||||
if v.ParentID == parentId {
|
||||
item := view.LayuiTree{}
|
||||
item.ID = strconv.FormatInt(int64(v.ID), 10)
|
||||
item.Title = v.Name
|
||||
item.Children = s.toTree(v.ID, data)
|
||||
if v.ParentID == 0 {
|
||||
item.Spread = true
|
||||
}
|
||||
res = append(res, &item)
|
||||
}
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
func (s *departmentService) toXmSelectTree(parentId int32, data []*system.Department) []*view.XmSelectTree {
|
||||
var res []*view.XmSelectTree
|
||||
for _, v := range data {
|
||||
if v.ParentID == parentId {
|
||||
item := view.XmSelectTree{
|
||||
Name: v.Name,
|
||||
Value: strconv.FormatInt(int64(v.ID), 10),
|
||||
Children: s.toXmSelectTree(v.ID, data),
|
||||
}
|
||||
res = append(res, &item)
|
||||
}
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
46
internal/erpserver/service/v1/system/login_log.go
Normal file
46
internal/erpserver/service/v1/system/login_log.go
Normal file
@@ -0,0 +1,46 @@
|
||||
package system
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"management/internal/db/model/dto"
|
||||
"management/internal/erpserver/model/system"
|
||||
v1 "management/internal/erpserver/service/v1"
|
||||
)
|
||||
|
||||
type loginLogService struct {
|
||||
repo system.LoginLogRepository
|
||||
}
|
||||
|
||||
var _ v1.LoginLogService = (*loginLogService)(nil)
|
||||
|
||||
func NewLoginLogService(repo system.LoginLogRepository) *loginLogService {
|
||||
return &loginLogService{
|
||||
repo: repo,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *loginLogService) Create(ctx context.Context, req *system.LoginLog) error {
|
||||
return s.repo.Create(ctx, req)
|
||||
}
|
||||
|
||||
func (s *loginLogService) List(ctx context.Context, q dto.SearchDto) ([]*system.LoginLog, int64, error) {
|
||||
return s.repo.List(ctx, q)
|
||||
}
|
||||
|
||||
func (s *loginLogService) LoginLatestTime(ctx context.Context, email string) time.Time {
|
||||
log, err := s.repo.GetLatest(ctx, email)
|
||||
if err != nil {
|
||||
return time.Time{}
|
||||
}
|
||||
return log.CreatedAt
|
||||
}
|
||||
|
||||
func (s *loginLogService) LoginCount(ctx context.Context, email string) int64 {
|
||||
count, err := s.repo.Count(ctx, email)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
return count
|
||||
}
|
||||
457
internal/erpserver/service/v1/system/menu.go
Normal file
457
internal/erpserver/service/v1/system/menu.go
Normal file
@@ -0,0 +1,457 @@
|
||||
package system
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"management/internal/db/model/dto"
|
||||
"management/internal/erpserver/model/system"
|
||||
"management/internal/erpserver/model/view"
|
||||
"management/internal/erpserver/repository"
|
||||
v1 "management/internal/erpserver/service/v1"
|
||||
"management/internal/pkg/know"
|
||||
"management/internal/pkg/redis"
|
||||
)
|
||||
|
||||
type menuService struct {
|
||||
redis redis.RedisCache
|
||||
store repository.Store
|
||||
repo system.MenuRepository
|
||||
rolesvc v1.RoleService
|
||||
rolemenusvc v1.RoleMenuService
|
||||
}
|
||||
|
||||
var _ v1.MenuService = (*menuService)(nil)
|
||||
|
||||
func NewMenuService(redis redis.RedisCache, store repository.Store, repo system.MenuRepository, rolesvc v1.RoleService, rolemenusvc v1.RoleMenuService) *menuService {
|
||||
return &menuService{
|
||||
redis: redis,
|
||||
store: store,
|
||||
repo: repo,
|
||||
rolesvc: rolesvc,
|
||||
rolemenusvc: rolemenusvc,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *menuService) Create(ctx context.Context, req *system.Menu) error {
|
||||
return s.repo.Create(ctx, req)
|
||||
}
|
||||
|
||||
func (s *menuService) Update(ctx context.Context, req *system.Menu) error {
|
||||
return s.repo.Update(ctx, req)
|
||||
}
|
||||
|
||||
func (s *menuService) Get(ctx context.Context, id int32) (*system.Menu, error) {
|
||||
return s.repo.Get(ctx, id)
|
||||
}
|
||||
|
||||
func (s *menuService) GetByUrl(ctx context.Context, url string) (*system.Menu, error) {
|
||||
return s.repo.GetByUrl(ctx, url)
|
||||
}
|
||||
|
||||
func (s *menuService) All(ctx context.Context) ([]*system.Menu, error) {
|
||||
key := know.GetManageKey(ctx, know.AllMenus)
|
||||
b, err := s.redis.GetBytes(ctx, key)
|
||||
if err == nil {
|
||||
var res []*system.Menu
|
||||
if err := json.Unmarshal(b, &res); err == nil {
|
||||
return res, nil
|
||||
}
|
||||
}
|
||||
|
||||
res, err := s.repo.All(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
b, err = json.Marshal(res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
_ = s.redis.Set(ctx, key, b, time.Hour*6)
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (s *menuService) ListMenuTree(ctx context.Context) ([]*view.MenuTree, error) {
|
||||
all, err := s.All(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return toListTree(0, all), nil
|
||||
}
|
||||
|
||||
func (s *menuService) ListByRoleID(ctx context.Context, roleID int32) ([]*dto.OwnerMenuDto, error) {
|
||||
key := know.GetManageKey(ctx, know.OwnerMenus, roleID)
|
||||
bs, err := s.redis.GetBytes(ctx, key)
|
||||
if err == nil {
|
||||
var res []*dto.OwnerMenuDto
|
||||
if err := json.Unmarshal(bs, &res); err == nil {
|
||||
return res, nil
|
||||
}
|
||||
}
|
||||
|
||||
return s.SetListByRoleID(ctx, roleID)
|
||||
}
|
||||
|
||||
func (s *menuService) SetListByRoleID(ctx context.Context, roleID int32) ([]*dto.OwnerMenuDto, error) {
|
||||
key := know.GetManageKey(ctx, know.OwnerMenus, roleID)
|
||||
menus, err := s.listByRoleID(ctx, roleID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res := toOwnerMenuDto(menus)
|
||||
b, err := json.Marshal(res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
_ = s.redis.Set(ctx, key, b, time.Hour*6)
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (s *menuService) ListByRoleIDToMap(ctx context.Context, roleID int32) (map[string]*dto.OwnerMenuDto, error) {
|
||||
key := know.GetManageKey(ctx, know.OwnerMenusMap, roleID)
|
||||
bs, err := s.redis.GetBytes(ctx, key)
|
||||
if err == nil {
|
||||
var res map[string]*dto.OwnerMenuDto
|
||||
if err := json.Unmarshal(bs, &res); err == nil {
|
||||
return res, nil
|
||||
}
|
||||
}
|
||||
|
||||
return s.SetListByRoleIDToMap(ctx, roleID)
|
||||
}
|
||||
|
||||
func (s *menuService) SetListByRoleIDToMap(ctx context.Context, roleID int32) (map[string]*dto.OwnerMenuDto, error) {
|
||||
key := know.GetManageKey(ctx, know.OwnerMenusMap, roleID)
|
||||
menus, err := s.listByRoleID(ctx, roleID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res := toOwnerMenuDtoMap(menus)
|
||||
b, err := json.Marshal(res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
_ = s.redis.Set(ctx, key, b, time.Hour*6)
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (s *menuService) OwerMenus(ctx context.Context, roleID int32) ([]*dto.MenuUIDto, error) {
|
||||
key := know.GetManageKey(ctx, know.AdminMenus, roleID)
|
||||
bs, err := s.redis.GetBytes(ctx, key)
|
||||
if err == nil {
|
||||
var res []*dto.MenuUIDto
|
||||
if err := json.Unmarshal(bs, &res); err == nil {
|
||||
return res, nil
|
||||
}
|
||||
}
|
||||
|
||||
return s.SetOwerMenus(ctx, roleID)
|
||||
}
|
||||
|
||||
func (s *menuService) SetOwerMenus(ctx context.Context, roleID int32) ([]*dto.MenuUIDto, error) {
|
||||
key := know.GetManageKey(ctx, know.AdminMenus, roleID)
|
||||
|
||||
menus, err := s.listByRoleID(ctx, roleID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res := convertToUITree(menus, 0)
|
||||
b, err := json.Marshal(res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
_ = s.redis.Set(ctx, key, b, time.Hour*6)
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (s *menuService) MenuViewData(ctx context.Context, roleID int32) ([]*dto.SetMenuDto, error) {
|
||||
// 获取该用户已经有的权限
|
||||
hs, err := s.listByRoleID(ctx, roleID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
all, err := s.All(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return toSetMenuTree(all, hs, 0), nil
|
||||
}
|
||||
|
||||
func (s *menuService) SetRoleMenu(ctx context.Context, roleID int32, rms []*system.RoleMenu) error {
|
||||
// 开启事务
|
||||
return s.store.TX(ctx, func(ctx context.Context) error {
|
||||
// 先删除该角色的所有权限
|
||||
err := s.rolemenusvc.DeleteByRoleID(ctx, roleID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 再添加该角色的所有权限
|
||||
return s.rolemenusvc.Create(ctx, rms)
|
||||
})
|
||||
}
|
||||
|
||||
func (s *menuService) RefreshCache(ctx context.Context) error {
|
||||
key := know.GetManageKey(ctx, know.AllMenus)
|
||||
res, err := s.All(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
b, err := json.Marshal(res)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_ = redis.Set(ctx, key, b, time.Hour*6)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *menuService) RebuildParentPath(ctx context.Context) error {
|
||||
return s.repo.RebuildParentPath(ctx)
|
||||
}
|
||||
|
||||
func (s *menuService) Tree(ctx context.Context, id int32) ([]*view.LayuiTree, error) {
|
||||
all, err := s.All(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.toTree(id, all), nil
|
||||
}
|
||||
|
||||
func (s *menuService) XmSelectTree(ctx context.Context, id int32) ([]*view.XmSelectTree, error) {
|
||||
all, err := s.All(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.toXmSelectTree(id, all), nil
|
||||
}
|
||||
|
||||
// listByRoleID 获取该角色所拥有的菜单集合
|
||||
func (s *menuService) listByRoleID(ctx context.Context, roleID int32) ([]*system.Menu, error) {
|
||||
role, err := s.rolesvc.Get(ctx, roleID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res, err := s.repo.All(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if role.Vip {
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// 通过角色获取所拥有的权限
|
||||
roleMenus, err := s.rolemenusvc.ListByRoleID(ctx, roleID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return findMenu(roleMenus, res), nil
|
||||
}
|
||||
|
||||
func (s *menuService) toTree(parentId int32, data []*system.Menu) []*view.LayuiTree {
|
||||
var res []*view.LayuiTree
|
||||
for _, v := range data {
|
||||
if v.ParentID == parentId {
|
||||
item := view.LayuiTree{}
|
||||
item.ID = strconv.FormatInt(int64(v.ID), 10)
|
||||
item.Title = v.Name
|
||||
item.Children = s.toTree(v.ID, data)
|
||||
if v.ParentID == 0 {
|
||||
item.Spread = true
|
||||
}
|
||||
res = append(res, &item)
|
||||
}
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
func (s *menuService) toXmSelectTree(parentId int32, data []*system.Menu) []*view.XmSelectTree {
|
||||
var res []*view.XmSelectTree
|
||||
for _, v := range data {
|
||||
if v.ParentID == parentId {
|
||||
item := view.XmSelectTree{
|
||||
Name: v.Name,
|
||||
Value: strconv.FormatInt(int64(v.ID), 10),
|
||||
Children: s.toXmSelectTree(v.ID, data),
|
||||
}
|
||||
res = append(res, &item)
|
||||
}
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
func findMenu(rms []*system.RoleMenu, ms []*system.Menu) []*system.Menu {
|
||||
var res []*system.Menu
|
||||
for _, rm := range rms {
|
||||
for _, m := range ms {
|
||||
if rm.MenuID == m.ID {
|
||||
res = append(res, m)
|
||||
}
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func toOwnerMenuDto(ms []*system.Menu) []*dto.OwnerMenuDto {
|
||||
var res []*dto.OwnerMenuDto
|
||||
for _, m := range ms {
|
||||
res = append(res, &dto.OwnerMenuDto{
|
||||
ID: m.ID,
|
||||
DisplayName: m.DisplayName,
|
||||
Url: m.Url,
|
||||
ParentID: m.ParentID,
|
||||
Avatar: m.Avatar,
|
||||
Style: m.Style,
|
||||
IsList: m.IsList,
|
||||
})
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func toOwnerMenuDtoMap(ms []*system.Menu) map[string]*dto.OwnerMenuDto {
|
||||
res := make(map[string]*dto.OwnerMenuDto)
|
||||
for _, m := range ms {
|
||||
res[m.Url] = &dto.OwnerMenuDto{
|
||||
ID: m.ID,
|
||||
DisplayName: m.DisplayName,
|
||||
Url: m.Url,
|
||||
ParentID: m.ParentID,
|
||||
Avatar: m.Avatar,
|
||||
Style: m.Style,
|
||||
IsList: m.IsList,
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func convertToUITree(data []*system.Menu, parentID int32) []*dto.MenuUIDto {
|
||||
var root []*dto.MenuUIDto
|
||||
for _, item := range data {
|
||||
if item.ParentID == parentID {
|
||||
if item.IsList {
|
||||
temp := &dto.MenuUIDto{
|
||||
ID: strings.ToLower(item.Url),
|
||||
Title: item.DisplayName,
|
||||
Icon: item.Avatar,
|
||||
Type: 1,
|
||||
OpenType: "_iframe",
|
||||
// OpenType: "_component",
|
||||
Href: item.Url,
|
||||
}
|
||||
root = append(root, temp)
|
||||
} else {
|
||||
temp := &dto.MenuUIDto{
|
||||
ID: strconv.Itoa(int(item.ID)),
|
||||
Title: item.DisplayName,
|
||||
Icon: item.Avatar,
|
||||
Type: 0,
|
||||
}
|
||||
temp.Children = convertToUITree(data, item.ID)
|
||||
root = append(root, temp)
|
||||
}
|
||||
}
|
||||
}
|
||||
return root
|
||||
}
|
||||
|
||||
func toSetMenuTree(data []*system.Menu, ids []*system.Menu, parentID int32) []*dto.SetMenuDto {
|
||||
var res []*dto.SetMenuDto
|
||||
for _, v := range data {
|
||||
if v.ParentID == parentID {
|
||||
isSelect := hasValueInArray(ids, v.ID)
|
||||
if v.IsList {
|
||||
item := dto.SetMenuDto{
|
||||
ID: v.ID,
|
||||
Name: v.DisplayName,
|
||||
Link: v.Type,
|
||||
IsList: v.IsList,
|
||||
IsSelect: isSelect,
|
||||
}
|
||||
item.Items = []*dto.SetMenuDto{
|
||||
{
|
||||
ID: v.ID,
|
||||
Name: "列表",
|
||||
Link: "btn",
|
||||
IsList: false,
|
||||
IsSelect: isSelect,
|
||||
Items: toSetMenuTree(data, ids, v.ID),
|
||||
},
|
||||
}
|
||||
item.Items = append(item.Items, toSetMenuTree(data, ids, v.ID)...)
|
||||
res = append(res, &item)
|
||||
} else {
|
||||
item := dto.SetMenuDto{
|
||||
ID: v.ID,
|
||||
Name: v.DisplayName,
|
||||
Link: v.Type,
|
||||
IsList: v.IsList,
|
||||
IsSelect: isSelect,
|
||||
Items: toSetMenuTree(data, ids, v.ID),
|
||||
}
|
||||
res = append(res, &item)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
func hasValueInArray(data []*system.Menu, id int32) bool {
|
||||
for _, v := range data {
|
||||
if v.ID == id {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func toListTree(parentId int32, data []*system.Menu) []*view.MenuTree {
|
||||
var res []*view.MenuTree
|
||||
for _, v := range data {
|
||||
if v.ParentID == parentId {
|
||||
item := view.MenuTree{}
|
||||
item.ID = v.ID
|
||||
item.Name = v.Name
|
||||
item.DisplayName = v.DisplayName
|
||||
item.Url = v.Url
|
||||
item.Type = v.Type
|
||||
item.ParentID = v.ParentID
|
||||
item.ParentPath = v.ParentPath
|
||||
item.Avatar = v.Avatar
|
||||
item.Style = v.Style
|
||||
item.Visible = v.Visible
|
||||
item.IsList = v.IsList
|
||||
item.Status = v.Status
|
||||
item.Sort = v.Sort
|
||||
item.CreatedAt = v.CreatedAt
|
||||
item.UpdatedAt = v.UpdatedAt
|
||||
item.Children = toListTree(v.ID, data)
|
||||
res = append(res, &item)
|
||||
}
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
210
internal/erpserver/service/v1/system/role.go
Normal file
210
internal/erpserver/service/v1/system/role.go
Normal file
@@ -0,0 +1,210 @@
|
||||
package system
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"management/internal/db/model/dto"
|
||||
db "management/internal/db/sqlc"
|
||||
"management/internal/erpserver/model/form"
|
||||
"management/internal/erpserver/model/system"
|
||||
"management/internal/erpserver/model/view"
|
||||
v1 "management/internal/erpserver/service/v1"
|
||||
"management/internal/pkg/convertor"
|
||||
"management/internal/pkg/know"
|
||||
"management/internal/pkg/redis"
|
||||
)
|
||||
|
||||
type roleService struct {
|
||||
repo system.RoleRepository
|
||||
}
|
||||
|
||||
var _ v1.RoleService = (*roleService)(nil)
|
||||
|
||||
func NewRoleService(repo system.RoleRepository) *roleService {
|
||||
return &roleService{
|
||||
repo: repo,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *roleService) Create(ctx context.Context, req *form.Role) error {
|
||||
parent := &system.Role{
|
||||
ID: 0,
|
||||
ParentID: 0,
|
||||
ParentPath: ",0,",
|
||||
}
|
||||
if *req.ParentID > 0 {
|
||||
var err error
|
||||
parent, err = s.repo.Get(ctx, *req.ParentID)
|
||||
if err != nil {
|
||||
return errors.New("父级节点错误")
|
||||
}
|
||||
}
|
||||
|
||||
var order int32 = 6666
|
||||
if *req.Sort > 0 {
|
||||
order = *req.Sort
|
||||
}
|
||||
|
||||
arg := &system.Role{
|
||||
Name: req.Name,
|
||||
DisplayName: req.DisplayName,
|
||||
ParentID: parent.ID,
|
||||
ParentPath: convertor.HandleParentPath(fmt.Sprintf("%s,%d,", parent.ParentPath, parent.ID)),
|
||||
Vip: false,
|
||||
Status: *req.Status,
|
||||
Sort: order,
|
||||
CreatedAt: time.Now(),
|
||||
UpdatedAt: time.Now(),
|
||||
}
|
||||
err := s.repo.Create(ctx, arg)
|
||||
if err != nil {
|
||||
if db.IsUniqueViolation(err) {
|
||||
return errors.New("角色名称已存在")
|
||||
}
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *roleService) Update(ctx context.Context, req *form.Role) error {
|
||||
parent := &system.Role{
|
||||
ID: 0,
|
||||
ParentID: 0,
|
||||
ParentPath: ",0,",
|
||||
}
|
||||
if *req.ParentID > 0 {
|
||||
var err error
|
||||
parent, err = s.repo.Get(ctx, *req.ParentID)
|
||||
if err != nil {
|
||||
return errors.New("父级节点错误")
|
||||
}
|
||||
}
|
||||
|
||||
role, err := s.repo.Get(ctx, *req.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var order int32 = 6666
|
||||
if *req.Sort > 0 {
|
||||
order = *req.Sort
|
||||
}
|
||||
|
||||
role.DisplayName = req.DisplayName
|
||||
role.Status = *req.Status
|
||||
role.ParentID = parent.ID
|
||||
role.ParentPath = convertor.HandleParentPath(fmt.Sprintf("%s,%d,", parent.ParentPath, parent.ID))
|
||||
role.Sort = order
|
||||
role.UpdatedAt = time.Now()
|
||||
err = s.repo.Update(ctx, role)
|
||||
return err
|
||||
}
|
||||
|
||||
func (s *roleService) Get(ctx context.Context, id int32) (*system.Role, error) {
|
||||
return s.repo.Get(ctx, id)
|
||||
}
|
||||
|
||||
func (s *roleService) All(ctx context.Context) ([]*system.Role, error) {
|
||||
key := know.GetManageKey(ctx, know.AllRoles)
|
||||
bs, err := redis.GetBytes(ctx, key)
|
||||
if err == nil {
|
||||
var res []*system.Role
|
||||
if err := json.Unmarshal(bs, &res); err == nil {
|
||||
return res, nil
|
||||
}
|
||||
}
|
||||
|
||||
res, err := s.repo.All(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
bs, err = json.Marshal(res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
_ = redis.Set(ctx, key, bs, time.Hour*6)
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (s *roleService) List(ctx context.Context, q dto.SearchDto) ([]*system.Role, int64, error) {
|
||||
return s.repo.List(ctx, q)
|
||||
}
|
||||
|
||||
func (s *roleService) RefreshCache(ctx context.Context) error {
|
||||
key := know.GetManageKey(ctx, know.AllRoles)
|
||||
res, err := s.All(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
b, err := json.Marshal(res)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_ = redis.Set(ctx, key, b, time.Hour*6)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *roleService) RebuildParentPath(ctx context.Context) error {
|
||||
return s.repo.RebuildParentPath(ctx)
|
||||
}
|
||||
|
||||
func (s *roleService) Tree(ctx context.Context, id int32) ([]*view.LayuiTree, error) {
|
||||
all, err := s.All(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.toTree(id, all), nil
|
||||
}
|
||||
|
||||
func (s *roleService) XmSelectTree(ctx context.Context, id int32) ([]*view.XmSelectTree, error) {
|
||||
all, err := s.All(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.toXmSelectTree(id, all), nil
|
||||
}
|
||||
|
||||
func (s *roleService) toTree(parentId int32, data []*system.Role) []*view.LayuiTree {
|
||||
var res []*view.LayuiTree
|
||||
for _, v := range data {
|
||||
if v.ParentID == parentId {
|
||||
item := view.LayuiTree{}
|
||||
item.ID = strconv.FormatInt(int64(v.ID), 10)
|
||||
item.Title = v.DisplayName
|
||||
item.Children = s.toTree(v.ID, data)
|
||||
if v.ParentID == 0 {
|
||||
item.Spread = true
|
||||
}
|
||||
res = append(res, &item)
|
||||
}
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
func (s *roleService) toXmSelectTree(parentId int32, data []*system.Role) []*view.XmSelectTree {
|
||||
var res []*view.XmSelectTree
|
||||
for _, v := range data {
|
||||
if v.ParentID == parentId {
|
||||
item := view.XmSelectTree{
|
||||
Name: v.DisplayName,
|
||||
Value: strconv.FormatInt(int64(v.ID), 10),
|
||||
Children: s.toXmSelectTree(v.ID, data),
|
||||
}
|
||||
res = append(res, &item)
|
||||
}
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
32
internal/erpserver/service/v1/system/role_menu.go
Normal file
32
internal/erpserver/service/v1/system/role_menu.go
Normal file
@@ -0,0 +1,32 @@
|
||||
package system
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"management/internal/erpserver/model/system"
|
||||
v1 "management/internal/erpserver/service/v1"
|
||||
)
|
||||
|
||||
type roleMenuService struct {
|
||||
repo system.RoleMenuRepository
|
||||
}
|
||||
|
||||
var _ v1.RoleMenuService = (*roleMenuService)(nil)
|
||||
|
||||
func NewRoleMenuService(repo system.RoleMenuRepository) *roleMenuService {
|
||||
return &roleMenuService{
|
||||
repo: repo,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *roleMenuService) Create(ctx context.Context, req []*system.RoleMenu) error {
|
||||
return s.repo.Create(ctx, req)
|
||||
}
|
||||
|
||||
func (s *roleMenuService) DeleteByRoleID(ctx context.Context, roleID int32) error {
|
||||
return s.repo.DeleteByRoleID(ctx, roleID)
|
||||
}
|
||||
|
||||
func (s *roleMenuService) ListByRoleID(ctx context.Context, roleID int32) ([]*system.RoleMenu, error) {
|
||||
return s.repo.ListByRoleID(ctx, roleID)
|
||||
}
|
||||
203
internal/erpserver/service/v1/system/user.go
Normal file
203
internal/erpserver/service/v1/system/user.go
Normal file
@@ -0,0 +1,203 @@
|
||||
package system
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"management/internal/db/model/dto"
|
||||
db "management/internal/db/sqlc"
|
||||
"management/internal/erpserver/model/form"
|
||||
"management/internal/erpserver/model/system"
|
||||
"management/internal/erpserver/model/view"
|
||||
v1 "management/internal/erpserver/service/v1"
|
||||
"management/internal/pkg/crypto"
|
||||
"management/internal/pkg/know"
|
||||
"management/internal/pkg/rand"
|
||||
"management/internal/pkg/session"
|
||||
|
||||
"github.com/drhin/logger"
|
||||
"github.com/google/uuid"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type userService struct {
|
||||
session session.Session
|
||||
log *logger.Logger
|
||||
repo system.UserRepository
|
||||
roleService v1.RoleService
|
||||
loginLogService v1.LoginLogService
|
||||
}
|
||||
|
||||
var _ v1.UserService = (*userService)(nil)
|
||||
|
||||
func NewUserService(session session.Session, log *logger.Logger, repo system.UserRepository, roleService v1.RoleService, loginLogService v1.LoginLogService) *userService {
|
||||
return &userService{
|
||||
session: session,
|
||||
log: log,
|
||||
repo: repo,
|
||||
roleService: roleService,
|
||||
loginLogService: loginLogService,
|
||||
}
|
||||
}
|
||||
|
||||
func (b *userService) Create(ctx context.Context, req *form.User) error {
|
||||
salt, err := rand.String(10)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
hashedPassword, err := crypto.BcryptHashPassword(req.Password + salt)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
initTime, err := time.ParseInLocation(time.DateTime, "0001-01-01 00:00:00", time.Local)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
user := &system.User{
|
||||
Uuid: uuid.Must(uuid.NewV7()),
|
||||
Email: req.Email,
|
||||
Username: req.Username,
|
||||
HashedPassword: hashedPassword,
|
||||
Salt: salt,
|
||||
Avatar: req.Avatar,
|
||||
Gender: req.Gender,
|
||||
DepartmentID: req.DepartmentID,
|
||||
RoleID: req.RoleID,
|
||||
Status: *req.Status,
|
||||
ChangePasswordAt: initTime,
|
||||
CreatedAt: time.Now(),
|
||||
UpdatedAt: time.Now(),
|
||||
}
|
||||
err = b.repo.Create(ctx, user)
|
||||
if err != nil {
|
||||
if db.IsUniqueViolation(err) {
|
||||
return errors.New("用户已经存在")
|
||||
}
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *userService) Update(ctx context.Context, req *form.User) error {
|
||||
user, err := b.repo.Get(ctx, *req.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
user.Username = req.Username
|
||||
user.Avatar = req.Avatar
|
||||
user.Gender = req.Gender
|
||||
user.DepartmentID = req.DepartmentID
|
||||
user.RoleID = req.RoleID
|
||||
user.Status = *req.Status
|
||||
user.UpdatedAt = time.Now()
|
||||
if req.ChangePassword == "on" {
|
||||
hashedPassword, err := crypto.BcryptHashPassword(req.Password + user.Salt)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
user.HashedPassword = hashedPassword
|
||||
user.ChangePasswordAt = time.Now()
|
||||
}
|
||||
return b.repo.Update(ctx, user)
|
||||
}
|
||||
|
||||
func (b *userService) All(ctx context.Context) ([]*system.User, error) {
|
||||
return b.repo.All(ctx)
|
||||
}
|
||||
|
||||
func (b *userService) List(ctx context.Context, q dto.SearchDto) ([]*system.User, int64, error) {
|
||||
return b.repo.List(ctx, q)
|
||||
}
|
||||
|
||||
func (b *userService) Get(ctx context.Context, id int32) (*system.User, error) {
|
||||
return b.repo.Get(ctx, id)
|
||||
}
|
||||
|
||||
func (b *userService) XmSelect(ctx context.Context) ([]*view.XmSelect, error) {
|
||||
all, err := b.repo.All(ctx)
|
||||
if err != nil || len(all) == 0 {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var res []*view.XmSelect
|
||||
for _, user := range all {
|
||||
res = append(res, &view.XmSelect{
|
||||
Name: user.Username,
|
||||
Value: strconv.Itoa(int(user.ID)),
|
||||
})
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (b *userService) Login(ctx context.Context, req *form.Login) error {
|
||||
l := system.NewLoginLog(req.Email, req.Os, req.Ip, req.Browser, req.Url, req.Referrer)
|
||||
err := b.login(ctx, req)
|
||||
if err != nil {
|
||||
if err := b.loginLogService.Create(ctx, l.SetMessage(err.Error())); err != nil {
|
||||
b.log.Error(err.Error(), err, zap.Any("login_log", l))
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
if err := b.loginLogService.Create(ctx, l.SetOk("登录成功")); err != nil {
|
||||
b.log.Error(err.Error(), err, zap.Any("login_log", l))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *userService) login(ctx context.Context, req *form.Login) error {
|
||||
user, err := b.repo.GetByEmail(ctx, req.Email)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = crypto.BcryptComparePassword(user.HashedPassword, req.Password+user.Salt)
|
||||
if err != nil {
|
||||
return errors.New("账号或密码错误")
|
||||
}
|
||||
|
||||
user.Role, err = b.roleService.Get(ctx, user.RoleID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if user.Role == nil || user.Role.ID == 0 {
|
||||
return errors.New("账号没有配置角色, 请联系管理员")
|
||||
}
|
||||
|
||||
// 登陆成功
|
||||
err = b.loginSuccess(ctx, user, req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *userService) loginSuccess(ctx context.Context, user *system.User, req *form.Login) error {
|
||||
auth := dto.AuthorizeUser{
|
||||
ID: user.ID,
|
||||
Uuid: user.Uuid,
|
||||
Email: user.Email,
|
||||
Username: user.Username,
|
||||
RoleID: user.Role.ID,
|
||||
RoleName: user.Role.DisplayName,
|
||||
OS: req.Os,
|
||||
IP: req.Ip,
|
||||
Browser: req.Browser,
|
||||
}
|
||||
|
||||
gob, err := json.Marshal(auth)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
b.session.Put(ctx, know.StoreName, gob)
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user