<template>
|
|
<view class="custom-tabbar" :class="{ 'tabbar-hidden': !showNavbar }">
|
|
<!-- 音频控制栏组件 -->
|
|
<AudioControls
|
|
:current-page="currentPage"
|
|
:course-id="courseId"
|
|
:voice-id="voiceId"
|
|
:book-pages="bookPages"
|
|
:is-text-page="isTextPage"
|
|
:should-load-audio="shouldLoadAudio"
|
|
:is-member="isMember"
|
|
:current-page-requires-member="currentPageRequiresMember"
|
|
:page-pay="pagePay"
|
|
:is-word-audio-playing="isWordAudioPlaying"
|
|
@previous-page="previousPage"
|
|
@next-page="nextPage"
|
|
@audio-state-change="onAudioStateChange"
|
|
@highlight-change="onHighlightChange"
|
|
@scroll-to-text="onScrollToText"
|
|
@voice-change-complete="onVoiceChangeComplete"
|
|
@voice-change-error="onVoiceChangeError"
|
|
@page-data-needed="onPageDataNeeded"
|
|
ref="audioControls"
|
|
/>
|
|
|
|
<view style="background-color: #fff;position: relative;z-index: 100">
|
|
<view class="tabbar-content">
|
|
<view class="tabbar-left">
|
|
<view class="tab-button" @click="toggleCoursePopup">
|
|
<image src="/static/course-icon.png" class="tab-icon" />
|
|
<text class="tab-text">课程</text>
|
|
</view>
|
|
<view class="tab-button" @click="toggleSound">
|
|
<image src="/static/voice-switch-icon.png" class="tab-icon" />
|
|
<text class="tab-text">音色切换</text>
|
|
</view>
|
|
</view>
|
|
|
|
<view class="tabbar-right">
|
|
<view class="page-controls">
|
|
<view class="page-numbers">
|
|
<view
|
|
v-for="(page, index) in bookPages"
|
|
:key="index"
|
|
class="page-number"
|
|
:class="{ 'active': (index + 1) === currentPage }"
|
|
@click="goToPage(index + 1)"
|
|
>
|
|
{{ index + 1 }}
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
<uv-safe-bottom></uv-safe-bottom>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<script>
|
|
import AudioControls from '../AudioControls.vue'
|
|
|
|
export default {
|
|
name: 'CustomTabbar',
|
|
components: {
|
|
AudioControls
|
|
},
|
|
props: {
|
|
showNavbar: {
|
|
type: Boolean,
|
|
default: true
|
|
},
|
|
currentPage: {
|
|
type: Number,
|
|
default: 1
|
|
},
|
|
courseId: {
|
|
type: String,
|
|
default: ''
|
|
},
|
|
voiceId: {
|
|
type: Number,
|
|
default: null
|
|
},
|
|
bookPages: {
|
|
type: Array,
|
|
default: () => []
|
|
},
|
|
isTextPage: {
|
|
type: Boolean,
|
|
default: false
|
|
},
|
|
shouldLoadAudio: {
|
|
type: Boolean,
|
|
default: false
|
|
},
|
|
isMember: {
|
|
type: Boolean,
|
|
default: false
|
|
},
|
|
currentPageRequiresMember: {
|
|
type: Boolean,
|
|
default: false
|
|
},
|
|
pagePay: {
|
|
type: Array,
|
|
default: () => []
|
|
},
|
|
isWordAudioPlaying: {
|
|
type: Boolean,
|
|
default: false
|
|
}
|
|
},
|
|
methods: {
|
|
toggleCoursePopup() {
|
|
this.$emit('toggle-course-popup')
|
|
},
|
|
toggleSound() {
|
|
this.$emit('toggle-sound')
|
|
},
|
|
goToPage(pageNumber) {
|
|
this.$emit('go-to-page', pageNumber)
|
|
},
|
|
previousPage() {
|
|
this.$emit('previous-page')
|
|
},
|
|
nextPage() {
|
|
this.$emit('next-page')
|
|
},
|
|
onAudioStateChange(audioState) {
|
|
this.$emit('audio-state-change', audioState)
|
|
},
|
|
onHighlightChange(highlightData) {
|
|
this.$emit('highlight-change', highlightData)
|
|
},
|
|
onVoiceChangeComplete(data) {
|
|
this.$emit('voice-change-complete', data)
|
|
},
|
|
onVoiceChangeError(error) {
|
|
this.$emit('voice-change-error', error)
|
|
},
|
|
onPageDataNeeded(pageNumber) {
|
|
this.$emit('page-data-needed', pageNumber)
|
|
},
|
|
onScrollToText(scrollData) {
|
|
this.$emit('scroll-to-text', scrollData)
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.custom-tabbar {
|
|
position: fixed;
|
|
bottom: 0;
|
|
left: 0;
|
|
right: 0;
|
|
border-top: 1rpx solid #EEEEEE;
|
|
z-index: 1000;
|
|
transition: transform 0.3s ease;
|
|
|
|
&.tabbar-hidden {
|
|
transform: translateY(100%);
|
|
}
|
|
}
|
|
|
|
.tabbar-content {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
padding: 24rpx 62rpx;
|
|
height: 88rpx;
|
|
}
|
|
|
|
.tabbar-left {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 35rpx;
|
|
}
|
|
|
|
.tab-button {
|
|
display: flex;
|
|
align-items: center;
|
|
flex-direction: column;
|
|
gap: 8rpx;
|
|
}
|
|
|
|
.tab-icon {
|
|
width: 52rpx;
|
|
height: 52rpx;
|
|
}
|
|
|
|
.tab-text {
|
|
font-family: PingFang SC;
|
|
font-size: 22rpx;
|
|
color: #999;
|
|
line-height: 24rpx;
|
|
}
|
|
|
|
.tabbar-right {
|
|
flex: 1;
|
|
display: flex;
|
|
justify-content: flex-end;
|
|
}
|
|
|
|
.page-controls {
|
|
display: flex;
|
|
align-items: center;
|
|
}
|
|
|
|
.page-numbers {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8rpx;
|
|
overflow-x: auto;
|
|
// max-width: 400rpx;
|
|
max-width: 50vw;
|
|
|
|
&::-webkit-scrollbar {
|
|
display: none;
|
|
}
|
|
}
|
|
|
|
.page-number {
|
|
min-width: 84rpx;
|
|
height: 58rpx;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
border-radius: 100rpx;
|
|
font-family: PingFang SC;
|
|
font-size: 30rpx;
|
|
color: #3B3D3D;
|
|
background-color: transparent;
|
|
border: 1px solid #3B3D3D;
|
|
transition: all 0.3s ease;
|
|
|
|
&.active {
|
|
border: 1px solid #06DADC;
|
|
color: #06DADC;
|
|
}
|
|
}
|
|
</style>
|