first commit
This commit is contained in:
@@ -0,0 +1,380 @@
|
||||
<template>
|
||||
<div class="approval-sidebar">
|
||||
<div class="sidebar-header">
|
||||
<h4>审批记录</h4>
|
||||
</div>
|
||||
<div class="timeline-container" v-if="historyApprovalRecords.length > 0">
|
||||
<div class="timeline-wrapper">
|
||||
<div
|
||||
v-for="(record, index) in historyApprovalRecords"
|
||||
:key="record.id"
|
||||
class="timeline-item">
|
||||
|
||||
<!-- 时间线节点 -->
|
||||
<div class="timeline-node">
|
||||
<div class="timeline-dot" :class="getDotClass(record.taskState)"></div>
|
||||
<div class="timeline-line" v-if="index < historyApprovalRecords.length - 1"></div>
|
||||
</div>
|
||||
|
||||
<!-- 审批内容 -->
|
||||
<div class="timeline-content">
|
||||
<div class="approval-card">
|
||||
<div class="card-header">
|
||||
<span class="task-name">{{ record.displayName }}</span>
|
||||
<span class="approval-time">{{ formatTimestamp(record.finishTime || record.createdAt) }}</span>
|
||||
</div>
|
||||
|
||||
<div class="card-body">
|
||||
<div class="info-item" v-if="record.operator && record.operator !== 'flow.auto'">
|
||||
<span class="label">办理人:</span>
|
||||
<span class="value">{{ getOperatorName(record) }}</span>
|
||||
</div>
|
||||
|
||||
<div class="info-item" v-if="record.ext && record.ext.submitType">
|
||||
<span class="label">操作:</span>
|
||||
<span class="value submit-type" :class="'submit-' + record.ext.submitType">
|
||||
{{ getSubmitTypeText(record.ext.submitType) }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="info-item" v-if="record.ext && record.ext.opinion">
|
||||
<span class="label">意见:</span>
|
||||
<span class="value">{{ record.ext.opinion }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="no-records">
|
||||
暂无审批记录
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
module.exports = {
|
||||
name: "SnakerFlowHisApproval",
|
||||
props: {
|
||||
task_id: {
|
||||
type: String | Number,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 历史审批记录
|
||||
historyApprovalRecords: [],
|
||||
|
||||
// 加载状态
|
||||
loading: false,
|
||||
|
||||
// 任务状态枚举
|
||||
taskStateEnum: {
|
||||
DOING: 10,
|
||||
FINISHED: 20,
|
||||
WITHDRAW: 30,
|
||||
INTERRUPT: 40,
|
||||
PENDING: 50,
|
||||
ABANDON: 99
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
// 获取实例ID(从task_id获取流程实例信息)
|
||||
instanceId() {
|
||||
return GetQueryString("instanceId")
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.loadHistoryApprovalRecords()
|
||||
},
|
||||
watch: {
|
||||
task_id: {
|
||||
handler(newVal) {
|
||||
if (newVal) {
|
||||
this.loadHistoryApprovalRecords()
|
||||
}
|
||||
},
|
||||
immediate: true
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 加载历史审批记录
|
||||
async loadHistoryApprovalRecords() {
|
||||
if (!this.instanceId && !this.task_id) return
|
||||
|
||||
this.loading = true
|
||||
try {
|
||||
const params = this.instanceId ?
|
||||
{ instanceId: this.instanceId } :
|
||||
{ taskId: this.task_id }
|
||||
|
||||
const response = await $.post("/flow/common/approvalRecord", params)
|
||||
if (response.code === 0) {
|
||||
this.historyApprovalRecords = response.data || []
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("加载历史审批记录失败:", error)
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
|
||||
// 格式化时间戳
|
||||
formatTimestamp(timestamp) {
|
||||
if (!timestamp) return ""
|
||||
const date = new Date(timestamp)
|
||||
return date.toLocaleString("zh-CN", {
|
||||
month: "2-digit",
|
||||
day: "2-digit",
|
||||
hour: "2-digit",
|
||||
minute: "2-digit"
|
||||
})
|
||||
},
|
||||
|
||||
// 获取操作人姓名
|
||||
getOperatorName(record) {
|
||||
if (!record.operator || record.operator === 'flow.auto') {
|
||||
return "系统自动"
|
||||
}
|
||||
if (record.ext && record.ext.operatorName) {
|
||||
return record.ext.operatorName
|
||||
}
|
||||
return record.operator
|
||||
},
|
||||
|
||||
// 获取提交类型文本
|
||||
getSubmitTypeText(submitType) {
|
||||
const typeMap = {
|
||||
'agree': '同意',
|
||||
'reject': '拒绝',
|
||||
'back': '退回',
|
||||
'transfer': '转办',
|
||||
'delegate': '委托',
|
||||
'submit': '提交'
|
||||
}
|
||||
return typeMap[submitType] || submitType
|
||||
},
|
||||
|
||||
// 获取节点样式类
|
||||
getDotClass(state) {
|
||||
switch (state) {
|
||||
case this.taskStateEnum.FINISHED:
|
||||
return "dot-success"
|
||||
case this.taskStateEnum.WITHDRAW:
|
||||
return "dot-warning"
|
||||
case this.taskStateEnum.INTERRUPT:
|
||||
case this.taskStateEnum.ABANDON:
|
||||
return "dot-danger"
|
||||
case this.taskStateEnum.PENDING:
|
||||
return "dot-info"
|
||||
case this.taskStateEnum.DOING:
|
||||
return "dot-primary"
|
||||
default:
|
||||
return "dot-default"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.approval-sidebar {
|
||||
width: 320px;
|
||||
background: #fff;
|
||||
border: 1px solid #ddd;
|
||||
height: fit-content;
|
||||
max-height: 80vh;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.sidebar-header {
|
||||
background: #f5f5f5;
|
||||
border-bottom: 1px solid #ddd;
|
||||
padding: 12px 16px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.sidebar-header h4 {
|
||||
margin: 0;
|
||||
font-size: 14px;
|
||||
font-weight: normal;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.timeline-container {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.timeline-wrapper {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.timeline-item {
|
||||
display: flex;
|
||||
margin-bottom: 20px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.timeline-item:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.timeline-node {
|
||||
position: relative;
|
||||
margin-right: 12px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.timeline-dot {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
border-radius: 50%;
|
||||
border: 2px solid #fff;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.dot-success {
|
||||
background: #52c41a;
|
||||
}
|
||||
|
||||
.dot-warning {
|
||||
background: #faad14;
|
||||
}
|
||||
|
||||
.dot-danger {
|
||||
background: #f5222d;
|
||||
}
|
||||
|
||||
.dot-primary {
|
||||
background: #1890ff;
|
||||
}
|
||||
|
||||
.dot-info {
|
||||
background: #999;
|
||||
}
|
||||
|
||||
.dot-default {
|
||||
background: #d9d9d9;
|
||||
}
|
||||
|
||||
.timeline-line {
|
||||
width: 1px;
|
||||
background: #e8e8e8;
|
||||
flex: 1;
|
||||
margin-top: 4px;
|
||||
min-height: 30px;
|
||||
}
|
||||
|
||||
.timeline-content {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.approval-card {
|
||||
background: #fff;
|
||||
border: 1px solid #e8e8e8;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.card-header {
|
||||
background: #fafafa;
|
||||
border-bottom: 1px solid #e8e8e8;
|
||||
padding: 8px 12px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.task-name {
|
||||
font-size: 13px;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.approval-time {
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.card-body {
|
||||
padding: 12px;
|
||||
}
|
||||
|
||||
.info-item {
|
||||
display: flex;
|
||||
margin-bottom: 6px;
|
||||
font-size: 12px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.info-item:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.label {
|
||||
color: #666;
|
||||
min-width: 50px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.value {
|
||||
color: #333;
|
||||
flex: 1;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.submit-type {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.submit-agree {
|
||||
color: #52c41a;
|
||||
}
|
||||
|
||||
.submit-reject {
|
||||
color: #f5222d;
|
||||
}
|
||||
|
||||
.submit-back {
|
||||
color: #faad14;
|
||||
}
|
||||
|
||||
.submit-transfer, .submit-delegate, .submit-submit {
|
||||
color: #1890ff;
|
||||
}
|
||||
|
||||
.no-records {
|
||||
padding: 40px 20px;
|
||||
text-align: center;
|
||||
color: #999;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
/* 滚动条样式 */
|
||||
.timeline-container::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
}
|
||||
|
||||
.timeline-container::-webkit-scrollbar-track {
|
||||
background: #f1f1f1;
|
||||
}
|
||||
|
||||
.timeline-container::-webkit-scrollbar-thumb {
|
||||
background: #c1c1c1;
|
||||
}
|
||||
|
||||
.timeline-container::-webkit-scrollbar-thumb:hover {
|
||||
background: #a8a8a8;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user