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
8 changes: 8 additions & 0 deletions ui/src/api/API_README.md
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,14 @@ System 不传 Workspace 文件夹条件;System 共享不提供智能体选择
将响应的 `tools` 与 `shared_tools` 合并为 `ToolItem[]`,用于包含已授权共享工具的选项查询;
按工具类型筛选时使用 `tool_type`。`workspace/shared/tool.ts` 的 `getAllTool(query)` 仅查询共享工具。

### System 共享资源工作空间授权

`system/shared-resources/authorization.ts` 通过 GET、POST
`/system/shared/<knowledge|model|tool>/<resourceId>/authorization` 查询和保存工作空间授权,
沿用 v2 System 共享授权协议,依赖部署端提供对应接口。配置类型为 `SharedWorkspaceAuthorization`,
包含 `authentication_type`(`WHITE_LIST`/`BLACK_LIST`)和 `workspace_id_list`;请求层直接解包配置。
弹窗通过 System Workspace API 查询工作空间,不读取路由中的工作空间 ID。

### System 共享工具

`system/shared-resources/tool/tool.ts` 使用 `/system/shared/tool`,维护分页、详情、创建、更新、删除、
Expand Down
16 changes: 16 additions & 0 deletions ui/src/api/admin/system/shared-resources/authorization.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { get, post } from '../../core/request'
import type { SharedResourceType, SharedWorkspaceAuthorization } from '@/api/types'

const prefix = '/system/shared'

/** 获取共享资源的工作空间授权配置。 */
const getSharedAuthorization = (resourceType: SharedResourceType, resourceId: string) => {
return get<SharedWorkspaceAuthorization | null>(`${prefix}/${resourceType.toLowerCase()}/${resourceId}/authorization`)
}

/** 保存共享资源的工作空间授权配置。 */
const postSharedAuthorization = (resourceType: SharedResourceType, resourceId: string, payload: SharedWorkspaceAuthorization) => {
return post<SharedWorkspaceAuthorization, boolean>(`${prefix}/${resourceType.toLowerCase()}/${resourceId}/authorization`, payload)
}

export default { getSharedAuthorization, postSharedAuthorization }
2 changes: 2 additions & 0 deletions ui/src/api/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,5 @@ export type * from './document'
export type * from './paragraph'
export type * from './termbase'
export type * from './chat-log'

export type * from './shared-authorization'
10 changes: 10 additions & 0 deletions ui/src/api/types/shared-authorization.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/** System 共享资源授权 API 与页面共用的业务类型。 */
import type { RESOURCE_TYPE } from '@/api/enums'
import type { ResourceType } from './resource-authorization'

export type SharedResourceType = Exclude<ResourceType, typeof RESOURCE_TYPE.APPLICATION>

