| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448 |
- <template>
- <view class="container">
- <view @click="aaaa">asdfasdfdasfads</view>
- <view class="icon-title-navBar-box">
- <view class="nav-bar-icon" @click="handleBack"></view>
- <view class="nav-bar-title">学习</view>
- </view>
- <!-- z-paging 列表 -->
- <z-paging ref="paging" @scroll="onScroll" @query="loadData" :refresher-enabled="false"
- :loading-more-enabled="false" :auto="false" :fixed="false" :hide-empty-view="true">
- <!-- 单元列表 -->
- <view v-for="(danyuan, danyuanIndex) in danyuanList" :key="danyuan.danyuanId"
- :id="'danyuan-' + danyuanIndex" class="danyuan-item">
- <!-- 当前学科信息 -->
- <view class="subject-info" v-if="subjectDetail">
- <text class="course-name">{{ subjectDetail.chanpinName }}</text>
- <text class="course-name">等级:{{ subjectDetail.dengjiName }}</text>
- <text class="course-name">版本:{{ subjectDetail.dengjiName }}</text>
- <text class="course-name">单元:{{ subjectDetail.curDanyuanName }}</text>
- <text class="course-name">课程:{{ subjectDetail.chanpinName }}</text>
- </view>
- <!-- 单元标题 -->
- <view class="danyuan-header">
- <text class="danyuan-title">{{ danyuan.danyuanName }}</text>
- <text class="danyuan-intro">{{ danyuan.danyuanIntro }}</text>
- </view>
- <!-- 节列表 -->
- <view v-if="danyuan.jieList && danyuan.jieList.length > 0">
- <view v-for="jie in danyuan.jieList" :key="jie.jieId" class="jie-item">
- <text class="jie-name">{{ jie.number }}. {{ jie.jieName }}</text>
- <text class="jie-desc">{{ jie.jieIntro }}</text>
- </view>
- </view>
- <!-- 无课程内容提示 -->
- <view v-else class="empty-jie">
- <text class="empty-text">暂无课程内容</text>
- </view>
- </view>
- </z-paging>
- <!-- 回到顶部按钮 -->
- <view v-if="showBackToTop" class="back-to-top" @click="scrollToTop">
- <text class="back-to-top-icon">↑</text>
- <text class="back-to-top-text">顶部</text>
- </view>
- <!-- 当前单元提示 -->
- <view v-if="currentUnitName" class="current-unit-tip">
- <text>{{ currentUnitName }}</text>
- </view>
-
- <CustomTabBar :currentTabNumber="0"></CustomTabBar>
-
- </view>
- </template>
- <script>
- import {
- shuxueChanpinBanben
- } from "@/api/chanpinneirong.js"
- import CustomTabBar from '@/components/custom-tabbar/custom-tabbar.vue';
- export default {
- data() {
- return {
- activeSubjectId: 2,
- // 学科详情数据
- subjectDetail: null,
- // 单元列表
- danyuanList: [],
- // 当前单元名称
- currentUnitName: '',
- // 单元位置信息
- unitPositions: [],
- // 新增:是否显示回到顶部按钮
- showBackToTop: false,
- // 新增:显示回到顶部按钮的阈值(滚动多少距离后显示)
- backToTopThreshold: 500
- }
- },
- components: {
- CustomTabBar
- },
- mounted() {
- //初始化加载数据
- this.$nextTick(() => {
- // this.$refs.paging.reload()
- })
- },
- methods: {
- aaaa(){
- this.$refs.paging.reload()
- },
- handleBack() {
- },
- // z-paging 加载数据
- async loadData() {
- // 目前只处理数学学科
- if (this.activeSubjectId !== 2) {
- this.$refs.paging.complete([])
- return
- }
- try {
- // 调用数学API
- const req = {
- banbenId: 7
- }
- const res = await shuxueChanpinBanben(req)
- if (res.code === 0 && res.data) {
- // 直接使用后端返回的数据
- this.subjectDetail = res.data
- this.danyuanList = res.data.danyuanList || []
- // 告诉z-paging加载完成
- this.$refs.paging.complete(this.danyuanList)
- // 计算单元位置
- this.$nextTick(() => {
- this.calculateUnitPositions()
- })
- }
- } catch (error) {
- console.error('加载失败:', error)
- this.$refs.paging.complete(false)
- }
- },
- // 计算单元位置
- calculateUnitPositions() {
- if (!this.danyuanList || this.danyuanList.length === 0) return
- // 清空位置信息
- this.unitPositions = []
- // 使用 $nextTick 确保DOM已更新
- this.$nextTick(() => {
- // 稍微延迟确保渲染完成
- setTimeout(() => {
- const query = uni.createSelectorQuery().in(this)
- // 一次性查询所有单元
- const selectors = this.danyuanList.map((_, index) => {
- return query.select(`#danyuan-${index}`).boundingClientRect()
- })
- // 执行查询
- query.exec((results) => {
- if (results && results.length === this.danyuanList.length) {
- results.forEach((rect, index) => {
- if (rect) {
- // 保存相对位置(注意:这是相对于屏幕的位置)
- this.$set(this.unitPositions, index, {
- top: rect.top,
- height: rect.height,
- name: this.danyuanList[index]
- .danyuanName
- })
- }
- })
- console.log('单元位置计算完成:', this.unitPositions)
- }
- })
- }, 100)
- })
- },
- // 滚动事件 - 修改后版本
- onScroll(e) {
- const scrollTop = e.detail.scrollTop
- console.log('滚动位置:', scrollTop)
- // 新增:控制回到顶部按钮的显示/隐藏
- this.showBackToTop = scrollTop > this.backToTopThreshold
- // 查找当前滚动到的单元
- let currentUnitName = ''
- for (let i = this.unitPositions.length - 1; i >= 0; i--) {
- const position = this.unitPositions[i]
- if (position && scrollTop >= position.top - 50) {
- currentUnitName = position.name
- break
- }
- }
- // 更新当前单元提示
- if (currentUnitName && currentUnitName !== this.currentUnitName) {
- this.currentUnitName = currentUnitName
- console.log('切换到单元:', currentUnitName)
- }
- },
- // 新增:回到顶部方法
- scrollToTop() {
- console.log('执行回到顶部')
- // 方法1: 使用z-paging的scrollToTop方法(最简单)
- if (this.$refs.paging) {
- this.$refs.paging.scrollToTop({
- animated: true,
- duration: 300
- })
- }
- // 方法2: 对于H5环境,额外滚动整个页面
- // #ifdef H5
- setTimeout(() => {
- window.scrollTo({
- top: 0,
- behavior: 'smooth'
- })
- }, 100)
- // #endif
- // 方法3: 对于App环境,使用uni的pageScrollTo
- // #ifdef APP-PLUS
- uni.pageScrollTo({
- scrollTop: 0,
- duration: 300
- })
- // #endif
- // 隐藏回到顶部按钮
- this.showBackToTop = false
- // 可选:显示提示
- uni.showToast({
- title: '回到顶部',
- icon: 'none',
- duration: 800
- })
- }
- }
- }
- </script>
- <style scoped>
- .container {
- height: 100vh;
- background-color: #f8f9fa;
- }
- /* 学科标签页 */
- .subject-tabs {
- background-color: white;
- padding: 20rpx 0;
- border-bottom: 1rpx solid #eee;
- }
- .tabs-scroll {
- white-space: nowrap;
- height: 80rpx;
- }
- .tabs-content {
- display: inline-flex;
- padding: 0 30rpx;
- }
- .tab-item {
- padding: 0 40rpx;
- height: 60rpx;
- display: flex;
- align-items: center;
- justify-content: center;
- }
- .tab-text {
- font-size: 32rpx;
- color: #666;
- position: relative;
- padding: 10rpx 0;
- }
- .tab-item.active .tab-text {
- color: #4a6fe3;
- font-weight: bold;
- }
- .tab-item.active .tab-text::after {
- content: '';
- position: absolute;
- bottom: 0;
- left: 0;
- right: 0;
- height: 4rpx;
- background-color: #4a6fe3;
- border-radius: 2rpx;
- }
- /* 学科信息 */
- .subject-info {
- padding: 30rpx;
- background-color: white;
- margin-bottom: 20rpx;
- }
- .course-name {
- display: block;
- font-size: 36rpx;
- font-weight: bold;
- color: #333;
- margin-bottom: 10rpx;
- }
- .current-info {
- display: block;
- font-size: 28rpx;
- color: #666;
- }
- /* 单元样式 */
- .danyuan-item {
- background-color: white;
- margin: 20rpx;
- border-radius: 16rpx;
- overflow: hidden;
- box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.05);
- margin-bottom: 30rpx;
- }
- .danyuan-header {
- background: #4a6fe3;
- padding: 30rpx;
- color: white;
- }
- .danyuan-title {
- display: block;
- font-size: 32rpx;
- font-weight: bold;
- margin-bottom: 10rpx;
- }
- .danyuan-intro {
- font-size: 28rpx;
- opacity: 0.9;
- }
- /* 节样式 */
- .jie-item {
- padding: 24rpx 30rpx;
- border-bottom: 1rpx solid #f0f0f0;
- }
- .jie-item:last-child {
- border-bottom: none;
- }
- .jie-name {
- display: block;
- font-size: 30rpx;
- font-weight: 500;
- color: #333;
- margin-bottom: 8rpx;
- }
- .jie-desc {
- display: block;
- font-size: 26rpx;
- color: #666;
- }
- /* 空课程提示 */
- .empty-jie {
- padding: 40rpx;
- text-align: center;
- }
- .empty-text {
- font-size: 28rpx;
- color: #999;
- }
- /* 新增:回到顶部按钮样式 */
- .back-to-top {
- position: fixed;
- bottom: 120rpx;
- right: 30rpx;
- width: 100rpx;
- height: 100rpx;
- background-color: rgba(74, 111, 227, 0.9);
- border-radius: 50%;
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- z-index: 999;
- box-shadow: 0 4rpx 20rpx rgba(74, 111, 227, 0.3);
- transition: all 0.3s ease;
- }
- .back-to-top:active {
- transform: scale(0.95);
- background-color: rgba(74, 111, 227, 1);
- }
- .back-to-top-icon {
- font-size: 40rpx;
- color: white;
- font-weight: bold;
- }
- .back-to-top-text {
- font-size: 22rpx;
- color: white;
- margin-top: 4rpx;
- }
- /* 当前单元提示 */
- .current-unit-tip {
- position: fixed;
- top: 200rpx;
- left: 50%;
- transform: translateX(-50%);
- background-color: rgba(74, 111, 227, 0.9);
- color: white;
- padding: 20rpx 40rpx;
- border-radius: 50rpx;
- font-size: 28rpx;
- z-index: 1000;
- box-shadow: 0 4rpx 20rpx rgba(74, 111, 227, 0.3);
- animation: fadeInOut 3s ease-in-out;
- }
- @keyframes fadeInOut {
- 0%,
- 100% {
- opacity: 0;
- transform: translateX(-50%) translateY(-20rpx);
- }
- 10%,
- 90% {
- opacity: 1;
- transform: translateX(-50%) translateY(0);
- }
- }
- </style>
|