zhxy-jsd/src/pages/base/xs/qj/components/progressList.vue

277 lines
6.5 KiB
Vue
Raw Normal View History

2025-08-28 00:57:52 +08:00
<template>
<view class="approval-progress">
<view class="progress-title">
<text class="applicant-name">审批进度</text>
</view>
<view class="divider"></view>
<view class="progress-list">
<view class="progress-item" v-for="(approver, index) in approvalList" :key="index">
<view class="progress-item-row">
<view class="item-avatar">
<image
:src="approver.avatar || '/static/base/home/11222.png'"
class="w-full h-full"
></image>
</view>
<view class="item-middle">
<text class="item-name">{{ approver.userName }}</text>
<text class="item-detail">{{ getSpTypeText(approver.spType) }}</text>
</view>
<view class="item-right">
<text class="item-time" v-if="approver.approveTime">{{ formatTime(approver.approveTime) }}</text>
<text class="item-status" :class="getStatusClass(approver.approveStatus)">
{{ getStatusText(approver.approveStatus) }}
</text>
</view>
</view>
<view class="progress-item-line" v-if="index < approvalList.length - 1"></view>
</view>
</view>
</view>
</template>
<script setup lang="ts">
import dayjs from "dayjs";
import { getXsQjApprovalProcessApi } from "@/api/base/server";
// 接收外部传入属性
const props = withDefaults(defineProps<{
qjId: string
}>(), {
qjId: ''
});
// 审批流程数据
const approvalList = ref<any[]>([]);
// 获取审批流程
const loadApprovalProcess = async () => {
if (!props.qjId) return;
try {
// 调用后端API获取审批流程数据
const res = await getXsQjApprovalProcessApi(props.qjId, 'XS_QJ');
if (res.resultCode === 1 && res.result) {
// 转换为前端显示格式后端已按sort字段排序
approvalList.value = res.result.map((item: any) => ({
userName: item.userName || getDefaultUserName(item.spType),
spType: item.spType,
approveStatus: item.approveStatus,
approveTime: item.approveTime,
approveRemark: item.approveRemark,
avatar: item.avatar || '/static/base/home/11222.png'
}));
} else {
loadMockData();
}
} catch (error) {
console.error('获取审批流程失败:', error);
// 如果API调用失败使用模拟数据
loadMockData();
}
};
// 获取默认用户名
const getDefaultUserName = (spType: string) => {
switch (spType) {
case 'SQ': return '学生';
case 'SP': return '班主任';
case 'CC': return '家长';
default: return '未知';
}
};
// 加载模拟数据(备用方案)
const loadMockData = () => {
const mockData = [
{
userName: '学生',
spType: 'SQ',
approveStatus: 'approved',
approveTime: new Date(),
approveRemark: '申请人提交',
avatar: '/static/base/home/11222.png'
},
{
userName: '班主任',
spType: 'SP',
approveStatus: 'pending',
approveTime: null,
approveRemark: '待审批',
avatar: '/static/base/home/11222.png'
}
];
approvalList.value = mockData;
};
// 获取审批类型文本
const getSpTypeText = (spType: string) => {
switch (spType) {
case 'SQ': return '申请人';
case 'SP': return '审批人';
case 'CC': return '抄送人';
default: return '';
}
};
// 获取状态文本
const getStatusText = (status: string) => {
switch (status) {
case 'apply': return '已申请';
case 'pending': return '待处理';
case 'approved': return '已同意';
case 'rejected': return '已拒绝';
case 'cc_sent': return '已抄送';
default: return '未知';
}
};
// 获取状态样式类
const getStatusClass = (status: string) => {
switch (status) {
case 'pending': return 'status-pending';
case 'approved': return 'status-approved';
case 'rejected': return 'status-rejected';
case 'cc_sent': return 'status-cc';
default: return '';
}
};
// 格式化时间
const formatTime = (time: string | Date) => {
if (!time) return '';
return dayjs(time).format('YYYY-MM-DD HH:mm');
};
// 监听qjId变化
watch(() => props.qjId, (newVal) => {
if (newVal) {
loadApprovalProcess();
}
});
// 初始化
if (props.qjId) {
loadApprovalProcess();
}
</script>
<style lang="scss" scoped>
.approval-progress {
margin: 15px;
background-color: #fff;
border-radius: 8px;
padding: 15px;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05);
.progress-title {
font-size: 16px;
font-weight: bold;
color: #333;
margin-bottom: 10px;
.applicant-name {
font-size: 16px;
font-weight: bold;
color: #333;
}
}
.divider {
height: 1px;
background-color: #eee;
margin-bottom: 15px;
}
.progress-list {
display: flex;
flex-direction: column;
.progress-item {
position: relative;
.progress-item-row {
display: flex;
align-items: center;
padding: 10px 0;
.item-avatar {
width: 40px;
height: 40px;
border-radius: 50%;
overflow: hidden;
margin-right: 12px;
flex-shrink: 0;
}
.item-middle {
flex: 1;
display: flex;
flex-direction: column;
.item-name {
font-size: 14px;
color: #333;
font-weight: 500;
margin-bottom: 4px;
}
.item-detail {
font-size: 12px;
color: #999;
}
}
.item-right {
display: flex;
flex-direction: column;
align-items: flex-end;
.item-time {
font-size: 12px;
color: #999;
margin-bottom: 4px;
}
.item-status {
font-size: 12px;
padding: 2px 8px;
border-radius: 10px;
&.status-pending {
background-color: #fff7e6;
color: #fa8c16;
}
&.status-approved {
background-color: #f6ffed;
color: #52c41a;
}
&.status-rejected {
background-color: #fff2f0;
color: #ff4d4f;
}
&.status-cc {
background-color: #f0f5ff;
color: #1890ff;
}
}
}
}
.progress-item-line {
height: 20px;
width: 2px;
background-color: #e8e8e8;
margin-left: 19px;
margin-top: -10px;
margin-bottom: -10px;
}
}
}
}
</style>