|
|
|
|
@ -94,10 +94,12 @@
|
|
|
|
|
</el-tag>
|
|
|
|
|
<div
|
|
|
|
|
v-if="scope.row.submission_status === 'draft' && scope.row.submission && scope.row.submission.approval_notes"
|
|
|
|
|
class="return-note"
|
|
|
|
|
:title="scope.row.submission.approval_notes"
|
|
|
|
|
class="return-note-wrapper"
|
|
|
|
|
>
|
|
|
|
|
退回意见:{{ scope.row.submission.approval_notes }}
|
|
|
|
|
<span class="return-note-text">退回意见:{{ scope.row.submission.approval_notes }}</span>
|
|
|
|
|
<el-button type="text" class="return-note-link" @click="showApprovalNotes(scope.row.submission.approval_notes)">
|
|
|
|
|
查看完整
|
|
|
|
|
</el-button>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
@ -108,36 +110,44 @@
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
|
|
|
|
|
<el-table-column fixed="right" label="操作" width="200">
|
|
|
|
|
<el-table-column fixed="right" label="操作" width="280">
|
|
|
|
|
<template slot-scope="scope">
|
|
|
|
|
<Button
|
|
|
|
|
v-if="!scope.row.submission && canWrite(scope.row)"
|
|
|
|
|
type="primary"
|
|
|
|
|
size="small"
|
|
|
|
|
style="margin-right: 5px;"
|
|
|
|
|
@click="openSubmissionForm(scope.row)"
|
|
|
|
|
>
|
|
|
|
|
填写分解表
|
|
|
|
|
</Button>
|
|
|
|
|
|
|
|
|
|
<Button
|
|
|
|
|
v-if="scope.row.submission && ['draft', 'submitted'].includes(scope.row.submission.status) && canWrite(scope.row)"
|
|
|
|
|
type="warning"
|
|
|
|
|
size="small"
|
|
|
|
|
style="margin-right: 5px;"
|
|
|
|
|
@click="editSubmissionForm(scope.row)"
|
|
|
|
|
>
|
|
|
|
|
修改分解表
|
|
|
|
|
</Button>
|
|
|
|
|
|
|
|
|
|
<Button
|
|
|
|
|
v-if="scope.row.submission"
|
|
|
|
|
type="info"
|
|
|
|
|
size="small"
|
|
|
|
|
@click="viewSubmissionForm(scope.row)"
|
|
|
|
|
>
|
|
|
|
|
查看详情
|
|
|
|
|
</Button>
|
|
|
|
|
<div class="action-group">
|
|
|
|
|
<Button
|
|
|
|
|
v-if="!scope.row.submission && canWrite(scope.row)"
|
|
|
|
|
type="primary"
|
|
|
|
|
size="small"
|
|
|
|
|
@click="openSubmissionForm(scope.row)"
|
|
|
|
|
>
|
|
|
|
|
填写分解表
|
|
|
|
|
</Button>
|
|
|
|
|
|
|
|
|
|
<Button
|
|
|
|
|
v-if="scope.row.submission && ['draft', 'submitted'].includes(scope.row.submission.status) && canWrite(scope.row)"
|
|
|
|
|
type="warning"
|
|
|
|
|
size="small"
|
|
|
|
|
@click="editSubmissionForm(scope.row)"
|
|
|
|
|
>
|
|
|
|
|
修改分解表
|
|
|
|
|
</Button>
|
|
|
|
|
|
|
|
|
|
<Button
|
|
|
|
|
v-if="scope.row.submission"
|
|
|
|
|
type="info"
|
|
|
|
|
size="small"
|
|
|
|
|
@click="viewSubmissionForm(scope.row)"
|
|
|
|
|
>
|
|
|
|
|
查看详情
|
|
|
|
|
</Button>
|
|
|
|
|
|
|
|
|
|
<Button
|
|
|
|
|
v-if="scope.row.submission"
|
|
|
|
|
size="small"
|
|
|
|
|
@click="openReviewHistory(scope.row)"
|
|
|
|
|
>
|
|
|
|
|
审核记录
|
|
|
|
|
</Button>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
</el-table>
|
|
|
|
|
@ -162,6 +172,37 @@
|
|
|
|
|
/>
|
|
|
|
|
</el-dialog>
|
|
|
|
|
|
|
|
|
|
<el-dialog
|
|
|
|
|
title="审核记录"
|
|
|
|
|
:visible.sync="historyDialogVisible"
|
|
|
|
|
width="760px"
|
|
|
|
|
:close-on-click-modal="false"
|
|
|
|
|
>
|
|
|
|
|
<div v-if="currentHistoryPackage">
|
|
|
|
|
<el-descriptions :column="2" border size="small" class="history-summary">
|
|
|
|
|
<el-descriptions-item label="上级包名称">{{ currentHistoryPackage.parent_name || '-' }}</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="执行部门">{{ currentHistoryPackage.department ? currentHistoryPackage.department.name : '-' }}</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="提交状态">{{ getStatusText(currentHistoryPackage.submission_status) }}</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="提交时间">{{ currentHistoryPackage.submission_date ? formatDate(currentHistoryPackage.submission_date) : '-' }}</el-descriptions-item>
|
|
|
|
|
</el-descriptions>
|
|
|
|
|
<el-timeline v-if="reviewHistories(currentHistoryPackage).length > 0" class="history-timeline">
|
|
|
|
|
<el-timeline-item
|
|
|
|
|
v-for="history in reviewHistories(currentHistoryPackage)"
|
|
|
|
|
:key="history.id"
|
|
|
|
|
:timestamp="formatDate(history.operated_at)"
|
|
|
|
|
placement="top"
|
|
|
|
|
>
|
|
|
|
|
<div class="timeline-card">
|
|
|
|
|
<div class="timeline-title">{{ getHistoryActionText(history) }}</div>
|
|
|
|
|
<div class="timeline-meta">{{ history.operator ? history.operator.name : '-' }} · {{ getHistoryStatusFlow(history) }}</div>
|
|
|
|
|
<div v-if="history.notes" class="timeline-notes">{{ history.notes }}</div>
|
|
|
|
|
</div>
|
|
|
|
|
</el-timeline-item>
|
|
|
|
|
</el-timeline>
|
|
|
|
|
<el-empty v-else :image-size="80" description="暂无审核记录" />
|
|
|
|
|
</div>
|
|
|
|
|
</el-dialog>
|
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
@ -195,6 +236,8 @@ export default {
|
|
|
|
|
yearOptions: [],
|
|
|
|
|
submissionDialogVisible: false,
|
|
|
|
|
currentPackage: null,
|
|
|
|
|
currentHistoryPackage: null,
|
|
|
|
|
historyDialogVisible: false,
|
|
|
|
|
submissionMode: 'create' // create, edit, view
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
@ -297,6 +340,11 @@ export default {
|
|
|
|
|
await this.openSubmissionDialog(packageItem, 'view')
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
openReviewHistory(packageItem) {
|
|
|
|
|
this.currentHistoryPackage = packageItem
|
|
|
|
|
this.historyDialogVisible = true
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
async openSubmissionDialog(packageItem, mode) {
|
|
|
|
|
try {
|
|
|
|
|
const packageDetail = await getPackageDecomposition(packageItem.id)
|
|
|
|
|
@ -380,21 +428,61 @@ export default {
|
|
|
|
|
rejected: '已拒绝'
|
|
|
|
|
}
|
|
|
|
|
return textMap[status] || '未知'
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
showApprovalNotes(notes) {
|
|
|
|
|
this.$alert(notes || '无退回意见', '完整退回意见', {
|
|
|
|
|
confirmButtonText: '关闭'
|
|
|
|
|
})
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
reviewHistories(packageItem) {
|
|
|
|
|
const histories = packageItem && packageItem.submission && packageItem.submission.review_histories
|
|
|
|
|
? packageItem.submission.review_histories
|
|
|
|
|
: []
|
|
|
|
|
return histories.slice().sort((a, b) => new Date(b.operated_at || 0).getTime() - new Date(a.operated_at || 0).getTime())
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
getHistoryActionText(history) {
|
|
|
|
|
const actionMap = {
|
|
|
|
|
submit: '提交审核',
|
|
|
|
|
resubmit: '重新提交',
|
|
|
|
|
approve: '审核通过',
|
|
|
|
|
return: '退回修改'
|
|
|
|
|
}
|
|
|
|
|
return actionMap[history.action] || history.action || '未知操作'
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
getHistoryStatusFlow(history) {
|
|
|
|
|
return `${this.getStatusText(history.from_status)} -> ${this.getStatusText(history.to_status)}`
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<style scoped>
|
|
|
|
|
.return-note {
|
|
|
|
|
.return-note-wrapper {
|
|
|
|
|
margin-top: 4px;
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
color: #e6a23c;
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
justify-content: center;
|
|
|
|
|
gap: 4px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.return-note-text {
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
color: #e6a23c;
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
text-overflow: ellipsis;
|
|
|
|
|
white-space: nowrap;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.return-note-link {
|
|
|
|
|
padding: 0;
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
flex-shrink: 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.container {
|
|
|
|
|
padding: 12px 16px 16px 16px;
|
|
|
|
|
}
|
|
|
|
|
@ -426,6 +514,15 @@ export default {
|
|
|
|
|
gap: 10px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.action-group {
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
justify-content: center;
|
|
|
|
|
gap: 6px;
|
|
|
|
|
flex-wrap: nowrap;
|
|
|
|
|
white-space: nowrap;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 统一表格行高 */
|
|
|
|
|
.v-table >>> .el-table__body tr {
|
|
|
|
|
height: 50px !important;
|
|
|
|
|
@ -459,6 +556,39 @@ export default {
|
|
|
|
|
height: 28px !important;
|
|
|
|
|
padding: 4px 8px !important;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.history-summary {
|
|
|
|
|
margin-bottom: 16px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.history-timeline {
|
|
|
|
|
margin-top: 20px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.timeline-card {
|
|
|
|
|
padding: 12px;
|
|
|
|
|
border: 1px solid #ebeef5;
|
|
|
|
|
border-radius: 6px;
|
|
|
|
|
background: #fff;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.timeline-title {
|
|
|
|
|
margin-bottom: 6px;
|
|
|
|
|
color: #303133;
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.timeline-meta {
|
|
|
|
|
color: #909399;
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.timeline-notes {
|
|
|
|
|
margin-top: 8px;
|
|
|
|
|
color: #606266;
|
|
|
|
|
line-height: 1.6;
|
|
|
|
|
word-break: break-all;
|
|
|
|
|
}
|
|
|
|
|
</style>
|
|
|
|
|
|
|
|
|
|
<style>
|
|
|
|
|
|