小说小程序前端代码仓库(小程序)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

280 lines
8.1 KiB

  1. <template>
  2. <view class="tipping-page">
  3. <!-- 顶部导航栏 -->
  4. <navbar title="读者亲密值榜单" bgColor="#ac4b2c" color="#fff" leftClick @leftClick="$utils.navigateBack" />
  5. <!-- 榜单前三名 -->
  6. <view class="top-three">
  7. <view class="top-item second" v-if="topList[1]">
  8. <view class="avatar-frame">
  9. <image class="frame-img" src="/pages_order/static/top/top1.png" mode="aspectFit"></image>
  10. <image class="avatar" :src="topList[1].hanHaiMember
  11. && topList[1].hanHaiMember.headImage" mode="aspectFill"></image>
  12. </view>
  13. <view class="badge">
  14. <image class="badge-img" src="/pages_order/static/book/dj.png" mode="aspectFit"></image>
  15. </view>
  16. <view class="name">{{
  17. topList[1].hanHaiMember
  18. && topList[1].hanHaiMember.nickName
  19. }}</view>
  20. <view class="score">{{ topList[1].num }} 亲密值</view>
  21. <view class="level">{{
  22. topList[1].commonBookAchievement
  23. && (topList[1].commonBookAchievement.oldName || topList[1].commonBookAchievement.title)
  24. }}</view>
  25. </view>
  26. <view class="top-item first" v-if="topList[0]">
  27. <view class="avatar-frame">
  28. <image class="frame-img" src="/pages_order/static/top/top1.png" mode="aspectFit"></image>
  29. <image class="avatar" :src="topList[0].hanHaiMember
  30. && topList[0].hanHaiMember.headImage" mode="aspectFill"></image>
  31. </view>
  32. <view class="badge">
  33. <image class="badge-img" :src="topList[0].icon" mode="aspectFit"></image>
  34. </view>
  35. <view class="name">{{
  36. topList[0].hanHaiMember
  37. && topList[0].hanHaiMember.nickName
  38. }}</view>
  39. <view class="score">{{ topList[0].num }} 亲密值</view>
  40. <view class="level">{{
  41. topList[0].commonBookAchievement
  42. && (topList[0].commonBookAchievement.oldName || topList[0].commonBookAchievement.title)
  43. }}</view>
  44. </view>
  45. <view class="top-item third" v-if="topList[2]">
  46. <view class="avatar-frame">
  47. <image class="frame-img" src="/pages_order/static/top/top1.png" mode="aspectFit"></image>
  48. <image class="avatar" :src="topList[2].hanHaiMember
  49. && topList[2].hanHaiMember.headImage" mode="aspectFill"></image>
  50. </view>
  51. <view class="badge">
  52. <image class="badge-img" src="/pages_order/static/book/dj.png" mode="aspectFit"></image>
  53. </view>
  54. <view class="name">{{ topList[2].name }}</view>
  55. <view class="score">{{ topList[2].num }} 亲密值</view>
  56. <view class="level">{{
  57. topList[2].commonBookAchievement
  58. && (topList[2].commonBookAchievement.oldName || topList[2].commonBookAchievement.title)
  59. }}</view>
  60. </view>
  61. </view>
  62. <!-- 榜单列表 -->
  63. <view class="rank-list"
  64. v-if="topList.length > 3">
  65. <RankListItem v-for="(item, idx) in topList"
  66. v-if="idx > 2"
  67. :index="idx + 1"
  68. :item="item"
  69. :key="item.id" />
  70. </view>
  71. <!-- 底部按钮 -->
  72. <view class="bottom-btn-area">
  73. <button class="tipping-btn"
  74. @click="$refs.interactiveGiftPopup.open"
  75. >互动打赏</button>
  76. </view>
  77. <interactiveGiftPopup ref="interactiveGiftPopup" :bookId="bookId" @giftSent="handleGiftSent"/>
  78. </view>
  79. </template>
  80. <script>
  81. import RankListItem from '../components/novel/RankListItem.vue'
  82. import interactiveGiftPopup from '../components/novel/interactiveGiftPopup.vue'
  83. export default {
  84. components: {
  85. RankListItem,
  86. interactiveGiftPopup,
  87. },
  88. data() {
  89. return {
  90. topList: [],
  91. rankList: [],
  92. bookId: 0,
  93. }
  94. },
  95. onLoad(options) {
  96. this.bookId = options.id;
  97. },
  98. onShow() {
  99. this.getTopList();
  100. },
  101. methods: {
  102. getTopList() {
  103. this.$fetch('getIntimacyRankList', {
  104. bookId: this.bookId,
  105. pageNo: 1,
  106. pageSize: 10
  107. }).then(res => {
  108. this.topList = res.records;
  109. });
  110. },
  111. handleGiftSent(giftData) {
  112. // 处理礼物发送后的逻辑
  113. console.log('礼物发送成功:', giftData);
  114. uni.showToast({
  115. title: `成功赠送${giftData.gift.title} x${giftData.count}`,
  116. icon: 'success'
  117. });
  118. // 重新获取小说详情,更新打赏相关数据
  119. this.getTopList();
  120. },
  121. }
  122. }
  123. </script>
  124. <style lang="scss" scoped>
  125. .tipping-page {
  126. min-height: 100vh;
  127. // background: linear-gradient(180deg, #b86e3b 0%, #e6b07c 100%);
  128. background-color: #ac4b2c;
  129. padding-bottom: 40rpx;
  130. }
  131. .top-three {
  132. display: flex;
  133. justify-content: center;
  134. align-items: flex-end;
  135. margin: 80rpx 0 200rpx 0;
  136. padding: 0 30rpx;
  137. gap: 20rpx;
  138. .top-item {
  139. display: flex;
  140. flex-direction: column;
  141. align-items: center;
  142. position: relative;
  143. border-top-left-radius: 110rpx;
  144. border-top-right-radius: 110rpx;
  145. gap: 10rpx;
  146. padding-bottom: 20rpx;
  147. &.first {
  148. z-index: 3;
  149. margin-top: -50rpx;
  150. background: linear-gradient(to bottom, #F8DA87, #F8DA8700);
  151. border: 1px solid #fff;
  152. }
  153. &.second {
  154. z-index: 2;
  155. background: linear-gradient(to bottom, #C2C9CD, #C2C9CD00);
  156. border: 1px solid #fff;
  157. top: 80rpx;
  158. }
  159. &.third {
  160. z-index: 2;
  161. background: linear-gradient(to bottom, #834941, #83494100);
  162. border: 1px solid #fff;
  163. top: 80rpx;
  164. }
  165. .avatar-frame {
  166. position: relative;
  167. width: 220rpx;
  168. height: 220rpx;
  169. margin-top: -50rpx;
  170. .frame-img {
  171. position: absolute;
  172. width: 120%;
  173. height: 120%;
  174. z-index: 2;
  175. top: 50%;
  176. left: 50%;
  177. transform: translate(-50%, -50%);
  178. }
  179. .avatar {
  180. position: absolute;
  181. top: 50%;
  182. left: 50%;
  183. transform: translate(-50%, -50%);
  184. width: 80%;
  185. height: 80%;
  186. border-radius: 50%;
  187. z-index: 1;
  188. }
  189. }
  190. .badge {
  191. width: 100rpx;
  192. height: 100rpx;
  193. z-index: 3;
  194. .badge-img {
  195. width: 100%;
  196. height: 100%;
  197. }
  198. }
  199. .name {
  200. width: 200rpx;
  201. overflow:hidden; //超出的文本隐藏
  202. text-overflow:ellipsis; //溢出用省略号显示
  203. white-space:nowrap; //溢出不换行
  204. margin-top: 10rpx;
  205. font-size: 30rpx;
  206. color: #FFFFFF;
  207. font-weight: bold;
  208. }
  209. .score {
  210. font-size: 28rpx;
  211. color: #FFFFFF;
  212. margin-top: 6rpx;
  213. }
  214. .level {
  215. position: absolute;
  216. bottom: -40rpx;
  217. width: 102%;
  218. text-align: center;
  219. padding: 6rpx 20rpx;
  220. background-color: #FFCC33;
  221. border-radius: 6rpx;
  222. font-size: 26rpx;
  223. color: #8B4513;
  224. font-weight: bold;
  225. box-sizing: border-box;
  226. }
  227. }
  228. }
  229. .rank-list {
  230. background: #FAE5BE;
  231. margin: 0 24rpx;
  232. padding: 20rpx;
  233. border-radius: 20rpx;
  234. display: flex;
  235. flex-direction: column;
  236. gap: 20rpx;
  237. }
  238. .bottom-btn-area {
  239. margin: 40rpx 24rpx 90rpx 24rpx;
  240. display: flex;
  241. flex-direction: column;
  242. gap: 24rpx;
  243. .tipping-btn {
  244. width: 100%;
  245. height: 80rpx;
  246. background: #fffbe6;
  247. color: #b86e3b;
  248. font-size: 32rpx;
  249. border-radius: 40rpx;
  250. font-weight: bold;
  251. letter-spacing: 2rpx;
  252. box-shadow: 0 4rpx 16rpx 0 rgba(184, 110, 59, 0.12);
  253. border: none;
  254. }
  255. }
  256. </style>