fix: allow bound tenant option loading
This commit is contained in:
@@ -42,6 +42,13 @@ func (s *sMiddleware) AdminAuth(r *ghttp.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
// 已绑定 IM 租户的后台账号需要读取自己的租户选项,用于各 IM 页面初始化租户下拉。
|
||||
// 业务层会继续按登录态 tenant_id 收敛查询范围,这里只绕过菜单权限,不扩大数据范围。
|
||||
if path == "/imTenant/list" && r.Method == "GET" && contexts.GetTenantId(ctx) > 0 {
|
||||
r.Middleware.Next()
|
||||
return
|
||||
}
|
||||
|
||||
// 验证路由访问权限
|
||||
if !service.AdminRole().Verify(ctx, path, r.Method) {
|
||||
g.Log().Debugf(ctx, "AdminAuth fail path:%+v, GetRoleKey:%+v, r.Method:%+v", path, contexts.GetRoleKey(ctx), r.Method)
|
||||
|
||||
@@ -479,6 +479,9 @@ func (s *sSysImTenant) View(ctx context.Context, in *sysin.ImTenantViewInp) (res
|
||||
if err = in.Filter(ctx); err != nil {
|
||||
return
|
||||
}
|
||||
if err = ensureImTenantTargetAllowed(ctx, in.Id); err != nil {
|
||||
return
|
||||
}
|
||||
if err = s.Model(ctx).WherePri(in.Id).Hook(hook.MemberSummary).Scan(&res); err != nil {
|
||||
err = gerror.Wrap(err, "获取IM租户信息失败,请稍后重试!")
|
||||
return
|
||||
@@ -536,6 +539,9 @@ func (s *sSysImTenant) Usage(ctx context.Context, in *sysin.ImTenantUsageInp) (r
|
||||
if err = in.Filter(ctx); err != nil {
|
||||
return
|
||||
}
|
||||
if err = ensureImTenantTargetAllowed(ctx, in.Id); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
var tenant *entity.ImTenant
|
||||
if err = s.Model(ctx).WherePri(in.Id).Scan(&tenant); err != nil {
|
||||
@@ -577,6 +583,23 @@ func (s *sSysImTenant) Usage(ctx context.Context, in *sysin.ImTenantUsageInp) (r
|
||||
return
|
||||
}
|
||||
|
||||
func ensureImTenantTargetAllowed(ctx context.Context, tenantId int64) error {
|
||||
if isImPlatformAdmin(ctx, contexts.GetUserId(ctx)) {
|
||||
return nil
|
||||
}
|
||||
if tenantId <= 0 {
|
||||
return gerror.New("商户ID不能为空")
|
||||
}
|
||||
boundTenantId := contexts.GetTenantId(ctx)
|
||||
if boundTenantId <= 0 {
|
||||
return gerror.New("当前管理员未关联IM租户")
|
||||
}
|
||||
if tenantId != boundTenantId {
|
||||
return gerror.New("无权访问其它商户")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *sSysImTenant) queryScalarInt64(ctx context.Context, db gdb.DB, label, sql string, warnings *[]string, args ...any) int64 {
|
||||
value, err := db.GetValue(ctx, sql, args...)
|
||||
if err != nil {
|
||||
|
||||
@@ -31,17 +31,8 @@ export async function loadImTenantOptions(
|
||||
|
||||
// 登录用户已绑定商户租户:仅返回自己商户选项(与后端 resolveImAdminScope 强制范围一致)
|
||||
if (boundTenantId > 0) {
|
||||
let tenant: any = null;
|
||||
try {
|
||||
const res = await TenantList({ ...params, id: boundTenantId, page: 1, perPage: 1 });
|
||||
tenant = (res?.list || []).find((item) => Number(item.id) === boundTenantId);
|
||||
} catch {
|
||||
tenant = null;
|
||||
}
|
||||
if (!tenant) {
|
||||
const info = readTokenUserInfo(useUserStore().getToken);
|
||||
tenant = { id: boundTenantId, name: info?.tenantName, code: info?.tenantCode };
|
||||
}
|
||||
const info = readCurrentUserInfo();
|
||||
const tenant = { id: boundTenantId, name: info?.tenantName, code: info?.tenantCode };
|
||||
target.value = [toTenantOption(tenant)];
|
||||
return target.value;
|
||||
}
|
||||
@@ -58,8 +49,7 @@ export async function loadImTenantOptions(
|
||||
|
||||
// 登录用户绑定的商户租户ID(按绑定租户判定,与后端 resolveImAdminScope 的范围逻辑一致)
|
||||
export function getBoundTenantId(): number {
|
||||
const userStore = useUserStore();
|
||||
const userInfo = { ...readTokenUserInfo(userStore.getToken), ...(userStore.getUserInfo as any) };
|
||||
const userInfo = readCurrentUserInfo();
|
||||
return Number(userInfo?.tenantId || userInfo?.tenantID || 0);
|
||||
}
|
||||
|
||||
@@ -109,6 +99,11 @@ function toTenantOption(item: any): ImTenantOption {
|
||||
};
|
||||
}
|
||||
|
||||
function readCurrentUserInfo() {
|
||||
const userStore = useUserStore();
|
||||
return { ...readTokenUserInfo(userStore.getToken), ...(userStore.getUserInfo as any) };
|
||||
}
|
||||
|
||||
function readTokenUserInfo(token: string) {
|
||||
try {
|
||||
const payload = token.split('.')[1];
|
||||
|
||||
Reference in New Issue
Block a user