小说网站前端代码仓库
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.

437 lines
12 KiB

  1. <template>
  2. <div class="intimacy-ranking-container">
  3. <div class="ranking-header">
  4. <div class="header-title">
  5. <img src="@/assets/images/读者榜单.png" alt="读者榜单" class="ranking-icon" />
  6. <span>读者亲密榜单</span>
  7. </div>
  8. </div>
  9. <div class="ranking-tabs">
  10. <div class="tab-list">
  11. <div v-for="(tab, index) in tabs" :key="index"
  12. :class="['tab-item', { active: activeTab === tab.value }]" @click="activeTab = tab.value">
  13. {{ tab.label }}
  14. </div>
  15. </div>
  16. </div>
  17. <div class="ranking-list">
  18. <div v-for="(item, index) in currentRankingList" :key="index" class="ranking-item">
  19. <div class="rank-num">
  20. <template v-if="index < 3">
  21. <div :class="['medal', `medal-${index + 1}`]">{{ index + 1 }}</div>
  22. </template>
  23. <template v-else>
  24. <div class="normal-rank">{{ index + 1 }}</div>
  25. </template>
  26. </div>
  27. <div class="user-avatar">
  28. <img :src="item.avatar" :alt="item.username">
  29. </div>
  30. <div class="user-info">
  31. <div class="username">{{ item.username }}</div>
  32. <div class="level-tag">
  33. {{ `护书者者 ${item.level}` }}
  34. </div>
  35. </div>
  36. <div class="intimacy-value">
  37. <div class="value">{{ item.value }}</div>
  38. <div class="label">亲密值</div>
  39. </div>
  40. </div>
  41. </div>
  42. </div>
  43. </template>
  44. <script>
  45. import { defineComponent, ref, computed } from 'vue';
  46. export default defineComponent({
  47. name: 'IntimacyRanking',
  48. props: {
  49. bookId: {
  50. type: String,
  51. default: ''
  52. }
  53. },
  54. setup(props) {
  55. const tabs = [
  56. { label: '总榜', value: 'all' },
  57. { label: '周榜', value: 'week' },
  58. { label: '月榜', value: 'month' }
  59. ];
  60. const activeTab = ref('all');
  61. const allRankingList = ref([
  62. {
  63. username: '周游',
  64. avatar: 'https://picsum.photos/100/100?random=1',
  65. level: '五',
  66. value: '8783452',
  67. },
  68. {
  69. username: '冯启明',
  70. avatar: 'https://picsum.photos/100/100?random=2',
  71. level: '五',
  72. value: '890379',
  73. },
  74. {
  75. username: '风静',
  76. avatar: 'https://picsum.photos/100/100?random=3',
  77. level: '四',
  78. value: '605039',
  79. },
  80. {
  81. username: '钱静',
  82. avatar: 'https://picsum.photos/100/100?random=4',
  83. level: '三',
  84. value: '532524',
  85. },
  86. {
  87. username: '线编码',
  88. avatar: 'https://picsum.photos/100/100?random=5',
  89. level: '三',
  90. value: '525524',
  91. },
  92. {
  93. username: '冯艾蓥',
  94. avatar: 'https://picsum.photos/100/100?random=6',
  95. level: '二',
  96. value: '496064',
  97. },
  98. {
  99. username: '李书琦',
  100. avatar: 'https://picsum.photos/100/100?random=7',
  101. level: '一',
  102. value: '372525',
  103. },
  104. {
  105. username: '李梅',
  106. avatar: 'https://picsum.photos/100/100?random=8',
  107. level: '一',
  108. value: '267476',
  109. },
  110. {
  111. username: '郑帆',
  112. avatar: 'https://picsum.photos/100/100?random=9',
  113. level: '一',
  114. value: '248480',
  115. },
  116. {
  117. username: '吴修德',
  118. avatar: 'https://picsum.photos/100/100?random=10',
  119. level: '一',
  120. value: '59053',
  121. }
  122. ]);
  123. const weekRankingList = ref([
  124. {
  125. username: '周游',
  126. avatar: 'https://picsum.photos/100/100?random=1',
  127. level: '五',
  128. value: '78452',
  129. },
  130. {
  131. username: '冯启明',
  132. avatar: 'https://picsum.photos/100/100?random=2',
  133. level: '五',
  134. value: '69037',
  135. },
  136. {
  137. username: '风静',
  138. avatar: 'https://picsum.photos/100/100?random=3',
  139. level: '四',
  140. value: '60509',
  141. },
  142. {
  143. username: '钱静',
  144. avatar: 'https://picsum.photos/100/100?random=4',
  145. level: '三',
  146. value: '53254',
  147. },
  148. {
  149. username: '线编码',
  150. avatar: 'https://picsum.photos/100/100?random=5',
  151. level: '三',
  152. value: '52554',
  153. },
  154. {
  155. username: '冯艾蓥',
  156. avatar: 'https://picsum.photos/100/100?random=6',
  157. level: '二',
  158. value: '49064',
  159. },
  160. {
  161. username: '李书琦',
  162. avatar: 'https://picsum.photos/100/100?random=7',
  163. level: '一',
  164. value: '37255',
  165. },
  166. {
  167. username: '李梅',
  168. avatar: 'https://picsum.photos/100/100?random=8',
  169. level: '一',
  170. value: '26747',
  171. },
  172. {
  173. username: '郑帆',
  174. avatar: 'https://picsum.photos/100/100?random=9',
  175. level: '一',
  176. value: '24848',
  177. },
  178. {
  179. username: '吴修德',
  180. avatar: 'https://picsum.photos/100/100?random=10',
  181. level: '一',
  182. value: '5953',
  183. }
  184. ]);
  185. const monthRankingList = ref([
  186. {
  187. username: '周游',
  188. avatar: 'https://picsum.photos/100/100?random=1',
  189. level: '五',
  190. value: '178452',
  191. },
  192. {
  193. username: '冯启明',
  194. avatar: 'https://picsum.photos/100/100?random=2',
  195. level: '五',
  196. value: '169037',
  197. },
  198. {
  199. username: '风静',
  200. avatar: 'https://picsum.photos/100/100?random=3',
  201. level: '四',
  202. value: '160509',
  203. },
  204. {
  205. username: '钱静',
  206. avatar: 'https://picsum.photos/100/100?random=4',
  207. level: '三',
  208. value: '153254',
  209. },
  210. {
  211. username: '线编码',
  212. avatar: 'https://picsum.photos/100/100?random=5',
  213. level: '三',
  214. value: '152554',
  215. },
  216. {
  217. username: '冯艾蓥',
  218. avatar: 'https://picsum.photos/100/100?random=6',
  219. level: '二',
  220. value: '149064',
  221. },
  222. {
  223. username: '李书琦',
  224. avatar: 'https://picsum.photos/100/100?random=7',
  225. level: '一',
  226. value: '137255',
  227. },
  228. {
  229. username: '李梅',
  230. avatar: 'https://picsum.photos/100/100?random=8',
  231. level: '一',
  232. value: '126747',
  233. },
  234. {
  235. username: '郑帆',
  236. avatar: 'https://picsum.photos/100/100?random=9',
  237. level: '一',
  238. value: '124848',
  239. },
  240. {
  241. username: '吴修德',
  242. avatar: 'https://picsum.photos/100/100?random=10',
  243. level: '一',
  244. value: '105953',
  245. }
  246. ]);
  247. const currentRankingList = computed(() => {
  248. if (activeTab.value === 'all') {
  249. return allRankingList.value;
  250. } else if (activeTab.value === 'week') {
  251. return weekRankingList.value;
  252. } else {
  253. return monthRankingList.value;
  254. }
  255. });
  256. return {
  257. tabs,
  258. activeTab,
  259. currentRankingList
  260. };
  261. }
  262. });
  263. </script>
  264. <style lang="scss" scoped>
  265. .intimacy-ranking-container {
  266. background-color: #fff;
  267. border-radius: 6px;
  268. box-shadow: 0 1px 2px rgba(0, 0, 0, 0.03);
  269. padding: 0 0 16px 0;
  270. overflow: hidden;
  271. margin-left: 0;
  272. .ranking-header {
  273. background-color: #0A2463;
  274. color: #fff;
  275. padding: 15px 20px;
  276. .header-title {
  277. display: flex;
  278. align-items: center;
  279. font-size: 18px;
  280. font-weight: bold;
  281. .ranking-icon {
  282. width: 28px;
  283. height: 28px;
  284. margin-right: 10px;
  285. }
  286. }
  287. }
  288. .ranking-tabs {
  289. padding: 12px 15px;
  290. border-bottom: 1px solid #eee;
  291. .tab-list {
  292. display: flex;
  293. .tab-item {
  294. padding: 6px 16px;
  295. font-size: 15px;
  296. color: #666;
  297. cursor: pointer;
  298. border-radius: 4px;
  299. transition: all 0.2s;
  300. &.active {
  301. background-color: #f0f5ff;
  302. color: #0A2463;
  303. font-weight: 500;
  304. }
  305. &:hover:not(.active) {
  306. color: #0A2463;
  307. }
  308. }
  309. }
  310. }
  311. .ranking-list {
  312. padding: 0 15px;
  313. .ranking-item {
  314. display: flex;
  315. align-items: center;
  316. padding: 12px 0;
  317. border-bottom: 1px solid #f5f5f5;
  318. &:last-child {
  319. border-bottom: none;
  320. }
  321. .rank-num {
  322. width: 30px;
  323. display: flex;
  324. justify-content: center;
  325. .medal {
  326. width: 22px;
  327. height: 22px;
  328. display: flex;
  329. align-items: center;
  330. justify-content: center;
  331. border-radius: 50%;
  332. font-size: 14px;
  333. font-weight: bold;
  334. color: #fff;
  335. &.medal-1 {
  336. background: linear-gradient(to bottom, #ffda44, #ff9c39);
  337. }
  338. &.medal-2 {
  339. background: linear-gradient(to bottom, #d3d3d3, #a0a0a0);
  340. }
  341. &.medal-3 {
  342. background: linear-gradient(to bottom, #ffc09f, #a15c20);
  343. }
  344. }
  345. .normal-rank {
  346. font-size: 16px;
  347. color: #999;
  348. }
  349. }
  350. .user-avatar {
  351. width: 44px;
  352. height: 44px;
  353. border-radius: 50%;
  354. overflow: hidden;
  355. margin: 0 12px;
  356. img {
  357. width: 100%;
  358. height: 100%;
  359. object-fit: cover;
  360. }
  361. }
  362. .user-info {
  363. flex: 1;
  364. min-width: 0;
  365. .username {
  366. font-size: 15px;
  367. font-weight: 500;
  368. color: #333;
  369. margin-bottom: 4px;
  370. white-space: nowrap;
  371. overflow: hidden;
  372. text-overflow: ellipsis;
  373. }
  374. .level-tag {
  375. font-size: 13px;
  376. color: #0A2463;
  377. background-color: #f0f5ff;
  378. display: inline-block;
  379. padding: 2px 8px;
  380. border-radius: 4px;
  381. }
  382. }
  383. .intimacy-value {
  384. text-align: right;
  385. min-width: 80px;
  386. .value {
  387. font-size: 16px;
  388. font-weight: bold;
  389. color: #ff7c6a;
  390. }
  391. .label {
  392. font-size: 12px;
  393. color: #999;
  394. }
  395. }
  396. }
  397. }
  398. }
  399. </style>