<template>
|
|
<view class="subscription-popup" :class="{'dark-mode': isDarkMode}">
|
|
<uv-popup ref="popup"
|
|
mode="bottom"
|
|
:closeOnClickOverlay="false"
|
|
@maskClick="$emit('maskClick')"
|
|
:customStyle="popupStyle">
|
|
<view class="content theme-transition">
|
|
<view class="popup-title theme-transition">{{ title }}</view>
|
|
|
|
<!-- 默认订阅界面 -->
|
|
<view v-if="!showBatchDialog" class="popup-btns">
|
|
<button class="popup-btn theme-transition" @click="handleSubscribe">订阅本章</button>
|
|
<button class="popup-btn theme-transition" @click="handleVideoUnlock">观看视频解锁</button>
|
|
<button class="popup-btn theme-transition" @click="showBatchSubscribe">批量订阅</button>
|
|
</view>
|
|
|
|
<!-- 批量订阅界面 -->
|
|
<view v-else class="batch-subscribe-content">
|
|
<view class="batch-title">选择订阅章节数量</view>
|
|
<view class="batch-info">
|
|
<text>从当前章节开始,可订阅 {{ availableChaptersCount }} 章</text>
|
|
</view>
|
|
<view v-if="availableChaptersCount === 0" class="no-chapters-tip">
|
|
<text>暂无需要付费的章节</text>
|
|
</view>
|
|
<view v-else>
|
|
<view class="batch-current-info">
|
|
<text>连续订阅 {{ batchCount }} 章</text>
|
|
</view>
|
|
<view class="batch-counter">
|
|
<button class="counter-btn" @click="decreaseBatchCount" :disabled="batchCount <= 1">-</button>
|
|
<input type="number" v-model="batchCount" class="counter-input"
|
|
:max="maxBatchCount" @input="validateBatchCount" />
|
|
<button class="counter-btn" @click="increaseBatchCount" :disabled="batchCount >= maxBatchCount">+</button>
|
|
</view>
|
|
</view>
|
|
<view class="batch-btns">
|
|
<button class="batch-cancel-btn theme-transition" @click="cancelBatchSubscribe">取消</button>
|
|
<button class="batch-confirm-btn theme-transition"
|
|
@click="handleBatchSubscribe"
|
|
:disabled="availableChaptersCount === 0">确认订阅</button>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</uv-popup>
|
|
</view>
|
|
</template>
|
|
|
|
<script>
|
|
import themeMixin from '@/mixins/themeMode.js'
|
|
|
|
export default {
|
|
name: 'subscriptionPopup',
|
|
mixins: [themeMixin],
|
|
props: {
|
|
title: {
|
|
type: String,
|
|
default: '这是付费章节 需要订阅后才能阅读'
|
|
},
|
|
chapterList: {
|
|
type: Array,
|
|
default: () => []
|
|
},
|
|
currentChapter: {
|
|
type: Object,
|
|
default: () => ({})
|
|
},
|
|
currentIndex: {
|
|
type: Number,
|
|
default: 0
|
|
},
|
|
bookId: {
|
|
type: [String, Number],
|
|
default: ''
|
|
}
|
|
},
|
|
data() {
|
|
return {
|
|
showBatchDialog: false,
|
|
batchCount: 5
|
|
}
|
|
},
|
|
computed: {
|
|
popupStyle() {
|
|
return {
|
|
'background': this.isDarkMode ? '#232323' : '#fff',
|
|
'padding': '48rpx 32rpx',
|
|
'text-align': 'center',
|
|
'border-radius': '24rpx',
|
|
'min-width': '500rpx'
|
|
}
|
|
},
|
|
// 计算从当前章节开始可以订阅的章节数量
|
|
availableChaptersCount() {
|
|
if (!this.chapterList.length || this.currentIndex < 0) return 0;
|
|
|
|
let count = 0;
|
|
for (let i = this.currentIndex; i < this.chapterList.length; i++) {
|
|
const chapter = this.chapterList[i];
|
|
if (chapter.isPay === 'Y' && !chapter.pay) {
|
|
count++;
|
|
}
|
|
}
|
|
return count;
|
|
},
|
|
// 限制批量订阅数量不能超过可订阅章节数
|
|
maxBatchCount() {
|
|
return Math.max(1, this.availableChaptersCount);
|
|
}
|
|
},
|
|
methods: {
|
|
// 打开弹窗
|
|
open() {
|
|
this.$refs.popup.open();
|
|
},
|
|
|
|
// 关闭弹窗
|
|
close() {
|
|
this.$refs.popup.close();
|
|
},
|
|
|
|
// 处理订阅按钮点击
|
|
handleSubscribe() {
|
|
this.$emit('subscribe');
|
|
this.close();
|
|
},
|
|
|
|
// 处理视频解锁按钮点击
|
|
handleVideoUnlock() {
|
|
this.$emit('videoUnlock');
|
|
this.close();
|
|
},
|
|
|
|
// 显示批量订阅选择界面
|
|
showBatchSubscribe() {
|
|
// 根据可订阅章节数设置合理的默认值
|
|
this.batchCount = Math.min(5, this.maxBatchCount);
|
|
this.showBatchDialog = true;
|
|
},
|
|
|
|
// 取消批量订阅
|
|
cancelBatchSubscribe() {
|
|
this.showBatchDialog = false;
|
|
},
|
|
|
|
// 处理批量订阅
|
|
handleBatchSubscribe() {
|
|
this.$emit('batchSubscribe', this.batchCount);
|
|
this.showBatchDialog = false;
|
|
},
|
|
|
|
// 减少批量订阅数量
|
|
decreaseBatchCount() {
|
|
if (this.batchCount > 1) {
|
|
this.batchCount--;
|
|
}
|
|
},
|
|
|
|
// 增加批量订阅数量
|
|
increaseBatchCount() {
|
|
if (this.batchCount < this.maxBatchCount) {
|
|
this.batchCount++;
|
|
}
|
|
},
|
|
|
|
// 验证批量订阅数量
|
|
validateBatchCount() {
|
|
this.batchCount = Math.max(1, Math.min(this.maxBatchCount, parseInt(this.batchCount)));
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.subscription-popup {
|
|
.content {
|
|
.popup-title {
|
|
font-size: 32rpx;
|
|
font-weight: bold;
|
|
color: #222;
|
|
margin-bottom: 24rpx;
|
|
word-wrap: break-word;
|
|
white-space: normal;
|
|
}
|
|
|
|
.popup-desc {
|
|
font-size: 26rpx;
|
|
color: #999;
|
|
margin-bottom: 40rpx;
|
|
word-wrap: break-word;
|
|
white-space: normal;
|
|
}
|
|
|
|
.popup-btns {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
justify-content: center;
|
|
gap: 24rpx;
|
|
|
|
.popup-btn {
|
|
background: #ff9800;
|
|
color: #fff;
|
|
border-radius: 32rpx;
|
|
font-size: 28rpx;
|
|
padding: 0 32rpx;
|
|
border: none;
|
|
margin-bottom: 16rpx;
|
|
word-break: keep-all;
|
|
|
|
&.popup-btn-video {
|
|
background: #fff3e0;
|
|
color: #ff9800;
|
|
border: 1px solid #ff9800;
|
|
}
|
|
|
|
&.popup-btn-batch {
|
|
background: #fff;
|
|
color: #ff9800;
|
|
border: 1px solid #ff9800;
|
|
}
|
|
}
|
|
}
|
|
|
|
.batch-subscribe-content {
|
|
.batch-title {
|
|
font-size: 28rpx;
|
|
color: #333;
|
|
margin-bottom: 16rpx;
|
|
text-align: center;
|
|
}
|
|
|
|
.batch-info {
|
|
font-size: 24rpx;
|
|
color: #666;
|
|
margin-bottom: 32rpx;
|
|
text-align: center;
|
|
}
|
|
|
|
.batch-current-info {
|
|
font-size: 24rpx;
|
|
color: #666;
|
|
text-align: center;
|
|
margin-bottom: 16rpx;
|
|
}
|
|
|
|
.batch-counter {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
gap: 16rpx;
|
|
margin-bottom: 32rpx;
|
|
|
|
.counter-btn {
|
|
width: 64rpx;
|
|
height: 64rpx;
|
|
border-radius: 50%;
|
|
background: #f5f5f5;
|
|
border: none;
|
|
font-size: 32rpx;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
color: #333;
|
|
|
|
&:disabled {
|
|
opacity: 0.5;
|
|
cursor: not-allowed;
|
|
}
|
|
}
|
|
|
|
.counter-input {
|
|
width: 120rpx;
|
|
height: 64rpx;
|
|
text-align: center;
|
|
border: 1px solid #ddd;
|
|
border-radius: 8rpx;
|
|
font-size: 28rpx;
|
|
}
|
|
}
|
|
|
|
.batch-btns {
|
|
display: flex;
|
|
gap: 24rpx;
|
|
justify-content: center;
|
|
|
|
.batch-cancel-btn {
|
|
background: #f5f5f5;
|
|
color: #666;
|
|
border-radius: 32rpx;
|
|
font-size: 28rpx;
|
|
padding: 0 32rpx;
|
|
border: none;
|
|
}
|
|
|
|
.batch-confirm-btn {
|
|
background: #ff9800;
|
|
color: #fff;
|
|
border-radius: 32rpx;
|
|
font-size: 28rpx;
|
|
padding: 0 32rpx;
|
|
border: none;
|
|
|
|
&:disabled {
|
|
background: #ccc;
|
|
color: #666;
|
|
cursor: not-allowed;
|
|
}
|
|
}
|
|
}
|
|
|
|
.no-chapters-tip {
|
|
font-size: 24rpx;
|
|
color: #999;
|
|
text-align: center;
|
|
}
|
|
}
|
|
}
|
|
|
|
&.dark-mode {
|
|
.content {
|
|
.popup-title {
|
|
color: $dark-text-color-primary;
|
|
}
|
|
|
|
.popup-desc {
|
|
color: $dark-text-color-tertiary;
|
|
}
|
|
|
|
.popup-btns {
|
|
.popup-btn {
|
|
background: #ff9800;
|
|
color: #fff;
|
|
|
|
&.popup-btn-video {
|
|
background: rgba(255, 152, 0, 0.1);
|
|
color: #ff9800;
|
|
border: 1px solid #ff9800;
|
|
}
|
|
|
|
&.popup-btn-batch {
|
|
background: $dark-bg-color-secondary;
|
|
color: #ff9800;
|
|
border: 1px solid #ff9800;
|
|
}
|
|
}
|
|
}
|
|
|
|
.batch-subscribe-content {
|
|
.batch-title {
|
|
color: $dark-text-color-primary;
|
|
}
|
|
|
|
.batch-info {
|
|
color: $dark-text-color-tertiary;
|
|
}
|
|
|
|
.batch-current-info {
|
|
color: $dark-text-color-primary;
|
|
}
|
|
|
|
.batch-counter {
|
|
.counter-btn {
|
|
background: $dark-bg-color-tertiary;
|
|
color: $dark-text-color-primary;
|
|
}
|
|
|
|
.counter-input {
|
|
background: $dark-bg-color-secondary;
|
|
border: 1px solid $dark-border-color;
|
|
color: $dark-text-color-primary;
|
|
}
|
|
}
|
|
|
|
.batch-btns {
|
|
.batch-cancel-btn {
|
|
background: $dark-bg-color-tertiary;
|
|
color: $dark-text-color-secondary;
|
|
}
|
|
|
|
.batch-confirm-btn {
|
|
background: #ff9800;
|
|
color: #fff;
|
|
|
|
&:disabled {
|
|
background: $dark-bg-color-tertiary;
|
|
color: $dark-text-color-tertiary;
|
|
}
|
|
}
|
|
}
|
|
|
|
.no-chapters-tip {
|
|
color: $dark-text-color-tertiary;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</style>
|