uniapp-app/pages_app/myWelfare/welfareDetail.vue
2026-02-02 17:44:10 +08:00

392 lines
8.4 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>
<navBar :title="'福利明细'" />
<view class="welfare-detail-page">
<!-- Tab 切换栏 -->
<view class="segmented-control">
<view
class="tab-item"
:class="{ active: activeTab === 1 }"
@click="switchTab(1)"
>
<text class="tab-text">视频下载</text>
</view>
<view class="divider"></view>
<view
class="tab-item"
:class="{ active: activeTab === 2 }"
@click="switchTab(2)"
>
<text class="tab-text">课件下载</text>
</view>
<view class="divider"></view>
<view
class="tab-item"
:class="{ active: activeTab === 6 }"
@click="switchTab(6)"
>
<text class="tab-text">查找文献</text>
</view>
</view>
<!-- 表格头部 -->
<view class="table-header">
<text class="col reason">原因</text>
<text class="col time">时间</text>
<text class="col count">次数</text>
</view>
<!-- 列表数据区域 -->
<scroll-view
class="table-body"
scroll-y
:show-scrollbar="false"
refresher-enabled
:refresher-triggered="refreshing"
@refresherrefresh="onRefresh"
@scrolltolower="onLoadMore"
:lower-threshold="100"
>
<view
class="row"
v-for="(item, index) in filteredList"
:key="index"
>
<text class="cell reason">{{ item.reason }}</text>
<text class="cell time">{{ item.time }}</text>
<text class="cell count" >{{ item.count }}</text>
</view>
<!-- 空数据状态 -->
<view v-if="!loading && filteredList.length === 0" class="empty-wrap">
<empty />
</view>
<!-- 加载更多提示 -->
<view v-if="loading" class="loading">
<text>加载中...</text>
</view>
<!-- 没有更多数据提示 -->
<!-- <view v-if="isLastPage && filteredList.length > 0" class="no-more">
<text>没有更多数据了</text>
</view> -->
</scroll-view>
</view>
</template>
<script setup>
import { ref, computed, onMounted } from 'vue';
import navBar from '@/components/navBar/navBar.vue';
import api from '@/api/api';
import dayjs from 'dayjs';
import empty from '@/components/empty/empty.vue';
// 当前选中的 Tab0: 视频下载, 1: 课件下载, 2: 查找文献)
const activeTab = ref(1);
const page = ref(1);
const pageSize = ref(10);
// 福利明细列表数据
const welfareList = ref([]);
// 加载状态
const loading = ref(false);
const refreshing = ref(false);
const isLastPage = ref(false);
// 根据 activeTab 过滤后的列表数据
const filteredList = computed(() => {
if (!welfareList.value || welfareList.value.length === 0) {
return [];
}
const typeMap = {
0: '视频下载',
1: '课件下载',
2: '查找文献'
};
const currentType = typeMap[activeTab.value];
return welfareList.value;
});
// Tab 切换
const switchTab = (index) => {
if (activeTab.value === index) return;
activeTab.value = index;
page.value = 1;
pageSize.value = 10;
welfareList.value = [];
isLastPage.value = false;
loading.value = false;
refreshing.value = false;
// 切换 Tab 时重新加载数据
loadWelfareDetail();
};
// 加载福利明细数据
const loadWelfareDetail = () => {
if (loading.value) return;
loading.value = true;
console.log(api);
// 调用 API 获取数据
api.welfareList({
type: activeTab.value,
page: page.value,
pageSize: pageSize.value
}).then(res => {
console.log(res);
if (res.code ==1) {
// 兼容两种数据结构:直接数组或包含 list 的对象
let rawList = [];
if (Array.isArray(res.data)) {
rawList = res.data;
isLastPage.value = false;
} else if (res.data.list && Array.isArray(res.data.list)) {
rawList = res.data.list;
isLastPage.value = !!res.data.isLastPage;
} else {
if (page.value === 1) {
welfareList.value = [];
}
isLastPage.value = false;
return;
}
// 将接口返回的数据映射到页面需要的格式
const formattedList = rawList.map(item => {
let timeStr = item.create_date || item.time || '';
// 使用 dayjs 格式化日期,只显示年月日
if (timeStr) {
timeStr = dayjs(timeStr).format('YYYY-MM-DD');
}
return {
reason: item.name || item.reason || '',
time: timeStr,
count: item.count_num ? parseInt(item.count_num) : (item.count || 0)
};
});
// 如果是第一页或刷新,替换数据;否则追加数据
if (page.value === 1 || refreshing.value) {
welfareList.value = formattedList;
} else {
welfareList.value = [...welfareList.value, ...formattedList];
}
} else {
if (page.value === 1) {
welfareList.value = [];
}
isLastPage.value = false;
}
}).catch(err => {
console.error('获取福利明细失败:', err);
if (page.value === 1) {
welfareList.value = [];
}
uni.showToast({
title: '获取福利明细失败',
icon: 'none'
});
}).finally(() => {
loading.value = false;
refreshing.value = false;
});
};
// 下拉刷新
const onRefresh = () => {
refreshing.value = true;
page.value = 1;
isLastPage.value = false;
loadWelfareDetail();
};
// 上拉加载更多
const onLoadMore = () => {
if (isLastPage.value || loading.value) return;
page.value += 1;
loadWelfareDetail();
};
onMounted(() => {
loadWelfareDetail();
});
</script>
<style scoped lang="scss">
// 变量定义
$bg-color: #f5f6f7;
$text-primary: #333333;
$text-secondary: #666666;
$text-light: #999999;
$border-color: #e5e5e5;
$white: #ffffff;
$theme-color: #8B2316;
$table-header-bg: #8B2316;
$divider-color: #cccccc;
$nav-height: 180rpx;
$segmented-height: 80rpx;
$table-header-height: 70rpx;
.welfare-detail-page {
min-height: 100vh;
background-color: $bg-color;
padding-top: $nav-height;
}
// Tab 切换栏
.segmented-control {
position: fixed;
top: calc(var(--status-bar-height) + 44px);
left: 0;
right: 0;
z-index: 10;
height: $segmented-height;
background-color: $white;
display: flex;
align-items: center;
padding: 0 30rpx;
border-bottom: 1rpx solid $border-color;
.tab-item {
flex: 1;
display: flex;
align-items: center;
justify-content: center;
height: 100%;
position: relative;
.tab-text {
font-size: 28rpx;
color: $text-secondary;
transition: all 0.3s ease;
}
&.active {
.tab-text {
color: $theme-color;
font-size: 30rpx;
font-weight: 500;
}
}
}
.divider {
width: 2rpx;
height: 40rpx;
background-color: $divider-color;
}
}
// 表格头部
.table-header {
position: fixed;
top: calc(var(--status-bar-height) + 44px + $segmented-height);
left: 0;
right: 0;
z-index: 5;
background: $table-header-bg;
color: $white;
display: flex;
justify-content: space-between;
align-items: center;
padding: 20rpx 30rpx;
font-size: 30rpx;
font-weight: 500;
height: $table-header-height;
box-sizing: border-box;
.col {
flex: 1;
text-align: center;
&.reason {
text-align: left;
}
&.time {
text-align: center;
}
&.count {
text-align: right;
}
}
}
// 列表数据区域
.table-body {
position: fixed;
left: 0;
right: 0;
top: calc(var(--status-bar-height) + 44px + $segmented-height + $table-header-height);
height: calc(100vh - var(--status-bar-height) - 44px - $segmented-height - $table-header-height);
background-color: #fff;
}
// 列表行
.row {
display: flex;
justify-content: space-between;
align-items: center;
padding: 24rpx 30rpx;
border-bottom: 2rpx solid #eee;
// background-color: #f5f5f5;
font-size: 28rpx;
color: $text-primary;
.cell {
flex: 1;
text-align: center;
&.reason {
text-align: left;
color: $text-primary;
}
&.time {
text-align: center;
color: $text-secondary;
}
&.count {
text-align: right;
color: $text-primary;
&.negative {
color: #e34d4d;
}
}
}
}
// 空数据状态
.empty-wrap {
padding-top: 200rpx;
display: flex;
flex-direction: column;
align-items: center;
color: #bdbdbd;
.empty-text {
margin-top: 20rpx;
font-size: 30rpx;
}
}
// 加载状态
.loading, .no-more {
text-align: center;
color: $text-light;
padding: 30rpx 0;
font-size: 26rpx;
text {
display: inline-block;
padding: 10rpx 20rpx;
border-radius: 20rpx;
}
}
</style>