- 将公告相关页面从 `novel` 目录移动到 `announcement` 目录 - 重构评论组件,优化代码结构 - 优化章节列表页面的导航栏和标签切换逻辑 - 删除不再使用的登录页面和旧版公告页面 - 更新 `pages.json` 中的路由配置master
| @ -1,93 +1,102 @@ | |||
| <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> | |||
| <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: '护书使者 五级' | |||
| } | |||
| } | |||
| } | |||
| 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> | |||
| .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,121 @@ | |||
| <template> | |||
| <!-- 公告详情页面 --> | |||
| <view class="announcement-container"> | |||
| <navbar title="公告详情" leftClick @leftClick="$utils.navigateBack" /> | |||
| <view class="award-section"> | |||
| <view class="award-item"> | |||
| <text class="award-title">长篇网文</text> | |||
| <view class="award-content"> | |||
| <view class="sub-award"> | |||
| <text class="sub-title">• 优质加更奖:</text> | |||
| <text class="detail">拟获奖作品156本,共发放奖金41.5万元,查看拟获奖名单请点击:</text> | |||
| <text class="link">优质加更奖拟获奖名单</text> | |||
| </view> | |||
| <view class="sub-award"> | |||
| <text class="sub-title">• 新书扶更奖:</text> | |||
| <text class="detail">拟获奖作品5574本,共发放奖金20万元,查看拟获奖名单请点击:</text> | |||
| <text class="link">新书扶更奖拟获奖名单</text> | |||
| </view> | |||
| <view class="sub-award"> | |||
| <text class="sub-title">• 拉新激励奖:</text> | |||
| <text class="detail">拟获奖作品50部,总计奖金65万,查看拟获奖名单请点击:</text> | |||
| <text class="link">2月拉新激励奖</text> | |||
| </view> | |||
| <view class="sub-award"> | |||
| <text class="sub-title">• 星火计划奖励:</text> | |||
| <text class="detail">拟获奖作品4178部,总计奖金55万,查看拟获奖名单请点击:</text> | |||
| <text class="link">2月星火计划奖励名单</text> | |||
| </view> | |||
| </view> | |||
| </view> | |||
| <view class="award-item"> | |||
| <text class="award-title">完结专场</text> | |||
| <view class="award-content"> | |||
| <view class="sub-award"> | |||
| <text class="sub-title">• 脱洞盛宴征文活动:</text> | |||
| <text class="detail">月度脱洞专题:拟获奖作品1260部,总计奖金45万,查看拟获奖名单请点击:</text> | |||
| <text class="link">2月完结专题奖励名单</text> | |||
| </view> | |||
| </view> | |||
| </view> | |||
| </view> | |||
| </view> | |||
| </template> | |||
| <script> | |||
| export default { | |||
| components: { | |||
| 'uv-navbar': () => import('@/uni_modules/uv-navbar/components/uv-navbar/uv-navbar.vue') | |||
| }, | |||
| data() { | |||
| return {} | |||
| }, | |||
| methods: { | |||
| // 可以添加点击链接跳转等方法 | |||
| } | |||
| } | |||
| </script> | |||
| <style lang="scss"> | |||
| .announcement-container { | |||
| padding: 30rpx; | |||
| background: #fff; | |||
| .header { | |||
| margin-bottom: 40rpx; | |||
| .title { | |||
| font-size: 36rpx; | |||
| font-weight: bold; | |||
| color: #333; | |||
| margin-bottom: 20rpx; | |||
| display: block; | |||
| } | |||
| .date { | |||
| font-size: 28rpx; | |||
| color: #666; | |||
| line-height: 1.6; | |||
| } | |||
| } | |||
| .award-section { | |||
| .award-item { | |||
| margin-bottom: 40rpx; | |||
| .award-title { | |||
| font-size: 32rpx; | |||
| font-weight: bold; | |||
| color: #333; | |||
| margin-bottom: 20rpx; | |||
| display: block; | |||
| } | |||
| .award-content { | |||
| .sub-award { | |||
| margin-bottom: 20rpx; | |||
| .sub-title { | |||
| font-size: 28rpx; | |||
| color: #333; | |||
| font-weight: 500; | |||
| } | |||
| .detail { | |||
| font-size: 28rpx; | |||
| color: #666; | |||
| } | |||
| .link { | |||
| color: #007AFF; | |||
| text-decoration: underline; | |||
| font-size: 28rpx; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| </style> | |||
| @ -0,0 +1,117 @@ | |||
| <template> | |||
| <view class="announcements-container"> | |||
| <navbar title="全部公告" leftClick @leftClick="$utils.navigateBack" /> | |||
| <view class="announcements-list"> | |||
| <view class="announcement-item" v-for="(item, index) in announcements" :key="index" | |||
| @click="$utils.navigateTo(`/pages_order/announcement/announcementDetail?id=${item.id}`)"> | |||
| <view class="item-left"> | |||
| <text class="tag">通讯</text> | |||
| <text class="title">{{ item.title }}</text> | |||
| </view> | |||
| <view class="item-right"> | |||
| <uv-icon name="arrow-right" color="#C8C8C8" size="28rpx"></uv-icon> | |||
| </view> | |||
| </view> | |||
| </view> | |||
| </view> | |||
| </template> | |||
| <script> | |||
| export default { | |||
| data() { | |||
| return { | |||
| announcements: [{ | |||
| id: 1, | |||
| title: '2025年2月平台福利活动拟获奖作品公示', | |||
| type: '通讯' | |||
| }, | |||
| { | |||
| id: 2, | |||
| title: '2025年2月平台福利活动拟获奖作品公示', | |||
| type: '通讯' | |||
| }, | |||
| { | |||
| id: 3, | |||
| title: '2025年2月平台福利活动拟获奖作品公示', | |||
| type: '通讯' | |||
| }, | |||
| { | |||
| id: 4, | |||
| title: '2025年2月平台福利活动拟获奖作品公示', | |||
| type: '通讯' | |||
| }, | |||
| { | |||
| id: 5, | |||
| title: '2025年2月平台福利活动拟获奖作品公示', | |||
| type: '通讯' | |||
| }, | |||
| { | |||
| id: 6, | |||
| title: '2025年2月平台福利活动拟获奖作品公示', | |||
| type: '通讯' | |||
| }, | |||
| { | |||
| id: 7, | |||
| title: '2025年2月平台福利活动拟获奖作品公示', | |||
| type: '通讯' | |||
| } | |||
| ] | |||
| } | |||
| }, | |||
| methods: { | |||
| } | |||
| } | |||
| </script> | |||
| <style lang="scss"> | |||
| .announcements-container { | |||
| min-height: 100vh; | |||
| background-color: #F8F8F8; | |||
| .announcements-list { | |||
| padding: 20rpx; | |||
| .announcement-item { | |||
| display: flex; | |||
| justify-content: space-between; | |||
| align-items: center; | |||
| background-color: #FFFFFF; | |||
| padding: 30rpx; | |||
| margin-bottom: 20rpx; | |||
| border-radius: 12rpx; | |||
| .item-left { | |||
| flex: 1; | |||
| margin-right: 20rpx; | |||
| .tag { | |||
| display: inline-block; | |||
| font-size: 24rpx; | |||
| color: #666666; | |||
| background-color: #F5F5F5; | |||
| padding: 4rpx 12rpx; | |||
| border-radius: 6rpx; | |||
| margin-bottom: 16rpx; | |||
| } | |||
| .title { | |||
| display: block; | |||
| font-size: 28rpx; | |||
| color: #333333; | |||
| line-height: 1.4; | |||
| } | |||
| } | |||
| .item-right { | |||
| display: flex; | |||
| align-items: center; | |||
| } | |||
| &:active { | |||
| background-color: #F9F9F9; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| </style> | |||
| @ -0,0 +1,194 @@ | |||
| <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="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="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> | |||
| export default { | |||
| components: { | |||
| }, | |||
| 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,103 @@ | |||
| <template> | |||
| <view class="comment-item"> | |||
| <view class="comment-header"> | |||
| <image class="avatar" | |||
| src="https://tse4-mm.cn.bing.net/th/id/OIP-C.iUyxJ_fxLjjX3kEBjteXWwAAAA?rs=1&pid=ImgDetMain" | |||
| mode="aspectFill"></image> | |||
| <text class="username">方香橙</text> | |||
| </view> | |||
| <view class="comment-body"> | |||
| <text class="content-text">我是本书的作者方香橙,这是一本甜文爽文哒!请放心入坑,五星好评!女主又美有个性可爱,绝对不圣母,不傻白!男主身心干净深情独宠媳妇儿一个人...</text> | |||
| <view class="comment-footer"> | |||
| <text class="comment-time">2024.07.09</text> | |||
| <view class="comment-likes" @click="goToCommentReply"> | |||
| <text class="like-icon">💬</text> | |||
| <text class="like-count">17</text> | |||
| </view> | |||
| </view> | |||
| </view> | |||
| </view> | |||
| <!-- | |||
| <view class="comment-item"> | |||
| <view class="comment-header"> | |||
| <image class="avatar" | |||
| src="https://tse4-mm.cn.bing.net/th/id/OIP-C.iUyxJ_fxLjjX3kEBjteXWwAAAA?rs=1&pid=ImgDetMain" | |||
| mode="aspectFill"></image> | |||
| <text class="username">战斗世界</text> | |||
| </view> | |||
| <view class="comment-body"> | |||
| <text class="content-text">这本小说了创意了雄天霸业奇新颖深刻以白色能量为主...</text> | |||
| </view> | |||
| </view> | |||
| --> | |||
| </template> | |||
| <script> | |||
| export default { | |||
| data() { | |||
| return { | |||
| } | |||
| }, | |||
| methods: { | |||
| } | |||
| } | |||
| </script> | |||
| <style scoped lang="scss"> | |||
| .comment-item { | |||
| display: flex; | |||
| flex-direction: column; | |||
| gap: 16rpx; | |||
| .comment-header { | |||
| display: flex; | |||
| align-items: center; | |||
| gap: 12rpx; | |||
| } | |||
| .avatar { | |||
| width: 64rpx; | |||
| height: 64rpx; | |||
| border-radius: 50%; | |||
| } | |||
| .username { | |||
| font-size: 28rpx; | |||
| color: #333; | |||
| font-weight: 500; | |||
| } | |||
| .comment-body { | |||
| padding-left: 76rpx; | |||
| } | |||
| .content-text { | |||
| font-size: 28rpx; | |||
| color: #333; | |||
| line-height: 1.6; | |||
| } | |||
| .comment-footer { | |||
| display: flex; | |||
| justify-content: space-between; | |||
| align-items: center; | |||
| margin-top: 16rpx; | |||
| } | |||
| .comment-time { | |||
| font-size: 24rpx; | |||
| color: #999; | |||
| } | |||
| .comment-likes { | |||
| display: flex; | |||
| align-items: center; | |||
| gap: 4rpx; | |||
| } | |||
| } | |||
| </style> | |||
| @ -0,0 +1,235 @@ | |||
| <template> | |||
| <uv-popup ref="popup" :round="30" :customStyle="{height: '70vh'}"> | |||
| <view class="catalog-popup-fullscreen"> | |||
| <view class="catalog-header"> | |||
| <view class="header-left" @click.stop="close"> | |||
| <uv-icon name="arrow-down" size="46" color="#333"/> | |||
| </view> | |||
| <view class="header-title">目录</view> | |||
| <view class="header-right" @click.stop="orderAsc = !orderAsc">倒序</view> | |||
| </view> | |||
| <scroll-view scroll-y class="catalog-list"> | |||
| <view v-for="(item, idx) in (orderAsc ? chapterList : [...chapterList].reverse())" :key="item.id" | |||
| @click="selectChapter(orderAsc ? idx : chapterList.length - 1 - idx)" | |||
| :class="['catalog-item', {active: (orderAsc ? idx : chapterList.length - 1 - idx) === currentIndex}]"> | |||
| <view class="item-main"> | |||
| <text class="item-title">{{ item.title }}</text> | |||
| <text v-if="item.vip" class="vip-tag">付费</text> | |||
| </view> | |||
| </view> | |||
| </scroll-view> | |||
| </view> | |||
| </uv-popup> | |||
| </template> | |||
| <script> | |||
| export default { | |||
| data() { | |||
| return { | |||
| chapterCount: 2814, | |||
| 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 | |||
| } | |||
| ] | |||
| } | |||
| }, | |||
| methods: { | |||
| open() { | |||
| this.$refs.popup.open('bottom') | |||
| }, | |||
| close() { | |||
| this.$refs.popup.close() | |||
| }, | |||
| selectChapter(){ | |||
| }, | |||
| selectChapter(idx) { | |||
| this.currentIndex = idx | |||
| this.showCatalog = false | |||
| // TODO: 跳转到对应章节内容 | |||
| }, | |||
| } | |||
| } | |||
| </script> | |||
| <style scoped lang="scss"> | |||
| .catalog-popup-fullscreen { | |||
| position: relative; | |||
| height: 100%; | |||
| width: 100vw; | |||
| background: #fff; | |||
| display: flex; | |||
| flex-direction: column; | |||
| 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 { | |||
| height: calc(100% - 180rpx); | |||
| 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; | |||
| } | |||
| } | |||
| </style> | |||
| @ -1,137 +0,0 @@ | |||
| <template> | |||
| <view class="announcements-container"> | |||
| <uv-navbar | |||
| title="全部公告" | |||
| :autoBack="true" | |||
| fixed | |||
| placeholder | |||
| titleStyle="color: #333; font-weight: 500;" | |||
| :border="false" | |||
| ></uv-navbar> | |||
| <view class="announcements-list"> | |||
| <view | |||
| class="announcement-item" | |||
| v-for="(item, index) in announcements" | |||
| :key="index" | |||
| @click="viewAnnouncement(item)" | |||
| > | |||
| <view class="item-left"> | |||
| <text class="tag">通讯</text> | |||
| <text class="title">{{ item.title }}</text> | |||
| </view> | |||
| <view class="item-right"> | |||
| <uv-icon name="arrow-right" color="#C8C8C8" size="28rpx"></uv-icon> | |||
| </view> | |||
| </view> | |||
| </view> | |||
| </view> | |||
| </template> | |||
| <script> | |||
| export default { | |||
| components: { | |||
| 'uv-navbar': () => import('@/uni_modules/uv-navbar/components/uv-navbar/uv-navbar.vue') | |||
| }, | |||
| data() { | |||
| return { | |||
| announcements: [ | |||
| { | |||
| id: 1, | |||
| title: '2025年2月平台福利活动拟获奖作品公示', | |||
| type: '通讯' | |||
| }, | |||
| { | |||
| id: 2, | |||
| title: '2025年2月平台福利活动拟获奖作品公示', | |||
| type: '通讯' | |||
| }, | |||
| { | |||
| id: 3, | |||
| title: '2025年2月平台福利活动拟获奖作品公示', | |||
| type: '通讯' | |||
| }, | |||
| { | |||
| id: 4, | |||
| title: '2025年2月平台福利活动拟获奖作品公示', | |||
| type: '通讯' | |||
| }, | |||
| { | |||
| id: 5, | |||
| title: '2025年2月平台福利活动拟获奖作品公示', | |||
| type: '通讯' | |||
| }, | |||
| { | |||
| id: 6, | |||
| title: '2025年2月平台福利活动拟获奖作品公示', | |||
| type: '通讯' | |||
| }, | |||
| { | |||
| id: 7, | |||
| title: '2025年2月平台福利活动拟获奖作品公示', | |||
| type: '通讯' | |||
| } | |||
| ] | |||
| } | |||
| }, | |||
| methods: { | |||
| viewAnnouncement(item) { | |||
| uni.navigateTo({ | |||
| url: `/pages_order/novel/announcement?id=${item.id}` | |||
| }) | |||
| } | |||
| } | |||
| } | |||
| </script> | |||
| <style lang="scss"> | |||
| .announcements-container { | |||
| min-height: 100vh; | |||
| background-color: #F8F8F8; | |||
| .announcements-list { | |||
| padding: 20rpx; | |||
| .announcement-item { | |||
| display: flex; | |||
| justify-content: space-between; | |||
| align-items: center; | |||
| background-color: #FFFFFF; | |||
| padding: 30rpx; | |||
| margin-bottom: 20rpx; | |||
| border-radius: 12rpx; | |||
| .item-left { | |||
| flex: 1; | |||
| margin-right: 20rpx; | |||
| .tag { | |||
| display: inline-block; | |||
| font-size: 24rpx; | |||
| color: #666666; | |||
| background-color: #F5F5F5; | |||
| padding: 4rpx 12rpx; | |||
| border-radius: 6rpx; | |||
| margin-bottom: 16rpx; | |||
| } | |||
| .title { | |||
| display: block; | |||
| font-size: 28rpx; | |||
| color: #333333; | |||
| line-height: 1.4; | |||
| } | |||
| } | |||
| .item-right { | |||
| display: flex; | |||
| align-items: center; | |||
| } | |||
| &:active { | |||
| background-color: #F9F9F9; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| </style> | |||
| @ -1,180 +0,0 @@ | |||
| <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> | |||
| @ -1,192 +1,220 @@ | |||
| <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> | |||
| <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 | |||
| // 可根据需要添加实际提交逻辑 | |||
| } | |||
| } | |||
| } | |||
| 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> | |||
| .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> | |||
| @ -1,167 +1,189 @@ | |||
| <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> | |||
| <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(() => {}) | |||
| } | |||
| } | |||
| } | |||
| 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> | |||
| .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> | |||
| @ -1,228 +1,263 @@ | |||
| <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> | |||
| <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' }) | |||
| // 可在此处添加支付逻辑 | |||
| } | |||
| } | |||
| } | |||
| 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> | |||
| .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> | |||
| @ -1,233 +1,279 @@ | |||
| <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> | |||
| <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' | |||
| ] | |||
| } | |||
| } | |||
| } | |||
| 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> | |||
| .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> | |||
| @ -1,299 +1,337 @@ | |||
| <template> | |||
| <view class="page-container"> | |||
| <view class="task-center"> | |||
| <uv-navbar | |||
| title="任务中心" | |||
| :autoBack="true" | |||
| fixed | |||
| placeholder | |||
| titleStyle="color: #222; font-weight: 500;" | |||
| :border="false" | |||
| :bgColor="'#fff9e2'" | |||
| > | |||
| <template #left> | |||
| <BackArrow :size="56" color="#222" @back="goBack" /> | |||
| </template> | |||
| </uv-navbar> | |||
| <view class="navbar-placeholder"></view> | |||
| <!-- 账户剩余 --> | |||
| <view class="account-balance"> | |||
| <view class="balance-label">账户剩余</view> | |||
| <view class="balance-value"><text class="num">9</text> <text class="unit">张 推荐票</text></view> | |||
| </view> | |||
| <!-- 打卡得奖励 --> | |||
| <view class="checkin-section"> | |||
| <view class="section-header"> | |||
| <text>打卡得奖励</text> | |||
| <view class="record-btn">打卡记录</view> | |||
| </view> | |||
| <view class="checkin-grid"> | |||
| <view v-for="day in 8" :key="day" class="checkin-day" :class="{ active: day <= checkedDays }"> | |||
| <view class="day-label" :class="{ bold: day <= checkedDays }">第{{ day }}天</view> | |||
| <image class="ticket-img" src="https://tse1-mm.cn.bing.net/th/id/OIP-C.pca_tFb6ZjyDNdQYgFvi0wHaE7?w=219&h=180&c=7&r=0&o=5&dpr=1.1&pid=1.7" mode="aspectFit" /> | |||
| <view class="ticket-num">+1</view> | |||
| </view> | |||
| </view> | |||
| <button | |||
| class="checkin-btn" | |||
| :class="{ 'checked-btn': isChecked }" | |||
| :disabled="isChecked" | |||
| @click="handleCheckin" | |||
| > | |||
| {{ isChecked ? '已签到' : '签到得奖励' }} | |||
| </button> | |||
| </view> | |||
| <!-- 更多任务 --> | |||
| <view class="more-tasks"> | |||
| <view class="more-header">更多任务</view> | |||
| <view class="task-list"> | |||
| <view class="task-item" v-for="(task, idx) in tasks" :key="idx" :class="{ 'no-border': idx === tasks.length - 1 }"> | |||
| <view class="task-info"> | |||
| <view class="task-title">{{ task.title }}</view> | |||
| <view class="task-desc">推荐票 +1</view> | |||
| </view> | |||
| <button | |||
| class="get-btn" | |||
| :class="{ 'received-btn': task.received }" | |||
| :disabled="task.received" | |||
| @click="handleReceive(idx)" | |||
| > | |||
| {{ task.received ? '已领取' : '去领取' }} | |||
| </button> | |||
| </view> | |||
| </view> | |||
| </view> | |||
| </view> | |||
| </view> | |||
| <view class="page-container"> | |||
| <view class="task-center"> | |||
| <uv-navbar title="任务中心" :autoBack="true" fixed placeholder titleStyle="color: #222; font-weight: 500;" | |||
| :border="false" :bgColor="'#fff9e2'"> | |||
| <template #left> | |||
| <BackArrow :size="56" color="#222" @back="goBack" /> | |||
| </template> | |||
| </uv-navbar> | |||
| <view class="navbar-placeholder"></view> | |||
| <!-- 账户剩余 --> | |||
| <view class="account-balance"> | |||
| <view class="balance-label">账户剩余</view> | |||
| <view class="balance-value"><text class="num">9</text> <text class="unit">张 推荐票</text></view> | |||
| </view> | |||
| <!-- 打卡得奖励 --> | |||
| <view class="checkin-section"> | |||
| <view class="section-header"> | |||
| <text>打卡得奖励</text> | |||
| <view class="record-btn">打卡记录</view> | |||
| </view> | |||
| <view class="checkin-grid"> | |||
| <view v-for="day in 8" :key="day" class="checkin-day" :class="{ active: day <= checkedDays }"> | |||
| <view class="day-label" :class="{ bold: day <= checkedDays }">第{{ day }}天</view> | |||
| <image class="ticket-img" | |||
| src="https://tse1-mm.cn.bing.net/th/id/OIP-C.pca_tFb6ZjyDNdQYgFvi0wHaE7?w=219&h=180&c=7&r=0&o=5&dpr=1.1&pid=1.7" | |||
| mode="aspectFit" /> | |||
| <view class="ticket-num">+1</view> | |||
| </view> | |||
| </view> | |||
| <button class="checkin-btn" :class="{ 'checked-btn': isChecked }" :disabled="isChecked" | |||
| @click="handleCheckin"> | |||
| {{ isChecked ? '已签到' : '签到得奖励' }} | |||
| </button> | |||
| </view> | |||
| <!-- 更多任务 --> | |||
| <view class="more-tasks"> | |||
| <view class="more-header">更多任务</view> | |||
| <view class="task-list"> | |||
| <view class="task-item" v-for="(task, idx) in tasks" :key="idx" | |||
| :class="{ 'no-border': idx === tasks.length - 1 }"> | |||
| <view class="task-info"> | |||
| <view class="task-title">{{ task.title }}</view> | |||
| <view class="task-desc">推荐票 +1</view> | |||
| </view> | |||
| <button class="get-btn" :class="{ 'received-btn': task.received }" :disabled="task.received" | |||
| @click="handleReceive(idx)"> | |||
| {{ task.received ? '已领取' : '去领取' }} | |||
| </button> | |||
| </view> | |||
| </view> | |||
| </view> | |||
| </view> | |||
| </view> | |||
| </template> | |||
| <script> | |||
| import uvNavbar from '@/uni_modules/uv-navbar/components/uv-navbar/uv-navbar.vue' | |||
| import uvIcon from '@/uni_modules/uv-icon/components/uv-icon/uv-icon.vue' | |||
| import BackArrow from './components/BackArrow.vue' | |||
| export default { | |||
| components: { uvNavbar, uvIcon, BackArrow }, | |||
| data() { | |||
| return { | |||
| checkedDays: 3, // 已签到天数 | |||
| tasks: [ | |||
| { title: '观看视频广告', received: false }, | |||
| { title: '每日首阅三个章节', received: false }, | |||
| { title: '每日首条评论', received: false }, | |||
| ], | |||
| isChecked: false, // 新增:签到按钮状态 | |||
| } | |||
| }, | |||
| methods: { | |||
| goBack() { | |||
| uni.navigateBack(); | |||
| }, | |||
| handleCheckin() { | |||
| if (this.checkedDays < 8) { | |||
| this.checkedDays++; | |||
| this.isChecked = true; | |||
| uni.showToast({ title: '签到成功', icon: 'success' }); | |||
| } else { | |||
| this.isChecked = true; | |||
| uni.showToast({ title: '已全部签到', icon: 'none' }); | |||
| } | |||
| }, | |||
| handleReceive(idx) { | |||
| this.tasks[idx].received = true; | |||
| uni.showToast({ title: '领取成功', icon: 'success' }); | |||
| }, | |||
| }, | |||
| } | |||
| import uvNavbar from '@/uni_modules/uv-navbar/components/uv-navbar/uv-navbar.vue' | |||
| import uvIcon from '@/uni_modules/uv-icon/components/uv-icon/uv-icon.vue' | |||
| import BackArrow from './components/BackArrow.vue' | |||
| export default { | |||
| components: { | |||
| uvNavbar, | |||
| uvIcon, | |||
| BackArrow | |||
| }, | |||
| data() { | |||
| return { | |||
| checkedDays: 3, // 已签到天数 | |||
| tasks: [{ | |||
| title: '观看视频广告', | |||
| received: false | |||
| }, | |||
| { | |||
| title: '每日首阅三个章节', | |||
| received: false | |||
| }, | |||
| { | |||
| title: '每日首条评论', | |||
| received: false | |||
| }, | |||
| ], | |||
| isChecked: false, // 新增:签到按钮状态 | |||
| } | |||
| }, | |||
| methods: { | |||
| goBack() { | |||
| uni.navigateBack(); | |||
| }, | |||
| handleCheckin() { | |||
| if (this.checkedDays < 8) { | |||
| this.checkedDays++; | |||
| this.isChecked = true; | |||
| uni.showToast({ | |||
| title: '签到成功', | |||
| icon: 'success' | |||
| }); | |||
| } else { | |||
| this.isChecked = true; | |||
| uni.showToast({ | |||
| title: '已全部签到', | |||
| icon: 'none' | |||
| }); | |||
| } | |||
| }, | |||
| handleReceive(idx) { | |||
| this.tasks[idx].received = true; | |||
| uni.showToast({ | |||
| title: '领取成功', | |||
| icon: 'success' | |||
| }); | |||
| }, | |||
| }, | |||
| } | |||
| </script> | |||
| <style scoped lang="scss"> | |||
| .page-container { | |||
| height: 100vh; | |||
| overflow: hidden; | |||
| } | |||
| .task-center { | |||
| background: #f8f8f8; | |||
| height: 100vh; | |||
| padding-bottom: 40rpx; | |||
| overflow: hidden; | |||
| box-sizing: border-box; | |||
| } | |||
| .navbar-placeholder { | |||
| height: 100rpx; | |||
| } | |||
| .account-balance { | |||
| background: linear-gradient(90deg, #ffe16b, #ffd700); | |||
| border-radius: 20rpx; | |||
| margin: 24rpx 24rpx 0 24rpx; | |||
| padding: 24rpx 32rpx; | |||
| display: flex; | |||
| align-items: center; | |||
| justify-content: space-between; | |||
| font-size: 30rpx; | |||
| color: #333; | |||
| .balance-label { | |||
| font-weight: 500; | |||
| } | |||
| .balance-value { | |||
| font-weight: bold; | |||
| color: #bfa100; | |||
| .num { | |||
| font-size: 24rpx; | |||
| } | |||
| .unit { | |||
| font-size: 22rpx; | |||
| } | |||
| } | |||
| } | |||
| .checkin-section { | |||
| background: #fff; | |||
| border-radius: 20rpx; | |||
| margin: 24rpx; | |||
| padding: 32rpx 24rpx 24rpx 24rpx; | |||
| box-shadow: 0 2rpx 8rpx rgba(255, 215, 0, 0.08); | |||
| border: 4rpx solid #ffe16b; | |||
| .section-header { | |||
| display: flex; | |||
| justify-content: space-between; | |||
| align-items: center; | |||
| font-size: 28rpx; | |||
| font-weight: 600; | |||
| margin-bottom: 24rpx; | |||
| .record-btn { | |||
| background: #d6ff4b ; | |||
| color: #383938; | |||
| border-radius: 24rpx; | |||
| padding: 6rpx 28rpx; | |||
| font-size: 24rpx; | |||
| } | |||
| } | |||
| .checkin-grid { | |||
| display: flex; | |||
| flex-wrap: wrap; | |||
| gap: 18rpx; | |||
| margin-bottom: 32rpx; | |||
| .checkin-day { | |||
| width: 22%; | |||
| background: #f7f7f7; | |||
| border-radius: 12rpx; | |||
| display: flex; | |||
| flex-direction: column; | |||
| align-items: center; | |||
| padding: 18rpx 0 10rpx 0; | |||
| border: 2rpx solid #f0f0f0; | |||
| &.active { | |||
| background: #d6ff4b !important; | |||
| border-color: #b6e900 !important; | |||
| .day-label, .ticket-num { | |||
| color: #222 !important; | |||
| font-weight: bold; | |||
| } | |||
| } | |||
| .day-label { | |||
| font-size: 24rpx; | |||
| font-weight: 600; | |||
| height: 90rpx; | |||
| margin-bottom: 8rpx; | |||
| color: #333; | |||
| &.bold { | |||
| font-weight: bold; | |||
| } | |||
| } | |||
| .ticket-img { | |||
| width: 48rpx; | |||
| height: 36rpx; | |||
| margin-bottom: 6rpx; | |||
| display: flex; | |||
| } | |||
| .ticket-num { | |||
| font-size: 22rpx; | |||
| color: #bfa100; | |||
| } | |||
| } | |||
| } | |||
| .checkin-btn { | |||
| width: 600rpx; | |||
| background: linear-gradient(90deg, #ffe16b, #ffd700); | |||
| color: #333; | |||
| font-size: 30rpx; | |||
| border-radius: 46rpx; | |||
| padding: 18rpx 0; | |||
| font-weight: bold; | |||
| margin-top: 8rpx; | |||
| transition: background 0.2s; | |||
| } | |||
| } | |||
| .checked-btn { | |||
| background: linear-gradient(90deg, #e0e0e0, #bdbdbd) !important; | |||
| color: #444 !important; | |||
| cursor: not-allowed; | |||
| } | |||
| .more-tasks { | |||
| background: #faffea; | |||
| border-radius: 20rpx; | |||
| margin: 0 24rpx; | |||
| padding: 24rpx 24rpx 8rpx 24rpx; | |||
| margin-top: 100rpx; | |||
| .more-header { | |||
| font-size: 28rpx; | |||
| color: #bfa100; | |||
| font-weight: 600; | |||
| margin-bottom: 18rpx; | |||
| } | |||
| .task-list { | |||
| .task-item { | |||
| display: flex; | |||
| align-items: center; | |||
| justify-content: space-between; | |||
| background: #fff; | |||
| border-radius: 0; | |||
| margin: 0; | |||
| padding: 18rpx 20rpx 10rpx 20rpx; | |||
| border-bottom: 1rpx solid #f2f2f2; | |||
| .task-info { | |||
| display: flex; | |||
| flex-direction: column; | |||
| align-items: flex-start; | |||
| flex: 1; | |||
| min-width: 0; | |||
| margin-top: 30rpx; | |||
| .task-title { | |||
| font-size: 26rpx; | |||
| color: #222; | |||
| font-weight: bold; | |||
| } | |||
| .task-desc { | |||
| font-size: 20rpx; | |||
| color: #bbb; | |||
| margin-top: 4rpx; | |||
| } | |||
| } | |||
| .get-btn { | |||
| background: #ffd700; | |||
| color: #fff; | |||
| font-size: 24rpx; | |||
| border-radius: 24rpx; | |||
| padding: 0 28rpx; | |||
| font-weight: bold; | |||
| border: none; | |||
| height: 48rpx; | |||
| display: flex; | |||
| align-items: center; | |||
| justify-content: center; | |||
| box-shadow: none; | |||
| white-space: nowrap; | |||
| margin-left: 18rpx; | |||
| transition: background 0.2s; | |||
| } | |||
| .received-btn { | |||
| background: linear-gradient(90deg, #e0e0e0, #bdbdbd) !important; | |||
| color: #444 !important; | |||
| cursor: not-allowed; | |||
| } | |||
| &.no-border { | |||
| border-bottom: none; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| </style> | |||
| .page-container { | |||
| height: 100vh; | |||
| overflow: hidden; | |||
| } | |||
| .task-center { | |||
| background: #f8f8f8; | |||
| height: 100vh; | |||
| padding-bottom: 40rpx; | |||
| overflow: hidden; | |||
| box-sizing: border-box; | |||
| } | |||
| .navbar-placeholder { | |||
| height: 100rpx; | |||
| } | |||
| .account-balance { | |||
| background: linear-gradient(90deg, #ffe16b, #ffd700); | |||
| border-radius: 20rpx; | |||
| margin: 24rpx 24rpx 0 24rpx; | |||
| padding: 24rpx 32rpx; | |||
| display: flex; | |||
| align-items: center; | |||
| justify-content: space-between; | |||
| font-size: 30rpx; | |||
| color: #333; | |||
| .balance-label { | |||
| font-weight: 500; | |||
| } | |||
| .balance-value { | |||
| font-weight: bold; | |||
| color: #bfa100; | |||
| .num { | |||
| font-size: 24rpx; | |||
| } | |||
| .unit { | |||
| font-size: 22rpx; | |||
| } | |||
| } | |||
| } | |||
| .checkin-section { | |||
| background: #fff; | |||
| border-radius: 20rpx; | |||
| margin: 24rpx; | |||
| padding: 32rpx 24rpx 24rpx 24rpx; | |||
| box-shadow: 0 2rpx 8rpx rgba(255, 215, 0, 0.08); | |||
| border: 4rpx solid #ffe16b; | |||
| .section-header { | |||
| display: flex; | |||
| justify-content: space-between; | |||
| align-items: center; | |||
| font-size: 28rpx; | |||
| font-weight: 600; | |||
| margin-bottom: 24rpx; | |||
| .record-btn { | |||
| background: #d6ff4b; | |||
| color: #383938; | |||
| border-radius: 24rpx; | |||
| padding: 6rpx 28rpx; | |||
| font-size: 24rpx; | |||
| } | |||
| } | |||
| .checkin-grid { | |||
| display: flex; | |||
| flex-wrap: wrap; | |||
| gap: 18rpx; | |||
| margin-bottom: 32rpx; | |||
| .checkin-day { | |||
| width: 22%; | |||
| background: #f7f7f7; | |||
| border-radius: 12rpx; | |||
| display: flex; | |||
| flex-direction: column; | |||
| align-items: center; | |||
| padding: 18rpx 0 10rpx 0; | |||
| border: 2rpx solid #f0f0f0; | |||
| &.active { | |||
| background: #d6ff4b !important; | |||
| border-color: #b6e900 !important; | |||
| .day-label, | |||
| .ticket-num { | |||
| color: #222 !important; | |||
| font-weight: bold; | |||
| } | |||
| } | |||
| .day-label { | |||
| font-size: 24rpx; | |||
| font-weight: 600; | |||
| height: 90rpx; | |||
| margin-bottom: 8rpx; | |||
| color: #333; | |||
| &.bold { | |||
| font-weight: bold; | |||
| } | |||
| } | |||
| .ticket-img { | |||
| width: 48rpx; | |||
| height: 36rpx; | |||
| margin-bottom: 6rpx; | |||
| display: flex; | |||
| } | |||
| .ticket-num { | |||
| font-size: 22rpx; | |||
| color: #bfa100; | |||
| } | |||
| } | |||
| } | |||
| .checkin-btn { | |||
| width: 600rpx; | |||
| background: linear-gradient(90deg, #ffe16b, #ffd700); | |||
| color: #333; | |||
| font-size: 30rpx; | |||
| border-radius: 46rpx; | |||
| padding: 18rpx 0; | |||
| font-weight: bold; | |||
| margin-top: 8rpx; | |||
| transition: background 0.2s; | |||
| } | |||
| } | |||
| .checked-btn { | |||
| background: linear-gradient(90deg, #e0e0e0, #bdbdbd) !important; | |||
| color: #444 !important; | |||
| cursor: not-allowed; | |||
| } | |||
| .more-tasks { | |||
| background: #faffea; | |||
| border-radius: 20rpx; | |||
| margin: 0 24rpx; | |||
| padding: 24rpx 24rpx 8rpx 24rpx; | |||
| margin-top: 100rpx; | |||
| .more-header { | |||
| font-size: 28rpx; | |||
| color: #bfa100; | |||
| font-weight: 600; | |||
| margin-bottom: 18rpx; | |||
| } | |||
| .task-list { | |||
| .task-item { | |||
| display: flex; | |||
| align-items: center; | |||
| justify-content: space-between; | |||
| background: #fff; | |||
| border-radius: 0; | |||
| margin: 0; | |||
| padding: 18rpx 20rpx 10rpx 20rpx; | |||
| border-bottom: 1rpx solid #f2f2f2; | |||
| .task-info { | |||
| display: flex; | |||
| flex-direction: column; | |||
| align-items: flex-start; | |||
| flex: 1; | |||
| min-width: 0; | |||
| margin-top: 30rpx; | |||
| .task-title { | |||
| font-size: 26rpx; | |||
| color: #222; | |||
| font-weight: bold; | |||
| } | |||
| .task-desc { | |||
| font-size: 20rpx; | |||
| color: #bbb; | |||
| margin-top: 4rpx; | |||
| } | |||
| } | |||
| .get-btn { | |||
| background: #ffd700; | |||
| color: #fff; | |||
| font-size: 24rpx; | |||
| border-radius: 24rpx; | |||
| padding: 0 28rpx; | |||
| font-weight: bold; | |||
| border: none; | |||
| height: 48rpx; | |||
| display: flex; | |||
| align-items: center; | |||
| justify-content: center; | |||
| box-shadow: none; | |||
| white-space: nowrap; | |||
| margin-left: 18rpx; | |||
| transition: background 0.2s; | |||
| } | |||
| .received-btn { | |||
| background: linear-gradient(90deg, #e0e0e0, #bdbdbd) !important; | |||
| color: #444 !important; | |||
| cursor: not-allowed; | |||
| } | |||
| &.no-border { | |||
| border-bottom: none; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| </style> | |||
| @ -1,258 +1,396 @@ | |||
| <!-- 钱包流水页面 --> | |||
| <template> | |||
| <view class="walletflow-page"> | |||
| <!-- 顶部导航栏 --> | |||
| <uv-navbar title="钱包流水" :autoBack="true" fixed placeholder titleStyle="color: #333; font-weight: 700;" :border="false"> | |||
| <template #left> | |||
| <BackArrow :size="56" color="#333" /> | |||
| </template> | |||
| </uv-navbar> | |||
| <view class="walletflow-page"> | |||
| <!-- 顶部导航栏 --> | |||
| <uv-navbar title="钱包流水" :autoBack="true" fixed placeholder titleStyle="color: #333; font-weight: 700;" | |||
| :border="false"> | |||
| <template #left> | |||
| <BackArrow :size="56" color="#333" /> | |||
| </template> | |||
| </uv-navbar> | |||
| <!-- 账户余额卡片 --> | |||
| <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> | |||
| <!-- 账户余额卡片 --> | |||
| <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> | |||
| <!-- 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> | |||
| import BackArrow from './components/BackArrow.vue'; | |||
| import BackArrow from './components/BackArrow.vue'; | |||
| export default { | |||
| components: { | |||
| BackArrow, | |||
| }, | |||
| 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' }) | |||
| } | |||
| } | |||
| } | |||
| export default { | |||
| components: { | |||
| BackArrow, | |||
| }, | |||
| 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; | |||
| } | |||
| } | |||
| } | |||
| .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> | |||
| @ -1,132 +0,0 @@ | |||
| <template> | |||
| <!-- 公告详情页面 --> | |||
| <view class="announcement-container"> | |||
| <uv-navbar | |||
| title="公告详情" | |||
| :autoBack="true" | |||
| fixed | |||
| placeholder | |||
| titleStyle="color: #333; font-weight: 500;" | |||
| :border="false" | |||
| ></uv-navbar> | |||
| <view class="header"> | |||
| <text class="title">2025年2月平台福利活动拟获奖作品公示</text> | |||
| <text class="date">岁序更替,华章日新。2025年,平台福利内容建设的实施进展,载誉前行。我们秉持"精品为本,重磅发布"的理念,现面向全体作者,重磅发布2025年度长篇网文作家福利,上线主新潮当中文网作家专属福利:全年奖、半年奖、季度奖、月度奖,总计奖金超过百万元。现将2025年2月,平台各项福利活动拟获奖作品公示如下:</text> | |||
| </view> | |||
| <view class="award-section"> | |||
| <view class="award-item"> | |||
| <text class="award-title">长篇网文</text> | |||
| <view class="award-content"> | |||
| <view class="sub-award"> | |||
| <text class="sub-title">• 优质加更奖:</text> | |||
| <text class="detail">拟获奖作品156本,共发放奖金41.5万元,查看拟获奖名单请点击:</text> | |||
| <text class="link">优质加更奖拟获奖名单</text> | |||
| </view> | |||
| <view class="sub-award"> | |||
| <text class="sub-title">• 新书扶更奖:</text> | |||
| <text class="detail">拟获奖作品5574本,共发放奖金20万元,查看拟获奖名单请点击:</text> | |||
| <text class="link">新书扶更奖拟获奖名单</text> | |||
| </view> | |||
| <view class="sub-award"> | |||
| <text class="sub-title">• 拉新激励奖:</text> | |||
| <text class="detail">拟获奖作品50部,总计奖金65万,查看拟获奖名单请点击:</text> | |||
| <text class="link">2月拉新激励奖</text> | |||
| </view> | |||
| <view class="sub-award"> | |||
| <text class="sub-title">• 星火计划奖励:</text> | |||
| <text class="detail">拟获奖作品4178部,总计奖金55万,查看拟获奖名单请点击:</text> | |||
| <text class="link">2月星火计划奖励名单</text> | |||
| </view> | |||
| </view> | |||
| </view> | |||
| <view class="award-item"> | |||
| <text class="award-title">完结专场</text> | |||
| <view class="award-content"> | |||
| <view class="sub-award"> | |||
| <text class="sub-title">• 脱洞盛宴征文活动:</text> | |||
| <text class="detail">月度脱洞专题:拟获奖作品1260部,总计奖金45万,查看拟获奖名单请点击:</text> | |||
| <text class="link">2月完结专题奖励名单</text> | |||
| </view> | |||
| </view> | |||
| </view> | |||
| </view> | |||
| </view> | |||
| </template> | |||
| <script> | |||
| export default { | |||
| components: { | |||
| 'uv-navbar': () => import('@/uni_modules/uv-navbar/components/uv-navbar/uv-navbar.vue') | |||
| }, | |||
| data() { | |||
| return {} | |||
| }, | |||
| methods: { | |||
| // 可以添加点击链接跳转等方法 | |||
| } | |||
| } | |||
| </script> | |||
| <style lang="scss"> | |||
| .announcement-container { | |||
| padding: 30rpx; | |||
| background: #fff; | |||
| .header { | |||
| margin-bottom: 40rpx; | |||
| .title { | |||
| font-size: 36rpx; | |||
| font-weight: bold; | |||
| color: #333; | |||
| margin-bottom: 20rpx; | |||
| display: block; | |||
| } | |||
| .date { | |||
| font-size: 28rpx; | |||
| color: #666; | |||
| line-height: 1.6; | |||
| } | |||
| } | |||
| .award-section { | |||
| .award-item { | |||
| margin-bottom: 40rpx; | |||
| .award-title { | |||
| font-size: 32rpx; | |||
| font-weight: bold; | |||
| color: #333; | |||
| margin-bottom: 20rpx; | |||
| display: block; | |||
| } | |||
| .award-content { | |||
| .sub-award { | |||
| margin-bottom: 20rpx; | |||
| .sub-title { | |||
| font-size: 28rpx; | |||
| color: #333; | |||
| font-weight: 500; | |||
| } | |||
| .detail { | |||
| font-size: 28rpx; | |||
| color: #666; | |||
| } | |||
| .link { | |||
| color: #007AFF; | |||
| text-decoration: underline; | |||
| font-size: 28rpx; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| </style> | |||
| @ -1,254 +1,182 @@ | |||
| <template> | |||
| <view class="chapter-container"> | |||
| <view class="header"> | |||
| <view class="nav-bar" style="position: relative; height: 44px;"> | |||
| <view class="back"> | |||
| <BackArrow :size="56" color="black" @back="goBack" /> | |||
| </view> | |||
| <view class="title">兽王进化:从被小萝莉...</view> | |||
| <view class="right-icons"></view> | |||
| </view> | |||
| <view class="tabs"> | |||
| <view class="tab" :class="{ active: activeTab === 'draft' }" @click="switchTab('draft')">草稿箱</view> | |||
| <view class="tab" :class="{ active: activeTab === 'published' }" @click="switchTab('published')">已发布</view> | |||
| </view> | |||
| </view> | |||
| <view class="chapter-list"> | |||
| <view class="chapter-item" v-for="(chapter, index) in chapters" :key="index" @click="editChapter(chapter)"> | |||
| <view class="chapter-info"> | |||
| <text class="chapter-title">章节名</text> | |||
| <text class="chapter-number">第{{index + 1}}章</text> | |||
| </view> | |||
| <uv-icon name="arrow-right" color="#999" size="28"></uv-icon> | |||
| </view> | |||
| </view> | |||
| <view class="bottom-actions"> | |||
| <button class="btn-settings" @click="handleSettings">设置作品</button> | |||
| <button class="btn-new" @click="addNewChapter">新建章节</button> | |||
| </view> | |||
| </view> | |||
| <view class="chapter-container"> | |||
| <navbar title="章节列表" leftClick @leftClick="$utils.navigateBack"/> | |||
| <view class="tabs"> | |||
| <uv-tabs :list="tabs" | |||
| :activeStyle="{color : '#0A2463', fontWeight : 600}" | |||
| lineColor="#0A2463" | |||
| :inactiveStyle="{color: '#0A2463'}" | |||
| lineHeight="8rpx" | |||
| lineWidth="50rpx" | |||
| :scrollable="false" | |||
| :current="activeTab" | |||
| @click="clickTabs"></uv-tabs> | |||
| </view> | |||
| <view class="chapter-list"> | |||
| <view class="chapter-item" v-for="(chapter, index) in chapters" :key="index" @click="editChapter(chapter)"> | |||
| <view class="chapter-info"> | |||
| <text class="chapter-title">章节名</text> | |||
| <text class="chapter-number">第{{index + 1}}章</text> | |||
| </view> | |||
| <uv-icon name="arrow-right" color="#999" size="28"></uv-icon> | |||
| </view> | |||
| </view> | |||
| <view class="bottom-actions"> | |||
| <button class="btn-settings" @click="handleSettings">设置作品</button> | |||
| <button class="btn-new" @click="addNewChapter">新建章节</button> | |||
| </view> | |||
| </view> | |||
| </template> | |||
| <script> | |||
| import BackArrow from './components/BackArrow.vue'; | |||
| import BackArrow from './components/BackArrow.vue'; | |||
| export default { | |||
| components: { | |||
| BackArrow, | |||
| }, | |||
| data() { | |||
| return { | |||
| activeTab: 'draft', | |||
| chapters: [] // 真实章节数据 | |||
| } | |||
| }, | |||
| onLoad(options) { | |||
| // 根据tab参数决定初始tab | |||
| if (options && options.tab === 'published') { | |||
| this.activeTab = 'published'; | |||
| } else { | |||
| this.activeTab = 'draft'; | |||
| } | |||
| this.loadChapters(); | |||
| // 判断是否需要弹窗 | |||
| if (options && options.fromSave === '1') { | |||
| uni.showToast({ | |||
| title: '保存成功', | |||
| icon: 'success' | |||
| }); | |||
| } | |||
| if (options && options.fromPublish === '1') { | |||
| uni.showToast({ | |||
| title: '发布成功', | |||
| icon: 'success' | |||
| }); | |||
| } | |||
| }, | |||
| methods: { | |||
| loadChapters() { | |||
| if (this.activeTab === 'published') { | |||
| this.chapters = uni.getStorageSync('publishedChapters') || []; | |||
| } else { | |||
| this.chapters = uni.getStorageSync('chapters') || []; | |||
| } | |||
| }, | |||
| goBack() { | |||
| uni.navigateBack() | |||
| }, | |||
| switchTab(tab) { | |||
| this.activeTab = tab; | |||
| this.loadChapters(); | |||
| }, | |||
| addNewChapter() { | |||
| uni.navigateTo({ | |||
| url: '/pages_order/author/editor' | |||
| }) | |||
| }, | |||
| editChapter(chapter) { | |||
| uni.navigateTo({ | |||
| url: '/pages_order/author/editor?id=' + chapter.id | |||
| }) | |||
| }, | |||
| handleSettings() { | |||
| uni.navigateTo({ | |||
| url: '/pages_order/novel/createNovel?type=edit' | |||
| }) | |||
| } | |||
| } | |||
| } | |||
| export default { | |||
| components: { | |||
| BackArrow, | |||
| }, | |||
| data() { | |||
| return { | |||
| tabs : [ | |||
| { | |||
| name : '已发布', | |||
| }, | |||
| { | |||
| name : '草稿箱', | |||
| } | |||
| ], | |||
| activeTab: 0, | |||
| chapters: [] // 真实章节数据 | |||
| } | |||
| }, | |||
| onLoad(options) { | |||
| // 根据tab参数决定初始tab | |||
| if (options.activeTab) { | |||
| this.activeTab = options.activeTab; | |||
| } | |||
| this.loadChapters(); | |||
| // 判断是否需要弹窗 | |||
| if (options && options.fromSave === '1') { | |||
| uni.showToast({ | |||
| title: '保存成功', | |||
| icon: 'success' | |||
| }); | |||
| } | |||
| if (options && options.fromPublish === '1') { | |||
| uni.showToast({ | |||
| title: '发布成功', | |||
| icon: 'success' | |||
| }); | |||
| } | |||
| }, | |||
| methods: { | |||
| loadChapters() { | |||
| if (this.activeTab === 'published') { | |||
| this.chapters = uni.getStorageSync('publishedChapters') || []; | |||
| } else { | |||
| this.chapters = uni.getStorageSync('chapters') || []; | |||
| } | |||
| }, | |||
| goBack() { | |||
| uni.navigateBack() | |||
| }, | |||
| clickTabs(tab) { | |||
| this.activeTab = tab.index; | |||
| }, | |||
| addNewChapter() { | |||
| uni.navigateTo({ | |||
| url: '/pages_order/author/editor' | |||
| }) | |||
| }, | |||
| editChapter(chapter) { | |||
| uni.navigateTo({ | |||
| url: '/pages_order/author/editor?id=' + chapter.id | |||
| }) | |||
| }, | |||
| handleSettings() { | |||
| uni.navigateTo({ | |||
| url: '/pages_order/novel/createNovel?type=edit' | |||
| }) | |||
| } | |||
| } | |||
| } | |||
| </script> | |||
| <style lang="scss" scoped> | |||
| .chapter-container { | |||
| min-height: 100vh; | |||
| background-color: #fff; | |||
| padding-bottom: 70px; | |||
| .header { | |||
| background: #fff; | |||
| .nav-bar { | |||
| position: relative; | |||
| height: 44px; | |||
| .back { | |||
| position: absolute; | |||
| left: 0; | |||
| top: 0; | |||
| bottom: 0; | |||
| width: 48px; | |||
| display: flex; | |||
| align-items: center; | |||
| justify-content: center; | |||
| z-index: 2; | |||
| } | |||
| .right-icons { | |||
| position: absolute; | |||
| right: 0; | |||
| top: 0; | |||
| bottom: 0; | |||
| width: 48px; | |||
| display: flex; | |||
| align-items: center; | |||
| justify-content: center; | |||
| z-index: 2; | |||
| } | |||
| .title { | |||
| position: absolute; | |||
| left: 0; | |||
| right: 0; | |||
| top: 0; | |||
| bottom: 0; | |||
| margin: auto; | |||
| height: 44px; | |||
| display: flex; | |||
| align-items: center; | |||
| justify-content: center; | |||
| font-size: 16px; | |||
| font-weight: 500; | |||
| color: #222; | |||
| overflow: hidden; | |||
| text-overflow: ellipsis; | |||
| white-space: nowrap; | |||
| text-align: center; | |||
| z-index: 1; | |||
| pointer-events: none; | |||
| } | |||
| } | |||
| .tabs { | |||
| display: flex; | |||
| margin-top: 4px; | |||
| margin-left: 120rpx; | |||
| justify-content: space-between; | |||
| .tab { | |||
| font-size: 15px; | |||
| color: #888; | |||
| margin-right: 120rpx; | |||
| position: relative; | |||
| &.active { | |||
| color: #223a7a; | |||
| font-weight: 600; | |||
| &::after { | |||
| content: ''; | |||
| display: block; | |||
| width: 24px; | |||
| height: 3px; | |||
| background: #223a7a; | |||
| border-radius: 2px; | |||
| position: absolute; | |||
| left: 50%; | |||
| transform: translateX(-50%); | |||
| bottom: -6px; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| .chapter-list { | |||
| padding: 20rpx 40rpx; | |||
| background-color: rgb(255, 254, 254); | |||
| margin: 50rpx 40rpx; | |||
| border-radius: 3%; | |||
| .chapter-item { | |||
| display: flex; | |||
| justify-content: space-between; | |||
| align-items: center; | |||
| padding: 15px 0; | |||
| border-bottom: 1px solid #eee; | |||
| .chapter-info { | |||
| .chapter-title { | |||
| font-size: 14px; | |||
| color: #999; | |||
| margin-bottom: 5px; | |||
| display: block; | |||
| } | |||
| .chapter-number { | |||
| font-size: 16px; | |||
| color: #333; | |||
| display: block; | |||
| } | |||
| } | |||
| .icon-arrow { | |||
| color: #999; | |||
| font-size: 16px; | |||
| } | |||
| } | |||
| } | |||
| .bottom-actions { | |||
| position: fixed; | |||
| bottom: 0; | |||
| left: 0; | |||
| right: 0; | |||
| display: flex; | |||
| padding: 10px 15px; | |||
| background: #fff; | |||
| box-shadow: 0 -2px 6px rgba(0,0,0,0.05); | |||
| button { | |||
| flex: 1; | |||
| height: 40px; | |||
| border-radius: 20px; | |||
| font-size: 16px; | |||
| margin: 0 5px; | |||
| &.btn-settings { | |||
| background: #fff; | |||
| border: 1px solid #ddd; | |||
| color: #333; | |||
| } | |||
| &.btn-new { | |||
| background: #2b4acb; | |||
| color: #fff; | |||
| border: none; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| </style> | |||
| .chapter-container { | |||
| min-height: 100vh; | |||
| background-color: #fff; | |||
| padding-bottom: 70px; | |||
| .chapter-list { | |||
| padding: 20rpx 40rpx; | |||
| background-color: rgb(255, 254, 254); | |||
| margin: 50rpx 40rpx; | |||
| border-radius: 3%; | |||
| .chapter-item { | |||
| display: flex; | |||
| justify-content: space-between; | |||
| align-items: center; | |||
| padding: 15px 0; | |||
| border-bottom: 1px solid #eee; | |||
| .chapter-info { | |||
| .chapter-title { | |||
| font-size: 14px; | |||
| color: #999; | |||
| margin-bottom: 5px; | |||
| display: block; | |||
| } | |||
| .chapter-number { | |||
| font-size: 16px; | |||
| color: #333; | |||
| display: block; | |||
| } | |||
| } | |||
| .icon-arrow { | |||
| color: #999; | |||
| font-size: 16px; | |||
| } | |||
| } | |||
| } | |||
| .bottom-actions { | |||
| padding-bottom: calc(env(safe-area-inset-bottom) + 30rpx); | |||
| position: fixed; | |||
| bottom: 0; | |||
| left: 0; | |||
| right: 0; | |||
| display: flex; | |||
| padding: 10px 15px; | |||
| background: #fff; | |||
| box-shadow: 0 -2px 6px rgba(0, 0, 0, 0.05); | |||
| button { | |||
| flex: 1; | |||
| height: 40px; | |||
| border-radius: 20px; | |||
| font-size: 16px; | |||
| margin: 0 5px; | |||
| &.btn-settings { | |||
| background: #fff; | |||
| border: 1px solid #ddd; | |||
| color: #333; | |||
| } | |||
| &.btn-new { | |||
| background: #2b4acb; | |||
| color: #fff; | |||
| border: none; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| </style> | |||
| @ -1,109 +0,0 @@ | |||
| <template> | |||
| <div class="login-page"> | |||
| <div class="logo-box"> | |||
| <img class="logo" src="/static/auth/headImage.png" alt="logo" /> | |||
| </div> | |||
| <div class="title">瀚涵中文网</div> | |||
| <LoginButton type="primary" @click="onLogin">登录</LoginButton> | |||
| <div class="cancel-row"> | |||
| <LoginButton type="secondary" @click="onCancel">取消登录</LoginButton> | |||
| <span class="arrow-icon">◆</span> | |||
| <span class="dashed-line"></span> | |||
| </div> | |||
| <AgreementCheck v-model:checked="checked"> | |||
| 我已阅读并同意<a href="#">《服务协议》</a>和<a href="#">《隐私政策》</a> | |||
| </AgreementCheck> | |||
| <div class="book-bg"></div> | |||
| </div> | |||
| </template> | |||
| <script> | |||
| import LoginButton from './components/LoginButton.vue'; | |||
| import AgreementCheck from './components/AgreementCheck.vue'; | |||
| export default { | |||
| name: 'NovelLogin', | |||
| components: { LoginButton, AgreementCheck }, | |||
| data() { | |||
| return { | |||
| checked: false | |||
| }; | |||
| }, | |||
| methods: { | |||
| onLogin() { | |||
| if (!this.checked) { | |||
| this.$toast && this.$toast('请先同意协议'); | |||
| return; | |||
| } | |||
| // 登录逻辑 | |||
| }, | |||
| onCancel() { | |||
| // 取消登录逻辑 | |||
| } | |||
| } | |||
| }; | |||
| </script> | |||
| <style scoped> | |||
| .login-page { | |||
| min-height: 100vh; | |||
| background: #eef2fc; | |||
| display: flex; | |||
| flex-direction: column; | |||
| align-items: center; | |||
| position: relative; | |||
| padding-top: 60px; | |||
| } | |||
| .logo-box { | |||
| width: 120px; | |||
| height: 120px; | |||
| background: #fff; | |||
| border-radius: 16px; | |||
| display: flex; | |||
| align-items: center; | |||
| justify-content: center; | |||
| margin-bottom: 16px; | |||
| box-shadow: 0 2px 8px #e0e6f6; | |||
| } | |||
| .logo { | |||
| width: 80px; | |||
| height: 80px; | |||
| object-fit: contain; | |||
| } | |||
| .title { | |||
| font-size: 22px; | |||
| font-weight: bold; | |||
| color: #222; | |||
| margin-bottom: 32px; | |||
| } | |||
| .cancel-row { | |||
| width: 80%; | |||
| display: flex; | |||
| align-items: center; | |||
| position: relative; | |||
| margin-bottom: 8px; | |||
| } | |||
| .arrow-icon { | |||
| color: #fd7e14; | |||
| font-size: 18px; | |||
| margin: 0 6px; | |||
| z-index: 2; | |||
| } | |||
| .dashed-line { | |||
| flex: 1; | |||
| border-bottom: 2px dashed #fd7e14; | |||
| height: 0; | |||
| margin-left: -8px; | |||
| } | |||
| .book-bg { | |||
| position: absolute; | |||
| left: 50%; | |||
| bottom: 0; | |||
| transform: translateX(-50%); | |||
| width: 220px; | |||
| height: 180px; | |||
| background: url('/static/auth/headImage.png') no-repeat center/contain; | |||
| opacity: 0.08; | |||
| z-index: 0; | |||
| } | |||
| </style> | |||
| @ -1,162 +1,163 @@ | |||
| <template> | |||
| <view class="vote-container"> | |||
| <!-- Empty space at the top --> | |||
| <view class="empty-space"></view> | |||
| <!-- Bottom sheet with voting interface --> | |||
| <view class="vote-sheet"> | |||
| <view class="sheet-header"> | |||
| <text class="sheet-title">投推荐票</text> | |||
| </view> | |||
| <view class="vote-options"> | |||
| <text class="option-label">推荐投票</text> | |||
| <view class="quick-options"> | |||
| <view class="option-btn" @click="setVotes(1)">1</view> | |||
| <view class="option-btn" @click="setVotes(5)">5</view> | |||
| <view class="option-btn" @click="setVotes(10)">10</view> | |||
| </view> | |||
| <text class="option-label">手动设置</text> | |||
| <view class="manual-input"> | |||
| <view class="minus-btn" @click="decreaseVotes">-</view> | |||
| <view class="vote-count"> | |||
| <text>x{{voteCount}}</text> | |||
| </view> | |||
| <view class="plus-btn" @click="increaseVotes">+</view> | |||
| </view> | |||
| </view> | |||
| <button class="submit-btn" @click="submitVote">投票</button> | |||
| </view> | |||
| </view> | |||
| <view class="vote-container"> | |||
| <!-- Empty space at the top --> | |||
| <view class="empty-space"></view> | |||
| <!-- Bottom sheet with voting interface --> | |||
| <view class="vote-sheet"> | |||
| <view class="sheet-header"> | |||
| <text class="sheet-title">投推荐票</text> | |||
| </view> | |||
| <view class="vote-options"> | |||
| <text class="option-label">推荐投票</text> | |||
| <view class="quick-options"> | |||
| <view class="option-btn" @click="setVotes(1)">1</view> | |||
| <view class="option-btn" @click="setVotes(5)">5</view> | |||
| <view class="option-btn" @click="setVotes(10)">10</view> | |||
| </view> | |||
| <text class="option-label">手动设置</text> | |||
| <view class="manual-input"> | |||
| <view class="minus-btn" @click="decreaseVotes">-</view> | |||
| <view class="vote-count"> | |||
| <text>x{{voteCount}}</text> | |||
| </view> | |||
| <view class="plus-btn" @click="increaseVotes">+</view> | |||
| </view> | |||
| </view> | |||
| <button class="submit-btn" @click="submitVote">投票</button> | |||
| </view> | |||
| </view> | |||
| </template> | |||
| <script> | |||
| export default { | |||
| data() { | |||
| return { | |||
| voteCount: 1 | |||
| } | |||
| }, | |||
| methods: { | |||
| setVotes(count) { | |||
| this.voteCount = count | |||
| }, | |||
| increaseVotes() { | |||
| this.voteCount++ | |||
| }, | |||
| decreaseVotes() { | |||
| if (this.voteCount > 1) { | |||
| this.voteCount-- | |||
| } | |||
| }, | |||
| submitVote() { | |||
| // TODO: Implement vote submission | |||
| uni.showToast({ | |||
| title: `已投${this.voteCount}票`, | |||
| icon: 'success' | |||
| }) | |||
| } | |||
| } | |||
| } | |||
| export default { | |||
| data() { | |||
| return { | |||
| voteCount: 1 | |||
| } | |||
| }, | |||
| methods: { | |||
| setVotes(count) { | |||
| this.voteCount = count | |||
| }, | |||
| increaseVotes() { | |||
| this.voteCount++ | |||
| }, | |||
| decreaseVotes() { | |||
| if (this.voteCount > 1) { | |||
| this.voteCount-- | |||
| } | |||
| }, | |||
| submitVote() { | |||
| // TODO: Implement vote submission | |||
| uni.showToast({ | |||
| title: `已投${this.voteCount}票`, | |||
| icon: 'success' | |||
| }) | |||
| } | |||
| } | |||
| } | |||
| </script> | |||
| <style lang="scss"> | |||
| .vote-container { | |||
| display: flex; | |||
| flex-direction: column; | |||
| height: 100vh; | |||
| background-color: rgba(0, 0, 0, 0.4); | |||
| } | |||
| .empty-space { | |||
| flex: 1; | |||
| } | |||
| .vote-sheet { | |||
| background-color: #fff; | |||
| border-radius: 20rpx 20rpx 0 0; | |||
| padding: 30rpx; | |||
| } | |||
| .sheet-header { | |||
| text-align: center; | |||
| margin-bottom: 40rpx; | |||
| } | |||
| .sheet-title { | |||
| font-size: 32rpx; | |||
| font-weight: 500; | |||
| } | |||
| .vote-options { | |||
| margin-bottom: 40rpx; | |||
| } | |||
| .option-label { | |||
| font-size: 28rpx; | |||
| color: #666; | |||
| margin-bottom: 20rpx; | |||
| } | |||
| .quick-options { | |||
| display: flex; | |||
| gap: 20rpx; | |||
| margin-top: 30rpx; | |||
| margin-bottom: 40rpx; | |||
| } | |||
| .option-btn { | |||
| flex: 1; | |||
| height: 80rpx; | |||
| background-color: #f5f5f5; | |||
| display: flex; | |||
| align-items: center; | |||
| justify-content: center; | |||
| border-radius: 8rpx; | |||
| font-size: 28rpx; | |||
| } | |||
| .manual-input { | |||
| margin-top: 30rpx; | |||
| display: flex; | |||
| align-items: center; | |||
| justify-content: center; | |||
| gap: 20rpx; | |||
| } | |||
| .minus-btn, .plus-btn { | |||
| width: 220rpx; | |||
| height: 80rpx; | |||
| background-color: #f5f5f5; | |||
| display: flex; | |||
| align-items: center; | |||
| justify-content: center; | |||
| border-radius: 8rpx; | |||
| font-size: 32rpx; | |||
| } | |||
| .vote-count { | |||
| width: 220rpx; | |||
| height: 82rpx; | |||
| background-color: #f5f5f5; | |||
| display: flex; | |||
| align-items: center; | |||
| justify-content: center; | |||
| border-radius: 8rpx; | |||
| font-size: 28rpx; | |||
| } | |||
| .submit-btn { | |||
| width: 100%; | |||
| height: 88rpx; | |||
| background-color: #000033; | |||
| color: #fff; | |||
| border-radius: 8rpx; | |||
| font-size: 32rpx; | |||
| display: flex; | |||
| align-items: center; | |||
| justify-content: center; | |||
| } | |||
| </style> | |||
| .vote-container { | |||
| display: flex; | |||
| flex-direction: column; | |||
| height: 100vh; | |||
| background-color: rgba(0, 0, 0, 0.4); | |||
| } | |||
| .empty-space { | |||
| flex: 1; | |||
| } | |||
| .vote-sheet { | |||
| background-color: #fff; | |||
| border-radius: 20rpx 20rpx 0 0; | |||
| padding: 30rpx; | |||
| } | |||
| .sheet-header { | |||
| text-align: center; | |||
| margin-bottom: 40rpx; | |||
| } | |||
| .sheet-title { | |||
| font-size: 32rpx; | |||
| font-weight: 500; | |||
| } | |||
| .vote-options { | |||
| margin-bottom: 40rpx; | |||
| } | |||
| .option-label { | |||
| font-size: 28rpx; | |||
| color: #666; | |||
| margin-bottom: 20rpx; | |||
| } | |||
| .quick-options { | |||
| display: flex; | |||
| gap: 20rpx; | |||
| margin-top: 30rpx; | |||
| margin-bottom: 40rpx; | |||
| } | |||
| .option-btn { | |||
| flex: 1; | |||
| height: 80rpx; | |||
| background-color: #f5f5f5; | |||
| display: flex; | |||
| align-items: center; | |||
| justify-content: center; | |||
| border-radius: 8rpx; | |||
| font-size: 28rpx; | |||
| } | |||
| .manual-input { | |||
| margin-top: 30rpx; | |||
| display: flex; | |||
| align-items: center; | |||
| justify-content: center; | |||
| gap: 20rpx; | |||
| } | |||
| .minus-btn, | |||
| .plus-btn { | |||
| width: 220rpx; | |||
| height: 80rpx; | |||
| background-color: #f5f5f5; | |||
| display: flex; | |||
| align-items: center; | |||
| justify-content: center; | |||
| border-radius: 8rpx; | |||
| font-size: 32rpx; | |||
| } | |||
| .vote-count { | |||
| width: 220rpx; | |||
| height: 82rpx; | |||
| background-color: #f5f5f5; | |||
| display: flex; | |||
| align-items: center; | |||
| justify-content: center; | |||
| border-radius: 8rpx; | |||
| font-size: 28rpx; | |||
| } | |||
| .submit-btn { | |||
| width: 100%; | |||
| height: 88rpx; | |||
| background-color: #000033; | |||
| color: #fff; | |||
| border-radius: 8rpx; | |||
| font-size: 32rpx; | |||
| display: flex; | |||
| align-items: center; | |||
| justify-content: center; | |||
| } | |||
| </style> | |||