diff --git a/api/auth/login.go b/api/auth/login.go index 84c435f..8dcf782 100644 --- a/api/auth/login.go +++ b/api/auth/login.go @@ -294,8 +294,12 @@ func getUserOrgs(userID string) ([]userOrgInfo, error) { continue } - // 解析角色ID - roles := parseRoles(m.RoleIDs) + // 从 UserRole 表查询用户的角色 + var roles []string + cfg.DB().Model(&models.UserRole{}). + Joins("JOIN roles ON user_roles.role_id = roles.id"). + Where("user_roles.user_id = ? AND user_roles.org_id = ?", userID, m.OrgID). + Pluck("roles.code", &roles) result = append(result, userOrgInfo{ OrgID: m.OrgID, @@ -308,11 +312,3 @@ func getUserOrgs(userID string) ([]userOrgInfo, error) { return result, nil } - -func parseRoles(roleIDs string) []string { - if roleIDs == "" { - return []string{} - } - // 简单解析,实际可能需要更复杂的逻辑 - return []string{} -} diff --git a/api/org/create.go b/api/org/create.go index 522b750..8b94830 100644 --- a/api/org/create.go +++ b/api/org/create.go @@ -47,16 +47,42 @@ func create(x *vigo.X, req *CreateRequest) (*models.Org, error) { return nil, vigo.ErrInternalServer.WithError(err) } + // 创建组织的默认角色 + adminRole := &models.Role{ + OrgID: &org.ID, + Code: "admin", + Name: "管理员", + Status: 1, + IsSystem: true, + } + memberRole := &models.Role{ + OrgID: &org.ID, + Code: "member", + Name: "成员", + Status: 1, + IsSystem: true, + } + if err := cfg.DB().Create(adminRole).Error; err != nil { + cfg.DB().Delete(org) + return nil, vigo.ErrInternalServer.WithError(err) + } + if err := cfg.DB().Create(memberRole).Error; err != nil { + cfg.DB().Delete(org) + cfg.DB().Delete(adminRole) + return nil, vigo.ErrInternalServer.WithError(err) + } + // 授予创建者 admin 角色 if err := auth.VBaseAuth.GrantRole(x.Context(), ownerID, org.ID, "admin"); err != nil { - // 最好回滚,这里简化处理 + // 回滚 + cfg.DB().Delete(&models.Role{}).Where("org_id = ?", org.ID) + cfg.DB().Delete(org) return nil, vigo.ErrInternalServer.WithError(err) } member := &models.OrgMember{ OrgID: org.ID, UserID: ownerID, - RoleIDs: "admin", Status: models.MemberStatusActive, JoinedAt: org.CreatedAt.Format("2006-01-02 15:04:05"), } diff --git a/auth/middleware.go b/auth/middleware.go index 49a3b71..3696f01 100644 --- a/auth/middleware.go +++ b/auth/middleware.go @@ -67,7 +67,14 @@ func AuthMiddleware() func(*vigo.X) error { } x.Set("org_id", orgID) - x.Set("org_roles", member.RoleIDs) + + // 从 UserRole 表查询用户的角色 + var roleCodes []string + cfg.DB().Model(&models.UserRole{}). + Joins("JOIN roles ON user_roles.role_id = roles.id"). + Where("user_roles.user_id = ? AND user_roles.org_id = ?", claims.UserID, orgID). + Pluck("roles.code", &roleCodes) + x.Set("org_roles", roleCodes) return nil } diff --git a/models/org.go b/models/org.go index 36fa671..37ee44e 100644 --- a/models/org.go +++ b/models/org.go @@ -41,7 +41,6 @@ type OrgMember struct { vigo.Model OrgID string `json:"org_id" gorm:"type:varchar(36);uniqueIndex:idx_org_user;not null"` UserID string `json:"user_id" gorm:"type:varchar(36);uniqueIndex:idx_org_user;not null"` - RoleIDs string `json:"role_ids" gorm:"size:200"` // 逗号分隔 Position string `json:"position" gorm:"size:50"` Department string `json:"department" gorm:"size:50"` JoinedAt string `json:"joined_at"` diff --git a/ui/langs.json b/ui/langs.json index e37bfcc..477e4d6 100644 --- a/ui/langs.json +++ b/ui/langs.json @@ -17,6 +17,7 @@ "common.loading": "Loading...", "common.not_found": "Not Found", "common.save": "Save", + "common.status": "Status", "nav.dashboard": "Dashboard", "nav.home": "Home", "nav.oauth": "OAuth Apps", @@ -24,6 +25,7 @@ "nav.roles": "Roles", "nav.profile": "Profile", "nav.users": "Users", + "org.code": "Code", "org.create": "Create Organization", "org.create_first": "Create Organization", "org.created": "Created successfully", @@ -36,6 +38,8 @@ "org.edit": "Edit Organization", "org.feature_coming": "Feature coming soon", "org.info": "Information", + "org.joined_at": "Joined At", + "org.max_members": "Max Members", "org.member_removed": "Member removed", "org.members": "Members", "org.name": "Organization Name", @@ -81,6 +85,7 @@ "common.loading": "加载中...", "common.not_found": "页面未找到", "common.save": "保存", + "common.status": "状态", "nav.dashboard": "仪表盘", "nav.home": "首页", "nav.oauth": "OAuth应用", @@ -88,6 +93,7 @@ "nav.roles": "角色管理", "nav.profile": "个人中心", "nav.users": "用户管理", + "org.code": "组织代码", "org.create": "创建组织", "org.create_first": "创建第一个组织", "org.created": "创建成功", @@ -100,6 +106,8 @@ "org.edit": "编辑组织", "org.feature_coming": "功能即将推出", "org.info": "基本信息", + "org.joined_at": "加入时间", + "org.max_members": "成员上限", "org.member_removed": "成员已移除", "org.members": "成员列表", "org.name": "组织名称", diff --git a/ui/page/sys/org/detail.html b/ui/page/sys/org/detail.html index 31af215..3e71533 100644 --- a/ui/page/sys/org/detail.html +++ b/ui/page/sys/org/detail.html @@ -182,6 +182,24 @@ color: var(--text-color-secondary); } + .status-badge { + display: inline-block; + padding: 2px 8px; + border-radius: var(--radius-full); + font-size: var(--font-size-xs); + font-weight: 500; + } + + .status-active { + background-color: color-mix(in srgb, var(--color-success), transparent 85%); + color: var(--color-success); + } + + .status-inactive { + background-color: color-mix(in srgb, var(--text-color-disabled), transparent 85%); + color: var(--text-color-secondary); + } + .loading-state { display: flex; flex-direction: column; @@ -267,6 +285,18 @@ ID {{ org.id }} +
+ {{ $t('org.code') }} + {{ org.code }} +
+
+ {{ $t('common.status') }} + + + {{ org.status === 1 ? 'Active' : 'Inactive' }} + + +
{{ $t('org.created_at') }} {{ formatDate(org.created_at) }} @@ -299,6 +329,8 @@ {{ $t('user.username') }} {{ $t('user.email') }} {{ $t('user.role') }} + {{ $t('common.status') }} + {{ $t('org.joined_at') }} {{ $t('common.actions') }} @@ -307,10 +339,16 @@ {{ member.username }} {{ member.email || '-' }} - - {{ member.role || 'member' }} + + {{ member.role_ids || 'member' }} + + + + + {{ member.status === 1 ? 'Active' : 'Inactive' }} + {{ formatDate(member.joined_at) }} @@ -347,6 +385,7 @@ orgId = $router.params.id; org = null; members = []; + totalMembers = 0; loading = false; currentUserId = $env.$vbase.user?.id; @@ -366,6 +405,7 @@ ]); org = orgRes; members = membersRes.items || []; + totalMembers = membersRes.total || 0; } catch (e) { $message.error(e.message); if (e.status === 404) {