Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion apps/system_manage/serializers/resource_chat_user_group.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from common.exception.app_exception import AppApiException
from common.utils.common import get_file_content
from maxkb.conf import PROJECT_DIR
from system_manage.models import ResourceChatUserGroupAuthorize, UserGroup
from system_manage.models import ResourceChatUserAuthorize, ResourceChatUserGroupAuthorize, UserGroup


class ResourceChatUserGroupQuerySerializer(serializers.Serializer):
Expand All @@ -29,20 +29,30 @@ def get_query_set(self):
resource_chat_user_group_authorize_query_set = QuerySet(ResourceChatUserGroupAuthorize).filter(
resource_id=resource_id, resource_type=resource_type
)
resource_chat_user_authorize_query_set = QuerySet(ResourceChatUserAuthorize).filter(
resource_id=resource_id, resource_type=resource_type
)
query_set = QuerySet(UserGroup)
if user_group_name is not None:
query_set = query_set.filter(name__contains=user_group_name)
if workspace_id is not None:
resource_chat_user_group_authorize_query_set = resource_chat_user_group_authorize_query_set.filter(
workspace_id=workspace_id
)
resource_chat_user_authorize_query_set = resource_chat_user_authorize_query_set.filter(
workspace_id=workspace_id
)
else:
resource_chat_user_group_authorize_query_set = resource_chat_user_group_authorize_query_set.filter(
workspace_id__isnull=True
)
resource_chat_user_authorize_query_set = resource_chat_user_authorize_query_set.filter(
workspace_id__isnull=True
)
return {
"default_query_set": query_set,
"resource_chat_user_group_authorize_query_set": resource_chat_user_group_authorize_query_set,
"resource_chat_user_authorize_query_set": resource_chat_user_authorize_query_set,
}

def list(self):
Expand Down
11 changes: 9 additions & 2 deletions apps/system_manage/sql/list_resource_chat_user_group.sql
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
SELECT user_group.*, COALESCE(resource_chat_user_group_authorize.is_auth,false) as is_auth
SELECT user_group.*, COALESCE(resource_chat_user_group_authorize.is_auth,false) as is_auth,
(SELECT COUNT(DISTINCT resource_chat_user_authorize.user_id)
FROM user_group_relation
JOIN (SELECT * FROM resource_chat_user_authorize ${resource_chat_user_authorize_query_set}) resource_chat_user_authorize
ON resource_chat_user_authorize.user_id = user_group_relation.user_id
AND resource_chat_user_authorize.user_group_id = user_group_relation.group_id
WHERE user_group_relation.group_id = user_group.id
AND resource_chat_user_authorize.is_auth = true) AS authorized_count
FROM "user_group"
LEFT JOIN (SELECT * FROM resource_chat_user_group_authorize ${resource_chat_user_group_authorize_query_set}) resource_chat_user_group_authorize
ON user_group.id = resource_chat_user_group_authorize.user_group_id
${default_query_set}
${default_query_set}
2 changes: 2 additions & 0 deletions ui/src/api/types/chat-user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,8 @@ export interface ChatUserAuthorizationGroup {
id: string
name: string
is_auth: boolean
/** 用户组内已授权对话用户数。 */
authorized_count: number
}

/** 用户组内的对话用户资源授权状态。 */
Expand Down
2 changes: 1 addition & 1 deletion ui/src/views/VIEW_README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1389,7 +1389,7 @@ API 地址、调用示例及 MCP 配置只读;后两个展示区参考工具 M
使用对应路由 ID 及 `RESOURCE_TYPE.APPLICATION / KNOWLEDGE`;授权类型必须大写,与后台授权记录及对话端查询一致。
两页通过 `hideHeader: true` 隐藏详情标题栏,使用普通 Flex 双栏容器,不嵌套 `MkViewLayout`。
外层 `ResourceDetailLayout` 统一管理整体滚动;侧栏复用 `w-sidebar-expanded`、`MkSearchList` 的搜索、选中和空态。
“按用户组”列表通过插槽展示名称及自动授权状态;接口尚未返回组已授权人数,手动授权组显示“已授权 —”,不以当前页勾选数代替。
“按用户组”列表通过插槽展示名称及自动授权状态;接口返回组已授权人数 `authorized_count`,自动授权组显示“(自动授权)”,手动授权组显示“(已授权 N)”,不以当前页勾选数代替。
右侧第一行展示组名和用户查询总数;下方工具栏左侧为默认按姓名查询的 `MkComplexSearch` 及自动授权开关,右侧为保存。
顶部 `MkComplexSearch` 按姓名、用户名排列;用户来源只在表头使用 `MkTableFilter mode="single"` 筛选,向接口传 `source`。
用户名、姓名搜索与表头来源可组合查询,清空一处条件不影响另一处,不额外重置搜索组件。
Expand Down
16 changes: 12 additions & 4 deletions ui/src/views/application-detail/chat-user/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,15 @@ function loadChatUserGroups() {
})
}

