before.vue 17 KB

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