feat: 增加工作流和知识库三级权限

- 抽取统一资源访问骨架与部门可见范围判断

- 接入工作流和知识库的 READ/MANAGE 权限校验

- 增加可见范围配置与只读态前端交互
This commit is contained in:
2026-03-29 17:25:55 +08:00
parent f49d94e2fe
commit 22ceabff96
58 changed files with 3053 additions and 85 deletions

View File

@@ -2,7 +2,9 @@
import { computed, onMounted, ref } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import { useAccess } from '@easyflow/access';
import { $t } from '@easyflow/locales';
import { useUserStore } from '@easyflow/stores';
import { ArrowLeft, Plus } from '@element-plus/icons-vue';
import { ElIcon, ElImage } from 'element-plus';
@@ -20,11 +22,34 @@ import KnowledgeSearchConfig from '#/views/ai/documentCollection/KnowledgeSearch
const route = useRoute();
const router = useRouter();
const userStore = useUserStore();
const { hasAccessByCodes } = useAccess();
const knowledgeId = ref<string>((route.query.id as string) || '');
const activeMenu = ref<string>((route.query.activeMenu as string) || '');
const knowledgeInfo = ref<any>({});
const selectedCategory = ref('');
const canManageKnowledgePermission = computed(() =>
hasAccessByCodes(['/api/v1/documentCollection/save']),
);
const isSuperAdmin = computed(() => {
return (
String(userStore.userInfo?.id || '') === '1' ||
(userStore.userRoles || []).includes('super_admin')
);
});
const canManageCurrentKnowledge = computed(() => {
if (!knowledgeInfo.value?.id || !canManageKnowledgePermission.value) {
return false;
}
return (
isSuperAdmin.value ||
String(userStore.userInfo?.id || '') ===
String(knowledgeInfo.value.createdBy || '')
);
});
const syncNavTitle = (title: string) => {
if (!title) {
@@ -163,6 +188,9 @@ const backDoc = () => {
<div class="description">
{{ knowledgeInfo.description || '' }}
</div>
<div v-if="!canManageCurrentKnowledge" class="permission-tip">
{{ $t('documentCollection.managePermissionHint') }}
</div>
</div>
<div class="doc-top-menu">
<button
@@ -184,7 +212,7 @@ const backDoc = () => {
<div class="doc-header" v-if="!viewDocVisible">
<HeaderSearch
v-if="!isFaqCollection"
:buttons="headerButtons"
:buttons="canManageCurrentKnowledge ? headerButtons : []"
@search="handleSearch"
@button-click="handleButtonClick"
/>
@@ -192,6 +220,7 @@ const backDoc = () => {
<DocumentTable
ref="documentTableRef"
:knowledge-id="knowledgeId"
:manageable="canManageCurrentKnowledge"
@view-doc="viewDoc"
v-if="!viewDocVisible"
/>
@@ -199,24 +228,32 @@ const backDoc = () => {
<ChunkDocumentTable
v-else
:document-id="documentId"
:manageable="canManageCurrentKnowledge"
:default-summary-prompt="knowledgeInfo.summaryPrompt"
/>
</div>
<div v-if="selectedCategory === 'faqList'" class="doc-table">
<FaqTable :knowledge-id="knowledgeId" />
<FaqTable
:knowledge-id="knowledgeId"
:manageable="canManageCurrentKnowledge"
/>
</div>
<!--知识检索-->
<div
v-if="selectedCategory === 'knowledgeSearch'"
class="doc-search-container"
>
<KnowledgeSearchConfig :document-collection-id="knowledgeId" />
<KnowledgeSearchConfig
:document-collection-id="knowledgeId"
:manageable="canManageCurrentKnowledge"
/>
<KnowledgeSearch :knowledge-id="knowledgeId" />
</div>
<!--配置-->
<div v-if="selectedCategory === 'config'">
<DocumentCollectionDataConfig
:detail-data="knowledgeInfo"
:manageable="canManageCurrentKnowledge"
@reload="getKnowledge"
/>
</div>
@@ -306,6 +343,13 @@ const backDoc = () => {
outline-offset: 1px;
}
.permission-tip {
margin-top: 4px;
font-size: 12px;
line-height: 1.5;
color: var(--el-text-color-secondary);
}
.doc-table {
background-color: var(--el-bg-color);
}