challengeList.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512
  1. <template>
  2. <view class="challenage-container">
  3. <view class="nav-container">
  4. <view v-for="(nav, ni) in navList" :key="ni" class="nav-item" :class="active === ni ? 'active' : ''" @click="(active = ni), ToTop()">{{ nav }}</view>
  5. </view>
  6. <view class="challenage-list">
  7. <template v-if="list.length > 0">
  8. <view v-for="item in list" :key="item.id" class="challenage-item">
  9. <!-- <view class="challenage-status" :class="Date.now() < item.guessing_endtime ? (item.status ? (item.status == 1 ? 'ing' : '') : 'no') : ''">
  10. {{
  11. (Date.now() &lt; item.guessing_endtime) ?
  12. !item.status ?
  13. '未应战' : item.status == 1 ?
  14. '对战中' : '已结束'
  15. : '已结束'
  16. }}
  17. </view> -->
  18. <view class="challenage-status" :class="item.status == 1 ? 'ing' : item.status == 0 ? 'no' : ''" v-if="active == 0">
  19. <view v-if="item.status == 0">未应战</view>
  20. <view v-if="item.status == 1">对战中</view>
  21. <view v-if="item.status == 2">已结束</view>
  22. <view v-if="item.status == 3">已拒绝</view>
  23. </view>
  24. <view class="challenage-status" :class="item.status == 1 ? 'ing' : ''" v-else>{{ item.status == 1 ? '对战中' : '已结束' }}</view>
  25. <view class="body body2">
  26. <view class="user-avatar" :class="item.status == 2 && item.challenge_id == item.success_id ? 'win' : ''">
  27. <view class="avatar-bg"><view class="avatar-img" :style="{ backgroundImage: `url(${item.challenge_avatar})` }" /></view>
  28. <view class="user-name">{{ item.challenge_nickname | getName }}</view>
  29. </view>
  30. <!-- 我的挑战 -->
  31. <template v-if="active === 0">
  32. <view class="challenage-info">
  33. <view class="info-title">
  34. <text class="text">“</text>
  35. <text class="text spec">{{ item.challenge_nickname | getName }}</text>
  36. <text class="text">”向你发起的挑战</text>
  37. </view>
  38. <view class="info-num">
  39. <view class="num">{{ Math.floor(item.day / 10) }}</view>
  40. <view class="num">{{ item.day % 10 }}</view>
  41. </view>
  42. <view class="info-time">{{ item.time }}</view>
  43. <view class="info-btn" :class="item.status == 1 || item.status == 2 ? 'active' : ''" @click="toDetail(item)">
  44. {{ item | getAction(nowActive) }}
  45. </view>
  46. </view>
  47. </template>
  48. <!-- 围观竞猜 挑战排行 -->
  49. <template v-else>
  50. <view class="challenage-info info2">
  51. <view class="challenage-vs">
  52. <view class="info-score">{{ item.challenge_total }}</view>
  53. <view class="vs-img"></view>
  54. <view class="info-score accept">{{ item.accept_total }}</view>
  55. </view>
  56. <!-- <view class="info-btn" :class="item.status !== 3 || Date.now() > item.guessing_endtime ? 'active' : ''" @click="toDetail(item)"> -->
  57. <view class="info-btn" :class="item.status == 1 ? 'active' : ''" @click="toDetail(item)">{{ item | getAction(nowActive) }}</view>
  58. </view>
  59. </template>
  60. <view class="user-avatar" :class="item.status == 2 && item.accept_id == item.success_id ? 'win' : ''">
  61. <view class="avatar-bg accept"><view class="avatar-img" :style="{ backgroundImage: `url(${item.accept_avatar})` }" /></view>
  62. <view class="user-name">{{ item.accept_nickname | getName }}</view>
  63. </view>
  64. </view>
  65. </view>
  66. </template>
  67. <template v-else>
  68. <view class="noTip">暂无竞猜挑战</view>
  69. </template>
  70. </view>
  71. <view class="start-challenge" @click="getChallenge">
  72. <view class="start-cilcle"></view>
  73. <view class="text">发起挑战</view>
  74. </view>
  75. </view>
  76. </template>
  77. <script>
  78. import { api_Mychallenge_list, api_GuessingList, api_GuessingRanklList } from '@/api.js';
  79. export default {
  80. data() {
  81. return {
  82. navList: ['我的挑战', '围观竞猜', '挑战排行'],
  83. pageTitle: '学分挑战',
  84. active: 1,
  85. nowActive: 0,
  86. list: [],
  87. page: 1,
  88. requesting: false,
  89. scrollViewHeight: 0,
  90. showScrollView: false,
  91. // scrollTop: 0
  92. };
  93. },
  94. watch: {
  95. active() {
  96. this.refresherrefresh();
  97. }
  98. },
  99. filters: {
  100. getAction(item, nowActive) {
  101. if (nowActive == 0) {
  102. if (item.status == 1 || item.status == 2) {
  103. return '挑战详情';
  104. } else if (item.status == 0) {
  105. if (item.type == 0) {
  106. return '查看详情';
  107. } else if (item.type == 1) {
  108. return '应战';
  109. }
  110. } else if (item.status == 3) {
  111. return '已拒绝';
  112. }
  113. } else {
  114. if (item.guessing) {
  115. return '已竞猜';
  116. } else {
  117. if (Date.now() > item.guessing_endtime) {
  118. return '竞猜结束';
  119. } else {
  120. return '围观竞猜';
  121. }
  122. }
  123. }
  124. return '';
  125. },
  126. getLong(long, index) {
  127. return (Number(long) > 9 ? String(long) : '0' + long)[index];
  128. },
  129. getName(name) {
  130. if (name) {
  131. return name.length > 8 ? name.slice(0, 8) + '...' : name;
  132. }
  133. return '';
  134. }
  135. },
  136. // onPageScroll(e) {
  137. // this.scrollTop = e.scrollTop;
  138. // },
  139. onLoad(e) {
  140. if (e.active) {
  141. this.active = Number(e.active);
  142. }
  143. this.request(true);
  144. uni.$on('RejectPK', id => (this.list.find(e => e.id == id).status = 3));
  145. uni.$on('AcceptPK', id => (this.list.find(e => e.id == id).status = 1));
  146. uni.$on('Guesst', id => (this.list.find(e => e.id == id).guessing = true));
  147. uni.$on('REDRESH', () => this.refresherrefresh());
  148. },
  149. onReachBottom() {
  150. this.request();
  151. },
  152. methods: {
  153. //返回顶部
  154. ToTop() {
  155. uni.pageScrollTo({
  156. scrollTop: 0,
  157. duration: 300
  158. });
  159. },
  160. refresherrefresh() {
  161. this.page = 1;
  162. this.request(true);
  163. },
  164. request(refresh) {
  165. if (!this.requesting && this.page > 0) {
  166. this.requesting = true;
  167. uni.loading();
  168. this.$ajax
  169. .get(
  170. this.active == 0
  171. ? api_Mychallenge_list + `?page=${this.page}`
  172. : this.active === 1
  173. ? api_GuessingList + `?page=${this.page}`
  174. : api_GuessingRanklList + `?page=${this.page}`
  175. )
  176. .then(([, { data: { data: { list, size } } }]) => {
  177. list.length < size ? (this.page = 0) : (this.page += 1);
  178. (this.list = refresh ? list : [...this.list, ...list]), (this.nowActive = this.active);
  179. uni.hideLoading();
  180. this.requesting = false;
  181. });
  182. }
  183. },
  184. getChallenge() {
  185. // 点击发起挑战
  186. uni.navigateTo({ url: '../challenge/challenge' });
  187. },
  188. toDetail(item) {
  189. const type = this.$options.filters.getAction(item, this.active);
  190. if (type == '查看详情' || type == '应战') {
  191. uni.pkInfo = {
  192. challenge_id: item.challenge_id,
  193. challenge_avatar: item.challenge_avatar,
  194. challenge_nickname: item.challenge_nickname,
  195. accept_id: item.accept_id,
  196. accept_avatar: item.accept_avatar,
  197. accept_nickname: item.accept_nickname,
  198. id: item.id
  199. };
  200. }
  201. if (type == '查看详情') {
  202. uni.navigateTo({ url: '../challenge/challenge?type=1' });
  203. } else if (type == '应战') {
  204. uni.navigateTo({ url: '../challenge/challenge?type=2' });
  205. } else if (type == '挑战详情' || type == '围观竞猜' || type == '已竞猜' || type == '竞猜结束') {
  206. uni.temp1 = item;
  207. uni.navigateTo({ url: '../challenge-detail/challenge-detail' + (type == '挑战详情' ? '?from=1' + '&active=' + this.active : '?active=' + this.active) });
  208. }
  209. }
  210. }
  211. };
  212. </script>
  213. <style lang="scss">
  214. page {
  215. width: 100%;
  216. min-height: 100vh;
  217. .challenage-container {
  218. width: 100%;
  219. min-height: 100vh;
  220. display: flex;
  221. flex-direction: column;
  222. .nav-container {
  223. width: 100%;
  224. height: 104rpx;
  225. background-color: #ffffff;
  226. padding: 0 30rpx;
  227. display: flex;
  228. align-items: center;
  229. justify-content: space-between;
  230. position: fixed;
  231. top: 0;
  232. left: 0;
  233. background: #fff;
  234. z-index: 9999;
  235. .nav-item {
  236. color: #333333;
  237. font-size: 32rpx;
  238. line-height: 44rpx;
  239. font-weight: bolder;
  240. &.active {
  241. color: #ea4a41 !important;
  242. position: relative;
  243. &::after {
  244. content: '';
  245. display: block;
  246. width: 30rpx;
  247. height: 4rpx;
  248. border-radius: 4rpx;
  249. background: linear-gradient(97deg, #f97c55 0%, #f44545 100%);
  250. position: absolute;
  251. left: 50%;
  252. bottom: 0;
  253. transform: translate(-50%, 4rpx);
  254. }
  255. }
  256. }
  257. }
  258. .challenage-list {
  259. margin-top: 120rpx;
  260. flex: 1;
  261. // overflow: hidden;
  262. overflow: scroll;
  263. -webkit-overflow-scrolling: touch;
  264. background-color: #f9f9fb;
  265. box-sizing: border-box;
  266. .noTip {
  267. width: 100%;
  268. padding: 20rpx 0;
  269. text-align: center;
  270. color: #999999;
  271. }
  272. .challenage-item {
  273. width: calc(100% - 60rpx);
  274. margin: 0 auto 30rpx auto;
  275. border-radius: 24rpx;
  276. background-color: #ffffff;
  277. padding: 30rpx;
  278. box-sizing: border-box;
  279. overflow: hidden;
  280. &:nth-of-type(1) {
  281. margin-top: 30rpx;
  282. }
  283. position: relative;
  284. .challenage-status {
  285. position: absolute;
  286. top: 0;
  287. right: 0;
  288. height: 56rpx;
  289. padding: 0 30rpx;
  290. line-height: 56rpx;
  291. color: #999999;
  292. font-size: 28rpx;
  293. border-bottom-left-radius: 56rpx;
  294. background-color: #eeeeee;
  295. font-weight: bolder;
  296. &.ing {
  297. background: linear-gradient(113deg, #ffc401 0%, #fe0000 100%) !important;
  298. color: #ffffff !important;
  299. }
  300. &.no {
  301. background: linear-gradient(180deg, #13aefe 0%, #7bc9fb 100%) !important;
  302. color: #ffffff !important;
  303. }
  304. }
  305. .body {
  306. width: 100%;
  307. display: flex;
  308. align-items: center;
  309. justify-content: space-between;
  310. &.body2 {
  311. padding-top: 10rpx !important;
  312. }
  313. .user-avatar {
  314. width: 140rpx;
  315. position: relative;
  316. &.win {
  317. &::before {
  318. content: '';
  319. display: block;
  320. width: 74rpx;
  321. height: 32rpx;
  322. background: url(../../static/new_challenge/win_t.png) center no-repeat;
  323. background-size: 100%;
  324. position: absolute;
  325. top: -30rpx;
  326. left: 50%;
  327. transform: translateX(-50%);
  328. z-index: 99;
  329. }
  330. &::after {
  331. content: '';
  332. display: block;
  333. width: 150rpx;
  334. height: 65rpx;
  335. background: url(../../static/new_challenge/win_b.png) center no-repeat;
  336. background-size: 100%;
  337. position: absolute;
  338. left: 50%;
  339. bottom: 24rpx;
  340. transform: translateX(-50%);
  341. z-index: 99;
  342. }
  343. }
  344. .avatar-bg {
  345. width: 140rpx;
  346. height: 124rpx;
  347. background: linear-gradient(180deg, #f97c55 0%, #f44545 100%);
  348. &.accept {
  349. background: linear-gradient(180deg, #13aefe 0%, #7bc9fb 100%);
  350. }
  351. clip-path: polygon(0 50%, 25% 0, 75% 0, 100% 50%, 75% 100%, 25% 100%);
  352. display: flex;
  353. align-items: center;
  354. justify-content: center;
  355. margin-bottom: 6rpx;
  356. .avatar-img {
  357. width: calc(100% - 20rpx);
  358. height: calc(100% - 12rpx);
  359. clip-path: polygon(0 50%, 25% 0, 75% 0, 100% 50%, 75% 100%, 25% 100%);
  360. background-position: center;
  361. background-repeat: no-repeat;
  362. background-size: 100%;
  363. background-color: transparent;
  364. }
  365. }
  366. .user-name {
  367. width: 140rpx;
  368. height: 40rpx;
  369. color: #333333;
  370. font-size: 28rpx;
  371. line-height: 40rpx;
  372. text-align: center;
  373. overflow: hidden;
  374. text-overflow: ellipsis;
  375. }
  376. }
  377. .challenage-info {
  378. flex: 1;
  379. overflow: hidden;
  380. display: flex;
  381. flex-direction: column;
  382. align-items: center;
  383. .info-title {
  384. width: 100%;
  385. text-align: center;
  386. margin-bottom: 20rpx;
  387. .text {
  388. color: #333333;
  389. font-size: 28rpx;
  390. line-height: 40rpx;
  391. &.spec {
  392. color: #ea4a41 !important;
  393. }
  394. }
  395. }
  396. .info-num {
  397. display: flex;
  398. align-items: center;
  399. justify-content: center;
  400. margin-bottom: 10rpx;
  401. .num {
  402. height: 86rpx;
  403. padding: 0 14rpx;
  404. background: linear-gradient(180deg, #f97c55 0%, #f44545 100%);
  405. color: #ffffff;
  406. font-size: 48rpx;
  407. line-height: 86rpx;
  408. border-radius: 8rpx;
  409. &:nth-of-type(1) {
  410. margin-right: 10rpx;
  411. }
  412. }
  413. }
  414. .info-time {
  415. color: #333333;
  416. font-size: 28rpx;
  417. line-height: 40rpx;
  418. margin-bottom: 20rpx;
  419. text-align: center;
  420. }
  421. .info-btn {
  422. width: 192rpx;
  423. height: 68rpx;
  424. border-radius: 68rpx;
  425. text-align: center;
  426. line-height: 68rpx;
  427. background-color: #f8f8f8;
  428. color: #333333;
  429. font-size: 28rpx;
  430. }
  431. &.info2 {
  432. .challenage-vs {
  433. display: flex;
  434. align-items: center;
  435. justify-content: space-between;
  436. margin-bottom: 28rpx;
  437. padding-top: 44rpx;
  438. .info-score {
  439. min-width: 104rpx;
  440. box-sizing: border-box;
  441. text-align: center;
  442. height: 62rpx;
  443. border-radius: 8rpx;
  444. line-height: 62rpx;
  445. padding: 0 8rpx;
  446. background: linear-gradient(92deg, #f97c55 0%, #f44545 100%);
  447. color: #ffffff;
  448. font-size: 36rpx;
  449. &.accept {
  450. background: linear-gradient(268deg, #13aefe 0%, #7bc9fb 100%) !important;
  451. }
  452. }
  453. .vs-img {
  454. width: 100rpx;
  455. height: 100rpx;
  456. background: url('https://api.jiuweiyun.cn/public/uploads/weapp/icon/vs.png') center no-repeat;
  457. background-size: 100%;
  458. margin: 0 10rpx;
  459. }
  460. }
  461. }
  462. }
  463. }
  464. }
  465. }
  466. .start-challenge {
  467. position: fixed;
  468. right: 0;
  469. bottom: 240rpx;
  470. height: 88rpx;
  471. border-top-left-radius: 88rpx;
  472. border-bottom-left-radius: 88rpx;
  473. padding: 0 24rpx 0 16rpx;
  474. background: linear-gradient(81deg, #ffc401 0%, #fe0000 100%);
  475. display: flex;
  476. align-items: center;
  477. justify-content: center;
  478. .start-cilcle {
  479. width: 68rpx;
  480. height: 68rpx;
  481. border-radius: 68rpx;
  482. background-color: #ffffff;
  483. margin-right: 20rpx;
  484. position: relative;
  485. &::after,
  486. &::before {
  487. content: '';
  488. display: block;
  489. width: 40rpx;
  490. height: 6rpx;
  491. background-color: #ffc401;
  492. position: absolute;
  493. left: 50%;
  494. top: 50%;
  495. transform: translate(-50%, -50%);
  496. }
  497. &::after {
  498. transform: translate(-50%, -50%) rotate(90deg) !important;
  499. }
  500. }
  501. .text {
  502. color: #ffffff;
  503. font-size: 32rpx;
  504. font-weight: bolder;
  505. }
  506. }
  507. }
  508. }
  509. </style>