zhxy-jsd/src/pages/base/xs/qj/components/progressList.vue
2025-09-05 22:25:34 +08:00

277 lines
6.6 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<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.spType, 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 = (spType: string, status: string) => {
switch (status) {
case 'apply': return '已申请';
case 'pending': return spType === 'CC' ? '待抄送' : '待处理';
case 'approved': return spType === 'CC' ? '已抄送' : '已同意';
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>