feat: 收敛AI资源发布审批生命周期
- 统一工作流、知识库、聊天助手的发布、重新发布、下线与删除链路 - 收敛审批编排、生命周期状态机与展示态,补齐审批管理和快照预览 - 调整审批管理权限模型为单入口页面加内部按钮权限
This commit is contained in:
38
easyflow-ui-admin/app/src/views/ai/shared/offline-impact.ts
Normal file
38
easyflow-ui-admin/app/src/views/ai/shared/offline-impact.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
import { h } from 'vue';
|
||||
|
||||
export interface OfflineImpactBinding {
|
||||
id?: number | string;
|
||||
title?: string;
|
||||
}
|
||||
|
||||
export interface OfflineImpactCheck {
|
||||
canProceed: boolean;
|
||||
hasBotBindings: boolean;
|
||||
hasWorkflowUsages: boolean;
|
||||
botBindings: OfflineImpactBinding[];
|
||||
workflowUsages: OfflineImpactBinding[];
|
||||
message?: string;
|
||||
}
|
||||
|
||||
function resolveTitle(item: OfflineImpactBinding) {
|
||||
return item.title || String(item.id || '');
|
||||
}
|
||||
|
||||
export function joinOfflineImpactTitles(items: OfflineImpactBinding[] = []) {
|
||||
return items.map(resolveTitle).filter(Boolean).join('、');
|
||||
}
|
||||
|
||||
export function buildOfflineImpactMessage(
|
||||
intro: string,
|
||||
items: OfflineImpactBinding[] = [],
|
||||
footer?: string,
|
||||
) {
|
||||
return h('div', [
|
||||
h('p', intro),
|
||||
h(
|
||||
'ul',
|
||||
items.map((item) => h('li', { key: String(item.id || item.title || '') }, resolveTitle(item))),
|
||||
),
|
||||
footer ? h('p', footer) : null,
|
||||
]);
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
export type AiPublishStatus =
|
||||
| 'DELETE_PENDING'
|
||||
| 'DRAFT'
|
||||
| 'OFFLINE'
|
||||
| 'OFFLINE_PENDING'
|
||||
| 'PUBLISHED'
|
||||
| 'PUBLISH_PENDING';
|
||||
|
||||
@@ -13,6 +15,8 @@ export function normalizeAiPublishStatus(
|
||||
switch (value) {
|
||||
case 'PUBLISHED':
|
||||
case 'PUBLISH_PENDING':
|
||||
case 'OFFLINE':
|
||||
case 'OFFLINE_PENDING':
|
||||
case 'DELETE_PENDING':
|
||||
return value;
|
||||
default:
|
||||
@@ -20,6 +24,17 @@ export function normalizeAiPublishStatus(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析用于页面展示的发布状态。
|
||||
* 已发布资源若存在当前审批实例,则视为“发布审批中”,用于统一状态文案与动作禁用。
|
||||
*/
|
||||
export function resolveAiResourceDisplayStatus(
|
||||
displayValue?: null | string,
|
||||
_fallbackValue?: null | string,
|
||||
): AiPublishStatus {
|
||||
return normalizeAiPublishStatus(displayValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前资源是否已有正式线上版本。
|
||||
*/
|
||||
@@ -27,12 +42,23 @@ export function isAiResourcePublished(value?: null | string) {
|
||||
return normalizeAiPublishStatus(value) === 'PUBLISHED';
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前资源是否处于已下线状态。
|
||||
*/
|
||||
export function isAiResourceOffline(value?: null | string) {
|
||||
return normalizeAiPublishStatus(value) === 'OFFLINE';
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前资源是否允许对外可见。
|
||||
*/
|
||||
export function isAiResourceExternallyVisible(value?: null | string) {
|
||||
const normalized = normalizeAiPublishStatus(value);
|
||||
return normalized === 'PUBLISHED' || normalized === 'DELETE_PENDING';
|
||||
return (
|
||||
normalized === 'PUBLISHED' ||
|
||||
normalized === 'DELETE_PENDING' ||
|
||||
normalized === 'OFFLINE_PENDING'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -45,7 +71,68 @@ export function isAiResourceSelectableForBot(value?: null | string) {
|
||||
/**
|
||||
* 当前资源是否处于审批处理中。
|
||||
*/
|
||||
export function isAiResourceApprovalPending(value?: null | string) {
|
||||
const normalized = normalizeAiPublishStatus(value);
|
||||
return normalized === 'PUBLISH_PENDING' || normalized === 'DELETE_PENDING';
|
||||
export function isAiResourceApprovalPending(
|
||||
displayValue?: null | string,
|
||||
_fallbackValue?: null | string,
|
||||
) {
|
||||
const normalized = resolveAiResourceDisplayStatus(displayValue);
|
||||
return (
|
||||
normalized === 'PUBLISH_PENDING' ||
|
||||
normalized === 'OFFLINE_PENDING' ||
|
||||
normalized === 'DELETE_PENDING'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前资源是否允许发起发布。
|
||||
*/
|
||||
export function canAiResourcePublish(
|
||||
displayValue?: null | string,
|
||||
_fallbackValue?: null | string,
|
||||
) {
|
||||
if (isAiResourceApprovalPending(displayValue)) {
|
||||
return false;
|
||||
}
|
||||
const normalized = resolveAiResourceDisplayStatus(displayValue);
|
||||
return normalized === 'DRAFT' || normalized === 'OFFLINE';
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前资源是否允许重新发布。
|
||||
*/
|
||||
export function canAiResourceRepublish(
|
||||
displayValue?: null | string,
|
||||
_fallbackValue?: null | string,
|
||||
) {
|
||||
if (isAiResourceApprovalPending(displayValue)) {
|
||||
return false;
|
||||
}
|
||||
return resolveAiResourceDisplayStatus(displayValue) === 'PUBLISHED';
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前资源是否允许发起下线。
|
||||
*/
|
||||
export function canAiResourceOffline(
|
||||
displayValue?: null | string,
|
||||
_fallbackValue?: null | string,
|
||||
) {
|
||||
if (isAiResourceApprovalPending(displayValue)) {
|
||||
return false;
|
||||
}
|
||||
return resolveAiResourceDisplayStatus(displayValue) === 'PUBLISHED';
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前资源是否允许发起删除。
|
||||
*/
|
||||
export function canAiResourceDelete(
|
||||
displayValue?: null | string,
|
||||
_fallbackValue?: null | string,
|
||||
) {
|
||||
if (isAiResourceApprovalPending(displayValue)) {
|
||||
return false;
|
||||
}
|
||||
const normalized = resolveAiResourceDisplayStatus(displayValue);
|
||||
return normalized === 'DRAFT' || normalized === 'OFFLINE';
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user