babyhealth/pages/tasks/approval.vue
2026-02-06 20:21:10 +08:00

461 lines
11 KiB
Vue
Raw Permalink 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="main-data-page">
<!-- 使用子头部组件 -->
<sub-header
title="业务审批"
@goBack="goBack"
@showMoreOptions="showMoreOptions"
/>
<view class="main-container">
<!-- 审批状态tabs -->
<view class="approval-tabs">
<view
v-for="tab in approvalTabs"
:key="tab.key"
class="tab-item"
:class="{ active: activeTab === tab.key }"
@click="switchTab(tab.key)"
>
{{ tab.label }}
<view v-if="(tab.key === 'pending' || tab.key === 'all') && tab.count > 0" class="tab-badge">{{ tab.count }}</view>
</view>
</view>
<!-- 审批列表 -->
<view class="approval-list">
<view
v-for="item in filteredApprovalList"
:key="item.id"
class="approval-item"
@click="viewDetail(item)"
>
<view class="item-header">
<view class="item-title">{{ item.title }}</view>
<view class="item-status" :class="item.status">
{{ getStatusText(item.status) }}
</view>
</view>
<view class="item-content">
<view class="item-info">
<text class="info-label">申请人:</text>
<text class="info-value">{{ item.applicant }}</text>
</view>
<view class="item-info">
<text class="info-label">申请时间:</text>
<text class="info-value">{{ item.applyTime }}</text>
</view>
<view class="item-info">
<text class="info-label">业务类型:</text>
<text class="info-value">{{ item.businessType }}</text>
</view>
</view>
<view class="item-footer">
<view class="priority" :class="item.priority">
{{ getPriorityText(item.priority) }}
</view>
<view class="item-amount" v-if="item.amount">
金额:{{ item.amount }}
</view>
</view>
</view>
<!-- 空状态 -->
<view v-if="filteredApprovalList.length === 0" class="empty-state">
<view class="empty-icon">📋</view>
<view class="empty-text">暂无{{ getCurrentTabLabel() }}审批</view>
</view>
</view>
</view>
</view>
</template>
<script setup>
import { ref, computed, onMounted } from "vue";
import SubHeader from "../components/subHeader.vue";
// 响应式数据
const activeTab = ref('all'); // 当前激活的tab
// 审批状态tabs配置
const approvalTabs = ref([
{ key: 'all', label: '全部', count: 0 },
{ key: 'pending', label: '待审批', count: 0 },
{ key: 'approved', label: '已通过', count: 0 },
{ key: 'rejected', label: '已拒绝', count: 0 }
]);
// 审批列表数据
const approvalList = ref([
{
id: 1,
title: '港口作业申请',
status: 'pending',
applicant: '张三',
applyTime: '2024-01-15 09:30',
businessType: '港口作业',
priority: 'high',
amount: '¥50,000'
},
{
id: 2,
title: '设备维修申请',
status: 'approved',
applicant: '李四',
applyTime: '2024-01-14 14:20',
businessType: '设备维护',
priority: 'medium',
amount: '¥15,000'
},
{
id: 3,
title: '人员调动申请',
status: 'rejected',
applicant: '王五',
applyTime: '2024-01-13 16:45',
businessType: '人事管理',
priority: 'low',
amount: null
},
{
id: 4,
title: '采购申请',
status: 'pending',
applicant: '赵六',
applyTime: '2024-01-12 11:15',
businessType: '采购管理',
priority: 'high',
amount: '¥80,000'
},
{
id: 5,
title: '安全培训申请',
status: 'approved',
applicant: '钱七',
applyTime: '2024-01-11 08:30',
businessType: '培训管理',
priority: 'medium',
amount: '¥5,000'
}
]);
// 计算属性根据当前tab过滤列表
const filteredApprovalList = computed(() => {
let filteredList = [];
if (activeTab.value === 'all') {
filteredList = approvalList.value;
} else {
filteredList = approvalList.value.filter(item => item.status === activeTab.value);
}
// 按照状态排序:待审批、已拒绝、已通过
const statusOrder = ['pending', 'rejected', 'approved'];
return filteredList.sort((a, b) => {
const aIndex = statusOrder.indexOf(a.status);
const bIndex = statusOrder.indexOf(b.status);
return aIndex - bIndex;
});
});
// 更新tabs计数
const updateTabCounts = () => {
approvalTabs.value.forEach(tab => {
if (tab.key === 'all') {
tab.count = approvalList.value.length;
} else {
tab.count = approvalList.value.filter(item => item.status === tab.key).length;
}
});
};
// 切换tab
const switchTab = (tabKey) => {
activeTab.value = tabKey;
};
// 获取状态文本
const getStatusText = (status) => {
const statusMap = {
pending: '待审批',
approved: '已通过',
rejected: '已拒绝'
};
return statusMap[status] || status;
};
// 获取优先级文本
const getPriorityText = (priority) => {
const priorityMap = {
high: '高',
medium: '中',
low: '低'
};
return priorityMap[priority] || priority;
};
// 获取当前tab标签
const getCurrentTabLabel = () => {
const currentTab = approvalTabs.value.find(tab => tab.key === activeTab.value);
return currentTab ? currentTab.label : '';
};
// 查看详情
const viewDetail = (item) => {
uni.navigateTo({
url: `/pages/tasks/approvalDetail?id=${item.id}&title=${encodeURIComponent(item.title)}&status=${item.status}&applicant=${encodeURIComponent(item.applicant)}&applyTime=${encodeURIComponent(item.applyTime)}&businessType=${encodeURIComponent(item.businessType)}&priority=${item.priority}&amount=${item.amount ? encodeURIComponent(item.amount) : ''}`
});
};
// 头部相关方法
const goBack = () => {
uni.navigateBack();
};
const showMoreOptions = () => {
uni.showActionSheet({
itemList: ["刷新", "返回首页"],
success: (res) => {
switch (res.tapIndex) {
case 0:
// 刷新数据
updateTabCounts();
uni.showToast({ title: "数据已刷新", icon: "success" });
break;
case 1:
uni.reLaunch({
url: "/pages/index/index",
});
uni.showToast({ title: "已返回工作台", icon: "success" });
break;
}
},
});
};
// 页面加载时处理URL参数
onMounted(() => {
const pages = getCurrentPages();
const currentPage = pages[pages.length - 1];
const options = currentPage.options;
// 如果URL中有activeTab参数则设置为对应的tab
if (options.activeTab) {
activeTab.value = options.activeTab;
}
// 初始化计数
updateTabCounts();
});
</script>
<style lang="scss" scoped>
// 变量定义
$border-radius: 16rpx;
$border-radius-small: 12rpx;
$border-radius-badge: 20rpx;
$spacing-small: 12rpx;
$spacing-medium: 20rpx;
$spacing-large: 30rpx;
$transition: all 0.3s ease;
.main-data-page {
background: var(--background);
min-height: 100vh;
padding-top: calc(var(--status-bar-height) + 88rpx);
padding-bottom: 40rpx;
.main-container {
padding: 24rpx;
}
}
// 审批状态tabs
.approval-tabs {
display: flex;
background: var(--surface);
border-radius: $border-radius;
margin-bottom: $spacing-large;
box-shadow: var(--shadow-md);
border: 1rpx solid var(--border-light);
overflow: hidden;
.tab-item {
flex: 1;
display: flex;
align-items: center;
justify-content: center;
padding: 24rpx 16rpx;
font-size: 28rpx;
color: var(--text-secondary);
background: var(--surface);
transition: $transition;
position: relative;
&.active {
background: var(--primary-color);
color: var(--white);
font-weight: 600;
.tab-badge {
background: rgba(255, 255, 255, 0.3);
}
}
.tab-badge {
background: var(--error);
color: var(--white);
font-size: 20rpx;
padding: 4rpx 8rpx;
border-radius: $border-radius-badge;
margin-left: 8rpx;
min-width: 32rpx;
text-align: center;
line-height: 1;
}
}
}
// 审批列表
.approval-list {
.approval-item {
background: var(--surface);
border-radius: $border-radius;
margin-bottom: $spacing-medium;
padding: $spacing-large;
box-shadow: var(--shadow);
border: 1rpx solid var(--border-light);
transition: $transition;
&:active {
transform: scale(0.98);
box-shadow: var(--shadow-md);
background: var(--surface-hover);
}
.item-header {
display: flex;
justify-content: space-between;
align-items: flex-start;
margin-bottom: $spacing-medium;
.item-title {
font-size: 32rpx;
font-weight: 600;
color: var(--title-color);
flex: 1;
margin-right: $spacing-medium;
}
.item-status {
padding: 8rpx 16rpx;
border-radius: $border-radius-badge;
font-size: 24rpx;
font-weight: 500;
white-space: nowrap;
&.pending {
background: var(--warning-light);
color: var(--warning);
}
&.approved {
background: var(--success-light);
color: var(--success);
}
&.rejected {
background: var(--error-light);
color: var(--error);
}
}
}
.item-content {
margin-bottom: $spacing-medium;
.item-info {
display: flex;
margin-bottom: $spacing-small;
&:last-child {
margin-bottom: 0;
}
.info-label {
font-size: 26rpx;
color: var(--text-muted);
width: 140rpx;
flex-shrink: 0;
}
.info-value {
font-size: 26rpx;
color: var(--text-color);
flex: 1;
}
}
}
.item-footer {
display: flex;
justify-content: space-between;
align-items: center;
.priority {
padding: 6rpx 12rpx;
border-radius: $border-radius-small;
font-size: 22rpx;
font-weight: 500;
&.high {
background: var(--error-light);
color: var(--error);
}
&.medium {
background: var(--warning-light);
color: var(--warning);
}
&.low {
background: var(--success-light);
color: var(--success);
}
}
.item-amount {
font-size: 26rpx;
color: var(--orange);
font-weight: 600;
}
}
}
}
// 空状态
.empty-state {
text-align: center;
padding: 120rpx 60rpx;
.empty-icon {
font-size: 120rpx;
margin-bottom: $spacing-large;
}
.empty-text {
font-size: 28rpx;
color: var(--text-muted);
}
}
// 支持安全区域的设备
@supports (padding: max(0px)) {
.main-data-page {
padding-top: calc(
var(--status-bar-height) + 88rpx + env(safe-area-inset-top)
);
}
}
</style>