feat(web-admin): show per-person approval lines on OA progress chain

Render name/opinion/time under multi-approver nodes; hide duplicate node comment.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
zlwuandCursor committed 2026-07-23 14:13:59 +08:00
1 parent 043e69f818
commit 1e2b903cd7
1 file changed
+66 -1
@@ -51,7 +51,22 @@
</span>
</span>
</div>
<div v-if="item.commentText" class="oa-flow-card__comment">
<div v-if="personLines(item).length" class="oa-person-lines">
<p
v-for="(line, li) in personLines(item)"
:key="`${item.key}-pl-${li}`"
class="oa-person-line"
:class="{
'is-ok': line.tone === 'ok',
'is-pending': line.tone === 'pending',
'is-danger': line.tone === 'danger',
'is-mute': line.tone === 'mute'
}"
>
{{ line.text }}
</p>
</div>
<div v-else-if="showNodeComment(item)" class="oa-flow-card__comment">
意见:{{ item.commentText }}
</div>
</div>
@@ -61,6 +76,11 @@
</template>
<script setup lang="ts">
import {
formatProgressPersonLines,
type ProgressPersonLine
} from '@/utils/oa-progress-person-lines'
defineOptions({ name: 'OaProgressChain' })
export type OaProgressPerson = {
@@ -149,6 +169,20 @@
return [{ nickName: name, status: item.status }]
}
function personLines(item: OaProgressChainItem): ProgressPersonLine[] {
if (item.kind === 'terminal' || item.kind === 'submit') return []
if (item.taskType === 'cc' || item.signMode === 'cc') return []
const list = displayPeople(item)
if (!list.length) return []
return formatProgressPersonLines(list)
}
function showNodeComment(item: OaProgressChainItem): boolean {
// 有按人行时不再展示节点级拼接意见,避免双份
if (personLines(item).length) return false
return Boolean(item.commentText)
}
function personChipClass(status?: string) {
const s = status || ''
if (s === 'approved' || s === 'completed') return 'is-ok'
@@ -338,6 +372,37 @@
line-height: 1.4;
}
.oa-person-lines {
margin-top: 8px;
display: grid;
gap: 4px;
}
.oa-person-line {
margin: 0;
color: var(--mint-text, #334155);
font-size: 12px;
line-height: 1.55;
word-break: break-word;
&.is-ok {
color: #059669;
font-weight: 500;
}
&.is-pending {
color: #d97706;
}
&.is-danger {
color: #dc2626;
}
&.is-mute {
color: #94a3b8;
}
}
.oa-person-chip {
display: inline-flex;
gap: 3px;