feat: 归档L03与L09审批发布能力
- 新增统一审批中心与审批管理页面,支持流程配置、审批详情与角色/用户审批对象 - 接入聊天助手、知识库、工作流的发布与删除审批,并补齐发布态校验与快照展示
This commit is contained in:
@@ -5,15 +5,30 @@ import { useRoute } from 'vue-router';
|
||||
import { usePreferences } from '@easyflow/preferences';
|
||||
import { getOptions, sortNodes } from '@easyflow/utils';
|
||||
|
||||
import { ArrowLeft, CircleCheck, Close } from '@element-plus/icons-vue';
|
||||
import {
|
||||
ArrowLeft,
|
||||
CircleCheck,
|
||||
Close,
|
||||
Promotion,
|
||||
} from '@element-plus/icons-vue';
|
||||
import { Tinyflow } from '@tinyflow-ai/vue';
|
||||
import { ElButton, ElDrawer, ElMessage, ElSkeleton } from 'element-plus';
|
||||
import {
|
||||
ElButton,
|
||||
ElDrawer,
|
||||
ElMessage,
|
||||
ElMessageBox,
|
||||
ElSkeleton,
|
||||
} from 'element-plus';
|
||||
|
||||
import { api } from '#/api/request';
|
||||
import CommonSelectDataModal from '#/components/commonSelectModal/CommonSelectDataModal.vue';
|
||||
import { $t } from '#/locales';
|
||||
import { router } from '#/router';
|
||||
import { getIconByValue } from '#/views/ai/model/modelUtils/defaultIcon';
|
||||
import {
|
||||
isAiResourceApprovalPending,
|
||||
normalizeAiPublishStatus,
|
||||
} from '#/views/ai/shared/publish-status';
|
||||
import ExecResult from '#/views/ai/workflow/components/ExecResult.vue';
|
||||
import SingleRun from '#/views/ai/workflow/components/SingleRun.vue';
|
||||
import WorkflowForm from '#/views/ai/workflow/components/WorkflowForm.vue';
|
||||
@@ -135,6 +150,7 @@ const customNode = ref();
|
||||
const showTinyFlow = ref(false);
|
||||
const saveLoading = ref(false);
|
||||
const checkLoading = ref(false);
|
||||
const publishLoading = ref(false);
|
||||
const checkIssuesVisible = ref(false);
|
||||
const checkResult = ref<any>(null);
|
||||
const checkContentSnapshot = ref<any>(null);
|
||||
@@ -234,6 +250,30 @@ const pluginSelectRef = ref();
|
||||
const updatePluginNode = ref<any>(null);
|
||||
const pageLoading = ref(false);
|
||||
const chainInfo = ref<any>(null);
|
||||
const publishActionText = computed(() => {
|
||||
switch (normalizeAiPublishStatus(workflowInfo.value?.publishStatus)) {
|
||||
case 'DELETE_PENDING': {
|
||||
return $t('aiWorkflow.publishStatusDeletePending');
|
||||
}
|
||||
case 'PUBLISH_PENDING': {
|
||||
return $t('aiWorkflow.publishStatusPublishPending');
|
||||
}
|
||||
case 'PUBLISHED': {
|
||||
return `${$t('aiWorkflow.publishStatusPublished')} · ${$t('button.republish')}`;
|
||||
}
|
||||
default: {
|
||||
return `${$t('aiWorkflow.publishStatusDraft')} · ${$t('button.submitPublishApproval')}`;
|
||||
}
|
||||
}
|
||||
});
|
||||
const publishActionDisabled = computed(
|
||||
() =>
|
||||
!workflowId.value ||
|
||||
saveLoading.value ||
|
||||
checkLoading.value ||
|
||||
publishLoading.value ||
|
||||
isAiResourceApprovalPending(workflowInfo.value?.publishStatus),
|
||||
);
|
||||
|
||||
function syncNavTitle(title: string) {
|
||||
if (!title) {
|
||||
@@ -458,6 +498,44 @@ function closeCheckIssues() {
|
||||
async function handleCheck() {
|
||||
await runCheck('PRE_EXECUTE');
|
||||
}
|
||||
async function handlePublish() {
|
||||
if (publishLoading.value) {
|
||||
return;
|
||||
}
|
||||
if (isAiResourceApprovalPending(workflowInfo.value?.publishStatus)) {
|
||||
ElMessage.warning($t('aiWorkflow.publishPendingHint'));
|
||||
return;
|
||||
}
|
||||
try {
|
||||
await ElMessageBox.confirm(
|
||||
$t('aiWorkflow.submitPublishApprovalConfirm'),
|
||||
$t('message.noticeTitle'),
|
||||
{
|
||||
confirmButtonText: $t('button.confirm'),
|
||||
cancelButtonText: $t('button.cancel'),
|
||||
type: 'info',
|
||||
},
|
||||
);
|
||||
} catch {
|
||||
return;
|
||||
}
|
||||
const saved = await handleSave();
|
||||
if (!saved) {
|
||||
return;
|
||||
}
|
||||
publishLoading.value = true;
|
||||
try {
|
||||
const res = await api.post('/api/v1/workflow/submitPublishApproval', {
|
||||
id: workflowId.value,
|
||||
});
|
||||
if (res.errorCode === 0) {
|
||||
ElMessage.success(res.message || $t('message.saveOkMessage'));
|
||||
await getWorkflowInfo(workflowId.value);
|
||||
}
|
||||
} finally {
|
||||
publishLoading.value = false;
|
||||
}
|
||||
}
|
||||
function onSubmit() {
|
||||
initState.value = !initState.value;
|
||||
}
|
||||
@@ -584,7 +662,7 @@ function onAsyncExecute(info: any) {
|
||||
<div class="workflow-head-actions">
|
||||
<ElButton
|
||||
:loading="checkLoading"
|
||||
:disabled="saveLoading"
|
||||
:disabled="saveLoading || publishLoading"
|
||||
:icon="CircleCheck"
|
||||
@click="handleCheck"
|
||||
>
|
||||
@@ -592,11 +670,21 @@ function onAsyncExecute(info: any) {
|
||||
</ElButton>
|
||||
<ElButton
|
||||
type="primary"
|
||||
:disabled="saveLoading || checkLoading"
|
||||
:disabled="saveLoading || checkLoading || publishLoading"
|
||||
@click="handleSave(true)"
|
||||
>
|
||||
{{ $t('button.save') }}(ctrl+s)
|
||||
</ElButton>
|
||||
<ElButton
|
||||
:icon="Promotion"
|
||||
:loading="publishLoading"
|
||||
:disabled="publishActionDisabled"
|
||||
class="workflow-publish-button"
|
||||
:class="`workflow-publish-button--${normalizeAiPublishStatus(workflowInfo?.publishStatus)}`"
|
||||
@click="handlePublish"
|
||||
>
|
||||
{{ publishActionText }}
|
||||
</ElButton>
|
||||
</div>
|
||||
</div>
|
||||
<Tinyflow
|
||||
@@ -695,8 +783,42 @@ function onAsyncExecute(info: any) {
|
||||
|
||||
.workflow-head-actions {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
:deep(.workflow-publish-button.el-button) {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
:deep(.workflow-publish-button.el-button:not(.is-disabled)) {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
:deep(.workflow-publish-button--DRAFT.el-button) {
|
||||
color: hsl(var(--foreground) / 72%);
|
||||
background: hsl(var(--muted) / 68%);
|
||||
border-color: hsl(var(--foreground) / 14%);
|
||||
}
|
||||
|
||||
:deep(.workflow-publish-button--PUBLISH_PENDING.el-button) {
|
||||
color: hsl(var(--warning));
|
||||
background: hsl(var(--warning) / 18%);
|
||||
border-color: hsl(var(--warning) / 24%);
|
||||
}
|
||||
|
||||
:deep(.workflow-publish-button--PUBLISHED.el-button) {
|
||||
color: hsl(var(--success));
|
||||
background: hsl(var(--success) / 18%);
|
||||
border-color: hsl(var(--success) / 24%);
|
||||
}
|
||||
|
||||
:deep(.workflow-publish-button--DELETE_PENDING.el-button) {
|
||||
color: hsl(var(--destructive));
|
||||
background: hsl(var(--destructive) / 16%);
|
||||
border-color: hsl(var(--destructive) / 24%);
|
||||
}
|
||||
|
||||
.tiny-flow-container {
|
||||
|
||||
Reference in New Issue
Block a user