test.vue 17 KB

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