@ -0,0 +1,26 @@ | |||||
<template> | |||||
<view v-if="show" style="position:fixed;top:200px;left:0;right:0;z-index:99999;background:#0f0;color:#fff;font-size:40rpx;text-align:center;">CatalogPopup弹窗测试</view> | |||||
</template> | |||||
<script> | |||||
export default { | |||||
name: 'CatalogPopup', | |||||
props: { | |||||
show: Boolean, | |||||
chapterList: Array, | |||||
currentIndex: Number, | |||||
orderAsc: Boolean, | |||||
top: { | |||||
type: String, | |||||
default: '196px' | |||||
}, | |||||
minHeight: { | |||||
type: String, | |||||
default: 'calc(100vh - 196px)' | |||||
} | |||||
}, | |||||
mounted() { | |||||
console.log('CatalogPopup mounted'); | |||||
} | |||||
} | |||||
</script> |
@ -0,0 +1,93 @@ | |||||
<template> | |||||
<view class="rank-item"> | |||||
<view class="rank-left"> | |||||
<image v-if="rankIcon" :src="rankIcon" class="rank-icon" /> | |||||
<image v-else-if="rankNumImg" :src="rankNumImg" class="rank-num-img" /> | |||||
<slot name="rankNum" v-else /> | |||||
<image v-if="medal" :src="medal" class="medal" /> | |||||
<image class="avatar" :src="avatar" mode="aspectFill" /> | |||||
<view class="name">{{ name }}</view> | |||||
</view> | |||||
<view class="rank-right"> | |||||
<view class="score">{{ score }} 亲密值</view> | |||||
<view class="level">{{ level }}</view> | |||||
</view> | |||||
</view> | |||||
</template> | |||||
<script> | |||||
export default { | |||||
name: 'RankListItem', | |||||
props: { | |||||
rankIcon: String, // 排名图片(前3名) | |||||
rankNumImg: String, // 排名数字图片(4-10名) | |||||
medal: String, // 勋章图片 | |||||
avatar: String, | |||||
name: String, | |||||
score: [String, Number], | |||||
level: { | |||||
type: String, | |||||
default: '护书使者 五级' | |||||
} | |||||
} | |||||
} | |||||
</script> | |||||
<style lang="scss" scoped> | |||||
.rank-item { | |||||
display: flex; | |||||
align-items: center; | |||||
justify-content: space-between; | |||||
background: #fffbe6; | |||||
border-radius: 16rpx; | |||||
margin-bottom: 18rpx; | |||||
box-shadow: 0 2rpx 8rpx 0 rgba(184,110,59,0.06); | |||||
padding: 0 24rpx; | |||||
height: 100rpx; | |||||
.rank-left { | |||||
display: flex; | |||||
align-items: center; | |||||
.rank-icon, .rank-num-img { | |||||
width: 38rpx; | |||||
height: 38rpx; | |||||
margin-right: 10rpx; | |||||
} | |||||
.medal { | |||||
width: 44rpx; | |||||
height: 44rpx; | |||||
margin-right: 10rpx; | |||||
} | |||||
.avatar { | |||||
width: 44rpx; | |||||
height: 44rpx; | |||||
border-radius: 50%; | |||||
margin-right: 14rpx; | |||||
border: 2rpx solid #ffd700; | |||||
object-fit: cover; | |||||
} | |||||
.name { | |||||
font-size: 26rpx; | |||||
color: #222; | |||||
font-weight: 500; | |||||
} | |||||
} | |||||
.rank-right { | |||||
display: flex; | |||||
flex-direction: column; | |||||
align-items: flex-end; | |||||
.score { | |||||
font-size: 22rpx; | |||||
color: #b86e3b; | |||||
} | |||||
.level { | |||||
font-size: 20rpx; | |||||
color: #fff; | |||||
background: #e6b07c; | |||||
border-radius: 8rpx; | |||||
padding: 2rpx 10rpx; | |||||
margin-top: 6rpx; | |||||
font-weight: 500; | |||||
} | |||||
} | |||||
} | |||||
</style> |
@ -0,0 +1,164 @@ | |||||
<template> | |||||
<!-- 礼物盒页面 --> | |||||
<view class="giftbox-container"> | |||||
<!-- 顶部标题栏 --> | |||||
<uv-navbar title="礼物盒" :autoBack="true" fixed placeholder rightIcon="more-dot-fill" /> | |||||
<!-- 礼物列表 --> | |||||
<view class="gift-list"> | |||||
<view | |||||
v-for="(gift, idx) in gifts" | |||||
:key="gift.id" | |||||
:class="['gift-item', { selected: idx === selectedIndex }]" | |||||
@click="selectGift(idx)" | |||||
> | |||||
<view class="gift-img"> | |||||
<text class="gift-emoji">{{ gift.emoji }}</text> | |||||
</view> | |||||
<view class="gift-name">{{ gift.name }}</view> | |||||
<view class="gift-info"> | |||||
<text class="gift-count">x{{ gift.count }}</text> | |||||
<text class="gift-bean">{{ gift.price }}豆豆</text> | |||||
</view> | |||||
</view> | |||||
</view> | |||||
<!-- 底部操作栏 --> | |||||
<view class="giftbox-bottom"> | |||||
<view class="giftbox-left">剩余:{{ gifts[selectedIndex].count }} 个</view> | |||||
<view class="giftbox-buy"> | |||||
<button class="buy-btn" @click="buyGift">购买</button> | |||||
<uv-number-box v-model="buyCount" :min="1" :max="gifts[selectedIndex].count" /> | |||||
</view> | |||||
</view> | |||||
</view> | |||||
</template> | |||||
<script> | |||||
export default { | |||||
components: { | |||||
'uv-navbar': () => import('@/uni_modules/uv-navbar/components/uv-navbar/uv-navbar.vue'), | |||||
'uv-number-box': () => import('@/uni_modules/uv-number-box/components/uv-number-box/uv-number-box.vue'), | |||||
}, | |||||
data() { | |||||
return { | |||||
gifts: [ | |||||
{ id: 1, name: '小星星', emoji: '🌟', count: 6, price: 1 }, | |||||
{ id: 2, name: '爱你哟', emoji: '🧡', count: 5, price: 1 }, | |||||
{ id: 3, name: '加油鸭', emoji: '🦆', count: 5, price: 1 }, | |||||
{ id: 4, name: '蓝色烟花', emoji: '🎆', count: 5, price: 1 }, | |||||
{ id: 5, name: '沙滩椅', emoji: '🏖️', count: 5, price: 1 }, | |||||
{ id: 6, name: '菠萝', emoji: '🍍', count: 5, price: 1 }, | |||||
{ id: 7, name: '咖啡', emoji: '☕', count: 5, price: 1 }, | |||||
{ id: 8, name: '早餐', emoji: '🥐', count: 5, price: 1 }, | |||||
{ id: 9, name: '花花', emoji: '🌷', count: 5, price: 1 }, | |||||
{ id: 10, name: '玫瑰', emoji: '🌹', count: 5, price: 1 }, | |||||
{ id: 11, name: '玫瑰花', emoji: '🥀', count: 5, price: 1 }, | |||||
{ id: 12, name: '跑车', emoji: '🏎️', count: 5, price: 1 }, | |||||
], | |||||
selectedIndex: 0, | |||||
buyCount: 1, | |||||
} | |||||
}, | |||||
methods: { | |||||
selectGift(idx) { | |||||
this.selectedIndex = idx | |||||
this.buyCount = 1 | |||||
}, | |||||
buyGift() { | |||||
// 跳转到礼物购买页面,并传递选中礼物信息 | |||||
const gift = this.gifts[this.selectedIndex] | |||||
uni.navigateTo({ | |||||
url: `/pages_order/novel/Giftpurchases?name=${encodeURIComponent(gift.name)}&price=${gift.price}&count=${this.buyCount}` | |||||
}) | |||||
}, | |||||
}, | |||||
} | |||||
</script> | |||||
<style scoped lang="scss"> | |||||
.giftbox-container { | |||||
min-height: 100vh; | |||||
background: #f8f8f8; | |||||
padding-bottom: 120rpx; | |||||
} | |||||
.gift-list { | |||||
display: flex; | |||||
flex-wrap: wrap; | |||||
gap: 24rpx; | |||||
padding: 32rpx 16rpx 0 16rpx; | |||||
} | |||||
.gift-item { | |||||
width: 30%; | |||||
background: #fff; | |||||
border-radius: 18rpx; | |||||
box-shadow: 0 2rpx 8rpx rgba(0,0,0,0.03); | |||||
margin-bottom: 24rpx; | |||||
display: flex; | |||||
flex-direction: column; | |||||
align-items: center; | |||||
padding: 24rpx 0 16rpx 0; | |||||
border: 2rpx solid transparent; | |||||
transition: border 0.2s; | |||||
} | |||||
.gift-item.selected { | |||||
border: 2rpx solid #223a7a; | |||||
box-shadow: 0 4rpx 16rpx 0 rgba(34,58,122,0.08); | |||||
} | |||||
.gift-img { | |||||
width: 80rpx; | |||||
height: 80rpx; | |||||
display: flex; | |||||
align-items: center; | |||||
justify-content: center; | |||||
margin-bottom: 8rpx; | |||||
} | |||||
.gift-emoji { | |||||
font-size: 56rpx; | |||||
} | |||||
.gift-name { | |||||
font-size: 28rpx; | |||||
color: #222; | |||||
margin-bottom: 4rpx; | |||||
} | |||||
.gift-info { | |||||
display: flex; | |||||
align-items: center; | |||||
gap: 8rpx; | |||||
font-size: 22rpx; | |||||
color: #888; | |||||
} | |||||
.giftbox-bottom { | |||||
position: fixed; | |||||
left: 0; | |||||
right: 0; | |||||
bottom: 0; | |||||
background: #fff; | |||||
display: flex; | |||||
align-items: center; | |||||
justify-content: space-between; | |||||
height: 100rpx; | |||||
padding: 0 32rpx; | |||||
box-shadow: 0 -2rpx 10rpx rgba(0,0,0,0.05); | |||||
z-index: 10; | |||||
} | |||||
.giftbox-left { | |||||
font-size: 28rpx; | |||||
color: #666; | |||||
} | |||||
.giftbox-buy { | |||||
display: flex; | |||||
align-items: center; | |||||
gap: 18rpx; | |||||
} | |||||
.buy-btn { | |||||
background: #223a7a; | |||||
color: #fff; | |||||
font-size: 28rpx; | |||||
border-radius: 32rpx; | |||||
padding: 0 36rpx; | |||||
height: 68rpx; | |||||
line-height: 68rpx; | |||||
border: none; | |||||
} | |||||
</style> |
@ -0,0 +1,278 @@ | |||||
<template> | |||||
<!-- 礼物购买页面 --> | |||||
<view class="gift-purchase-page"> | |||||
<!-- 顶部导航栏 --> | |||||
<uv-navbar title="礼物购买" :autoBack="true" fixed placeholder /> | |||||
<!-- 礼物购买卡片 --> | |||||
<view class="card gift-card"> | |||||
<view class="card-title">礼物购买</view> | |||||
<view class="form-row"> | |||||
<view class="form-label">礼物名称</view> | |||||
<view class="form-value">{{ giftName }}</view> | |||||
</view> | |||||
<view class="divider"></view> | |||||
<view class="form-row"> | |||||
<view class="form-label required"><text class="star">*</text> 购买数量</view> | |||||
<input class="form-input" placeholder="请输入数量" v-model="buyCount" type="number" :placeholder-style="'color:#bbb;'" :style="buyCount ? 'color:#222;' : ''" /> | |||||
</view> | |||||
<view class="divider"></view> | |||||
<view class="form-row"> | |||||
<view class="form-label">支付方式</view> | |||||
</view> | |||||
<view class="form-row"> | |||||
<view class="balance">账户余额:<text class="bean">{{ balance }} 豆豆</text></view> | |||||
</view> | |||||
</view> | |||||
<!-- 订单信息卡片 --> | |||||
<view class="card order-card"> | |||||
<view class="order-title">订单信息</view> | |||||
<view class="row"> | |||||
<view class="order-content">内容</view> | |||||
</view> | |||||
<view class="row total-row"> | |||||
<view class="order-total-label">合计:</view> | |||||
<view class="order-total"><text class="order-total-highlight">{{ totalPrice.toFixed(2) }}</text> 元</view> | |||||
</view> | |||||
<view class="order-divider"></view> | |||||
</view> | |||||
<!-- 提示信息 --> | |||||
<view class="tip-text"> | |||||
请仔细核查并确认相关信息。因用户个人疏忽导致的充值错误,需由用户自行承担。一旦完成充值,概不退换。 | |||||
</view> | |||||
<!-- 底部购买按钮 --> | |||||
<view class="footer-bar"> | |||||
<button class="buy-btn" @click="handleBuy">购买</button> | |||||
</view> | |||||
</view> | |||||
</template> | |||||
<script> | |||||
export default { | |||||
data() { | |||||
return { | |||||
giftName: '小星星', | |||||
price: 0.1, // 单价 | |||||
buyCount: '', | |||||
balance: 0, // 账户余额 | |||||
} | |||||
}, | |||||
computed: { | |||||
totalPrice() { | |||||
const count = parseInt(this.buyCount, 10) | |||||
return isNaN(count) ? 0 : count * this.price | |||||
} | |||||
}, | |||||
onLoad(query) { | |||||
// 支持通过路由参数动态显示礼物信息 | |||||
if (query.name) this.giftName = decodeURIComponent(query.name) | |||||
if (query.price) this.price = Number(query.price) | |||||
if (query.count) this.buyCount = query.count | |||||
}, | |||||
methods: { | |||||
handleBuy() { | |||||
if (!this.buyCount || parseInt(this.buyCount, 10) <= 0) { | |||||
uni.showToast({ title: '请输入购买数量', icon: 'none' }) | |||||
return | |||||
} | |||||
// 这里可添加余额校验和购买逻辑 | |||||
uni.showToast({ title: `成功购买${this.buyCount}个${this.giftName}`, icon: 'success' }) | |||||
} | |||||
} | |||||
} | |||||
</script> | |||||
<style scoped lang="scss"> | |||||
.gift-purchase-page { | |||||
min-height: 100vh; | |||||
background: #f8f8f8; | |||||
padding-bottom: 120rpx; | |||||
} | |||||
.card { | |||||
background: #fff; | |||||
border-radius: 18rpx; | |||||
margin: 24rpx 16rpx 0 16rpx; | |||||
padding: 24rpx 24rpx 10rpx 24rpx; | |||||
box-shadow: 0 2rpx 8rpx rgba(0,0,0,0.03); | |||||
} | |||||
.card-title { | |||||
font-size: 24rpx; | |||||
font-weight: bold; | |||||
color: #222; | |||||
margin-bottom: 18rpx; | |||||
} | |||||
.row { | |||||
display: flex; | |||||
align-items: center; | |||||
margin-bottom: 16rpx; | |||||
} | |||||
.label { | |||||
color: #888; | |||||
font-size: 26rpx; | |||||
width: 160rpx; | |||||
} | |||||
.label.required { | |||||
color: #222; | |||||
font-weight: 500; | |||||
} | |||||
.value { | |||||
color: #222; | |||||
font-size: 26rpx; | |||||
} | |||||
.input { | |||||
flex: 1; | |||||
border: none; | |||||
border-bottom: 1rpx solid #eee; | |||||
font-size: 26rpx; | |||||
padding: 8rpx 0; | |||||
background: transparent; | |||||
outline: none; | |||||
} | |||||
.order-card { | |||||
border-radius: 20px; | |||||
box-shadow: 0 2px 8px rgba(0,0,0,0.04); | |||||
padding: 24px 20px 16px 20px; | |||||
margin: 16px; | |||||
position: relative; | |||||
} | |||||
.order-title { | |||||
font-size: 18px; | |||||
font-weight: bold; | |||||
color: #222; | |||||
margin-bottom: 12px; | |||||
} | |||||
.order-content { | |||||
color: #bbb; | |||||
font-size: 15px; | |||||
margin-bottom: 8px; | |||||
} | |||||
.row.total-row { | |||||
display: flex; | |||||
align-items: center; | |||||
margin-bottom: 0; | |||||
} | |||||
.order-total-label { | |||||
color: #222; | |||||
font-size: 18px; | |||||
font-weight: 500; | |||||
} | |||||
.order-total { | |||||
color: #222; | |||||
font-size: 18px; | |||||
font-weight: 500; | |||||
margin-left: 8px; | |||||
} | |||||
.order-total-highlight { | |||||
color: #ff7e00; | |||||
font-size: 18px; | |||||
font-weight: bold; | |||||
margin: 0 2px; | |||||
} | |||||
.order-divider { | |||||
width: 100%; | |||||
height: 1px; | |||||
background: #f2f2f2; | |||||
margin-top: 16px; | |||||
} | |||||
.tip-text { | |||||
color: #bbb; | |||||
font-size: 22rpx; | |||||
margin: 32rpx 32rpx 0 32rpx; | |||||
line-height: 1.6; | |||||
} | |||||
.footer-bar { | |||||
position: fixed; | |||||
left: 0; | |||||
right: 0; | |||||
bottom: 90rpx; | |||||
background: #fff; | |||||
padding: 24rpx 32rpx 32rpx 32rpx; | |||||
box-shadow: 0 -2rpx 10rpx rgba(0,0,0,0.05); | |||||
z-index: 10; | |||||
} | |||||
.buy-btn { | |||||
width: 100%; | |||||
background: #223a7a; | |||||
color: #fff; | |||||
font-size: 32rpx; | |||||
border-radius: 32rpx; | |||||
height: 88rpx; | |||||
line-height: 88rpx; | |||||
border: none; | |||||
font-weight: 500; | |||||
} | |||||
.card.gift-card { | |||||
border-radius: 20px; | |||||
box-shadow: 0 2px 8px rgba(0,0,0,0.04); | |||||
padding: 24px 20px 16px 20px; | |||||
margin: 16px; | |||||
position: relative; | |||||
} | |||||
.card-title { | |||||
font-size: 18px; | |||||
font-weight: bold; | |||||
color: #222; | |||||
margin-bottom: 12px; | |||||
} | |||||
.form-row { | |||||
display: flex; | |||||
flex-direction: column; | |||||
align-items: flex-start; | |||||
min-height: 36px; | |||||
padding: 0; | |||||
margin-top: 5rpx; | |||||
} | |||||
.form-label { | |||||
color: #888; | |||||
font-size: 14px; | |||||
margin-bottom: 9px; | |||||
font-weight: 400; | |||||
margin-top: 5px; | |||||
} | |||||
.form-label.required { | |||||
color: #222; | |||||
font-weight: 500; | |||||
display: flex; | |||||
align-items: center; | |||||
} | |||||
.star { | |||||
color: #e94f7a; | |||||
margin-right: 2px; | |||||
font-size: 16px; | |||||
} | |||||
.form-value { | |||||
color: #0e0e0e; | |||||
font-size: 14px; | |||||
font-weight: 600; | |||||
margin-bottom: 2px; | |||||
} | |||||
.form-input { | |||||
flex: 1; | |||||
border: none; | |||||
background: transparent; | |||||
font-size: 14px; | |||||
outline: none; | |||||
padding: 0; | |||||
color: #222; | |||||
} | |||||
.divider { | |||||
height: 1px; | |||||
background: #f2f2f2; | |||||
margin: 0 0 0 0; | |||||
border: none; | |||||
} | |||||
.balance { | |||||
color: #0e0e0e; | |||||
font-size: 14px; | |||||
margin: 0 0 8px 0; | |||||
} | |||||
.bean { | |||||
color: #222; | |||||
font-weight: 600; | |||||
} | |||||
</style> |
@ -0,0 +1,180 @@ | |||||
<template> | |||||
<view class="my-comment-page"> | |||||
<navbar title="我的评论" :leftClick="true" @leftClick="goBack" /> | |||||
<view class="comment-section"> | |||||
<view class="section-title">未读评论·{{ unreadComments.length }}</view> | |||||
<view v-for="(item, idx) in unreadComments" :key="'unread-' + idx" class="comment-card"> | |||||
<uv-avatar :src="item.avatar" size="44" shape="circle" class="avatar" /> | |||||
<view class="comment-main"> | |||||
<view class="comment-header"> | |||||
<text class="username">{{ item.username }}</text> | |||||
<text class="from">来自《{{ item.bookTitle }}》</text> | |||||
</view> | |||||
<view class="comment-content">{{ item.content }}</view> | |||||
<view class="comment-footer"> | |||||
<text class="comment-time">{{ item.time }}</text> | |||||
<view class="reply-btn-wrap" @click="goToReply(item)"> | |||||
<text class="reply-btn">回复</text> | |||||
</view> | |||||
</view> | |||||
</view> | |||||
</view> | |||||
</view> | |||||
<view class="comment-section history-section"> | |||||
<view class="section-title">历史评论</view> | |||||
<view v-for="(item, idx) in historyComments" :key="'history-' + idx" class="comment-card"> | |||||
<uv-avatar :src="item.avatar" size="44" shape="circle" class="avatar" /> | |||||
<view class="comment-main"> | |||||
<view class="comment-header"> | |||||
<text class="username">{{ item.username }}</text> | |||||
<text class="from">来自《{{ item.bookTitle }}》</text> | |||||
</view> | |||||
<view class="comment-content">{{ item.content }}</view> | |||||
<view class="comment-footer"> | |||||
<text class="comment-time">{{ item.time }}</text> | |||||
<view class="reply-btn-wrap" @click="goToReply(item)"> | |||||
<text class="reply-btn">回复</text> | |||||
</view> | |||||
</view> | |||||
</view> | |||||
</view> | |||||
</view> | |||||
</view> | |||||
</template> | |||||
<script> | |||||
import navbar from '@/components/base/navbar.vue' | |||||
export default { | |||||
components: { navbar }, | |||||
data() { | |||||
return { | |||||
unreadComments: [ | |||||
{ | |||||
avatar: 'https://tse4-mm.cn.bing.net/th/id/OIP-C.iUyxJ_fxLjjX3kEBjteXWwAAAA?rs=1&pid=ImgDetMain', | |||||
username: '方香橙', | |||||
bookTitle: '重生之财富滚滚', | |||||
content: '我是本书的作者方香橙,这是一本甜文爽文哒!请放心入坑,五星好评!女主又美有个性可爱,绝对不圣母,不傻白!男主身心干净深情独宠媳妇儿一个人...', | |||||
time: '2024.07.09' | |||||
}, | |||||
{ | |||||
avatar: 'https://tse4-mm.cn.bing.net/th/id/OIP-C.iUyxJ_fxLjjX3kEBjteXWwAAAA?rs=1&pid=ImgDetMain', | |||||
username: '战斗世界', | |||||
bookTitle: '重生之财富滚滚', | |||||
content: '这本书打破了我看甜文套路之前的观念女主真的太可爱太有趣和以往看过的一个NPC介绍有很大不同', | |||||
time: '2024.06.09' | |||||
}, | |||||
{ | |||||
avatar: 'https://tse4-mm.cn.bing.net/th/id/OIP-C.iUyxJ_fxLjjX3kEBjteXWwAAAA?rs=1&pid=ImgDetMain', | |||||
username: '战斗世界', | |||||
bookTitle: '重生之财富滚滚', | |||||
content: '这本书打破了我看甜文套路之前的观念女主真的太可爱太有趣和以往看过的一个NPC介绍有很大不同', | |||||
time: '2024.06.09' | |||||
} | |||||
], | |||||
historyComments: [ | |||||
{ | |||||
avatar: 'https://tse4-mm.cn.bing.net/th/id/OIP-C.iUyxJ_fxLjjX3kEBjteXWwAAAA?rs=1&pid=ImgDetMain', | |||||
username: '方香橙', | |||||
bookTitle: '重生之财富滚滚', | |||||
content: '我是本书的作者方香橙,这是一本甜文爽文哒!请放心入坑,五星好评!女主又美有个性可爱,绝对不圣母,不傻白!男主身心干净深情独宠媳妇儿一个人...', | |||||
time: '2024.07.09' | |||||
} | |||||
] | |||||
} | |||||
}, | |||||
methods: { | |||||
goBack() { | |||||
uni.navigateBack() | |||||
}, | |||||
goToReply(item) { | |||||
uni.navigateTo({ url: '/pages_order/novel/Respondcomments' }) | |||||
} | |||||
} | |||||
} | |||||
</script> | |||||
<style scoped lang="scss"> | |||||
.my-comment-page { | |||||
min-height: 100vh; | |||||
background: #f8f8f8; | |||||
display: flex; | |||||
flex-direction: column; | |||||
} | |||||
.comment-section { | |||||
background: #fff; | |||||
margin: 24rpx 24rpx 0 24rpx; | |||||
border-radius: 16rpx; | |||||
padding: 24rpx 24rpx 0 24rpx; | |||||
margin-bottom: 24rpx; | |||||
} | |||||
.section-title { | |||||
color: #222; | |||||
font-size: 28rpx; | |||||
font-weight: 500; | |||||
margin-bottom: 16rpx; | |||||
} | |||||
.comment-card { | |||||
display: flex; | |||||
align-items: flex-start; | |||||
margin-bottom: 32rpx; | |||||
} | |||||
.avatar { | |||||
width: 56rpx; | |||||
height: 56rpx; | |||||
border-radius: 50%; | |||||
margin-right: 16rpx; | |||||
flex-shrink: 0; | |||||
} | |||||
.comment-main { | |||||
flex: 1; | |||||
display: flex; | |||||
flex-direction: column; | |||||
} | |||||
.comment-header { | |||||
display: flex; | |||||
align-items: center; | |||||
gap: 12rpx; | |||||
margin-bottom: 4rpx; | |||||
} | |||||
.username { | |||||
font-size: 26rpx; | |||||
color: #222; | |||||
font-weight: 500; | |||||
} | |||||
.from { | |||||
font-size: 22rpx; | |||||
color: #bdbdbd; | |||||
} | |||||
.comment-content { | |||||
font-size: 26rpx; | |||||
color: #333; | |||||
margin-bottom: 12rpx; | |||||
} | |||||
.comment-footer { | |||||
display: flex; | |||||
align-items: center; | |||||
font-size: 22rpx; | |||||
color: #bdbdbd; | |||||
justify-content: space-between; | |||||
padding-right: 8rpx; | |||||
} | |||||
.comment-time { | |||||
color: #bdbdbd; | |||||
} | |||||
.reply-btn-wrap { | |||||
display: flex; | |||||
align-items: center; | |||||
cursor: pointer; | |||||
} | |||||
.reply-btn { | |||||
color: #223a6b; | |||||
font-weight: 500; | |||||
margin-left: 0; | |||||
font-size: 24rpx; | |||||
} | |||||
.history-section { | |||||
margin-top: 24rpx; | |||||
} | |||||
</style> |
@ -0,0 +1,192 @@ | |||||
<template> | |||||
<view class="achievement-page"> | |||||
<uv-navbar title="读者成就设置" fixed placeholder></uv-navbar> | |||||
<view class="achievement-card"> | |||||
<view class="card-title-row"> | |||||
<view class="card-title">阅读成就设置</view> | |||||
<view v-if="isPending" class="pending-tag">设置审核中</view> | |||||
</view> | |||||
<view class="achievement-list"> | |||||
<view class="achievement-item"> | |||||
<image class="badge-img" src="https://tse3-mm.cn.bing.net/th/id/OIP-C.wUsFZgl70iE4tI7b_HKaKgHaHa?w=166&h=180&c=7&r=0&o=5&dpr=1.1&pid=1.7" mode="aspectFill" /> | |||||
<view class="input-area"> | |||||
<view class="label-row"> | |||||
<text class="required">*</text> | |||||
<text class="label">一级成就名称</text> | |||||
</view> | |||||
<input class="input" v-model="level1" placeholder="请输入" placeholder-class="input-placeholder" /> | |||||
</view> | |||||
</view> | |||||
<view class="divider"></view> | |||||
<view class="achievement-item"> | |||||
<image class="badge-img" src="https://tse3-mm.cn.bing.net/th/id/OIP-C.wUsFZgl70iE4tI7b_HKaKgHaHa?w=166&h=180&c=7&r=0&o=5&dpr=1.1&pid=1.7" mode="aspectFill" /> | |||||
<view class="input-area"> | |||||
<view class="label-row"> | |||||
<text class="required">*</text> | |||||
<text class="label">二级成就名称</text> | |||||
</view> | |||||
<input class="input" v-model="level2" placeholder="请输入" placeholder-class="input-placeholder" /> | |||||
</view> | |||||
</view> | |||||
<view class="divider"></view> | |||||
<view class="achievement-item"> | |||||
<image class="badge-img" src="https://tse3-mm.cn.bing.net/th/id/OIP-C.wUsFZgl70iE4tI7b_HKaKgHaHa?w=166&h=180&c=7&r=0&o=5&dpr=1.1&pid=1.7" mode="aspectFill" /> | |||||
<view class="input-area"> | |||||
<view class="label-row"> | |||||
<text class="required">*</text> | |||||
<text class="label">三级成就名称</text> | |||||
</view> | |||||
<input class="input" v-model="level3" placeholder="请输入" placeholder-class="input-placeholder" /> | |||||
</view> | |||||
</view> | |||||
</view> | |||||
</view> | |||||
<view class="bottom-btn-area"> | |||||
<button class="submit-btn" :disabled="isPending" :class="{disabled: isPending, pending: isPending}" @click="submit"> | |||||
{{ isPending ? '设置' : '提交申请' }} | |||||
</button> | |||||
</view> | |||||
</view> | |||||
</template> | |||||
<script> | |||||
export default { | |||||
data() { | |||||
return { | |||||
level1: '', | |||||
level2: '', | |||||
level3: '', | |||||
isPending: false | |||||
} | |||||
}, | |||||
methods: { | |||||
submit() { | |||||
if (!this.level1 || !this.level2 || !this.level3) { | |||||
uni.showToast({ title: '请填写所有成就名称', icon: 'none' }) | |||||
return | |||||
} | |||||
this.isPending = true | |||||
// 可根据需要添加实际提交逻辑 | |||||
} | |||||
} | |||||
} | |||||
</script> | |||||
<style scoped lang="scss"> | |||||
.achievement-page { | |||||
min-height: 100vh; | |||||
background: #f7f8fa; | |||||
display: flex; | |||||
flex-direction: column; | |||||
} | |||||
.achievement-card { | |||||
background: #fff; | |||||
border-radius: 20rpx; | |||||
margin: 40rpx 32rpx 0 32rpx; | |||||
padding: 32rpx 24rpx; | |||||
box-shadow: 0 4rpx 24rpx 0 rgba(0,0,0,0.04); | |||||
} | |||||
.card-title-row { | |||||
display: flex; | |||||
align-items: center; | |||||
justify-content: space-between; | |||||
} | |||||
.card-title { | |||||
font-size: 32rpx; | |||||
font-weight: bold; | |||||
margin-bottom: 32rpx; | |||||
} | |||||
.achievement-list { | |||||
display: flex; | |||||
flex-direction: column; | |||||
gap: 0; | |||||
} | |||||
.achievement-item { | |||||
display: flex; | |||||
align-items: flex-start; | |||||
padding: 18rpx 0 10rpx 0; | |||||
} | |||||
.badge-img { | |||||
width: 72rpx; | |||||
height: 72rpx; | |||||
margin-right: 20rpx; | |||||
border-radius: 50%; | |||||
background: #f5f5f5; | |||||
object-fit: cover; | |||||
border: 2rpx solid #fff; | |||||
box-shadow: 0 2rpx 8rpx 0 rgba(0,0,0,0.04); | |||||
} | |||||
.input-area { | |||||
margin-top: 15rpx; | |||||
flex: 1; | |||||
display: flex; | |||||
flex-direction: column; | |||||
justify-content: flex-start; | |||||
} | |||||
.label-row { | |||||
display: flex; | |||||
align-items: center; | |||||
margin-bottom: 6rpx; | |||||
} | |||||
.required { | |||||
color: #e23d3d; | |||||
font-size: 28rpx; | |||||
margin-right: 4rpx; | |||||
} | |||||
.label { | |||||
font-size: 28rpx; | |||||
color: #222; | |||||
font-weight: bold; | |||||
} | |||||
.input { | |||||
width: 100%; | |||||
border: none; | |||||
border-bottom: 1.5rpx solid #ececec; | |||||
font-size: 28rpx; | |||||
background: transparent; | |||||
padding: 8rpx 0 6rpx 0; | |||||
margin-bottom: 2rpx; | |||||
} | |||||
.input-placeholder { | |||||
color: #d2d2d2; | |||||
font-size: 26rpx; | |||||
} | |||||
.divider { | |||||
height: 1rpx; | |||||
background: #f3f3f3; | |||||
margin: 0 0 0 92rpx; | |||||
} | |||||
.bottom-btn-area { | |||||
margin-top: auto; | |||||
padding: 48rpx 32rpx 32rpx 32rpx; | |||||
background: transparent; | |||||
} | |||||
.submit-btn { | |||||
width: 100%; | |||||
height: 88rpx; | |||||
background: #0a2e6d; | |||||
color: #fff; | |||||
font-size: 32rpx; | |||||
border-radius: 44rpx; | |||||
font-weight: bold; | |||||
letter-spacing: 2rpx; | |||||
transition: background 0.2s; | |||||
} | |||||
.submit-btn.disabled { | |||||
background: #807a7a; | |||||
color: #fff; | |||||
} | |||||
.submit-btn.pending { | |||||
background: #0a226d; | |||||
color: #fff; | |||||
} | |||||
.pending-tag { | |||||
background: #807a7a; | |||||
color: #fff; | |||||
font-size: 24rpx; | |||||
border-radius: 10rpx; | |||||
padding: 6rpx 24rpx; | |||||
margin-left: 20rpx; | |||||
margin-bottom: 32rpx; | |||||
} | |||||
</style> |
@ -0,0 +1,206 @@ | |||||
<template> | |||||
<view class="respond-comments-page"> | |||||
<!-- 顶部导航栏 --> | |||||
<navbar title="回复评论" :leftClick="true" @leftClick="goBack"> | |||||
<template #left> | |||||
<uv-icon name="arrow-left" customPrefix="uvicon" size="22" color="#222" /> | |||||
</template> | |||||
</navbar> | |||||
<!-- 原评论展示 --> | |||||
<view class="origin-comment-card"> | |||||
<view class="comment-header"> | |||||
<image class="avatar" :src="comment.avatar" mode="aspectFill" /> | |||||
<view class="user-info"> | |||||
<text class="username">{{ comment.username }}</text> | |||||
</view> | |||||
</view> | |||||
<view class="comment-content">{{ comment.content }}</view> | |||||
<view class="comment-footer"> | |||||
<text class="comment-time">{{ comment.time }}</text> | |||||
<text class="comment-reply-count"> | |||||
<uv-icon name="chat" customPrefix="uvicon" size="18" color="#bdbdbd" style="margin-right: 4rpx;" /> | |||||
{{ comment.replyCount }} | |||||
</text> | |||||
</view> | |||||
</view> | |||||
<!-- 回复输入区 --> | |||||
<view class="reply-area"> | |||||
<view class="form-label-row"> | |||||
<text class="required-star">*</text> | |||||
<text class="form-label">回复内容</text> | |||||
</view> | |||||
<uv-input | |||||
v-model="replyContent" | |||||
type="text" | |||||
:maxlength="200" | |||||
placeholder="请输入回复内容" | |||||
border="surround" | |||||
clearable | |||||
class="reply-input" | |||||
/> | |||||
</view> | |||||
<!-- 底部提交按钮 --> | |||||
<view class="reply-footer"> | |||||
<button class="submit-btn" :disabled="!replyContent.trim()" @click="submitReply">发送</button> | |||||
</view> | |||||
</view> | |||||
</template> | |||||
<script> | |||||
import navbar from '@/components/base/navbar.vue' | |||||
export default { | |||||
components: { navbar }, | |||||
data() { | |||||
return { | |||||
comment: { | |||||
avatar: 'https://tse4-mm.cn.bing.net/th/id/OIP-C.iUyxJ_fxLjjX3kEBjteXWwAAAA?rs=1&pid=ImgDetMain', | |||||
username: '方香橙', | |||||
content: '我是本书的作者方香橙,这是一本甜文爽文哒!请放心入坑,五星好评!女主又美有个性可爱,绝对不圣母,不傻白!男主身心干净深情独宠媳妇儿一个人...', | |||||
time: '2024.07.09', | |||||
replyCount: 17 | |||||
}, | |||||
replyContent: '' | |||||
} | |||||
}, | |||||
methods: { | |||||
goBack() { | |||||
uni.navigateBack() | |||||
}, | |||||
submitReply() { | |||||
if (!this.replyContent.trim()) { | |||||
uni.showToast({ title: '请输入回复内容', icon: 'none' }) | |||||
return | |||||
} | |||||
// 实际开发中可调用API提交 | |||||
uni.showToast({ title: '回复成功', icon: 'success' }) | |||||
this.replyContent = '' | |||||
setTimeout(() => { | |||||
uni.navigateBack() | |||||
}, 1000) | |||||
} | |||||
} | |||||
} | |||||
</script> | |||||
<style scoped lang="scss"> | |||||
.respond-comments-page { | |||||
min-height: 100vh; | |||||
background: #f8f8f8; | |||||
display: flex; | |||||
flex-direction: column; | |||||
} | |||||
.origin-comment-card { | |||||
background: #fff; | |||||
margin: 24rpx 24rpx 0 24rpx; | |||||
padding: 24rpx 24rpx 0 24rpx; | |||||
margin-bottom: 0; | |||||
border-radius: 0; | |||||
box-shadow: none; | |||||
padding-bottom: 0; | |||||
} | |||||
.comment-header { | |||||
display: flex; | |||||
align-items: center; | |||||
margin-bottom: 8rpx; | |||||
} | |||||
.avatar { | |||||
width: 56rpx; | |||||
height: 56rpx; | |||||
border-radius: 50%; | |||||
margin-right: 16rpx; | |||||
} | |||||
.user-info { | |||||
display: flex; | |||||
flex-direction: column; | |||||
} | |||||
.username { | |||||
font-size: 26rpx; | |||||
color: #222; | |||||
font-weight: 500; | |||||
} | |||||
.comment-content { | |||||
font-size: 26rpx; | |||||
color: #333; | |||||
margin-bottom: 12rpx; | |||||
} | |||||
.comment-footer { | |||||
display: flex; | |||||
align-items: center; | |||||
font-size: 22rpx; | |||||
color: #bdbdbd; | |||||
justify-content: space-between; | |||||
} | |||||
.comment-time { | |||||
color: #bdbdbd; | |||||
margin-top: 18rpx; | |||||
} | |||||
.comment-reply-count { | |||||
display: flex; | |||||
align-items: center; | |||||
font-size: 22rpx; | |||||
color: #bdbdbd; | |||||
} | |||||
.reply-area { | |||||
background: #fff; | |||||
margin: 0 24rpx 0 24rpx; | |||||
padding: 0 24rpx 24rpx 24rpx; | |||||
display: flex; | |||||
flex-direction: column; | |||||
border-radius: 0; | |||||
box-shadow: none; | |||||
margin-top: 0; | |||||
} | |||||
.form-label-row { | |||||
display: flex; | |||||
align-items: center; | |||||
margin-bottom: 8rpx; | |||||
margin-top: 50rpx; | |||||
} | |||||
.required-star { | |||||
color: #e23d3d; | |||||
font-size: 22rpx; | |||||
margin-right: 4rpx; | |||||
line-height: 1; | |||||
} | |||||
.form-label { | |||||
color: #222; | |||||
font-size: 26rpx; | |||||
font-weight: 400; | |||||
} | |||||
.reply-input { | |||||
margin-top: 12rpx; | |||||
border: none !important; | |||||
box-shadow: none !important; | |||||
} | |||||
.reply-footer { | |||||
position: fixed; | |||||
left: 0; | |||||
right: 0; | |||||
bottom: 90rpx; | |||||
background: #fff; | |||||
padding: 24rpx 32rpx 32rpx 32rpx; | |||||
box-shadow: 0 -2rpx 12rpx rgba(0,0,0,0.03); | |||||
z-index: 10; | |||||
} | |||||
.submit-btn { | |||||
width: 100%; | |||||
height: 80rpx; | |||||
background: #0a225f !important; | |||||
color: #fff !important; | |||||
font-size: 30rpx; | |||||
border-radius: 40rpx; | |||||
font-weight: 500; | |||||
letter-spacing: 2rpx; | |||||
border: none; | |||||
box-shadow: none; | |||||
margin: 0 auto; | |||||
display: block; | |||||
text-align: center; | |||||
line-height: 80rpx; | |||||
} | |||||
.submit-btn:disabled { | |||||
background: #bdbdbd; | |||||
color: #fff; | |||||
} | |||||
</style> |
@ -0,0 +1,167 @@ | |||||
<template> | |||||
<view class="review-page"> | |||||
<!-- 顶部导航栏 --> | |||||
<navbar title="写书评" :leftClick="true" @leftClick="goBack" /> | |||||
<view class="review-content"> | |||||
<view class="book-title-label">书本名称</view> | |||||
<view class="book-title">《{{ bookTitle }}》</view> | |||||
<view class="form-area flex-grow"> | |||||
<view class="form-label-row"> | |||||
<text class="required-star">*</text> | |||||
<text class="form-label">书评内容</text> | |||||
</view> | |||||
<textarea v-model="form.content" class="review-textarea custom-placeholder full-textarea" placeholder="请输入书评内容" /> | |||||
</view> | |||||
</view> | |||||
<view class="review-footer"> | |||||
<view class="footer-divider"></view> | |||||
<button class="submit-btn" @click="submitReview">发布</button> | |||||
</view> | |||||
</view> | |||||
</template> | |||||
<script> | |||||
import navbar from '@/components/base/navbar.vue' | |||||
export default { | |||||
components: { navbar }, | |||||
data() { | |||||
return { | |||||
bookTitle: '', | |||||
form: { | |||||
content: '' | |||||
}, | |||||
rules: { | |||||
content: [ | |||||
{ required: true, message: '请输入书评内容', trigger: ['blur', 'change'] } | |||||
] | |||||
} | |||||
} | |||||
}, | |||||
onLoad(options) { | |||||
// 通过路由参数获取书名 | |||||
this.bookTitle = options.title || '未知书名' | |||||
}, | |||||
methods: { | |||||
goBack() { | |||||
uni.navigateBack() | |||||
}, | |||||
submitReview() { | |||||
this.$refs.reviewForm.validate().then(() => { | |||||
// 提交逻辑,实际开发中可调用API | |||||
uni.showToast({ title: '发布成功', icon: 'success' }) | |||||
setTimeout(() => { | |||||
uni.navigateBack() | |||||
}, 1000) | |||||
}).catch(() => {}) | |||||
} | |||||
} | |||||
} | |||||
</script> | |||||
<style scoped lang="scss"> | |||||
.review-page { | |||||
min-height: 100vh; | |||||
background: #f8f8f8; | |||||
display: flex; | |||||
flex-direction: column; | |||||
margin-top: -50rpx; | |||||
} | |||||
.review-content { | |||||
background: #fff; | |||||
margin: 24rpx 24rpx 0 24rpx; | |||||
border-radius: 16rpx; | |||||
padding: 32rpx 24rpx 24rpx 24rpx; | |||||
display: flex; | |||||
flex-direction: column; | |||||
flex: 1; | |||||
min-height: 0; | |||||
padding-bottom: 140rpx; | |||||
margin-top: calc(var(--status-bar-height, 0px) + 100rpx); | |||||
} | |||||
.flex-grow { | |||||
flex: 1 1 0; | |||||
display: flex; | |||||
flex-direction: column; | |||||
min-height: 0; | |||||
} | |||||
.book-title-label { | |||||
color: #bdbdbd; | |||||
font-size: 24rpx; | |||||
margin-bottom: 4rpx; | |||||
} | |||||
.book-title { | |||||
font-size: 28rpx; | |||||
color: #222; | |||||
margin-bottom: 36rpx; | |||||
border-bottom: 1px solid #ededed; | |||||
padding-bottom: 8rpx; | |||||
} | |||||
.form-area { | |||||
margin-top: 18rpx; | |||||
} | |||||
.form-label-row { | |||||
display: flex; | |||||
align-items: center; | |||||
margin-bottom: 8rpx; | |||||
} | |||||
.required-star { | |||||
color: #e23d3d; | |||||
font-size: 22rpx; | |||||
margin-right: 4rpx; | |||||
line-height: 1; | |||||
} | |||||
.form-label { | |||||
color: #222; | |||||
font-size: 26rpx; | |||||
font-weight: 400; | |||||
} | |||||
.review-textarea { | |||||
width: 100%; | |||||
min-height: 320rpx; | |||||
border: none; | |||||
background: transparent; | |||||
font-size: 28rpx; | |||||
color: #333; | |||||
resize: none; | |||||
margin-top: 0; | |||||
outline: none; | |||||
} | |||||
.review-textarea.custom-placeholder::placeholder { | |||||
color: #d2d2d2; | |||||
font-size: 26rpx; | |||||
} | |||||
.full-textarea { | |||||
flex: 1; | |||||
min-height: 0; | |||||
max-height: none; | |||||
box-sizing: border-box; | |||||
margin-bottom: 0; | |||||
} | |||||
.review-footer { | |||||
position: fixed; | |||||
left: 0; | |||||
right: 0; | |||||
bottom: 90rpx; | |||||
background: #fff; | |||||
padding: 24rpx 32rpx 32rpx 32rpx; | |||||
box-shadow: 0 -2rpx 12rpx rgba(0,0,0,0.03); | |||||
z-index: 10; | |||||
} | |||||
.footer-divider { | |||||
width: 100%; | |||||
height: 2rpx; | |||||
background: #f2f2f2; | |||||
margin-bottom: 24rpx; | |||||
} | |||||
.submit-btn { | |||||
width: 100%; | |||||
height: 80rpx; | |||||
background: #0a225f; | |||||
color: #fff; | |||||
font-size: 30rpx; | |||||
border-radius: 40rpx; | |||||
font-weight: 500; | |||||
letter-spacing: 2rpx; | |||||
} | |||||
</style> |
@ -0,0 +1,228 @@ | |||||
<template> | |||||
<view class="subscription-info-container"> | |||||
<uv-navbar title="订阅信息" :autoBack="true" fixed placeholder titleStyle="color: #333; font-weight: 700;" :border="false" leftIconSize="46" /> | |||||
<view class="content-area"> | |||||
<view class="card"> | |||||
<view class="section-title">订阅章节</view> | |||||
<view class="row row-split"> | |||||
<template v-if="!showBatch"> | |||||
<text class="label">章节名称</text> | |||||
<view class="row-content"> | |||||
<text class="value">第1章 2004</text> | |||||
<text class="batch-link" @click="showBatch = true">批量订阅</text> | |||||
</view> | |||||
</template> | |||||
<template v-else> | |||||
<view class="batch-row"> | |||||
<view class="batch-left"> | |||||
<text class="star">*</text> | |||||
<text class="batch-title">批量订阅</text> | |||||
</view> | |||||
</view> | |||||
<view class="batch-input-row"> | |||||
<input class="batch-input" v-model="batchCount" placeholder="请输入订阅数" placeholder-class="batch-placeholder" /> | |||||
<text class="batch-action" @click="batchSubscribeAction">订阅本章</text> | |||||
</view> | |||||
<view class="batch-divider"></view> | |||||
</template> | |||||
</view> | |||||
<view class="row row-split"> | |||||
<text class="label">章节信息</text> | |||||
<view class="row-content"> | |||||
<text class="value">本次订阅消耗:10 豆豆</text> | |||||
</view> | |||||
</view> | |||||
<view class="row"> | |||||
<text class="label">支付方式</text> | |||||
<view class="row-content"> | |||||
<text class="value">账户余额:0 豆豆</text> | |||||
</view> | |||||
</view> | |||||
</view> | |||||
<view class="card order-info"> | |||||
<view class="section-title">订单信息</view> | |||||
<view class="row"> | |||||
<text class="label">内容</text> | |||||
</view> | |||||
<view class="row"> | |||||
<text class="price"><span class="total-label">合计:</span><span class="total-amount">0.10 元</span></text> | |||||
</view> | |||||
</view> | |||||
<view class="tips"> | |||||
请仔细检查并确认相关信息,因用户个人疏忽导致的充值错误、章节用户自行承担。一旦完成充值,概不退换。 | |||||
</view> | |||||
</view> | |||||
<button class="pay-btn" @click="payAndSubscribe">支付并订阅</button> | |||||
</view> | |||||
</template> | |||||
<script> | |||||
export default { | |||||
data() { | |||||
return { | |||||
showBatch: false, | |||||
batchCount: '' | |||||
} | |||||
}, | |||||
methods: { | |||||
batchSubscribe() { | |||||
uni.showToast({ title: '批量订阅功能开发中', icon: 'none' }) | |||||
}, | |||||
batchSubscribeAction() { | |||||
// Implementation of batchSubscribeAction method | |||||
}, | |||||
payAndSubscribe() { | |||||
uni.showToast({ title: '支付成功,已订阅', icon: 'success' }) | |||||
// 可在此处添加支付逻辑 | |||||
} | |||||
} | |||||
} | |||||
</script> | |||||
<style scoped> | |||||
.subscription-info-container { | |||||
background: #f8f8f8; | |||||
height: 100vh; | |||||
overflow: hidden; | |||||
position: relative; | |||||
} | |||||
.content-area { | |||||
padding-bottom: 180rpx; | |||||
} | |||||
body { | |||||
overflow: hidden; | |||||
} | |||||
.card { | |||||
background: #fff; | |||||
border-radius: 24rpx; | |||||
margin: 32rpx 24rpx 0 24rpx; | |||||
padding: 32rpx 24rpx; | |||||
box-shadow: 0 2rpx 8rpx rgba(0,0,0,0.03); | |||||
} | |||||
.section-title { | |||||
font-size: 32rpx; | |||||
font-weight: bold; | |||||
color: #222; | |||||
margin-bottom: 24rpx; | |||||
} | |||||
.row { | |||||
display: flex; | |||||
flex-direction: column; | |||||
padding: 10rpx 0; | |||||
margin-top: 10rpx; | |||||
} | |||||
.row-split { | |||||
border-bottom: 1px solid #f0f0f0; | |||||
} | |||||
.label { | |||||
color: #888; | |||||
font-size: 26rpx; | |||||
margin-bottom: 4rpx; | |||||
margin-top: 20rpx; | |||||
} | |||||
.row-content { | |||||
display: flex; | |||||
flex-direction: row; | |||||
align-items: center; | |||||
justify-content: space-between; | |||||
} | |||||
.value { | |||||
color: #222; | |||||
font-size: 26rpx; | |||||
} | |||||
.batch-link { | |||||
color: #3478f6; | |||||
font-size: 24rpx; | |||||
margin-left: 24rpx; | |||||
} | |||||
.order-info { | |||||
margin-top: 32rpx; | |||||
} | |||||
.order-row { | |||||
flex-direction: row; | |||||
align-items: center; | |||||
justify-content: space-between; | |||||
padding: 10rpx 0; | |||||
} | |||||
.price { | |||||
font-size: 28rpx; | |||||
margin-left: 0; | |||||
} | |||||
.total-label { | |||||
color: #222; | |||||
} | |||||
.total-amount { | |||||
color: #ff6600; | |||||
} | |||||
.tips { | |||||
color: #bbb; | |||||
font-size: 22rpx; | |||||
margin: 32rpx 24rpx 0 24rpx; | |||||
line-height: 1.6; | |||||
} | |||||
.pay-btn { | |||||
position: fixed; | |||||
left: 24rpx; | |||||
right: 24rpx; | |||||
bottom: 90rpx; | |||||
background: #0a297e; | |||||
color: #fff; | |||||
font-size: 32rpx; | |||||
border-radius: 40rpx; | |||||
height: 88rpx; | |||||
line-height: 88rpx; | |||||
text-align: center; | |||||
font-weight: bold; | |||||
z-index: 100; | |||||
} | |||||
.batch-row { | |||||
display: flex; | |||||
align-items: center; | |||||
justify-content: space-between; | |||||
margin-bottom: 0; | |||||
} | |||||
.batch-left { | |||||
display: flex; | |||||
align-items: center; | |||||
} | |||||
.star { | |||||
color: #f5222d; | |||||
margin-right: 6rpx; | |||||
font-size: 26rpx; | |||||
} | |||||
.batch-title { | |||||
font-size: 26rpx; | |||||
color: #222; | |||||
font-weight: 500; | |||||
} | |||||
.batch-action { | |||||
color: #3478f6; | |||||
font-size: 24rpx; | |||||
margin-left: 24rpx; | |||||
} | |||||
.batch-input-row { | |||||
display: flex; | |||||
align-items: center; | |||||
margin-top: 4rpx; | |||||
} | |||||
.batch-input { | |||||
flex: 1; | |||||
border: none; | |||||
font-size: 24rpx; | |||||
color: #bbb; | |||||
background: transparent; | |||||
outline: none; | |||||
padding: 0; | |||||
height: 40rpx; | |||||
} | |||||
.batch-placeholder { | |||||
color: #bbb; | |||||
font-size: 24rpx; | |||||
} | |||||
.batch-divider { | |||||
height: 2rpx; | |||||
background: #f0f0f0; | |||||
width: 100%; | |||||
margin-top: 4rpx; | |||||
} | |||||
</style> |
@ -0,0 +1,233 @@ | |||||
<template> | |||||
<view class="tipping-page"> | |||||
<!-- 顶部导航栏 --> | |||||
<uv-navbar title="读者亲密值榜单" fixed placeholder></uv-navbar> | |||||
<!-- 榜单前三名 --> | |||||
<view class="top-three"> | |||||
<view class="top-item second"> | |||||
<image class="avatar" :src="topList[1].avatar" mode="aspectFill" /> | |||||
<view class="name">{{ topList[1].name }}</view> | |||||
<view class="score">{{ topList[1].score }} 亲密值</view> | |||||
<view class="level">护书使者 五级</view> | |||||
</view> | |||||
<view class="top-item first"> | |||||
<image class="avatar" :src="topList[0].avatar" mode="aspectFill" /> | |||||
<view class="name">{{ topList[0].name }}</view> | |||||
<view class="score">{{ topList[0].score }} 亲密值</view> | |||||
<view class="level">护书使者 五级</view> | |||||
</view> | |||||
<view class="top-item third"> | |||||
<image class="avatar" :src="topList[2].avatar" mode="aspectFill" /> | |||||
<view class="name">{{ topList[2].name }}</view> | |||||
<view class="score">{{ topList[2].score }} 亲密值</view> | |||||
<view class="level">护书使者 五级</view> | |||||
</view> | |||||
</view> | |||||
<!-- 榜单列表 --> | |||||
<view class="rank-list"> | |||||
<RankListItem | |||||
v-for="(item, idx) in rankList" | |||||
:key="item.id" | |||||
:rankIcon="idx < 3 ? rankIcons[idx] : ''" | |||||
:rankNumImg="idx >= 3 ? ('/static/rank-num-' + (idx+1) + '.png') : ''" | |||||
medal="/static/medal.png" | |||||
:avatar="item.avatar" | |||||
:name="item.name" | |||||
:score="item.score" | |||||
level="护书使者 五级" | |||||
/> | |||||
</view> | |||||
<!-- 底部按钮 --> | |||||
<view class="bottom-btn-area"> | |||||
<button class="tipping-btn">互动打赏</button> | |||||
</view> | |||||
</view> | |||||
</template> | |||||
<script> | |||||
import RankListItem from '@/components/novel/RankListItem.vue' | |||||
export default { | |||||
components: { RankListItem }, | |||||
data() { | |||||
return { | |||||
topList: [ | |||||
{ | |||||
avatar: 'https://tse4-mm.cn.bing.net/th/id/OIP-C.iUyxJ_fxLjjX3kEBjteXWwAAAA?rs=1&pid=ImgDetMain', | |||||
name: '周海', | |||||
score: 6785452 | |||||
}, | |||||
{ | |||||
avatar: 'https://tse4-mm.cn.bing.net/th/id/OIP-C.iUyxJ_fxLjjX3kEBjteXWwAAAA?rs=1&pid=ImgDetMain', | |||||
name: '冯冉冉', | |||||
score: 6785452 | |||||
}, | |||||
{ | |||||
avatar: 'https://tse4-mm.cn.bing.net/th/id/OIP-C.iUyxJ_fxLjjX3kEBjteXWwAAAA?rs=1&pid=ImgDetMain', | |||||
name: '南静', | |||||
score: 6785452 | |||||
} | |||||
], | |||||
rankList: [ | |||||
{ id: 4, avatar: 'https://tse4-mm.cn.bing.net/th/id/OIP-C.iUyxJ_fxLjjX3kEBjteXWwAAAA?rs=1&pid=ImgDetMain', name: '钱胡胡', score: 5325324 }, | |||||
{ id: 5, avatar: 'https://tse4-mm.cn.bing.net/th/id/OIP-C.iUyxJ_fxLjjX3kEBjteXWwAAAA?rs=1&pid=ImgDetMain', name: '冯艺瑄', score: 4819704 }, | |||||
{ id: 6, avatar: 'https://tse4-mm.cn.bing.net/th/id/OIP-C.iUyxJ_fxLjjX3kEBjteXWwAAAA?rs=1&pid=ImgDetMain', name: '王凡宏', score: 4696874 }, | |||||
{ id: 7, avatar: 'https://tse4-mm.cn.bing.net/th/id/OIP-C.iUyxJ_fxLjjX3kEBjteXWwAAAA?rs=1&pid=ImgDetMain', name: '辛书萍', score: 3722953 }, | |||||
{ id: 8, avatar: 'https://tse4-mm.cn.bing.net/th/id/OIP-C.iUyxJ_fxLjjX3kEBjteXWwAAAA?rs=1&pid=ImgDetMain', name: '李婷', score: 2872476 }, | |||||
{ id: 9, avatar: 'https://tse4-mm.cn.bing.net/th/id/OIP-C.iUyxJ_fxLjjX3kEBjteXWwAAAA?rs=1&pid=ImgDetMain', name: '郑盈', score: 2464869 }, | |||||
{ id: 10, avatar: 'https://tse4-mm.cn.bing.net/th/id/OIP-C.iUyxJ_fxLjjX3kEBjteXWwAAAA?rs=1&pid=ImgDetMain', name: '吴承联', score: 990238 } | |||||
], | |||||
rankIcons: [ | |||||
'https://img.yzcdn.cn/vant/rank-1.png', | |||||
'https://img.yzcdn.cn/vant/rank-2.png', | |||||
'https://img.yzcdn.cn/vant/rank-3.png' | |||||
] | |||||
} | |||||
} | |||||
} | |||||
</script> | |||||
<style lang="scss" scoped> | |||||
.tipping-page { | |||||
min-height: 100vh; | |||||
background: linear-gradient(180deg, #b86e3b 0%, #e6b07c 100%); | |||||
padding-bottom: 40rpx; | |||||
} | |||||
.top-three { | |||||
display: flex; | |||||
justify-content: center; | |||||
align-items: flex-end; | |||||
margin: 40rpx 0 20rpx 0; | |||||
.top-item { | |||||
display: flex; | |||||
flex-direction: column; | |||||
align-items: center; | |||||
background: #fff7e0; | |||||
border-radius: 20rpx; | |||||
margin: 0 16rpx; | |||||
padding: 24rpx 18rpx 18rpx 18rpx; | |||||
box-shadow: 0 4rpx 16rpx 0 rgba(0,0,0,0.08); | |||||
position: relative; | |||||
width: 180rpx; | |||||
.avatar { | |||||
width: 90rpx; | |||||
height: 90rpx; | |||||
border-radius: 50%; | |||||
border: 4rpx solid #ffd700; | |||||
margin-bottom: 10rpx; | |||||
} | |||||
.name { | |||||
font-size: 28rpx; | |||||
font-weight: bold; | |||||
color: #b86e3b; | |||||
margin-bottom: 6rpx; | |||||
} | |||||
.score { | |||||
font-size: 24rpx; | |||||
color: #e6b07c; | |||||
margin-bottom: 4rpx; | |||||
} | |||||
.level { | |||||
font-size: 22rpx; | |||||
color: #b86e3b; | |||||
background: #ffe7b2; | |||||
border-radius: 10rpx; | |||||
padding: 2rpx 12rpx; | |||||
} | |||||
} | |||||
.first { | |||||
transform: scale(1.15); | |||||
z-index: 2; | |||||
background: #fffbe6; | |||||
box-shadow: 0 8rpx 24rpx 0 rgba(255,215,0,0.18); | |||||
} | |||||
.second, .third { | |||||
z-index: 1; | |||||
opacity: 0.95; | |||||
} | |||||
} | |||||
.rank-list { | |||||
background: transparent; | |||||
margin: 0 24rpx; | |||||
margin-top: 20rpx; | |||||
.rank-item { | |||||
display: flex; | |||||
align-items: center; | |||||
justify-content: space-between; | |||||
background: #fffbe6; | |||||
border-radius: 16rpx; | |||||
margin-bottom: 18rpx; | |||||
box-shadow: 0 2rpx 8rpx 0 rgba(184,110,59,0.06); | |||||
padding: 0 24rpx; | |||||
height: 100rpx; | |||||
.rank-left { | |||||
display: flex; | |||||
align-items: center; | |||||
.rank-icon, .rank-num-img { | |||||
width: 38rpx; | |||||
height: 38rpx; | |||||
margin-right: 10rpx; | |||||
} | |||||
.medal { | |||||
width: 44rpx; | |||||
height: 44rpx; | |||||
margin-right: 10rpx; | |||||
} | |||||
.avatar { | |||||
width: 44rpx; | |||||
height: 44rpx; | |||||
border-radius: 50%; | |||||
margin-right: 14rpx; | |||||
border: 2rpx solid #ffd700; | |||||
object-fit: cover; | |||||
} | |||||
.name { | |||||
font-size: 26rpx; | |||||
color: #222; | |||||
font-weight: 500; | |||||
} | |||||
} | |||||
.rank-right { | |||||
display: flex; | |||||
flex-direction: column; | |||||
align-items: flex-end; | |||||
.score { | |||||
font-size: 22rpx; | |||||
color: #b86e3b; | |||||
} | |||||
.level { | |||||
font-size: 20rpx; | |||||
color: #fff; | |||||
background: #e6b07c; | |||||
border-radius: 8rpx; | |||||
padding: 2rpx 10rpx; | |||||
margin-top: 6rpx; | |||||
font-weight: 500; | |||||
} | |||||
} | |||||
} | |||||
} | |||||
.bottom-btn-area { | |||||
margin: 40rpx 24rpx 90rpx 24rpx; | |||||
display: flex; | |||||
flex-direction: column; | |||||
gap: 24rpx; | |||||
.tipping-btn { | |||||
width: 100%; | |||||
height: 80rpx; | |||||
background: #fffbe6; | |||||
color: #b86e3b; | |||||
font-size: 32rpx; | |||||
border-radius: 40rpx; | |||||
font-weight: bold; | |||||
letter-spacing: 2rpx; | |||||
box-shadow: 0 4rpx 16rpx 0 rgba(184,110,59,0.12); | |||||
border: none; | |||||
} | |||||
} | |||||
</style> |
@ -0,0 +1,249 @@ | |||||
<!-- 钱包流水页面 --> | |||||
<template> | |||||
<view class="walletflow-page"> | |||||
<!-- 顶部导航栏 --> | |||||
<uv-navbar title="钱包流水" :autoBack="true" fixed placeholder titleStyle="color: #333; font-weight: 700;" :border="false" /> | |||||
<!-- 账户余额卡片 --> | |||||
<view class="balance-card"> | |||||
<view class="balance-label">账户</view> | |||||
<view class="balance-row"> | |||||
<text class="balance-amount">{{ balance }}</text> | |||||
<button class="recharge-btn" @click="goRecharge">充值</button> | |||||
</view> | |||||
</view> | |||||
<!-- tab和流水列表卡片 --> | |||||
<view class="flow-card"> | |||||
<view class="tab-header"> | |||||
<view :class="['tab-item', {active: activeTab === 0}]" @click="activeTab = 0"> | |||||
充值 | |||||
<view v-if="activeTab === 0" class="tab-underline"></view> | |||||
</view> | |||||
<view :class="['tab-item', {active: activeTab === 1}]" @click="activeTab = 1"> | |||||
支付 | |||||
<view v-if="activeTab === 1" class="tab-underline"></view> | |||||
</view> | |||||
</view> | |||||
<scroll-view scroll-y class="flow-list"> | |||||
<view v-if="activeTab === 0"> | |||||
<view class="flow-item" v-for="(item, idx) in rechargeList" :key="idx"> | |||||
<view class="flow-item-row"> | |||||
<view class="flow-item-left"> | |||||
<view class="flow-title">{{ item.title }}</view> | |||||
<view class="flow-date">{{ item.date }}</view> | |||||
</view> | |||||
<view class="flow-amount plus">+{{ item.amount }}</view> | |||||
</view> | |||||
</view> | |||||
</view> | |||||
<view v-else> | |||||
<view class="flow-item" v-for="(item, idx) in payList" :key="idx"> | |||||
<view class="flow-item-row"> | |||||
<view class="flow-item-left"> | |||||
<view class="flow-title">{{ item.title }}</view> | |||||
<view class="flow-date">{{ item.date }}</view> | |||||
</view> | |||||
<view class="flow-amount minus">-{{ item.amount }}</view> | |||||
</view> | |||||
</view> | |||||
</view> | |||||
</scroll-view> | |||||
</view> | |||||
</view> | |||||
</template> | |||||
<script> | |||||
export default { | |||||
data() { | |||||
return { | |||||
balance: 34532, | |||||
activeTab: 0, | |||||
rechargeList: [ | |||||
{ title: '豆豆充值', date: '2025.03.18', amount: 55 }, | |||||
{ title: '豆豆充值', date: '2025.03.18', amount: 55 }, | |||||
{ title: '豆豆充值', date: '2025.03.18', amount: 55 }, | |||||
{ title: '推荐票', date: '2025.03.18', amount: 5 }, | |||||
{ title: '豆豆充值', date: '2025.03.18', amount: 55 }, | |||||
{ title: '豆豆充值', date: '2025.03.18', amount: 55 }, | |||||
{ title: '豆豆充值', date: '2025.03.18', amount: 55 }, | |||||
{ title: '豆豆充值', date: '2025.03.18', amount: 55 }, | |||||
{ title: '豆豆充值', date: '2025.03.18', amount: 55 }, | |||||
{ title: '豆豆充值', date: '2025.03.18', amount: 55 }, | |||||
{ title: '豆豆充值', date: '2025.03.18', amount: 55 }, | |||||
{ title: '豆豆充值', date: '2025.03.18', amount: 55 }, | |||||
{ title: '豆豆充值', date: '2025.03.18', amount: 55 }, | |||||
{ title: '豆豆充值', date: '2025.03.18', amount: 55 }, | |||||
], | |||||
payList: [ | |||||
{ title: '章节支付', date: '2025.03.18', amount: 10 }, | |||||
{ title: '章节支付', date: '2025.03.18', amount: 10 }, | |||||
{ title: '章节支付', date: '2025.03.18', amount: 10 }, | |||||
{ title: '章节支付', date: '2025.03.18', amount: 10 }, | |||||
{ title: '章节支付', date: '2025.03.18', amount: 10 }, | |||||
{ title: '章节支付', date: '2025.03.18', amount: 10 }, | |||||
{ title: '章节支付', date: '2025.03.18', amount: 10 }, | |||||
{ title: '章节支付', date: '2025.03.18', amount: 10 }, | |||||
{ title: '章节支付', date: '2025.03.18', amount: 10 }, | |||||
{ title: '章节支付', date: '2025.03.18', amount: 10 }, | |||||
{ title: '章节支付', date: '2025.03.18', amount: 10 }, | |||||
{ title: '章节支付', date: '2025.03.18', amount: 10 }, | |||||
{ title: '章节支付', date: '2025.03.18', amount: 10 }, | |||||
{ title: '章节支付', date: '2025.03.18', amount: 10 }, | |||||
{ title: '章节支付', date: '2025.03.18', amount: 10 }, | |||||
] | |||||
} | |||||
}, | |||||
methods: { | |||||
goRecharge() { | |||||
uni.showToast({ title: '充值功能开发中', icon: 'none' }) | |||||
} | |||||
} | |||||
} | |||||
</script> | |||||
<style lang="scss" scoped> | |||||
.walletflow-page { | |||||
min-height: 100vh; | |||||
background: linear-gradient(180deg, #f8f8fc 0%, #fff 100%); | |||||
padding-bottom: 30rpx; | |||||
} | |||||
.balance-card { | |||||
background: linear-gradient(90deg, #f7f2fa 0%, #fbeaf2 100%); | |||||
border-radius: 18rpx; | |||||
margin: 24rpx 12rpx 0 12rpx; | |||||
padding: 18rpx 24rpx 14rpx 24rpx; | |||||
box-shadow: none; | |||||
border: 1rpx solid #ede7ef; | |||||
position: relative; | |||||
display: flex; | |||||
flex-direction: column; | |||||
min-height: 130rpx; | |||||
justify-content: center; | |||||
.balance-label { | |||||
color: #bbb; | |||||
font-size: 26rpx; | |||||
margin-bottom: 8rpx; | |||||
} | |||||
.balance-row { | |||||
display: flex; | |||||
align-items: center; | |||||
margin-top: 0; | |||||
position: relative; | |||||
.balance-amount { | |||||
color: #e94f7a; | |||||
font-size: 48rpx; | |||||
font-weight: bold; | |||||
} | |||||
.recharge-btn { | |||||
position: absolute; | |||||
right: 0; | |||||
top: 50%; | |||||
transform: translateY(-50%); | |||||
background: linear-gradient(90deg, #ffb6c1 0%, #fa5a99 100%); | |||||
color: #fff; | |||||
font-size: 28rpx; | |||||
border-radius: 32rpx; | |||||
padding: 0 40rpx; | |||||
height: 56rpx; | |||||
line-height: 56rpx; | |||||
font-weight: 500; | |||||
border: none; | |||||
box-shadow: none; | |||||
display: flex; | |||||
align-items: center; | |||||
justify-content: center; | |||||
} | |||||
} | |||||
} | |||||
.flow-card { | |||||
background: #fff; | |||||
border-radius: 20rpx; | |||||
margin: 32rpx 16rpx 0 16rpx; | |||||
box-shadow: 0 4rpx 24rpx 0 rgba(0,0,0,0.06); | |||||
padding-bottom: 8rpx; | |||||
overflow: hidden; | |||||
} | |||||
.tab-header { | |||||
display: flex; | |||||
margin: 0; | |||||
background: #fff; | |||||
border-top-left-radius: 20rpx; | |||||
border-top-right-radius: 20rpx; | |||||
overflow: hidden; | |||||
.tab-item { | |||||
flex: 1; | |||||
text-align: center; | |||||
font-size: 30rpx; | |||||
color: #888; | |||||
padding: 0 0 18rpx 0; | |||||
font-weight: bold; | |||||
background: transparent; | |||||
position: relative; | |||||
&.active { | |||||
color: #223a7a; | |||||
font-weight: bold; | |||||
} | |||||
.tab-underline { | |||||
position: absolute; | |||||
left: 50%; | |||||
bottom: 0; | |||||
transform: translateX(-50%); | |||||
width: 44rpx; | |||||
height: 4rpx; | |||||
background: #223a7a; | |||||
border-radius: 2rpx; | |||||
margin-top: 4rpx; | |||||
} | |||||
} | |||||
} | |||||
.flow-list { | |||||
margin: 0; | |||||
padding: 0 16rpx; | |||||
max-height: 75vh; | |||||
background: #fff; | |||||
} | |||||
.flow-item { | |||||
border-bottom: 1px solid #f5f5f5; | |||||
padding: 18rpx 0 8rpx 0; | |||||
&:last-child { | |||||
border-bottom: none; | |||||
} | |||||
.flow-item-row { | |||||
display: flex; | |||||
align-items: flex-start; | |||||
justify-content: space-between; | |||||
padding-right: 45rpx; | |||||
padding-left: 15rpx; | |||||
} | |||||
.flow-item-left { | |||||
display: flex; | |||||
flex-direction: column; | |||||
align-items: flex-start; | |||||
.flow-title { | |||||
font-size: 28rpx; | |||||
color: #222; | |||||
font-weight: 500; | |||||
margin-bottom: 2rpx; | |||||
} | |||||
.flow-date { | |||||
color: #bbb; | |||||
font-size: 22rpx; | |||||
margin-top: 0; | |||||
} | |||||
} | |||||
.flow-amount { | |||||
font-size: 26rpx; | |||||
font-weight: 500; | |||||
margin-left: 24rpx; | |||||
margin-top: 2rpx; | |||||
&.plus { | |||||
color: #223a7a; | |||||
} | |||||
&.minus { | |||||
color: #e94f7a; | |||||
} | |||||
} | |||||
} | |||||
</style> |
@ -0,0 +1,232 @@ | |||||
<template> | |||||
<view class="comments-page"> | |||||
<!-- 顶部导航栏 --> | |||||
<navbar title="评论详情" :leftClick="true" @leftClick="goBack" /> | |||||
<!-- 书本名称 --> | |||||
<view class="book-title-area"> | |||||
<view class="book-title-label">书本名称</view> | |||||
<view class="book-title">《{{ bookTitle }}》</view> | |||||
</view> | |||||
<!-- 主评论卡片 --> | |||||
<view class="comment-card"> | |||||
<view class="comment-header"> | |||||
<image class="avatar" :src="comment.avatar" mode="aspectFill" /> | |||||
<view class="user-info"> | |||||
<text class="username">{{ comment.username }}</text> | |||||
</view> | |||||
</view> | |||||
<view class="comment-content">{{ comment.content }}</view> | |||||
<view class="comment-footer"> | |||||
<text class="comment-time">{{ comment.time }}</text> | |||||
</view> | |||||
</view> | |||||
<!-- 全部评论列表 --> | |||||
<view class="all-reply-area"> | |||||
<view class="all-reply-header">全部评论·{{ comment.replyCount }}</view> | |||||
<view class="reply-list"> | |||||
<view class="reply-item" v-for="(item, idx) in replies" :key="idx"> | |||||
<image class="reply-avatar" :src="item.avatar" mode="aspectFill" /> | |||||
<view class="reply-main"> | |||||
<view class="reply-username">{{ item.username }}</view> | |||||
<view class="reply-content">{{ item.content }}</view> | |||||
<view class="reply-time">{{ item.time }}</view> | |||||
</view> | |||||
</view> | |||||
</view> | |||||
</view> | |||||
<!-- 底部回复按钮 --> | |||||
<view class="reply-footer"> | |||||
<button class="submit-btn" @click="goToRespond">回复评论</button> | |||||
</view> | |||||
</view> | |||||
</template> | |||||
<script> | |||||
import navbar from '@/components/base/navbar.vue' | |||||
export default { | |||||
components: { navbar }, | |||||
data() { | |||||
return { | |||||
bookTitle: '这游戏也太真实了', | |||||
comment: { | |||||
avatar: 'https://tse4-mm.cn.bing.net/th/id/OIP-C.iUyxJ_fxLjjX3kEBjteXWwAAAA?rs=1&pid=ImgDetMain', | |||||
username: '方香橙', | |||||
content: '我是本书的作者方香橙,这是一本甜文爽文哒!请放心入坑,五星好评!女主又美有个性可爱,绝对不圣母,不傻白!男主身心干净深情独宠媳妇儿一个人...', | |||||
time: '2024.07.09', | |||||
replyCount: 17 | |||||
}, | |||||
replies: [ | |||||
{ | |||||
avatar: 'https://tse4-mm.cn.bing.net/th/id/OIP-C.iUyxJ_fxLjjX3kEBjteXWwAAAA?rs=1&pid=ImgDetMain', | |||||
username: '方香橙', | |||||
content: '我是本书的作者方香橙,这是一本甜文爽文哒!请放心入坑,五星好评!女主又美有个性可爱,绝对不圣母,不傻白!男主身心干净深情独宠媳妇儿一个人...', | |||||
time: '2024.07.09' | |||||
}, | |||||
{ | |||||
avatar: 'https://tse4-mm.cn.bing.net/th/id/OIP-C.iUyxJ_fxLjjX3kEBjteXWwAAAA?rs=1&pid=ImgDetMain', | |||||
username: '战斗世界', | |||||
content: '这本书打破了我看甜文套路之前的观念女主真的太可爱太有趣和以往看过的一个NPC介绍有很大不同', | |||||
time: '2024.07.09' | |||||
} | |||||
] | |||||
} | |||||
}, | |||||
methods: { | |||||
goBack() { | |||||
uni.navigateBack() | |||||
}, | |||||
goToRespond() { | |||||
uni.navigateTo({ url: '/pages_order/novel/Respondcomments' }) | |||||
}, | |||||
submitReply() { | |||||
uni.showToast({ title: '功能开发中', icon: 'none' }) | |||||
} | |||||
} | |||||
} | |||||
</script> | |||||
<style scoped lang="scss"> | |||||
.comments-page { | |||||
min-height: 100vh; | |||||
background: #f8f8f8; | |||||
display: flex; | |||||
flex-direction: column; | |||||
} | |||||
.book-title-area { | |||||
background: #fff; | |||||
margin: 24rpx 24rpx 0 24rpx; | |||||
border-radius: 16rpx; | |||||
padding: 24rpx 24rpx 0 24rpx; | |||||
} | |||||
.book-title-label { | |||||
color: #bdbdbd; | |||||
font-size: 24rpx; | |||||
margin-bottom: 4rpx; | |||||
} | |||||
.book-title { | |||||
font-size: 28rpx; | |||||
color: #222; | |||||
margin-bottom: 16rpx; | |||||
border-bottom: 1px solid #ededed; | |||||
padding-bottom: 8rpx; | |||||
} | |||||
.comment-card { | |||||
background: #fff; | |||||
margin: 0 24rpx 0 24rpx; | |||||
border-radius: 16rpx; | |||||
padding: 24rpx 24rpx 0 24rpx; | |||||
box-shadow: 0 2rpx 8rpx rgba(0,0,0,0.03); | |||||
margin-bottom: 0; | |||||
} | |||||
.comment-header { | |||||
display: flex; | |||||
align-items: center; | |||||
margin-bottom: 8rpx; | |||||
} | |||||
.avatar { | |||||
width: 56rpx; | |||||
height: 56rpx; | |||||
border-radius: 50%; | |||||
margin-right: 16rpx; | |||||
} | |||||
.user-info { | |||||
display: flex; | |||||
flex-direction: column; | |||||
} | |||||
.username { | |||||
font-size: 26rpx; | |||||
color: #222; | |||||
font-weight: 500; | |||||
} | |||||
.comment-content { | |||||
font-size: 26rpx; | |||||
color: #333; | |||||
margin-bottom: 12rpx; | |||||
} | |||||
.comment-footer { | |||||
display: flex; | |||||
align-items: center; | |||||
font-size: 22rpx; | |||||
color: #bdbdbd; | |||||
} | |||||
.comment-time { | |||||
color: #bdbdbd; | |||||
margin-top: 18rpx; | |||||
} | |||||
.all-reply-area { | |||||
background: #fff; | |||||
margin: 0 24rpx 0 24rpx; | |||||
border-radius: 16rpx; | |||||
padding: 24rpx 24rpx 16rpx 24rpx; | |||||
margin-top: 24rpx; | |||||
} | |||||
.all-reply-header { | |||||
color: #222; | |||||
font-size: 28rpx; | |||||
font-weight: 500; | |||||
margin-bottom: 16rpx; | |||||
} | |||||
.reply-list { | |||||
margin-top: 40rpx; | |||||
display: flex; | |||||
flex-direction: column; | |||||
gap: 50rpx; | |||||
} | |||||
.reply-item { | |||||
display: flex; | |||||
align-items: flex-start; | |||||
} | |||||
.reply-avatar { | |||||
width: 44rpx; | |||||
height: 44rpx; | |||||
border-radius: 50%; | |||||
margin-right: 16rpx; | |||||
flex-shrink: 0; | |||||
} | |||||
.reply-main { | |||||
flex: 1; | |||||
display: flex; | |||||
flex-direction: column; | |||||
} | |||||
.reply-username { | |||||
font-size: 24rpx; | |||||
color: #222; | |||||
font-weight: 500; | |||||
margin-bottom: 4rpx; | |||||
} | |||||
.reply-content { | |||||
font-size: 24rpx; | |||||
color: #333; | |||||
margin-bottom: 6rpx; | |||||
word-break: break-all; | |||||
} | |||||
.reply-time { | |||||
font-size: 20rpx; | |||||
color: #bdbdbd; | |||||
} | |||||
.reply-footer { | |||||
position: fixed; | |||||
left: 0; | |||||
right: 0; | |||||
bottom: 90rpx; | |||||
background: #fff; | |||||
padding: 24rpx 32rpx 32rpx 32rpx; | |||||
box-shadow: 0 -2rpx 12rpx rgba(0,0,0,0.03); | |||||
z-index: 10; | |||||
} | |||||
.submit-btn { | |||||
width: 100%; | |||||
height: 80rpx; | |||||
background: #0a225f; | |||||
color: #fff; | |||||
font-size: 30rpx; | |||||
border-radius: 40rpx; | |||||
font-weight: 500; | |||||
letter-spacing: 2rpx; | |||||
} | |||||
</style> |
@ -0,0 +1,116 @@ | |||||
<template> | |||||
<view class="creator-page"> | |||||
<uv-navbar title="请成为创作者" fixed placeholder></uv-navbar> | |||||
<view class="form-card"> | |||||
<view class="form-item"> | |||||
<text class="required">*</text> | |||||
<text class="label">笔名</text> | |||||
<input v-model="penName" placeholder="请输入" class="input" placeholder-class="input-placeholder" /> | |||||
</view> | |||||
<view class="form-item"> | |||||
<text class="required">*</text> | |||||
<text class="label">简介</text> | |||||
<textarea v-model="intro" placeholder="请输入" class="textarea" placeholder-class="input-placeholder" /> | |||||
</view> | |||||
</view> | |||||
<view class="footer-btn-area"> | |||||
<button class="submit-btn" @click="submit">成为创作者</button> | |||||
</view> | |||||
</view> | |||||
</template> | |||||
<script> | |||||
export default { | |||||
data() { | |||||
return { | |||||
penName: '', | |||||
intro: '' | |||||
} | |||||
}, | |||||
methods: { | |||||
submit() { | |||||
if (!this.penName) { | |||||
uni.showToast({ title: '请输入笔名', icon: 'none' }) | |||||
return | |||||
} | |||||
if (!this.intro) { | |||||
uni.showToast({ title: '请输入简介', icon: 'none' }) | |||||
return | |||||
} | |||||
// 这里可以添加提交逻辑 | |||||
uni.showToast({ title: '申请成功', icon: 'success' }) | |||||
setTimeout(() => { | |||||
uni.navigateBack() | |||||
}, 800) | |||||
} | |||||
} | |||||
} | |||||
</script> | |||||
<style scoped lang="scss"> | |||||
.creator-page { | |||||
min-height: 100vh; | |||||
background: #f7f8fa; | |||||
display: flex; | |||||
flex-direction: column; | |||||
} | |||||
.form-card { | |||||
background: #fff; | |||||
border-radius: 20rpx; | |||||
margin: 40rpx 32rpx 0 32rpx; | |||||
padding: 32rpx 24rpx; | |||||
box-shadow: 0 4rpx 24rpx 0 rgba(0,0,0,0.04); | |||||
} | |||||
.form-item { | |||||
display: flex; | |||||
flex-direction: column; | |||||
margin-bottom: 32rpx; | |||||
position: relative; | |||||
} | |||||
.required { | |||||
color: #e23d3d; | |||||
font-size: 28rpx; | |||||
margin-right: 4rpx; | |||||
} | |||||
.label { | |||||
font-size: 28rpx; | |||||
color: #222; | |||||
font-weight: bold; | |||||
margin-bottom: 12rpx; | |||||
} | |||||
.input, .textarea { | |||||
width: 100%; | |||||
height: 80rpx; | |||||
border: none; | |||||
border-bottom: 1.5rpx solid #ececec; | |||||
font-size: 28rpx; | |||||
background: transparent; | |||||
padding: 18rpx 0 12rpx 0; | |||||
margin-bottom: 2rpx; | |||||
} | |||||
.input-placeholder { | |||||
color: #d2d2d2; | |||||
font-size: 26rpx; | |||||
} | |||||
.textarea { | |||||
min-height: 120rpx; | |||||
resize: none; | |||||
} | |||||
.footer-btn-area { | |||||
margin-top: auto; | |||||
padding: 48rpx 32rpx 32rpx 32rpx; | |||||
background: transparent; | |||||
margin-bottom: 80rpx; | |||||
} | |||||
.submit-btn { | |||||
width: 100%; | |||||
height: 88rpx; | |||||
background: #0a2e6d; | |||||
color: #fff; | |||||
font-size: 32rpx; | |||||
border-radius: 44rpx; | |||||
font-weight: bold; | |||||
letter-spacing: 2rpx; | |||||
transition: background 0.2s; | |||||
} | |||||
</style> |
@ -0,0 +1,448 @@ | |||||
<template> | |||||
<!-- 小说文本页面 --> | |||||
<view class="reader-container" @click.native="toggleFullScreen"> | |||||
<uv-navbar title="这游戏也太真实了" :autoBack="true" fixed placeholder titleStyle="color: #333; font-weight: 700;" :border="false"> | |||||
<template #left> | |||||
<uv-icon name="arrow-left" size="46" color="#333" @click="$emit('back')" /> | |||||
</template> | |||||
</uv-navbar> | |||||
<view class="chapter-title">第1章 2004</view> | |||||
<scroll-view scroll-y class="chapter-content" style="height: 70vh;" @touchend="handleTouchEnd" @scroll="handleScroll" @tap="handleContentClick"> | |||||
<text> | |||||
华星,华东地区某个省市区,不知名街后居民…… | |||||
读朱自清的荷塘月色,品读鲁迅的从百草园到三味书屋,看梁实秋的雅舍!一篇篇经典散文,想起来就像藏在脑海里的动画,优雅唯美的画面,好像夜晚的微风,轻抚着凝望远方的脸颊!美文入心!感慨万千!下面是100篇名家经典散文摘抄,敬请你的欣赏! | |||||
100篇名家经典散文摘抄 | |||||
《叶圣陶散文》为"名家经典珍藏"丛书之一,收录了叶圣陶先生的散文精品数十篇。这些作品内容丰富,题材各异,构思精巧,文笔精巧、语言幽默、内蕴深厚、风格恬淡,充分显示了叶圣陶先生的文学功底及丰富的人生阅历,从一个侧面反映了作者的思想感情及创作风格,非常值得一读。叶圣陶是20世纪中国一位杰出的作家、教育家和出版家,又是中国现代儿童文学创作的先行者。作为散文家,他早期和周作人、朱自清共同成为文学研究会散文创作的中坚,后来又成为开明派散文的代表,其散文被一九三五年出版的《中国新文学大系》选录的篇数仅次于周作人、鲁迅和朱自清。 | |||||
1、朱自清《荷塘月色》片段 | |||||
路上只我一个人,背着手踱着。这一片天地好像是我的;我也像超出了平常旳自己,到了另一世界里。我爱热闹,也爱冷静;爱群居,也爱独处。像今晚上,一个人在这苍茫旳月下,什么都可以想,什么都可以不想,便觉是个自由的人。白天里一定要做的事,一定要说的话,现在都可不理。这是独处的妙处,我且受用这无边的荷香月色好了。 | |||||
曲曲折折的荷塘上面,弥望旳是田田的叶子。叶子出水很高,像亭亭旳舞女旳裙。层层的叶子中间,零星地点缀着些白花,有袅娜(niǎo,nuó)地开着旳,有羞涩地打着朵儿旳;正如一粒粒的明珠,又如碧天里的星星,又如刚出浴的美人。微风过处,送来缕缕清香,仿佛远处高楼上渺茫的歌声似的。这时候叶子与花也有一丝的颤动,像闪电般,霎时传过荷塘的那边去了。叶子本是肩并肩密密地挨着,这便宛然有了一道凝碧的波痕。叶子底下是脉脉(mò)的流水,遮住了,不能见一些颜色;而叶子却更见风致了。 | |||||
月光如流水一般,静静地泻在这一片叶子和花上。薄薄的青雾浮起在荷塘里。叶子和花仿佛在牛乳中洗过一样;又像笼着轻纱的梦。虽然是满月,天上却有一层淡淡的云,所以不能朗照;但我以为这恰是到了好处——酣眠固不可少,小睡也别有风味的。月光是隔了树照过来的,高处丛生的灌木,落下参差的斑驳的黑影,峭楞楞如鬼一般;弯弯的杨柳的稀疏的倩影,却又像是画在荷叶上。塘中的月色并不均匀;但光与影有着和谐的旋律,如梵婀(ē)玲(英语violin小提琴的译音)上奏着的名曲。 | |||||
荷塘的四面,远远近近,高高低低都是树,而杨柳最多。这些树将一片荷塘重重围住;只在小路一旁,漏着几段空隙,像是特为月光留下的。树色一例是阴阴的,乍看像一团烟雾;但杨柳的丰姿,便在烟雾里也辨得出。树梢上隐隐约约的是一带远山,只有些大意罢了。树缝里也漏着一两点路灯光,没精打采的,是渴睡人的眼。这时候最热闹的,要数树上的蝉声与水里的蛙声;但热闹是它们的,我什么也没有。 | |||||
2、鲁迅《从百草园到三味书屋》片段 | |||||
100篇名家经典散文摘抄 | |||||
《叶圣陶散文》为"名家经典珍藏"丛书之一,收录了叶圣陶先生的散文精品数十篇。这些作品内容丰富,题材各异,构思精巧,文笔精巧、语言幽默、内蕴深厚、风格恬淡,充分显示了叶圣陶先生的文学功底及丰富的人生阅历,从一个侧面反映了作者的思想感情及创作风格,非常值得一读。叶圣陶是20世纪中国一位杰出的作家、教育家和出版家,又是中国现代儿童文学创作的先行者。作为散文家,他早期和周作人、朱自清共同成为文学研究会散文创作的中坚,后来又成为开明派散文的代表,其散文被一九三五年出版的《中国新文学大系》选录的篇数仅次于周作人、鲁迅和朱自清。 | |||||
1、朱自清《荷塘月色》片段 | |||||
路上只我一个人,背着手踱着。这一片天地好像是我的;我也像超出了平常旳自己,到了另一世界里。我爱热闹,也爱冷静;爱群居,也爱独处。像今晚上,一个人在这苍茫旳月下,什么都可以想,什么都可以不想,便觉是个自由的人。白天里一定要做的事,一定要说的话,现在都可不理。这是独处的妙处,我且受用这无边的荷香月色好了。 | |||||
曲曲折折的荷塘上面,弥望旳是田田的叶子。叶子出水很高,像亭亭旳舞女旳裙。层层的叶子中间,零星地点缀着些白花,有袅娜(niǎo,nuó)地开着旳,有羞涩地打着朵儿旳;正如一粒粒的明珠,又如碧天里的星星,又如刚出浴的美人。微风过处,送来缕缕清香,仿佛远处高楼上渺茫的歌声似的。这时候叶子与花也有一丝的颤动,像闪电般,霎时传过荷塘的那边去了。叶子本是肩并肩密密地挨着,这便宛然有了一道凝碧的波痕。叶子底下是脉脉(mò)的流水,遮住了,不能见一些颜色;而叶子却更见风致了。 | |||||
月光如流水一般,静静地泻在这一片叶子和花上。薄薄的青雾浮起在荷塘里。叶子和花仿佛在牛乳中洗过一样;又像笼着轻纱的梦。虽然是满月,天上却有一层淡淡的云,所以不能朗照;但我以为这恰是到了好处——酣眠固不可少,小睡也别有风味的。月光是隔了树照过来的,高处丛生的灌木,落下参差的斑驳的黑影,峭楞楞如鬼一般;弯弯的杨柳的稀疏的倩影,却又像是画在荷叶上。塘中的月色并不均匀;但光与影有着和谐的旋律,如梵婀(ē)玲(英语violin小提琴的译音)上奏着的名曲。 | |||||
荷塘的四面,远远近近,高高低低都是树,而杨柳最多。这些树将一片荷塘重重围住;只在小路一旁,漏着几段空隙,像是特为月光留下的。树色一例是阴阴的,乍看像一团烟雾;但杨柳的丰姿,便在烟雾里也辨得出。树梢上隐隐约约的是一带远山,只有些大意罢了。树缝里也漏着一两点路灯光,没精打采的,是渴睡人的眼。这时候最热闹的,要数树上的蝉声与水里的蛙声;但热闹是它们的,我什么也没有。 | |||||
2、鲁迅《从百草园到三味书屋》片段 | |||||
100篇名家经典散文摘抄 | |||||
<!-- 这里填充章节内容,后续可通过props或API获取 --> | |||||
</text> | |||||
</scroll-view> | |||||
<view class="bottom-bar" v-if="!isFullScreen"> | |||||
<view class="bottom-left"> | |||||
<view class="bar-item"> | |||||
<view class="bar-icon"> <uv-icon name="plus"></uv-icon> </view> | |||||
<text class="bar-label">加入书架</text> | |||||
</view> | |||||
<view class="bar-item"> | |||||
<view class="bar-icon"> <uv-icon name="eye-fill"></uv-icon> </view> | |||||
<text class="bar-label">夜间</text> | |||||
</view> | |||||
</view> | |||||
<view class="bottom-right"> | |||||
<button class="outline-btn"><text class="btn-text">上一章</text></button> | |||||
<button class="outline-btn" @click="showCatalog = true"><text class="btn-text">目录</text></button> | |||||
<button class="outline-btn"><text class="btn-text">下一章</text></button> | |||||
</view> | |||||
</view> | |||||
<uv-popup v-model="showPopup" mode="center" :closeOnClickOverlay="true"> | |||||
<view style="padding: 48rpx 32rpx; text-align: center; background: #fff; border-radius: 24rpx; min-width: 500rpx;"> | |||||
<view style="font-size: 32rpx; font-weight: bold; color: #222; margin-bottom: 24rpx;">这是付费章节 需要订阅后才能阅读</view> | |||||
<view style="font-size: 26rpx; color: #999; margin-bottom: 40rpx;">订阅后可继续阅读本章内容</view> | |||||
<view style="display: flex; justify-content: center; gap: 24rpx;"> | |||||
<button style="background: #ff9800; color: #fff; border-radius: 32rpx; font-size: 28rpx; padding: 0 32rpx; border: none;" @click="goToSubscription">订阅本章</button> | |||||
<button style="background: #fff3e0; color: #ff9800; border-radius: 32rpx; font-size: 28rpx; padding: 0 32rpx; border: 1px solid #ff9800;">观看视频解锁</button> | |||||
<button style="background: #fff; color: #ff9800; border-radius: 32rpx; font-size: 28rpx; padding: 0 32rpx; border: 1px solid #ff9800;">批量订阅</button> | |||||
</view> | |||||
</view> | |||||
</uv-popup> | |||||
<!-- 目录弹窗(顶部196px边距,底部无边距,宽度100vw,高度自适应,顶部圆角,底部无圆角) --> | |||||
<view v-if="showCatalog" class="catalog-popup-fullscreen" style="top:196px;bottom:0;height:auto;min-height:calc(100vh - 196px);"> | |||||
<view class="catalog-header"> | |||||
<view class="header-left" @click="showCatalog = false"> | |||||
<uv-icon name="arrow-down" size="46" color="#333" @click="goBack" /> | |||||
</view> | |||||
<view class="header-title">目录</view> | |||||
<view class="header-right" @click="reverseOrder">倒序</view> | |||||
</view> | |||||
<scroll-view scroll-y class="catalog-list" style="padding-bottom:0;margin-bottom:0;"> | |||||
<view v-for="(item, idx) in displayList" :key="item.id" @click="selectChapter(idx)" | |||||
:class="['catalog-item', {active: idx === currentIndex}]"> | |||||
<view class="item-main"> | |||||
<text class="item-title">{{ item.title }}</text> | |||||
<text v-if="item.vip" class="vip-tag" @click.stop="showPayPopup = true">付费</text> | |||||
</view> | |||||
</view> | |||||
</scroll-view> | |||||
</view> | |||||
<view v-if="showPayPopup" class="pay-popup-mask" @click="showPayPopup = false"> | |||||
<view class="pay-popup" @click.stop> | |||||
<view class="pay-title">这是付费章节 需要订阅后才能阅读</view> | |||||
<view class="pay-desc">订阅后可继续阅读本章内容</view> | |||||
<view class="pay-btns"> | |||||
<button class="pay-btn" @click="goToSubscription">订阅本章</button> | |||||
<button class="pay-btn pay-btn-video">观看视频解锁</button> | |||||
<button class="pay-btn pay-btn-batch">批量订阅</button> | |||||
</view> | |||||
</view> | |||||
</view> | |||||
</view> | |||||
</template> | |||||
<script> | |||||
export default { | |||||
components: { | |||||
'uv-popup': () => import('@/uni_modules/uv-popup/components/uv-popup/uv-popup.vue') | |||||
}, | |||||
data() { | |||||
return { | |||||
isFullScreen: false, | |||||
lastTap: 0, | |||||
showPopup: false, | |||||
popupShown: false, // 只弹一次 | |||||
showCatalog: false, | |||||
orderAsc: true, | |||||
currentIndex: 0, | |||||
chapterList: [ | |||||
{ id: 1, title: '第一章 重回2004', vip: false }, | |||||
{ id: 2, title: '第二章 陈年旧恨', vip: false }, | |||||
{ id: 3, title: '第三章 再相见', vip: false }, | |||||
{ id: 4, title: '第四章 李东的邀请', vip: false }, | |||||
{ id: 5, title: '第五章 小气的男', vip: false }, | |||||
{ id: 6, title: '第六章 先送谁?', vip: false }, | |||||
{ id: 7, title: '第七章 打听行情', vip: false }, | |||||
{ id: 8, title: '第八章 省城探路', vip: false }, | |||||
{ id: 9, title: '第九章 订货', vip: false }, | |||||
{ id: 10, title: '第十章 第一桶金', vip: true }, | |||||
{ id: 11, title: '第十一章 高富帅来袭', vip: true }, | |||||
{ id: 12, title: '第十二章 故学后,挥场见!', vip: true }, | |||||
{ id: 13, title: '第十三章 你来我往', vip: true }, | |||||
{ id: 14, title: '第十四章 你来我往', vip: true }, | |||||
{ id: 15, title: '第十五章 你来我往', vip: true }, | |||||
{ id: 16, title: '第十六章 你来我往', vip: true }, | |||||
{ id: 17, title: '第十七章 你来我往', vip: true }, | |||||
{ id: 18, title: '第十八章 你来我往', vip: true }, | |||||
], | |||||
showPayPopup: false | |||||
} | |||||
}, | |||||
computed: { | |||||
displayList() { | |||||
return this.orderAsc ? this.chapterList : [...this.chapterList].reverse() | |||||
} | |||||
}, | |||||
methods: { | |||||
handleContentClick() { | |||||
this.toggleFullScreen(); | |||||
}, | |||||
handleTouchEnd(e) { | |||||
this.toggleFullScreen(); | |||||
}, | |||||
handleScroll(e) { | |||||
// 获取滚动位置 | |||||
const scrollTop = e.detail.scrollTop; | |||||
console.log('scrollTop:', scrollTop); | |||||
// 当滚动超过50且弹窗未显示过时,显示弹窗 | |||||
if (scrollTop > 50 && !this.popupShown) { | |||||
this.showPopup = true; | |||||
this.popupShown = true; | |||||
} | |||||
}, | |||||
toggleFullScreen() { | |||||
this.isFullScreen = !this.isFullScreen | |||||
}, | |||||
reverseOrder() { | |||||
this.orderAsc = !this.orderAsc | |||||
}, | |||||
selectChapter(idx) { | |||||
this.currentIndex = this.orderAsc ? idx : this.chapterList.length - 1 - idx | |||||
this.showCatalog = false | |||||
// TODO: 跳转到对应章节内容 | |||||
}, | |||||
goToSubscription() { | |||||
uni.navigateTo({ | |||||
url: '/pages_order/novel/SubscriptionInformation' | |||||
}) | |||||
} | |||||
}, | |||||
mounted() { | |||||
// #ifdef H5 | |||||
if (typeof window !== 'undefined') { | |||||
window.onscroll = () => { | |||||
const scrollTop = document.documentElement.scrollTop || document.body.scrollTop; | |||||
if (scrollTop > 50 && !this.popupShown) { | |||||
this.showPopup = true; | |||||
this.popupShown = true; | |||||
} | |||||
}; | |||||
} | |||||
// #endif | |||||
}, | |||||
beforeDestroy() { | |||||
// #ifdef H5 | |||||
if (typeof window !== 'undefined') { | |||||
window.onscroll = null; | |||||
} | |||||
// #endif | |||||
}, | |||||
onLoad(options) { | |||||
// 可接收小说id、章节id等参数 | |||||
// this.novelId = options.id | |||||
} | |||||
} | |||||
</script> | |||||
<style lang="scss" scoped> | |||||
.reader-container { | |||||
min-height: 100vh; | |||||
background: #fff; | |||||
display: flex; | |||||
flex-direction: column; | |||||
} | |||||
.chapter-title { | |||||
font-size: 32rpx; | |||||
font-weight: bold; | |||||
margin: 40rpx 32rpx 24rpx 32rpx; | |||||
} | |||||
.chapter-content { | |||||
flex: 1; | |||||
padding: 0 32rpx; | |||||
font-size: 28rpx; | |||||
color: #222; | |||||
line-height: 2.2; | |||||
margin-bottom: 120rpx; | |||||
} | |||||
.bottom-bar { | |||||
position: fixed; | |||||
left: 0; | |||||
right: 0; | |||||
bottom: 0; | |||||
background: #fff; | |||||
display: flex; | |||||
justify-content: center; | |||||
align-items: center; | |||||
height: 180rpx; | |||||
box-shadow: 0 -2rpx 10rpx rgba(0,0,0,0.05); | |||||
z-index: 10; | |||||
padding: 0 40rpx 10rpx 40rpx; | |||||
} | |||||
.bottom-left { | |||||
display: flex; | |||||
align-items: flex-end; | |||||
gap: 48rpx; | |||||
} | |||||
.bar-item { | |||||
display: flex; | |||||
flex-direction: column; | |||||
align-items: center; | |||||
justify-content: flex-end; | |||||
} | |||||
.bar-icon { | |||||
width: 48rpx; | |||||
height: 48rpx; | |||||
margin-bottom: 4rpx; | |||||
margin-right: 1rpx; | |||||
} | |||||
.bar-label { | |||||
font-size: 22rpx; | |||||
color: #b3b3b3; | |||||
margin-top: 2rpx; | |||||
} | |||||
.bottom-right { | |||||
display: flex; | |||||
align-items: flex-end; | |||||
gap: 32rpx; | |||||
margin-left: 40rpx; | |||||
} | |||||
.outline-btn { | |||||
min-width: 110rpx; | |||||
padding: 0 28rpx; | |||||
height: 60rpx; | |||||
line-height: 60rpx; | |||||
background: #fff; | |||||
color: #223a7a; | |||||
border: 2rpx solid #223a7a; | |||||
border-radius: 32rpx; | |||||
font-size: 28rpx; | |||||
font-weight: bold; | |||||
margin: 0; | |||||
display: flex; | |||||
align-items: center; | |||||
justify-content: center; | |||||
} | |||||
.btn-text { | |||||
font-weight: bold; | |||||
color: #223a7a; | |||||
font-size: 28rpx; | |||||
border-bottom: 2rpx solid #223a7a; | |||||
padding-bottom: 2rpx; | |||||
} | |||||
.catalog-popup-fullscreen { | |||||
position: fixed; | |||||
left: 0; | |||||
top: 0; | |||||
width: 100vw; | |||||
height: 100vh; | |||||
background: #fff; | |||||
z-index: 9999; | |||||
border-top-left-radius: 32rpx; | |||||
border-top-right-radius: 32rpx; | |||||
border-bottom-left-radius: 0; | |||||
border-bottom-right-radius: 0; | |||||
display: flex; | |||||
flex-direction: column; | |||||
box-shadow: 0 8rpx 48rpx rgba(0,0,0,0.18); | |||||
overflow: hidden; | |||||
} | |||||
.catalog-header { | |||||
display: flex; | |||||
align-items: center; | |||||
justify-content: space-between; | |||||
padding: 0 24rpx; | |||||
height: 96rpx; | |||||
border-bottom: 1px solid #eee; | |||||
position: sticky; | |||||
top: 0; | |||||
background: #fff; | |||||
z-index: 2; | |||||
} | |||||
.header-left { | |||||
width: 60rpx; | |||||
display: flex; | |||||
align-items: center; | |||||
justify-content: flex-start; | |||||
} | |||||
.header-title { | |||||
flex: 1; | |||||
text-align: center; | |||||
font-size: 32rpx; | |||||
font-weight: bold; | |||||
color: #222; | |||||
} | |||||
.header-right { | |||||
color: #223a7a; | |||||
font-size: 28rpx; | |||||
font-weight: 500; | |||||
min-width: 80rpx; | |||||
text-align: right; | |||||
} | |||||
.catalog-list { | |||||
flex: 1; | |||||
overflow: auto; | |||||
padding-bottom: 40rpx; | |||||
} | |||||
.catalog-item { | |||||
padding: 0 32rpx; | |||||
min-height: 80rpx; | |||||
display: flex; | |||||
flex-direction: column; | |||||
justify-content: center; | |||||
border-bottom: 1px solid #f5f5f5; | |||||
background: #fff; | |||||
color: #222; | |||||
font-size: 30rpx; | |||||
position: relative; | |||||
} | |||||
.catalog-item.active { | |||||
color: #ff5a5f; | |||||
background: #fff7f7; | |||||
} | |||||
.item-main { | |||||
display: flex; | |||||
align-items: center; | |||||
gap: 16rpx; | |||||
} | |||||
.item-title { | |||||
font-size: 30rpx; | |||||
} | |||||
.vip-tag { | |||||
background: #ffe1b2; | |||||
color: #ff9900; | |||||
border-radius: 20rpx; | |||||
font-size: 24rpx; | |||||
padding: 2rpx 18rpx; | |||||
margin-left: 16rpx; | |||||
} | |||||
.pay-popup-mask { | |||||
position: fixed; | |||||
left: 0; top: 0; right: 0; bottom: 0; | |||||
background: rgba(0,0,0,0.5); | |||||
z-index: 10000; | |||||
} | |||||
.pay-popup { | |||||
position: absolute; | |||||
left: 0; | |||||
right: 0; | |||||
bottom: 0; | |||||
background: #232323; | |||||
border-top-left-radius: 24rpx; | |||||
border-top-right-radius: 24rpx; | |||||
border-bottom-left-radius: 0; | |||||
border-bottom-right-radius: 0; | |||||
min-width: 500rpx; | |||||
width: 100%; | |||||
padding: 48rpx 32rpx 32rpx 32rpx; | |||||
text-align: center; | |||||
color: #fff; | |||||
} | |||||
.pay-title { | |||||
font-size: 32rpx; | |||||
font-weight: bold; | |||||
color: #fff; | |||||
margin-bottom: 24rpx; | |||||
margin-right: 50rpx; | |||||
} | |||||
.pay-desc { | |||||
font-size: 26rpx; | |||||
color: #999; | |||||
margin-bottom: 40rpx; | |||||
margin-right: 50rpx; | |||||
} | |||||
.pay-btns { | |||||
display: flex; | |||||
justify-content: center; | |||||
gap: 24rpx; | |||||
margin-right: 50rpx; | |||||
} | |||||
.pay-btn { | |||||
background: #ff9800; | |||||
color: #fff; | |||||
border-radius: 32rpx; | |||||
font-size: 28rpx; | |||||
padding: 0 32rpx; | |||||
border: none; | |||||
} | |||||
.pay-btn-video { | |||||
background: #ff9800; | |||||
color: #fff; | |||||
border-radius: 32rpx; | |||||
font-size: 28rpx; | |||||
padding: 0 32rpx; | |||||
border: none; | |||||
} | |||||
.pay-btn-batch { | |||||
background: #ff9800; | |||||
color: #fff; | |||||
border-radius: 32rpx; | |||||
font-size: 28rpx; | |||||
padding: 0 32rpx; | |||||
border: none; | |||||
} | |||||
</style> |