export interface SharedWorkspaceAuthorization {
authentication_type: 'WHITE_LIST' | 'BLACK_LIST'
workspace_id_list: string[]
}
2 changes: 1 addition & 1 deletion ui/src/components/business/workspace-dropdown/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ const emit = defineEmits<{ select: [option: WorkspaceItem] }>()
<template #default="{ text }">
<!-- 切换工作空间 -->
<el-button text class="flex-align-center max-w-50 gap-1 rounded-md px-2! py-[7px]! text-N900!">
<MkIcon name="icon_moments-categories_outlined" class="mr-1" />
<MkIcon name="icon_moments-categories_outlined" class="mr-1 shrink-0" />
<span class="min-w-0 flex-1 truncate" :title="text">{{ text }}</span>
<MkIcon :icon="CaretBottom" :size="14" class="ml-1 text-N600!" />
</el-button>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,8 @@ function handleConfirm() {
<el-checkbox :indeterminate="selectionIndeterminate" :model-value="allSelected" class="mr-0!" @change="handleSelectAllChange">
全部
</el-checkbox>
<el-checkbox-group v-model="pendingValues" class="flex-column gap-2">
<el-checkbox
v-for="option in options"
:key="`${typeof option.value}:${option.value}`"
:value="option.value"
:disabled="option.disabled"
class="mk-table-filter__option mr-0! w-full min-w-0"
>
<el-checkbox-group v-model="pendingValues" class="mk-checkbox-group-vertical gap-2">
<el-checkbox v-for="option in options" :key="`${typeof option.value}:${option.value}`" :value="option.value" :disabled="option.disabled">
<span class="block min-w-0 truncate" :title="option.label">{{ option.label }}</span>
</el-checkbox>
</el-checkbox-group>
Expand All @@ -68,19 +62,11 @@ function handleConfirm() {

<div class="p-3 text-right">
<!-- 清除多选筛选 -->
<el-button class="min-w-12! w-12!" size="small" @click="handleReset">重置</el-button>
<el-button plain class="min-w-12! w-12!" size="small" @click="handleReset">重置</el-button>
<!-- 确认多选筛选 -->
<el-button class="min-w-12! w-12!" size="small" type="primary" @click="handleConfirm">确定</el-button>
</div>
</el-popover>
</template>

<style scoped lang="scss">
/* 多选选项 */
.mk-table-filter__option {
:deep(.el-checkbox__label) {
min-width: 0;
overflow: hidden;
}
}
</style>
<style scoped lang="scss"></style>
3 changes: 3 additions & 0 deletions ui/src/styles/STYLE_README.md
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,9 @@ CSS 自定义属性同样按变量名排序。嵌套选择器、伪类和媒体

## 常用交互工具类

纵向复选框组在 `el-checkbox-group` 上添加 `mk-checkbox-group-vertical`,由 `app.scss` 统一
设置纵向排列、8px 间距、选项整行宽度及长标签省略;标签文本需提供原生 `title`。

纵向单选组在 `el-radio-group` 上添加 `mk-radio-group-vertical`,统一整行宽度、8px 间距及
多行选项的顶部对齐;普通单行和带描述的选项均可使用。

Expand Down
19 changes: 19 additions & 0 deletions ui/src/styles/app.scss
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,25 @@ h6 {
z-index: 1;
}

/* checkbox */
.mk-checkbox-group-vertical {
display: flex;
flex-direction: column;

.el-checkbox {
margin-right: 0;
min-width: 0;
width: 100%;
}

.el-checkbox__label {
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}

/* dot */
// 状态圆点
.mk-dot-danger {
Expand Down
5 changes: 4 additions & 1 deletion ui/src/views/VIEW_README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
| `knowledge-detail/library/document/`、`tags/` | 文档及标签维护 |
| `knowledge-detail/library/image/` | 图片列表,复用文档操作 |
| `knowledge-detail/hit-test/` | 召回测试参数、文本/图片查询及结果展示 |
| `knowledge-detail/problem/` | 问题查询、维护与分段关联 |
| `knowledge-detail/problem/` | 问题查询、维护与分段关联 |
| `knowledge-detail/termbase/` | 知识库自定义分词维护 |
| `knowledge-detail/chat-user/`、`external-retrieval/` | 对话授权与外部检索配置 |
| `knowledge-detail/setting/base/`、`document-strategy/`、`scheduled-sync/` | 基础设置、文档策略、定时同步与日志 |
Expand Down Expand Up @@ -96,6 +96,9 @@
- System 模型/工具使用表格,保留既有权限、引用数量删除提示和末页回退;不新增不存在的创建/导入能力。
工作空间列与选项仅企业版显示,筛选 `workspace_ids` 使用 JSON 数组字符串。
- Workspace 共享知识库只读;System 共享资源页面按自身 API 维护,不组合 Workspace 文件夹移动等操作。
- System 共享知识库、模型、工具菜单复用功能本地 `authorized-workspace-action/index.vue`,打开同目录的
`AuthorizedWorkspaceDialog` 配置工作空间白名单/黑名单;保留弹窗实例,关闭动画结束后清空本次数据,
保存失败保留草稿。

资源授权和关联资源入口按需挂载公共抽屉,关闭动画结束后卸载。授权使用资源数据的
`workspace_id`;关联资源抽屉的查询与工作空间展示规则见组件和 API 文档。
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,30 +176,10 @@ defineExpose({ open })
</script>

<template>
<MkDialog
v-model="visible"
title="显示设置"
:width="960"
:before-close="
(done: () => void) => {
if (!loading && !saving) done()
}
"
@closed="handleClosed"
>
<template #header>
<div class="flex-between pr-6">
<h3>显示设置</h3>
<!-- 恢复默认展示配置 -->
<el-button link :disabled="!loaded || loading || saving" @click="handleRestoreDefault">
<MkIcon :icon="Refresh" />
<span>恢复默认</span>
</el-button>
</div>
</template>
<MkDialog v-model="visible" title="显示设置" align-center class="mk-aside-content-dialog" :width="1000" @closed="handleClosed">
<div v-loading="loading" class="min-h-60">
<div v-if="loaded" class="grid gap-6 md:grid-cols-[400px_minmax(0,1fr)]" :inert="saving">
<div class="relative h-142 rounded-lg border border-N200 bg-N100 p-5">
<div v-if="loaded" class="grid gap-6 grid-cols-2" :inert="saving">
<div class="relative">
<div class="flex-column h-full overflow-hidden rounded-xl border border-N200 bg-white shadow-lg">
<div class="flex-between gap-3 border-b border-N200 bg-N100 px-4 py-3" :style="previewHeaderStyle">
<div class="flex-align-center min-w-0 gap-2">
Expand Down Expand Up @@ -249,105 +229,104 @@ defineExpose({ open })
</el-avatar>
</div>
</div>
<el-scrollbar max-height="568px">
<el-form :model="displayForm" label-position="top" class="pr-3" @submit.prevent>
<div class="grid grid-cols-2 gap-4">
<el-form-item label="自定义主题色">
<div class="flex-align-center gap-2">
<el-color-picker v-model="displayForm.custom_theme.theme_color" />
<span v-if="!displayForm.custom_theme.theme_color" class="text-N600">默认</span>
</div>
</el-form-item>
<el-form-item label="头部标题字体颜色"><el-color-picker v-model="displayForm.custom_theme.header_font_color" /></el-form-item>
</div>
<el-form-item label="语言">
<el-select v-model="displayForm.language" clearable placeholder="跟随系统">
<el-option v-for="language in languageOptions" :key="language.value" :label="language.label" :value="language.value" />
</el-select>
</el-form-item>
<div class="space-y-3">
<template v-for="field in imageFields" :key="field.key">
<div class="rounded-lg border border-N200 p-3">
<div class="flex-between gap-3">
<h6>{{ field.label }}</h6>
<div class="flex-align-center gap-3">
<el-checkbox v-if="'visibility' in field" v-model="displayForm[field.visibility]">显示</el-checkbox>
<!-- 替换当前展示图片 -->
<el-upload
action="#"
:auto-upload="false"
:show-file-list="false"
accept="image/jpeg,image/png,image/gif"
:on-change="(file: UploadFile) => handleImageChange(file, field.key)"
>
<el-button size="small">替换</el-button>
</el-upload>
</div>
<div>
<el-scrollbar max-height="568px">
<el-form :model="displayForm" label-position="top" class="pr-3" @submit.prevent>
<div class="grid grid-cols-2 gap-4">
<el-form-item label="自定义主题色">
<div class="flex-align-center gap-2">
<el-color-picker v-model="displayForm.custom_theme.theme_color" />
<span v-if="!displayForm.custom_theme.theme_color" class="text-N600">默认</span>
</div>
<p class="mt-2 text-sm text-N600">
{{ field.key === 'chat_background' ? '' : '建议尺寸 32 × 32,' }}支持 JPG、PNG、GIF,大小不超过 10 MB
</p>
<div v-if="field.key === 'float_icon'" class="mt-3 border-t border-N200 pt-3">
<div class="flex-between mb-2">
<span>图标默认位置</span>
<el-checkbox v-model="displayForm.draggable">可拖拽位置</el-checkbox>
</el-form-item>
<el-form-item label="头部标题字体颜色"><el-color-picker v-model="displayForm.custom_theme.header_font_color" /></el-form-item>
</div>
<el-form-item label="语言">
<el-select v-model="displayForm.language" clearable placeholder="跟随系统">
<el-option v-for="language in languageOptions" :key="language.value" :label="language.label" :value="language.value" />
</el-select>
</el-form-item>
<div class="space-y-3">
<template v-for="field in imageFields" :key="field.key">
<div class="rounded-lg border border-N200 p-3">
<div class="flex-between gap-3">
<h6>{{ field.label }}</h6>
<div class="flex-align-center gap-3">
<el-checkbox v-if="'visibility' in field" v-model="displayForm[field.visibility]">显示</el-checkbox>
<!-- 替换当前展示图片 -->
<el-upload
action="#"
:auto-upload="false"
:show-file-list="false"
accept="image/jpeg,image/png,image/gif"
:on-change="(file: UploadFile) => handleImageChange(file, field.key)"
>
<el-button size="small">替换</el-button>
</el-upload>
</div>
</div>
<div class="grid grid-cols-2 gap-3">
<div class="flex-align-center gap-1">
<el-select v-model="displayForm.float_location.x.type" class="w-17! shrink-0">
<el-option label="左" value="left" />
<el-option label="右" value="right" />
</el-select>
<el-input-number
v-model="displayForm.float_location.x.value"
class="min-w-0! w-full!"
:min="0"
:precision="0"
:value-on-clear="0"
controls-position="right"
align="left"
/>
<span>px</span>
<p class="mt-2 text-sm text-N600">
{{ field.key === 'chat_background' ? '' : '建议尺寸 32 × 32,' }}支持 JPG、PNG、GIF,大小不超过 10 MB
</p>
<div v-if="field.key === 'float_icon'" class="mt-3 border-t border-N200 pt-3">
<div class="flex-between mb-2">
<span>图标默认位置</span>
<el-checkbox v-model="displayForm.draggable">可拖拽位置</el-checkbox>
</div>
<div class="flex-align-center gap-1">
<el-select v-model="displayForm.float_location.y.type" class="w-17! shrink-0">
<el-option label="上" value="top" />
<el-option label="下" value="bottom" />
</el-select>
<el-input-number
v-model="displayForm.float_location.y.value"
class="min-w-0! w-full!"
:min="0"
:precision="0"
:value-on-clear="0"
controls-position="right"
align="left"
/>
<span>px</span>
<div class="grid grid-cols-2 gap-3">
<div class="flex-align-center gap-1">
<el-select v-model="displayForm.float_location.x.type" class="w-17! shrink-0">
<el-option label="左" value="left" />
<el-option label="右" value="right" />
</el-select>
<el-input-number
v-model="displayForm.float_location.x.value"
class="min-w-0! w-full!"
:min="0"
:precision="0"
:value-on-clear="0"
controls-position="right"
align="left"
/>
<span>px</span>
</div>
<div class="flex-align-center gap-1">
<el-select v-model="displayForm.float_location.y.type" class="w-17! shrink-0">
<el-option label="上" value="top" />
<el-option label="下" value="bottom" />
</el-select>
<el-input-number
v-model="displayForm.float_location.y.value"
class="min-w-0! w-full!"
:min="0"
:precision="0"
:value-on-clear="0"
controls-position="right"
align="left"
/>
<span>px</span>
</div>
</div>
</div>
</div>
</div>
</template>
</div>
<div class="mt-3 flex-column items-start">
<el-checkbox v-for="option in displayOptions" :key="option.key" v-model="displayForm[option.key]">{{ option.label }}</el-checkbox>
<el-input v-if="displayForm.disclaimer" v-model="displayForm.disclaimer_value" :maxlength="128" placeholder="请输入免责声明" />
</div>
</el-form>
</el-scrollbar>
</div>
<div v-else-if="!loading" class="flex-col-center min-h-60 gap-3">
<span class="text-N600">显示设置加载失败</span>
<!-- 重新加载展示配置 -->
<el-button @click="loadSetting">重新加载</el-button>
</template>
</div>
<div class="mt-3 flex-column items-start">
<el-checkbox v-for="option in displayOptions" :key="option.key" v-model="displayForm[option.key]">{{ option.label }}</el-checkbox>
<el-input v-if="displayForm.disclaimer" v-model="displayForm.disclaimer_value" :maxlength="128" placeholder="请输入免责声明" />
</div>
</el-form>
</el-scrollbar>
<el-button link :disabled="!loaded || loading || saving" @click="handleRestoreDefault">
<MkIcon :icon="Refresh" />
<span>恢复默认</span>
</el-button>
<!-- 取消展示设置 -->
<el-button :disabled="loading || saving" @click="visible = false">取消</el-button>
<!-- 保存展示设置 -->
<el-button type="primary" :loading="saving" :disabled="!loaded || loading" @click="handleSave">保存</el-button>
</div>
</div>
</div>
<template #footer>
<!-- 取消展示设置 -->
<el-button :disabled="loading || saving" @click="visible = false">取消</el-button>
<!-- 保存展示设置 -->
<el-button type="primary" :loading="saving" :disabled="!loaded || loading" @click="handleSave">保存</el-button>
</template>
</MkDialog>
</template>
Loading
Loading