- 修复办理页「查看流程图」双 hash URL:改 router.resolve + toAppHashUrl 单 hash
- 修复管理端办件抽屉「查看大图」域名尾点(origin + BASE_URL("./") 拼接)
- 新增 flowError 口径层与办理页内联失败条,审批失败提示可读、不泄漏堆栈
- 审批节点抽屉新增「预览候选人」真入口 + AssigneePreviewModal(只读,不写回定义)
- 线级停发/恢复失败改为单条错误面,避免同错双 toast
- 审批抽屉核心区/高级设置分层;插入菜单常用/高级分组
- 新增 FlowAssignEmbed 选人 iframe 父侧宿主(origin/source/信封/context 四校验)
- 修复 /diagram、/assign-preview 面包屑误显示「流程编辑器」
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
<script setup lang="ts">
|
||||
/**
|
||||
* 审批节点候选人预览弹窗(编辑器内入口,验收报告 P2-1)。
|
||||
* 只读展示 resolveNodePreview 的结果:草稿解析 + 已发布版本对账 + 明确的不可预览原因。
|
||||
* 关闭不做任何写回——它只接收抽屉里的本地表单快照。
|
||||
*/
|
||||
import { ref } from "vue";
|
||||
import { Modal, Alert, Tag, Button } from "view-ui-plus";
|
||||
import { resolveNodePreview, type PreviewApi, type PreviewDept, type PreviewNodeConfig } from "../assignPreview";
|
||||
import { flowApi } from "@/api/module/flow";
|
||||
|
||||
const api: PreviewApi = {
|
||||
deptMembers: (deptId) => flowApi.deptMembers(deptId).send() as Promise<any[]>,
|
||||
lookupUser: (userId) => flowApi.mapLookupUser(userId).send() as Promise<any>,
|
||||
applyPreview: (flowGuid) => flowApi.applyPreview(flowGuid).send() as Promise<any>,
|
||||
};
|
||||
|
||||
const visible = ref(false);
|
||||
const loading = ref(false);
|
||||
const title = ref("预览候选人");
|
||||
const result = ref<Awaited<ReturnType<typeof resolveNodePreview>> | null>(null);
|
||||
|
||||
async function show(cfg: PreviewNodeConfig, depts: PreviewDept[], flowGuid = ""): Promise<void> {
|
||||
visible.value = true;
|
||||
loading.value = true;
|
||||
result.value = null;
|
||||
title.value = `预览候选人 · ${cfg.name || "未命名节点"}`;
|
||||
try {
|
||||
result.value = await resolveNodePreview(cfg, depts, api, flowGuid);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
defineExpose({ show });
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Modal v-model="visible" :title="title" :width="620" :footer-hide="true">
|
||||
<div v-if="loading" class="muted" style="padding: 24px 0; text-align: center">正在解析候选人…</div>
|
||||
<template v-else-if="result">
|
||||
<Alert v-if="result.blocked" type="warning" show-icon class="pv-block">{{ result.blocked }}</Alert>
|
||||
<div class="pv-headline">
|
||||
<b>{{ result.headline }}</b>
|
||||
<span class="pv-source">数据源:{{ result.rows.length ? "FL 科室映射 / UserBase 既有接口" : "未取到候选" }}</span>
|
||||
</div>
|
||||
<div v-if="result.rows.length" class="pv-rows">
|
||||
<div v-for="r in result.rows" :key="r.userId" class="pv-row">
|
||||
<Tag :color="r.warn ? 'warning' : 'blue'">{{ r.userName }}</Tag>
|
||||
<span class="pv-id">#{{ r.userId }}</span>
|
||||
<span v-if="r.warn" class="pv-warn">{{ r.warn }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="muted">(本节点当前没有可展示的候选人)</div>
|
||||
|
||||
<div class="pv-pub" v-if="result.published">
|
||||
<div class="pv-pub-title">已发布版本对账</div>
|
||||
<div class="pv-pub-body">
|
||||
<Tag :color="result.published.state === 'ok' ? 'success' : result.published.state === 'missing' ? 'default' : 'warning'">
|
||||
{{ result.published.state === "ok" ? "可比对" : result.published.state === "missing" ? "草稿节点未发布" : "不可比对" }}
|
||||
</Tag>
|
||||
<span>{{ result.published.text }}</span>
|
||||
</div>
|
||||
<div v-if="result.published.state === 'ok' && result.published.rows.length" class="pv-rows">
|
||||
<Tag v-for="p in result.published.rows" :key="p.userId" color="green">{{ p.userName }}</Tag>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ul class="pv-notes">
|
||||
<li v-for="(n, i) in result.notes" :key="i">{{ n }}</li>
|
||||
</ul>
|
||||
</template>
|
||||
<div style="margin-top: 12px; text-align: right">
|
||||
<Button @click="visible = false">关闭</Button>
|
||||
</div>
|
||||
</Modal>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.pv-block { margin-bottom: 10px; }
|
||||
.pv-headline { display: flex; align-items: baseline; gap: 10px; margin-bottom: 10px; }
|
||||
.pv-source { color: #808695; font-size: 12px; }
|
||||
.pv-rows { display: flex; flex-wrap: wrap; gap: 6px 0; margin-bottom: 12px; }
|
||||
.pv-row { display: flex; align-items: center; gap: 6px; width: 100%; }
|
||||
.pv-id { color: #c5c8ce; font-size: 12px; }
|
||||
.pv-warn { color: #ff9900; font-size: 12px; }
|
||||
.pv-pub { border-top: 1px dashed #e8eaec; padding-top: 10px; margin-bottom: 10px; }
|
||||
.pv-pub-title { font-weight: 600; font-size: 13px; margin-bottom: 6px; }
|
||||
.pv-pub-body { display: flex; align-items: flex-start; gap: 8px; font-size: 13px; }
|
||||
.pv-notes { margin: 0; padding-left: 18px; color: #808695; font-size: 12px; line-height: 1.7; }
|
||||
</style>
|
||||
Reference in New Issue
Block a user