You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
crmeb/app/pages/supply_chain/approval/index.vue

275 lines
6.6 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<view class="approval-page">
<view class="content">
<!-- 审批状态筛选 -->
<view class="filter-section">
<view class="filter-tab" :class="activeStatus === 'all' ? 'active' : ''" @click="activeStatus = 'all'">全部</view>
<view class="filter-tab" :class="activeStatus === 'pending' ? 'active' : ''" @click="activeStatus = 'pending'">待处理</view>
<view class="filter-tab" :class="activeStatus === 'processed' ? 'active' : ''" @click="activeStatus = 'processed'">已处理</view>
</view>
<!-- 审批列表 -->
<view class="approval-list">
<view class="approval-item" v-for="(item, index) in filteredApprovals" :key="index">
<view class="item-header">
<view class="header-left">
<text class="approval-type">{{ item.type }}</text>
<text class="approval-status" :class="statusClassMap[item.status]">{{ item.status }}</text>
</view>
<text class="approval-time">{{ item.time }}</text>
</view>
<view class="item-body">
<view class="info-item">
<text class="label">申请人</text>
<text class="value">{{ item.applicant }}</text>
</view>
<view class="info-item">
<text class="label">申请内容</text>
<text class="value">{{ item.content }}</text>
</view>
<view class="info-item" v-if="item.amount">
<text class="label">申请数量</text>
<text class="value">{{ item.amount }}</text>
</view>
</view>
<view class="item-footer" v-if="item.status === '待处理'">
<view class="reject-btn" @click="rejectApproval(item.id)">拒绝</view>
<view class="approve-btn" @click="approveApproval(item.id)">同意</view>
</view>
<view class="item-footer" v-else>
<text class="process-result">{{ item.result || '' }}</text>
</view>
</view>
</view>
<!-- 空状态 -->
<view class="empty-state" v-if="filteredApprovals.length === 0">
<text class="iconfont icon-wushuju"></text>
<text class="empty-text">暂无审批单据</text>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
activeStatus: 'all',
statusClassMap: {
'待处理': 'status-pending',
'已处理': 'status-processed'
},
approvals: [
{ id: 1, type: '采购申请', status: '待处理', time: '2026-03-07 10:00', applicant: '张三', content: '采购有机蔬菜100斤', amount: 100 },
{ id: 2, type: '领用申请', status: '待处理', time: '2026-03-07 09:30', applicant: '李四', content: '领用维修耗材', amount: 50 },
{ id: 3, type: '采购申请', status: '已处理', time: '2026-03-06 16:00', applicant: '王五', content: '采购新鲜水果50斤', amount: 50, result: '已同意' },
{ id: 4, type: '领用申请', status: '已处理', time: '2026-03-06 14:00', applicant: '赵六', content: '领用办公用品', amount: 30, result: '已拒绝' }
]
};
},
computed: {
filteredApprovals() {
if (this.activeStatus === 'all') {
return this.approvals;
} else if (this.activeStatus === 'pending') {
return this.approvals.filter(item => item.status === '待处理');
} else if (this.activeStatus === 'processed') {
return this.approvals.filter(item => item.status === '已处理');
}
}
},
methods: {
approveApproval(id) {
// 模拟同意审批
uni.showToast({
title: '审批已同意',
icon: 'success'
});
// 更新审批状态
const approval = this.approvals.find(item => item.id === id);
if (approval) {
approval.status = '已处理';
approval.result = '已同意';
}
},
rejectApproval(id) {
// 模拟拒绝审批
uni.showToast({
title: '审批已拒绝',
icon: 'none'
});
// 更新审批状态
const approval = this.approvals.find(item => item.id === id);
if (approval) {
approval.status = '已处理';
approval.result = '已拒绝';
}
}
}
};
</script>
<style lang="scss">
.approval-page {
.content {
padding: 30rpx;
.filter-section {
display: flex;
margin-bottom: 30rpx;
background-color: #fff;
border-radius: 10rpx;
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.1);
.filter-tab {
flex: 1;
height: 80rpx;
display: flex;
align-items: center;
justify-content: center;
font-size: 26rpx;
color: #666;
position: relative;
&.active {
color: #409EFF;
&::after {
content: '';
position: absolute;
bottom: 0;
left: 50%;
transform: translateX(-50%);
width: 60rpx;
height: 4rpx;
background-color: #409EFF;
border-radius: 2rpx;
}
}
}
}
.approval-list {
.approval-item {
background-color: #fff;
border-radius: 10rpx;
padding: 20rpx;
margin-bottom: 20rpx;
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.1);
.item-header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 15rpx;
.header-left {
display: flex;
align-items: center;
.approval-type {
font-size: 26rpx;
font-weight: 600;
color: #333;
margin-right: 20rpx;
}
.approval-status {
padding: 5rpx 15rpx;
border-radius: 15rpx;
font-size: 20rpx;
}
.status-pending {
background-color: #E6F7FF;
color: #409EFF;
}
.status-processed {
background-color: #F6FFED;
color: #52C41A;
}
}
.approval-time {
font-size: 22rpx;
color: #999;
}
}
.item-body {
margin-bottom: 15rpx;
.info-item {
display: flex;
margin-bottom: 10rpx;
.label {
width: 100rpx;
font-size: 24rpx;
color: #666;
}
.value {
flex: 1;
font-size: 24rpx;
color: #333;
}
}
}
.item-footer {
display: flex;
align-items: center;
justify-content: flex-end;
.reject-btn,
.approve-btn {
padding: 8rpx 24rpx;
border-radius: 16rpx;
font-size: 22rpx;
margin-left: 20rpx;
}
.reject-btn {
background-color: #f5f5f5;
color: #666;
}
.approve-btn {
background-color: #409EFF;
color: #fff;
}
.process-result {
font-size: 22rpx;
color: #999;
}
}
}
}
.empty-state {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 400rpx;
.iconfont {
font-size: 80rpx;
color: #ddd;
margin-bottom: 20rpx;
}
.empty-text {
font-size: 24rpx;
color: #999;
}
}
}
}
</style>