Files
flow-center-front/src/views/flow/admin/def-editor/components/NodeCard.vue
T
chenxing f0ec500348 B3-1 编辑器右信息面板 + 校验清单定位(先加面板,保存链路不动)
- index.vue:画布与面板包进 .ed-body(flex row),新增 aside.ed-info 五分区——
  流程信息(名称/编码/归属应用,与画布同源同一 ref,编码沿用 !!editId||!!baseGuid 禁用)/
  状态与版本(状态 Tag + v 版本号 + flowGuid 等宽 + 复制,新建态显示「保存后生成」)/
  校验问题清单(错误在前警告在后,项内 path+msg)/ 结构统计(walkItems 递归四类计数)/
  快捷入口(流程设置/源码/图示预览,:disabled=!editId 同现状)
- sourceFlowGuid ref:load() 里 defGet 后取 d.flowGuid,新建态空串
- locateIssue:清单项点击 scrollIntoView 居中 + .nd-locate 高亮 2.8s;三张卡片根元素加 :id="'nd-'+node.uid",
  uid 为空的清单项 class=fix 不可点;高亮样式走 :deep(卡片在子组件内)
- 画布左对齐:.ed-canvas align-items center→flex-start

验证:npm run build 通过;npx tsc --noEmit 48 条=基线无新增;convert 往返 ALL PASS
2026-10-12 16:19:51 +08:00

137 lines
3.5 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script setup lang="ts">
// 审批节点卡片(方案 §3.2):标题 + 审批人摘要 + 会签/时限标签 + 就地校验标注;hover 显示删除
import { computed, inject } from "vue";
import { ApprovalNode, EDITOR_CTX, assigneeText, nodeTags } from "../model";
const props = defineProps<{ node: ApprovalNode }>();
const ctx = inject(EDITOR_CTX)!;
const issues = computed(() => ctx.issueOf(props.node.uid));
const hasError = computed(() => issues.value.some((i) => i.level === "error"));
const summary = computed(() => assigneeText(props.node.assignee, ctx.depts, ctx.userNames));
const tags = computed(() => nodeTags(props.node));
// 删除控件在卡片内,点击不应顺带打开配置抽屉(确认气泡已 transfer 到 body,不受影响)
function onOpen(e: MouseEvent): void {
if ((e.target as HTMLElement).closest(".nc-del")) return;
ctx.openNode(props.node.uid);
}
</script>
<template>
<div :id="'nd-' + node.uid" class="node-card" :class="{ error: hasError }" @click="onOpen">
<div class="nc-head">
<span class="nc-icon">审</span>
<span class="nc-name">{{ node.name || "未命名节点" }}</span>
<!-- view-ui-plus 无 Popconfirm 组件,二次确认用 Poptip 的 confirm 模式 -->
<Poptip
confirm
title="删除该审批节点?"
ok-text="删除"
cancel-text="取消"
transfer
@on-ok="ctx.removeNode(node.uid)"
>
<span class="nc-del" title="删除节点">×</span>
</Poptip>
</div>
<div class="nc-sub">{{ summary }}</div>
<div class="nc-sub last">
<span v-for="t in tags" :key="t" class="tag">{{ t }}</span>
</div>
<div v-for="(i, k) in issues" :key="k" class="nc-issue" :class="i.level">⚠ {{ i.msg }}</div>
</div>
</template>
<style scoped>
.node-card {
width: 264px;
background: #fff;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
cursor: pointer;
border: 2px solid transparent;
transition: all 0.15s;
}
.node-card:hover {
border-color: var(--brand);
}
.node-card.error {
border-color: #ed4014;
}
.nc-head {
display: flex;
align-items: center;
gap: 8px;
padding: 12px 14px 2px;
}
.nc-icon {
flex: none;
width: 26px;
height: 26px;
border-radius: 6px;
background: #e8f3ff;
color: var(--brand);
display: flex;
align-items: center;
justify-content: center;
font-size: 13px;
}
.nc-name {
flex: 1;
font-weight: 600;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.nc-del {
flex: none;
width: 20px;
height: 20px;
border-radius: 50%;
display: none;
align-items: center;
justify-content: center;
color: #fff;
background: #c5c9d1;
font-size: 13px;
line-height: 1;
}
.node-card:hover .nc-del {
display: inline-flex;
}
.nc-del:hover {
background: #ed4014;
}
.nc-sub {
padding: 4px 16px 0;
color: #808695;
font-size: 12px;
line-height: 1.6;
word-break: break-all;
}
.nc-sub.last {
padding-bottom: 12px;
}
.tag {
display: inline-block;
padding: 1px 6px;
margin-right: 4px;
border-radius: 4px;
font-size: 11px;
background: #f5f7fa;
color: #808695;
}
.nc-issue {
padding: 4px 16px 8px;
font-size: 12px;
}
.nc-issue.error {
color: #ed4014;
}
.nc-issue.warn {
color: #ff9900;
}
</style>