// 仅刷新用户组列表及已授权人数,保留当前选中的用户组。
function refreshChatUserGroups() {
return ChatUserApi.getUserGroupList(resource.value).then((groups) => {
const currentId = currentGroup.value?.id
chatUserGroups.value = groups
currentGroup.value = groups.find((group) => group.id === currentId) ?? groups[0]
})
}

function handleSelectGroup(group: ChatUserAuthorizationGroup) {
if (loading.value || currentGroup.value?.id === group.id) return
currentGroup.value = group
Expand Down Expand Up @@ -130,7 +139,7 @@ function handleSave() {
// 先记住已保存结果,列表刷新失败时不重复提示未保存。
savedAuthorization.value = Object.fromEntries(payload.map(({ chat_user_id, is_auth }) => [chat_user_id, is_auth]))
MsgSuccess('保存成功')
return loadChatUsers()
return loadChatUsers().then(refreshChatUserGroups)
})
.finally(() => {
loading.value = false
Expand All @@ -149,7 +158,7 @@ function handleAutoAuthorizationChange(value: string | number | boolean) {
chatUsers.value = []
savedAuthorization.value = {}
MsgSuccess('保存成功')
return loadChatUsers()
return loadChatUsers().then(refreshChatUserGroups)
})
.finally(() => {
loading.value = false
Expand All @@ -170,8 +179,7 @@ onMounted(() => loadChatUserGroups())
<template #default="{ row }">
<span class="min-w-0 truncate" :title="row.name">{{ row.name }}</span>
<span class="shrink-0 font-normal text-N500">
<!-- TODO:接入用户组已授权人数,当前接口未返回统计字段。 -->
{{ row.is_auth ? '(自动授权)' : '(已授权 —)' }}
{{ row.is_auth ? '(自动授权)' : `(已授权 ${row.authorized_count ?? 0})` }}
</span>
</template>
</MkSearchList>
Expand Down
16 changes: 12 additions & 4 deletions ui/src/views/knowledge-detail/chat-user/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,15 @@ function loadChatUserGroups() {
})
}

// 仅刷新用户组列表及已授权人数,保留当前选中的用户组。
function refreshChatUserGroups() {
return ChatUserApi.getUserGroupList(resource.value).then((groups) => {
const currentId = currentGroup.value?.id
chatUserGroups.value = groups
currentGroup.value = groups.find((group) => group.id === currentId) ?? groups[0]
})
}

function handleSelectGroup(group: ChatUserAuthorizationGroup) {
if (loading.value || currentGroup.value?.id === group.id) return
currentGroup.value = group
Expand Down Expand Up @@ -130,7 +139,7 @@ function handleSave() {
// 先记住已保存结果,列表刷新失败时不重复提示未保存。
savedAuthorization.value = Object.fromEntries(payload.map(({ chat_user_id, is_auth }) => [chat_user_id, is_auth]))
MsgSuccess('保存成功')
return loadChatUsers()
return loadChatUsers().then(refreshChatUserGroups)
})
.finally(() => {
loading.value = false
Expand All @@ -149,7 +158,7 @@ function handleAutoAuthorizationChange(value: string | number | boolean) {
chatUsers.value = []
savedAuthorization.value = {}
MsgSuccess('保存成功')
return loadChatUsers()
return loadChatUsers().then(refreshChatUserGroups)
})
.finally(() => {
loading.value = false
Expand All @@ -170,8 +179,7 @@ onMounted(() => loadChatUserGroups())
<template #default="{ row }">
<span class="min-w-0 truncate" :title="row.name">{{ row.name }}</span>
<span class="shrink-0 font-normal text-N500">
<!-- TODO:接入用户组已授权人数,当前接口未返回统计字段。 -->
{{ row.is_auth ? '(自动授权)' : '(已授权 —)' }}
{{ row.is_auth ? '(自动授权)' : `(已授权 ${row.authorized_count ?? 0})` }}
</span>
</template>
</MkSearchList>
Expand Down
Loading