feat: 收敛AI资源发布审批生命周期
- 统一工作流、知识库、聊天助手的发布、重新发布、下线与删除链路 - 收敛审批编排、生命周期状态机与展示态,补齐审批管理和快照预览 - 调整审批管理权限模型为单入口页面加内部按钮权限
This commit is contained in:
@@ -46,9 +46,16 @@ import PageSide from '#/components/page/PageSide.vue';
|
||||
import DocumentCollectionModal from '#/views/ai/documentCollection/DocumentCollectionModal.vue';
|
||||
import AiResourceCornerMeta from '#/views/ai/shared/AiResourceCornerMeta.vue';
|
||||
import {
|
||||
buildOfflineImpactMessage,
|
||||
type OfflineImpactCheck,
|
||||
} from '#/views/ai/shared/offline-impact';
|
||||
import {
|
||||
canAiResourceDelete,
|
||||
canAiResourceOffline,
|
||||
canAiResourcePublish,
|
||||
canAiResourceRepublish,
|
||||
isAiResourceApprovalPending,
|
||||
isAiResourcePublished,
|
||||
normalizeAiPublishStatus,
|
||||
resolveAiResourceDisplayStatus,
|
||||
} from '#/views/ai/shared/publish-status';
|
||||
|
||||
const router = useRouter();
|
||||
@@ -186,24 +193,41 @@ const actions: ActionButton[] = [
|
||||
{
|
||||
icon: Promotion,
|
||||
text: (row) =>
|
||||
isAiResourcePublished(row.publishStatus)
|
||||
canAiResourceRepublish(row.displayPublishStatus, row.publishStatus)
|
||||
? $t('button.republish')
|
||||
: $t('button.submitPublishApproval'),
|
||||
: $t('button.publish'),
|
||||
permission: '/api/v1/documentCollection/save',
|
||||
placement: 'inline',
|
||||
visible: (row) =>
|
||||
canAiResourcePublish(row.displayPublishStatus, row.publishStatus) ||
|
||||
canAiResourceRepublish(row.displayPublishStatus, row.publishStatus),
|
||||
onClick(row) {
|
||||
if (!ensureManageKnowledgeItem(row)) {
|
||||
return;
|
||||
}
|
||||
submitPublishApproval(row);
|
||||
submitPublishAction(row);
|
||||
},
|
||||
},
|
||||
{
|
||||
text: $t('button.submitDeleteApproval'),
|
||||
icon: Promotion,
|
||||
text: $t('button.offline'),
|
||||
permission: '/api/v1/documentCollection/save',
|
||||
placement: 'menu',
|
||||
visible: (row) => canAiResourceOffline(row.displayPublishStatus, row.publishStatus),
|
||||
onClick(row) {
|
||||
if (!ensureManageKnowledgeItem(row)) {
|
||||
return;
|
||||
}
|
||||
submitOfflineAction(row);
|
||||
},
|
||||
},
|
||||
{
|
||||
text: $t('button.delete'),
|
||||
icon: Delete,
|
||||
tone: 'danger',
|
||||
permission: '/api/v1/documentCollection/remove',
|
||||
placement: 'menu',
|
||||
visible: (row) => canAiResourceDelete(row.displayPublishStatus, row.publishStatus),
|
||||
onClick(row) {
|
||||
if (!ensureManageKnowledgeItem(row)) {
|
||||
return;
|
||||
@@ -216,14 +240,22 @@ const actions: ActionButton[] = [
|
||||
onMounted(() => {
|
||||
getCategoryList();
|
||||
});
|
||||
const submitPublishApproval = async (item: any) => {
|
||||
if (isAiResourceApprovalPending(item.publishStatus)) {
|
||||
function isRepublishAction(item: any) {
|
||||
return canAiResourceRepublish(item.displayPublishStatus, item.publishStatus);
|
||||
}
|
||||
|
||||
const submitPublishAction = async (item: any) => {
|
||||
if (
|
||||
isAiResourceApprovalPending(item.displayPublishStatus, item.publishStatus)
|
||||
) {
|
||||
ElMessage.warning($t('documentCollection.publishPendingHint'));
|
||||
return;
|
||||
}
|
||||
try {
|
||||
await ElMessageBox.confirm(
|
||||
$t('documentCollection.submitPublishApprovalConfirm'),
|
||||
isRepublishAction(item)
|
||||
? $t('documentCollection.submitRepublishApprovalConfirm')
|
||||
: $t('documentCollection.submitPublishApprovalConfirm'),
|
||||
$t('message.noticeTitle'),
|
||||
{
|
||||
confirmButtonText: $t('button.confirm'),
|
||||
@@ -245,8 +277,71 @@ const submitPublishApproval = async (item: any) => {
|
||||
reloadKnowledgeList();
|
||||
}
|
||||
};
|
||||
const submitOfflineAction = async (item: any) => {
|
||||
if (
|
||||
isAiResourceApprovalPending(item.displayPublishStatus, item.publishStatus)
|
||||
) {
|
||||
ElMessage.warning($t('documentCollection.publishPendingHint'));
|
||||
return;
|
||||
}
|
||||
const impactRes = await api.get<{
|
||||
data: OfflineImpactCheck;
|
||||
errorCode: number;
|
||||
}>(
|
||||
'/api/v1/documentCollection/offlineImpactCheck',
|
||||
{
|
||||
params: { id: item.id },
|
||||
},
|
||||
);
|
||||
if (impactRes.errorCode !== 0) {
|
||||
return;
|
||||
}
|
||||
if (impactRes.data?.hasWorkflowUsages) {
|
||||
await ElMessageBox.alert(
|
||||
buildOfflineImpactMessage(
|
||||
$t('documentCollection.offlineImpactWorkflowBlockedIntro'),
|
||||
impactRes.data.workflowUsages,
|
||||
$t('documentCollection.offlineImpactWorkflowBlockedFooter'),
|
||||
),
|
||||
$t('message.noticeTitle'),
|
||||
{
|
||||
confirmButtonText: $t('button.confirm'),
|
||||
type: 'warning',
|
||||
},
|
||||
);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
await ElMessageBox.confirm(
|
||||
impactRes.data?.hasBotBindings
|
||||
? buildOfflineImpactMessage(
|
||||
$t('documentCollection.offlineImpactBoundBotsIntro'),
|
||||
impactRes.data.botBindings,
|
||||
$t('documentCollection.offlineImpactBoundBotsFooter'),
|
||||
)
|
||||
: $t('documentCollection.submitOfflineApprovalConfirm'),
|
||||
$t('message.noticeTitle'),
|
||||
{
|
||||
confirmButtonText: $t('button.confirm'),
|
||||
cancelButtonText: $t('button.cancel'),
|
||||
type: 'warning',
|
||||
},
|
||||
);
|
||||
} catch {
|
||||
return;
|
||||
}
|
||||
const res = await api.post('/api/v1/documentCollection/submitOfflineApproval', {
|
||||
id: item.id,
|
||||
});
|
||||
if (res.errorCode === 0) {
|
||||
ElMessage.success(res.message || $t('message.saveOkMessage'));
|
||||
reloadKnowledgeList();
|
||||
}
|
||||
};
|
||||
const submitDeleteApproval = async (item: any) => {
|
||||
if (isAiResourceApprovalPending(item.publishStatus)) {
|
||||
if (
|
||||
isAiResourceApprovalPending(item.displayPublishStatus, item.publishStatus)
|
||||
) {
|
||||
ElMessage.warning($t('documentCollection.deletePendingHint'));
|
||||
return;
|
||||
}
|
||||
@@ -274,14 +369,29 @@ const submitDeleteApproval = async (item: any) => {
|
||||
reloadKnowledgeList();
|
||||
}
|
||||
};
|
||||
function resolvePublishStatusMeta(status?: string) {
|
||||
switch (normalizeAiPublishStatus(status)) {
|
||||
function resolvePublishStatusMeta(
|
||||
displayPublishStatus?: string,
|
||||
publishStatus?: string,
|
||||
) {
|
||||
switch (resolveAiResourceDisplayStatus(displayPublishStatus, publishStatus)) {
|
||||
case 'DELETE_PENDING': {
|
||||
return {
|
||||
label: $t('documentCollection.publishStatusDeletePending'),
|
||||
tone: 'danger',
|
||||
};
|
||||
}
|
||||
case 'OFFLINE_PENDING': {
|
||||
return {
|
||||
label: $t('documentCollection.publishStatusOfflinePending'),
|
||||
tone: 'pending',
|
||||
};
|
||||
}
|
||||
case 'OFFLINE': {
|
||||
return {
|
||||
label: $t('documentCollection.publishStatusOffline'),
|
||||
tone: 'draft',
|
||||
};
|
||||
}
|
||||
case 'PUBLISH_PENDING': {
|
||||
return {
|
||||
label: $t('documentCollection.publishStatusPublishPending'),
|
||||
@@ -553,11 +663,11 @@ function changeCategory(category: any) {
|
||||
<template #publish>
|
||||
<div
|
||||
class="knowledge-publish-chip"
|
||||
:class="`knowledge-publish-chip--${resolvePublishStatusMeta(item.publishStatus).tone}`"
|
||||
:class="`knowledge-publish-chip--${resolvePublishStatusMeta(item.displayPublishStatus, item.publishStatus).tone}`"
|
||||
>
|
||||
<span class="knowledge-publish-chip__dot"></span>
|
||||
<span>{{
|
||||
resolvePublishStatusMeta(item.publishStatus).label
|
||||
resolvePublishStatusMeta(item.displayPublishStatus, item.publishStatus).label
|
||||
}}</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user