Files
SmartParks_uniapp/pages/sys/workbench/oa/oa.vue

454 lines
9.5 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="oa-container">
<!-- 搜索框 -->
<view class="oa-search">
<view class="search-box">
<image src="/static/ic_search_gray.png" class="search-icon" />
<text class="search-placeholder">申批名称内容发起人编号</text>
</view>
</view>
<!-- tab栏 -->
<view class="oa-tabs">
<view v-for="(tab, idx) in tabs" :key="idx" :class="['oa-tab', {active: idx === activeTab}]"
@click="changeTab(idx)">
{{ tab }}
<view v-if="idx === activeTab" class="tab-underline"></view>
</view>
</view>
<!-- 列表区 -->
<view class="oa-list-container">
<scroll-view
v-for="(tab, idx) in tabs"
:key="idx"
v-show="idx === activeTab"
class="oa-list-scroll"
scroll-y
:refresher-enabled="false">
<view v-for="(item, index) in tabData[idx]" :key="index" class="oa-card" @click="goToDetail(item)">
<view class="card-row">
<view class="card-type">{{ item.type }}</view>
<view class="card-status-tag" :class="item.statusClass">{{ item.status }}</view>
</view>
<view class="card-info">
<view class="card-leave-type">请假类型<text class="card-leave-type">{{ item.leaveType }}</text></view>
<view class="card-leave-type">
<text>开始时间{{ item.startTime }}</text>
</view>
<view class="card-leave-type">
<text>结束时间{{ item.endTime }}</text>
</view>
</view>
<view class="card-footer">
<view class="card-user">
<view class="user-avatar" :style="{backgroundColor: item.avatarColor}">{{ item.avatarText }}</view>
<text class="user-name">{{ item.userName }}</text>
</view>
<text class="card-datetime">{{ item.dateTime }}</text>
</view>
</view>
</scroll-view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
tabs: ['待办', '已办', '已发起'],
activeTab: 2, // 默认选中已发起
tabData: [
[], // 待办
[], // 已办
[] // 已发起
],
tabLoaded: [false, false, false], // 每个tab是否已加载
loading: false
}
},
computed: {
list() {
return this.tabData[this.activeTab];
}
},
created() {
this.loadAllTabsData(); // 预加载所有标签页数据
},
methods: {
goBack() {
uni.navigateBack();
},
// 跳转到详情页
goToDetail(item) {
uni.navigateTo({
url: './oaDetail'
});
},
async changeTab(idx) {
this.activeTab = idx;
// 移除切换标签时的加载逻辑,避免重复调用接口
/*
if (!this.tabLoaded[idx]) {
await this.loadTabData(idx);
}
*/
},
async loadTabData(idx) {
this.loading = true;
// 模拟接口请求不同tab返回不同mock数据
let data = [];
if (idx === 0) { // 待办
data = [
{
type: '请假',
leaveType: '病假',
status: '待办',
statusClass: 'orange',
startTime: '2025-07-13',
endTime: '2025-07-15',
userName: '余永乐',
avatarText: '余',
avatarColor: '#4B7BF5',
dateTime: '07-12 18:28:22'
}
];
} else if (idx === 1) { // 已办
data = [
{
type: '请假',
leaveType: '病假',
status: '已通过',
statusClass: 'green',
startTime: '2025-07-13',
endTime: '2025-07-15',
userName: '余永乐',
avatarText: '余',
avatarColor: '#4B7BF5',
dateTime: '07-12 18:28:22'
}
];
} else { // 已发起
data = [
{
type: '请假',
leaveType: '病假',
status: '已通过',
statusClass: 'green',
startTime: '2025-07-13',
endTime: '2025-07-15',
userName: '余永乐',
avatarText: '余',
avatarColor: '#4B7BF5',
dateTime: '07-12 18:28:22'
},
{
type: '请假',
leaveType: '病假',
status: '待审核',
statusClass: 'orange',
startTime: '2025-07-13',
endTime: '2025-07-15',
userName: '余永乐',
avatarText: '余',
avatarColor: '#4B7BF5',
dateTime: '07-12 18:28:22'
},
{
type: '请假',
leaveType: '病假',
status: '待审核',
statusClass: 'orange',
startTime: '2025-07-13',
endTime: '2025-07-15',
userName: '余永乐',
avatarText: '余',
avatarColor: '#4B7BF5',
dateTime: '07-12 18:28:22'
},
{
type: '请假',
leaveType: '病假',
status: '待审核',
statusClass: 'orange',
startTime: '2025-07-13',
endTime: '2025-07-15',
userName: '余永乐',
avatarText: '余',
avatarColor: '#4B7BF5',
dateTime: '07-12 18:28:22'
},
{
type: '请假',
leaveType: '病假',
status: '待审核',
statusClass: 'orange',
startTime: '2025-07-13',
endTime: '2025-07-15',
userName: '余永乐',
avatarText: '余',
avatarColor: '#4B7BF5',
dateTime: '07-12 18:28:22'
},
{
type: '请假',
leaveType: '病假',
status: '待审核',
statusClass: 'orange',
startTime: '2025-07-13',
endTime: '2025-07-15',
userName: '余永乐',
avatarText: '余',
avatarColor: '#4B7BF5',
dateTime: '07-12 18:28:22'
},
{
type: '请假',
leaveType: '病假',
status: '待审核',
statusClass: 'orange',
startTime: '2025-07-13',
endTime: '2025-07-15',
userName: '余永乐',
avatarText: '余',
avatarColor: '#4B7BF5',
dateTime: '07-12 18:28:22'
},
{
type: '请假',
leaveType: '病假',
status: '待审核',
statusClass: 'orange',
startTime: '2025-07-13',
endTime: '2025-07-15',
userName: '余永乐',
avatarText: '余',
avatarColor: '#4B7BF5',
dateTime: '07-12 18:28:22'
}
];
}
// 模拟网络延迟
await new Promise(res => setTimeout(res, 300));
this.$set(this.tabData, idx, data);
this.$set(this.tabLoaded, idx, true);
this.loading = false;
},
// 添加预加载所有标签页数据的方法
async loadAllTabsData() {
// 并行加载所有标签页数据,提高加载速度
const loadPromises = [0, 1, 2].map((index) => {
return this.loadTabData(index);
});
await Promise.all(loadPromises);
// 标记所有标签页已加载
this.tabLoaded = [true, true, true];
}
}
}
</script>
<style scoped>
.oa-container {
height: 100vh;
background: #f7f7f7;
display: flex;
flex-direction: column;
overflow: hidden;
}
.oa-back {
position: absolute;
left: 37rpx;
width: 15rpx;
height: 33rpx;
}
.oa-title {
font-size: 36rpx;
color: #000;
}
.oa-search {
background: #fff;
padding: 20rpx 30rpx;
flex-shrink: 0;
}
.search-box {
height: 70rpx;
background: #F7F7F7;
border-radius: 35rpx;
display: flex;
align-items: center;
justify-content: flex-start;
padding: 0 30rpx;
}
.search-icon {
width: 30rpx;
height: 30rpx;
margin-right: 10rpx;
}
.search-placeholder {
color: #9A9A9A;
font-size: 28rpx;
}
.oa-tabs {
display: flex;
align-items: center;
justify-content: space-around;
background: #fff;
height: 80rpx;
border-bottom: 1px solid #f0f0f0;
flex-shrink: 0;
}
.oa-tab {
flex: 1;
text-align: center;
font-size: 32rpx;
color: #737373;
position: relative;
padding: 0 0 10rpx 0;
cursor: pointer;
}
.oa-tab.active {
color: #007CFF;
font-weight: bold;
}
.tab-underline {
width: 60rpx;
height: 6rpx;
background: #2186FF;
border-radius: 3rpx;
margin: 0 auto;
margin-top: 8rpx;
}
.oa-list-container {
flex: 1;
position: relative;
}
.oa-list-scroll {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
padding: 0 35rpx;
overflow-y: auto;
padding-bottom: 50rpx;
height: calc(100vh - 80rpx - 32rpx - 150rpx); /* 减去顶部区域高度 */
box-sizing: border-box;
}
.oa-list {
margin: 25rpx 0 0 0;
padding: 0 35rpx;
flex: 1;
overflow-y: auto;
padding-bottom: 50rpx;
}
.oa-card {
background: #fff;
border-radius: 10rpx;
margin-bottom: 26rpx;
padding: 20rpx 20rpx 20rpx 20rpx;
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
}
.card-row {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 46rpx;
}
.card-type {
width: 126rpx;
height: 46rpx;
font-weight: 600;
font-size: 32rpx;
padding-left: 10rpx;
padding-top: 7rpx;
border-radius: 15rpx;
color: #fff;
background: linear-gradient(90deg, #007CFF 0%, #FFFFFF 100%);
}
.card-status-tag {
font-size: 28rpx;
}
.card-status-tag.orange {
color: #F27A0F;
}
.card-status-tag.green {
color: #0AC88F;
}
.card-status-tag.gray {
color: #8F8F8F;
background-color: rgba(143, 143, 143, 0.1);
border: 1px solid #8F8F8F;
}
.card-info {
font-size: 26rpx;
color: #333;
margin-bottom: 42rpx;
}
.card-leave-type {
color: #626262;
font-size: 28;
margin-bottom: 24rpx;
}
.card-footer {
display: flex;
align-items: center;
justify-content: space-between;
}
.card-user {
display: flex;
align-items: center;
}
.user-avatar {
width: 54rpx;
height: 54rpx;
border-radius: 27rpx;
background-color: #688CFF;
color: #fff;
display: flex;
align-items: center;
justify-content: center;
font-size: 24rpx;
margin-right: 18rpx;
}
.user-name {
font-size: 24rpx;
color: #626262;
}
.card-datetime {
font-size: 24rpx;
color: #626262;
}
</style>