feat: 审批流程改为时间轴样式,增加审批人/抄送人标识
- 审批流程使用时间轴样式显示 - 增加"审批人"和"抄送人"标签 - 已审批节点显示审批人姓名和审批时间 - 未审批节点显示节点名称(人名) - 当前审批节点高亮显示 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -64,6 +64,9 @@
|
||||
.approverItem {
|
||||
padding: 8px 0;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.approverItem:last-child {
|
||||
@@ -73,12 +76,15 @@
|
||||
.approverName {
|
||||
font-size: 15px;
|
||||
color: #333;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.approverType {
|
||||
font-size: 13px;
|
||||
color: #999;
|
||||
color: #fff;
|
||||
background: #666;
|
||||
padding: 2px 8px;
|
||||
border-radius: 4px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.formData {
|
||||
@@ -183,6 +189,20 @@
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
background: #e8e8e8;
|
||||
color: #999;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.timelineDot.done {
|
||||
background: #52c41a;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.timelineDot.current {
|
||||
background: #1890ff;
|
||||
color: #fff;
|
||||
box-shadow: 0 0 0 4px rgba(24, 144, 255, 0.2);
|
||||
}
|
||||
|
||||
.timelineDotIcon {
|
||||
@@ -197,6 +217,18 @@
|
||||
font-size: 15px;
|
||||
color: #333;
|
||||
margin-bottom: 4px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.timelineType {
|
||||
font-size: 13px;
|
||||
color: #fff;
|
||||
background: #666;
|
||||
padding: 2px 8px;
|
||||
border-radius: 4px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.timelineName {
|
||||
|
||||
@@ -331,11 +331,15 @@ export default function ApprovalDetail() {
|
||||
{/* 当前审批节点 */}
|
||||
{detail.status === 'pending' && currentApprovers.length > 0 && (
|
||||
<Card title="当前审批" className={styles.section}>
|
||||
{currentApprovers.map((item, index) => (
|
||||
<div key={index} className={styles.approverItem}>
|
||||
<div className={styles.approverName}>{getNodeApproversNames(item.nodeId, item.nodeType)}</div>
|
||||
</div>
|
||||
))}
|
||||
{currentApprovers.map((item, index) => {
|
||||
const typeLabel = item.nodeType === 'notify' ? '抄送人' : '审批人'
|
||||
return (
|
||||
<div key={index} className={styles.approverItem}>
|
||||
<span className={styles.approverType}>{typeLabel}</span>
|
||||
<span className={styles.approverName}>{getNodeApproversNames(item.nodeId, item.nodeType)}</span>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</Card>
|
||||
)}
|
||||
|
||||
@@ -364,31 +368,50 @@ export default function ApprovalDetail() {
|
||||
{/* 审批流程 */}
|
||||
{detail.flow?.nodes && detail.flow.nodes.length > 0 && (
|
||||
<Card title="审批流程" className={styles.section}>
|
||||
<div className={styles.flowNodes}>
|
||||
<div className={styles.timeline}>
|
||||
{detail.flow.nodes.map((node, index) => {
|
||||
const isCurrent = detail.current_nodes?.includes(node.id)
|
||||
const record = detail.records.find((r) => r.node_id === node.id)
|
||||
const records = detail.records.filter(r => r.node_id === node.id && r.action !== 'submit')
|
||||
const hasApproved = records.length > 0
|
||||
|
||||
let status: 'pending' | 'done' = 'pending'
|
||||
if (record) {
|
||||
status = 'done'
|
||||
// 判断节点状态
|
||||
let nodeStatus: 'pending' | 'done' = 'pending'
|
||||
if (hasApproved) {
|
||||
nodeStatus = 'done'
|
||||
} else if (!isCurrent && index > 0) {
|
||||
// 检查前面的节点是否完成
|
||||
const prevNode = detail.flow.nodes[index - 1]
|
||||
const prevRecord = detail.records.find((r) => r.node_id === prevNode.id)
|
||||
if (prevRecord) status = 'done'
|
||||
if (prevRecord) nodeStatus = 'done'
|
||||
}
|
||||
|
||||
// 获取节点类型标签
|
||||
const typeLabel = node.type === 'notify' ? '抄送人' : '审批人'
|
||||
|
||||
// 获取显示名称和审批时间
|
||||
let displayName = node.name || '待定'
|
||||
let approvalTime = ''
|
||||
|
||||
if (hasApproved && records[0]) {
|
||||
displayName = records[0].approver?.name || displayName
|
||||
approvalTime = formatTime(records[0].created_at)
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
key={node.id}
|
||||
className={`${styles.flowNode} ${styles[status]} ${isCurrent ? styles.current : ''}`}
|
||||
>
|
||||
<div className={styles.flowNodeDot}>
|
||||
{status === 'done' ? '✓' : index + 1}
|
||||
<div key={node.id} className={styles.timelineItem}>
|
||||
<div className={`${styles.timelineDot} ${nodeStatus === 'done' ? styles.done : ''} ${isCurrent ? styles.current : ''}`}>
|
||||
{nodeStatus === 'done' ? '✓' : index + 1}
|
||||
</div>
|
||||
<div className={styles.flowNodeContent}>
|
||||
<div className={styles.flowNodeName}>{getNodeDisplayName(node)}</div>
|
||||
<div className={styles.timelineContent}>
|
||||
<div className={styles.timelineTitle}>
|
||||
<span className={styles.timelineType}>{typeLabel}</span>
|
||||
<span className={styles.timelineName}>{displayName}</span>
|
||||
</div>
|
||||
{approvalTime && (
|
||||
<div className={styles.timelineTime}>{approvalTime}</div>
|
||||
)}
|
||||
{hasApproved && records[0]?.comment && (
|
||||
<div className={styles.timelineComment}>备注: {records[0].comment}</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user