<template> <view class="content"> <u-subsection mode="subsection" :active-color="mainColor" :list="tabList" :current="current" @change="tabsChange"></u-subsection> <swiper :current="swiperCurrent" @animationfinish="animationfinish" class="swiper-box"> <swiper-item class="swiper-item" v-for="(item, index1) in tabList" :key="index1"> <scroll-view scroll-y class="scroll-box" @scrolltolower="handleLoadMore" :refresher-enabled="true" :refresher-triggered="triggered" :refresher-threshold="100" refresher-background="white" @refresherrefresh="onRefresh" @refresherrestore="onRestore"> <view class="filter-date-box"> <u-icon name="arrow-left" color="#999999" size="48" @click="previousMonth()"></u-icon> <text class="filter-date">{{item.year}}年{{item.month}}月</text> <u-icon name="arrow-right" color="#999999" size="48" @click="nextMonth()"></u-icon> </view> <view class="rank-box"> <u-line-progress :active-color="mainColor" :percent="item.percent" height="40"></u-line-progress> <text class="rank-text" v-if="index1 == 1">签到人次:{{item.signCount}}人</text> </view> <u-card :head-border-bottom="false" :foot-border-top="false" padding="0px" margin="0" borderRadius="0" v-for="(site, index2) in item.tableList" :key="index2" class="class-card"> <view class="class-content" slot="body"> <view class="info-sort"> <u-image :src="index2 == 0 ? iconPath1 : (index2 == 1 ? iconPath2 : iconPath3)" mode="aspectFit" width="24px" height="24px" v-if="index2 < 3"></u-image> <text v-else>{{index2 + 1}}</text> </view> <view class="class-info-text">{{site.name}} {{index1 == 1 ? site.stuSignNo + '课时' :''}}</view> <view class="class-info-img"> <u-avatar :src="site.url" size="100"></u-avatar> </view> </view> </u-card> <u-divider v-if="item.isOver" bg-color="transparent">没有更多了</u-divider> </scroll-view> </swiper-item> </swiper> <u-top-tips ref="uTips"></u-top-tips> </view> </template> <script> import { mapGetters } from 'vuex' const NET = require('@/utils/request') const API = require('@/config/api') export default { computed: { ...mapGetters([ 'mainColor', 'handleCustomStyle', 'handleDefaultCustomStyle', ]) }, data() { return { iconPath1: API.getServerImg + 'jinpai.png', iconPath2: API.getServerImg + 'yinpai.png', iconPath3: API.getServerImg + 'tongpai.png', triggered: false, tabList: [{ name: '续费率', isOver: false, pageIndex: 1, year: '', month: '', percent: 0, signCount: '', tableList: [], }, { name: '签到率', isOver: false, pageIndex: 1, year: '', month: '', percent: 0, signCount: '', tableList: [], }], current: 0, swiperCurrent: 0, } }, onLoad() { this.tabList.forEach(site => { site.year = new Date().getFullYear() site.month = new Date().getMonth() + 1 }) this.getTableList(0) this.getTableList(1) this.getRank(0) this.getRank(1) }, onReady() {}, methods: { // tab页面切换 tabsChange(index) { this.swiperCurrent = index; }, // swiper滑动结束,分别设置tabs和swiper的状态 animationfinish(e) { let current = e.detail.current; this.swiperCurrent = current; this.current = current; }, // 上一个月 previousMonth() { if (this.tabList[this.current].month == 1) { this.tabList[this.current].year-- this.tabList[this.current].month = 12 } else { this.tabList[this.current].month-- } this.onRefresh(1) }, // 下一个月 nextMonth() { if (this.tabList[this.current].month == 12) { this.tabList[this.current].year++ this.tabList[this.current].month = 1 } else { this.tabList[this.current].month++ } this.onRefresh(1) }, // 下拉刷新 onRefresh(type) { if (!this.triggered) { if (type != 1) { this.triggered = true } this.tabList[this.current].isOver = false this.tabList[this.current].pageIndex = 1 this.tabList[this.current].tableList = [] this.getTableList(this.current) this.getRank(this.current) } }, // 重置下拉刷新状态 onRestore() { this.triggered = 'restore' this.triggered = false }, // 懒加载 handleLoadMore() { if (!this.tabList[this.current].isOver) { this.tabList[this.current].pageIndex++ this.getTableList(this.current) } }, // 获取列表数据 getTableList(index) { NET.request(index == 0 ? API.getRenewRankingList : API.getSignRankingList, { date: this.tabList[index].year + '-' + this.tabList[index].month, page: this.tabList[index].pageIndex, size: 20, }, 'POST').then(res => { this.triggered = false this.tabList[index].tableList = this.tabList[index].tableList.concat(res.data.row) this.tabList[index].isOver = res.data.row.length != 20 }).catch(error => { this.triggered = false this.$refs.uTips.show({ title: error.message, type: 'warning', }) }) }, // 获取比率 getRank(index) { NET.request(index == 0 ? API.getRenewPercent : API.getSignPercent, { date: this.tabList[index].year + '-' + this.tabList[index].month, }, 'POST').then(res => { this.tabList[index].percent = parseFloat(res.data.percent) this.tabList[index].signCount = JSON.stringify(res.data.signCount) }).catch(error => { this.$refs.uTips.show({ title: error.message, type: 'warning', }) }) } }, } </script> <style> page { width: 100%; height: 100%; background-color: #f7f7f7; } </style> <style lang="scss" scoped> @import "@/static/css/themes.scss"; .content { width: 100%; float: left; .swiper-box { height: calc(100vh - 34px); .swiper-item { height: calc(100vh - 34px); .scroll-box { width: 100%; height: calc(100vh - 34px); .filter-date-box { height: 48px; display: flex; justify-content: space-between; align-items: center; padding: 10px 15px; background-color: #FFFFFF; .filter-date { text-align: center; font-size: 16px; font-weight: bold; line-height: 28px; flex: 1; } } .rank-box { height: 30px; display: flex; justify-content: space-between; align-items: center; padding: 0 15px; background-color: #FFFFFF; u-line-progress { flex: 1; } .rank-text { padding-left: 10px; font-size: 11px; color: $mainColor; } } .class-card { border-bottom: 1px solid #cccccc; .class-content { padding: 5px 15px; display: flex; align-items: center; .info-sort { width: 34px; display: flex; align-items: center; justify-content: center; margin-right: 5px; } .class-info-img { width: 50px; height: 50px; margin-right: 5px; display: flex; align-items: center; justify-content: center; } .class-info-text { line-height: 20px; font-size: 14px; flex: 1; } } } .class-card:last-child { border-bottom: none; } } } } u-divider { padding: 10px 0; display: flex; } } </style>