diff --git a/deploy/sql/init/user.sql b/deploy/sql/init/user.sql index 4ba0c5a..34f7370 100644 --- a/deploy/sql/init/user.sql +++ b/deploy/sql/init/user.sql @@ -57,7 +57,7 @@ CREATE TABLE IF NOT EXISTS `user_organization` ( -- 角色表 CREATE TABLE IF NOT EXISTS `role` ( `id` int UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'id' , - `code` VARCHAR(255) NOT NULL COMMENT 'code', + `code` VARCHAR(64) NOT NULL COMMENT 'code', `name` VARCHAR(255) NOT NULL COMMENT '名称', `created_by` VARCHAR(64) DEFAULT '' COMMENT '创建人', `created_on` DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL COMMENT '记录创建时间', @@ -67,6 +67,18 @@ CREATE TABLE IF NOT EXISTS `role` ( UNIQUE KEY `uk_code` (`code`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb3 COMMENT='角色表'; +-- 用户角色表 +CREATE TABLE IF NOT EXISTS `user_role` ( + `id` int UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'id' , + `user_account` VARCHAR(64) NOT NULL COMMENT '用户账号', + `role_code` VARCHAR(64) NOT NULL COMMENT '名称', + `created_by` VARCHAR(64) DEFAULT '' COMMENT '创建人', + `created_on` DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL COMMENT '记录创建时间', + `modified_by` VARCHAR(64) DEFAULT '' COMMENT '修改人', + `modified_on` DATETIME DEFAULT CURRENT_TIMESTAMP null on update CURRENT_TIMESTAMP COMMENT '记录修改时间', + PRIMARY KEY (`id`), + UNIQUE KEY `uk_user_role` (`user_account`,`role_code`) +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb3 COMMENT='用户角色表'; -- 组织角色表 CREATE TABLE IF NOT EXISTS `organization_role` ( @@ -174,3 +186,16 @@ CREATE TABLE IF NOT EXISTS `user_info`( -- 默认管理员 pwd:Passw0rd@20240703 REPLACE INTO `user`(`account`,`name`,`mobile`,`email`,`pwd`,`salt`,`created_by`) values ('admin','admin','13077164722','puff.guo@foxmail.com','5b5b2a3ddd62790986676e50e6c4a31b4516ab8387a3a2421df8ebe13b5f4d37','12345678900987654321','admin'); + +-- init application +REPLACE INTO `application` (`code`,`secret`,`name`,`description`,`created_by`) VALUES('user-busniss-center','146E5EA66B4B6036C6BBF395CC90C30E','用户中心','用户,统一登陆等','admin'); + +--init menu +REPLACE INTO `menu`(`app_code`,`code`,`name`,`parent_code`,`type`,`order`,`icon`,`path`,`child_path`,`is_show`,`created_by`) VALUES('user-busniss-center','index','首页','',1,0,'home','/home','',1,'admin'); +REPLACE INTO `menu`(`app_code`,`code`,`name`,`parent_code`,`type`,`order`,`icon`,`path`,`child_path`,`is_show`,`created_by`) VALUES('user-busniss-center','user','用户','',1,1,'user','/user','',1,'admin'); +REPLACE INTO `menu`(`app_code`,`code`,`name`,`parent_code`,`type`,`order`,`icon`,`path`,`child_path`,`is_show`,`created_by`) VALUES('user-busniss-center','organization','组织','',1,2,'organization','/organization','',1,'admin'); +REPLACE INTO `menu`(`app_code`,`code`,`name`,`parent_code`,`type`,`order`,`icon`,`path`,`child_path`,`is_show`,`created_by`) VALUES('user-busniss-center','role','角色','',1,3,'role','/role','',1,'admin'); +REPLACE INTO `menu`(`app_code`,`code`,`name`,`parent_code`,`type`,`order`,`icon`,`path`,`child_path`,`is_show`,`created_by`) VALUES('user-busniss-center','application','应用','',1,4,'application','/application','',1,'admin'); + +-- init role +REPLACE INTO `role` (`code`,`name`,`created_by`) VALUES('admin','超级管理员','admin'); \ No newline at end of file diff --git a/internal/models/application/application.go b/internal/models/application/application.go index 20c5734..c6cb184 100644 --- a/internal/models/application/application.go +++ b/internal/models/application/application.go @@ -12,6 +12,7 @@ type ApplicationInfo struct { CreatedOn time.Time `json:"created_on"` // 记录创建时间 ModifiedBy string `json:"modified_by"` // 修改人 ModifiedOn time.Time `json:"modified_on"` // 记录修改时间 + Menus []Menu `json:"menus"` } type Menu struct { diff --git a/internal/models/application/request.go b/internal/models/application/request.go index 026f664..c236720 100644 --- a/internal/models/application/request.go +++ b/internal/models/application/request.go @@ -8,7 +8,7 @@ type CreateReq struct { } type ResetSecretReq struct { - Id uint `json:"id" binding:"required"` + Code string `json:"code" binding:"required"` Secret string `json:"secret" binding:"required,len=32"` } @@ -34,7 +34,10 @@ func (q *Query) Default() { } type List struct { - List []ApplicationInfo `json:"list"` + List []ApplicationInfo `json:"list"` + Total int64 + Page int + PageSize int } type MenusReq struct { @@ -42,11 +45,11 @@ type MenusReq struct { } type DeleteAppReq struct { - Id uint `json:"id" binding:"required"` + Id uint `form:"id" json:"id" binding:"required"` } type GetAppReq struct { - Id uint `form:"id" json:"id" binding:"required"` + Code string `form:"code" json:"code" binding:"required"` } type CreateMenuReq struct { diff --git a/internal/models/user/user.go b/internal/models/user/user.go index 3325bff..8edf6b6 100644 --- a/internal/models/user/user.go +++ b/internal/models/user/user.go @@ -9,8 +9,8 @@ import ( type UserStatus int const ( - EnableUserStatus UserStatus = 0 - DisableUserStatus UserStatus = 1 + EnableUserStatus UserStatus = 1 + DisableUserStatus UserStatus = 0 ) type LoginInfo struct { @@ -83,3 +83,10 @@ func (q *Query) Default() { type Enable struct { Id uint `json:"id" binding:"required"` } + +type SearchRsp struct { + List []User + Page int + PageSize int + Total int64 +} diff --git a/internal/repo/application.go b/internal/repo/application.go index 05f3e21..191fc3d 100644 --- a/internal/repo/application.go +++ b/internal/repo/application.go @@ -38,6 +38,7 @@ type ApplicationRepo interface { Search(ctx context.Context, query Query) ([]Application, error) ResetSecret(ctx context.Context, app Application) error DelApp(ctx context.Context,id uint)error + SearchCount(ctx context.Context, query Query) (int64, error) } type applicationRepoS struct { @@ -69,7 +70,7 @@ func (u *applicationRepoS) SaveApplication(ctx context.Context, application Appl } func (u *applicationRepoS) CreateApplication(ctx context.Context, application Application) error { - return u.db.Create(application).Error + return u.db.Create(&application).Error } @@ -87,10 +88,22 @@ func (u *applicationRepoS) Search(ctx context.Context, query Query) ([]Applicati } func (u *applicationRepoS) ResetSecret(ctx context.Context, app Application) error { - err := u.db.Model(&Application{}).Where("id = ?", app.ID).Update("secret",app.Secret).Error + err := u.db.Model(&Application{}).Where("code = ?", app.Code).Update("secret",app.Secret).Error return err } func (u *applicationRepoS) DelApp(ctx context.Context,id uint)error{ return u.db.Where("id = ?",id).Delete(&Application{}).Error +} + +func (u *applicationRepoS) SearchCount(ctx context.Context, query Query) (int64, error){ + var total int64 + keyword := fmt.Sprintf("%%%s%%", query.Keyword) + db := u.db.Model(&Application{}) + if query.Keyword != "" { + db = db.Where("code like ? or name like ?", keyword, keyword) + } + + err := db.Count(&total).Error + return total, err } \ No newline at end of file diff --git a/internal/repo/convert.go b/internal/repo/convert.go index 8f86a0d..875378e 100644 --- a/internal/repo/convert.go +++ b/internal/repo/convert.go @@ -9,7 +9,7 @@ import ( func convertMenu(menu Menu) appModel.Menu { aMenu := appModel.Menu{} - copier.Copy(aMenu, menu) + copier.Copy(&aMenu, menu) return aMenu } diff --git a/internal/repo/menu.go b/internal/repo/menu.go index 63b311e..3ad3136 100644 --- a/internal/repo/menu.go +++ b/internal/repo/menu.go @@ -11,7 +11,7 @@ import ( ) func init(){ - do.Provide[ApplicationRepo](nil, NewApplicationRepoS) + do.Provide[MenuRepo](nil, NewMenuRepo) } // 菜单 diff --git a/internal/repo/organization_role.go b/internal/repo/organization_role.go index 228786a..2ebd628 100644 --- a/internal/repo/organization_role.go +++ b/internal/repo/organization_role.go @@ -10,7 +10,7 @@ import ( func init(){ - do.Provide[UserOrganizationRepo](nil,NewUserOrganizationRepo) + do.Provide[OrganizationRoleRepo](nil,NewOrganizationRoleRepo) } // 组织角色表 diff --git a/internal/repo/user.go b/internal/repo/user.go index fad976a..0778c3e 100644 --- a/internal/repo/user.go +++ b/internal/repo/user.go @@ -42,7 +42,9 @@ type UserRepo interface { CreateUser(ctx context.Context, user *User) error SetUserStatus(ctx context.Context, id uint, status userModel.UserStatus) error Search(ctx context.Context, query *userModel.Query) ([]User, error) + SearchCount(ctx context.Context, query *userModel.Query) (int64, error) ResetPwd(ctx context.Context, user User) error + GetUserById(ctx context.Context, id uint) (user User, err error) } type userRepoS struct { @@ -104,3 +106,21 @@ func (u *userRepoS) ResetPwd(ctx context.Context, user User) error { err := u.db.Model(&User{}).Where("id = ?", user.ID).Updates(map[string]any{"pwd": user.Pwd, "salt": user.Salt}).Error return err } + +func (u *userRepoS) SearchCount(ctx context.Context, query *userModel.Query) (int64, error) { + keyword := fmt.Sprintf("%%%s%%", query.Keyword) + + db := u.db.Model(&User{}) + if query.Keyword != "" { + db = db.Where("account like ? or name like ?", keyword, keyword) + } + + var total int64 + err := db.Count(&total).Error + return total, err +} + +func (u *userRepoS)GetUserById(ctx context.Context, id uint) (user User, err error){ + err = u.db.Where("id = ?", id).Take(&user).Error + return +} \ No newline at end of file diff --git a/internal/service/application/application.go b/internal/service/application/application.go index c8005fb..ca15883 100644 --- a/internal/service/application/application.go +++ b/internal/service/application/application.go @@ -5,6 +5,7 @@ import ( appModel "busniess-user-center/internal/models/application" "busniess-user-center/internal/repo" "busniess-user-center/pkg/redis" + contextUtil "busniess-user-center/pkg/utils/context" "context" "fmt" @@ -37,18 +38,33 @@ func NewApplicationService(i *do.Injector) (ApplicationService, error) { } func (a *applicationService) Create(ctx context.Context, info *appModel.CreateReq) error { - dbApp := repo.Application{} - err := copier.Copy(dbApp, info) + session, err := contextUtil.GetSession(ctx) if err != nil { return err } + _, err = a.appRepo.GetAppByCode(ctx, info.Code) + if err != nil && err != gorm.ErrRecordNotFound { + return err + } + + if err == nil { + return fmt.Errorf("应用code:%s已经存在", info.Code) + } + + dbApp := repo.Application{} + err = copier.Copy(&dbApp, info) + if err != nil { + return err + } + + dbApp.CreatedBy = session.Account return a.appRepo.CreateApplication(ctx, dbApp) } func (a *applicationService) ResetSecret(ctx context.Context, info *appModel.ResetSecretReq) error { dbApp := repo.Application{} - err := copier.Copy(dbApp, info) + err := copier.Copy(&dbApp, info) if err != nil { return err } @@ -63,7 +79,7 @@ func (a *applicationService) Delete(ctx context.Context, req *appModel.DeleteApp } func (a *applicationService) GetApp(ctx context.Context, req *appModel.GetAppReq) (app appModel.ApplicationInfo, err error) { - dbApp, err := a.appRepo.GetAppById(ctx, req.Id) + dbApp, err := a.appRepo.GetAppByCode(ctx, req.Code) if err != nil && err != gorm.ErrRecordNotFound { return } @@ -72,14 +88,19 @@ func (a *applicationService) GetApp(ctx context.Context, req *appModel.GetAppReq return } - err = copier.Copy(app, dbApp) + app.Menus, err = a.menuRepo.GetAppMenus(ctx, dbApp.Code) + if err != nil { + return + } + + err = copier.Copy(&app, dbApp) return } func (a *applicationService) Search(ctx context.Context, query *appModel.Query) (rsp appModel.List, err error) { query.Default() dbQuery := repo.Query{} - err = copier.Copy(dbQuery, query) + err = copier.Copy(&dbQuery, query) if err != nil { return } @@ -89,12 +110,21 @@ func (a *applicationService) Search(ctx context.Context, query *appModel.Query) return } + total, err := a.appRepo.SearchCount(ctx, dbQuery) + if err != nil { + return + } + for _, item := range dbList { info := appModel.ApplicationInfo{} - copier.Copy(info, item) + copier.Copy(&info, item) rsp.List = append(rsp.List, info) } + rsp.Page = query.Page + rsp.PageSize = query.PageSize + rsp.Total = total + return } @@ -105,7 +135,7 @@ func (a *applicationService) Menus(ctx context.Context, info *appModel.MenusReq) func (a *applicationService) CreateMenu(ctx context.Context, info *appModel.CreateMenuReq) error { // todo 校验权限 menu := repo.Menu{} - err := copier.Copy(menu, info) + err := copier.Copy(&menu, info) if err != nil { return err } @@ -143,3 +173,19 @@ func (a *applicationService) DeleteMenu(ctx context.Context, info *appModel.DelM err := a.menuRepo.DelMenuById(ctx, info.Id) return err } + +func (a *applicationService) Modify(ctx context.Context, info *appModel.Application) error { + dbApp := repo.Application{} + err := copier.Copy(&dbApp, info) + if err != nil { + return err + } + + app, err := a.appRepo.GetAppByCode(ctx, info.Info.Code) + if err != nil { + return err + } + + dbApp.ID = app.ID + return a.appRepo.SaveApplication(ctx, dbApp) +} diff --git a/internal/service/application/interface.go b/internal/service/application/interface.go index 57feccc..d0fbbd2 100644 --- a/internal/service/application/interface.go +++ b/internal/service/application/interface.go @@ -12,4 +12,5 @@ type ApplicationService interface { GetApp(ctx context.Context, req *appModel.GetAppReq) (app appModel.ApplicationInfo, err error) Search(ctx context.Context, query *appModel.Query) (rsp appModel.List, err error) Menus(ctx context.Context, info *appModel.MenusReq) (rsp []appModel.Menu, err error) + Modify(ctx context.Context, info *appModel.Application) error } diff --git a/internal/service/organization/organization.go b/internal/service/organization/organization.go index 7127855..7bfa349 100644 --- a/internal/service/organization/organization.go +++ b/internal/service/organization/organization.go @@ -88,7 +88,7 @@ func (o *organizationService) Organization(ctx context.Context, info *orgModel.G return } - copier.Copy(org, dbOrg) + copier.Copy(&org, dbOrg) return } diff --git a/internal/service/role/role.go b/internal/service/role/role.go index bfab2a6..d353608 100644 --- a/internal/service/role/role.go +++ b/internal/service/role/role.go @@ -74,13 +74,13 @@ func (o *roleService) Role(ctx context.Context, info *roleModel.GetReq) (role ro return } - err = copier.Copy(role, dbRole) + err = copier.Copy(&role, dbRole) return } func (o *roleService) Search(ctx context.Context, info *roleModel.Query) ([]roleModel.Role, error) { dbQuery := repo.Query{} - copier.Copy(dbQuery, info) + copier.Copy(&dbQuery, info) dbRoles, err := o.roleRepo.Search(ctx, dbQuery) if err != nil { return nil, err diff --git a/internal/service/user/interface.go b/internal/service/user/interface.go index 30f2c23..66a1e2b 100644 --- a/internal/service/user/interface.go +++ b/internal/service/user/interface.go @@ -13,7 +13,7 @@ type UserService interface { Modify(ctx context.Context, mInfo *userModel.ModifyInfo) error Disable(ctx context.Context, req *userModel.Enable) error Enable(ctx context.Context, req *userModel.Enable) error - Search(ctx context.Context, query *userModel.Query) ([]userModel.User, error) + Search(ctx context.Context, query *userModel.Query) (*userModel.SearchRsp, error) ResetPwd(ctx context.Context, req *userModel.ResetPwdReq) error GetUser(ctx context.Context, req *userModel.GetUserReq) (user userModel.User, err error) } diff --git a/internal/service/user/user.go b/internal/service/user/user.go index 56db663..9450718 100644 --- a/internal/service/user/user.go +++ b/internal/service/user/user.go @@ -183,7 +183,7 @@ func (u *userService) Enable(ctx context.Context, req *userModel.Enable) error { return u.repo.SetUserStatus(ctx, req.Id, userModel.EnableUserStatus) } -func (u *userService) Search(ctx context.Context, query *userModel.Query) ([]userModel.User, error) { +func (u *userService) Search(ctx context.Context, query *userModel.Query) (*userModel.SearchRsp, error) { // 获取操作用户 _, err := contextUtil.GetSession(ctx) if err != nil { @@ -196,8 +196,19 @@ func (u *userService) Search(ctx context.Context, query *userModel.Query) ([]use return nil, err } - list := convertUserList(users) - return list, err + total, err := u.repo.SearchCount(ctx, query) + if err != nil { + return nil, err + } + + rsp := &userModel.SearchRsp{ + List: convertUserList(users), + Page: query.Page, + PageSize: query.PageSize, + Total: total, + } + + return rsp, err } func (u *userService) ResetPwd(ctx context.Context, req *userModel.ResetPwdReq) error { @@ -208,7 +219,7 @@ func (u *userService) ResetPwd(ctx context.Context, req *userModel.ResetPwdReq) } // 判断是否本人操作 - rUser, err := u.repo.GetUserByAccount(ctx, session.Account) + rUser, err := u.repo.GetUserById(ctx, req.Id) if err != nil && err != gorm.ErrRecordNotFound { return err } diff --git a/internal/service/user/util.go b/internal/service/user/util.go index 45346ff..5539c43 100644 --- a/internal/service/user/util.go +++ b/internal/service/user/util.go @@ -69,7 +69,7 @@ func (u *userService) removeCookie(ctx context.Context) { } func convertUserList(users []repo.User) []userModel.User { - list := make([]userModel.User, len(users)) + list := make([]userModel.User,0, len(users)) for _, item := range users { list = append(list, convertUser(item)) } diff --git a/server/application/application.go b/server/application/application.go index d137ef5..47b18b2 100644 --- a/server/application/application.go +++ b/server/application/application.go @@ -32,9 +32,10 @@ func RegisterRoute(api *gin.RouterGroup) { server := do.MustInvoke[*ApplicationServer](nil) api.POST("/create", ginUtil.WrapNoRsp(server.Create)) api.POST("/reset", ginUtil.WrapNoRsp(server.ResetSecret)) - api.POST("/delete", ginUtil.WrapNoRsp(server.DelApp)) + api.DELETE("/delete", ginUtil.WrapNoRsp(server.DelApp)) api.GET("/search", ginUtil.Wrap(server.Search)) - api.GET("/menus", ginUtil.WrapNoRsp(server.ResetSecret)) + api.GET("/application", ginUtil.Wrap(server.Get)) + api.GET("/modify", ginUtil.WrapNoRsp(server.Modify)) } func (u *ApplicationServer) Create(ctx context.Context, req *appModel.CreateReq) (err error) { @@ -58,3 +59,7 @@ func (u *ApplicationServer) ResetSecret(ctx context.Context, req *appModel.Reset func (u *ApplicationServer) DelApp(ctx context.Context, req *appModel.DeleteAppReq) error { return u.applicationService.Delete(ctx, req) } + +func (u *ApplicationServer) Modify(ctx context.Context, info *appModel.Application) error { + return u.applicationService.Modify(ctx, info) +} diff --git a/server/user/user.go b/server/user/user.go index 7a26b9a..63fd8b4 100644 --- a/server/user/user.go +++ b/server/user/user.go @@ -83,7 +83,7 @@ func (u *UserServer) Enable(ctx context.Context, req *userModel.Enable) error { return u.userService.Enable(ctx, req) } -func (u *UserServer) Search(ctx context.Context, query *userModel.Query) ([]userModel.User, error) { +func (u *UserServer) Search(ctx context.Context, query *userModel.Query) (*userModel.SearchRsp, error) { query.Default() return u.userService.Search(ctx, query) }