四零语境前端代码仓库
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.

706 lines
15 KiB

3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
  1. <template>
  2. <view class="container">
  3. <view class="header">
  4. <!-- #ifndef H5 -->
  5. <view class="header-bg">
  6. <image src="/static/member-background.png" class="header-img" mode="scaleToFill" />
  7. <text class="header-title">会员中心</text>
  8. </view>
  9. <!-- #endif -->
  10. <view class="header-content">
  11. <view class="zuanshi">
  12. <image src="/static/member-diamond.png" mode="scaleToFill" class="zuanshi-img" />
  13. </view>
  14. <view v-if="!isMember" class="noVip-container">
  15. <image src="/static/VIP.png" mode="aspectFit" class="VIP-img" />
  16. <text class="intro">{{ configParamContent('member_info') || '共19项会员特权 | 3 项年VIP专属特权' }}</text>
  17. <view class="border"></view>
  18. <view class="info">
  19. <view class="avatar-box">
  20. <image :src="userInfo.avatar" mode="aspectFill" class="avatar" />
  21. <text class="name">{{ userInfo.name }}</text>
  22. </view>
  23. <uv-button :text="isLogin ? '立即开通' : '前往登陆'" @click="goRecharge" type="primary" :customStyle="{
  24. width: '160rpx',
  25. height: '60rpx',
  26. borderRadius: '198rpx',
  27. backgroundColor: '#06DADC',
  28. color: '#fff',
  29. fontSize: '28rpx',
  30. fontWeight: '500',
  31. lineHeight: '60rpx',
  32. letterSpacing: '0%',
  33. verticalAlign: 'middle',
  34. }" />
  35. </view>
  36. </view>
  37. <view v-else>
  38. <!-- 代码加在这里 -->
  39. <view class="vip-container ">
  40. <view class="avatar-box ">
  41. <image :src="userInfo.avatar" mode="aspectFill" class="avatar" />
  42. <text class="name">{{ userInfo.name }}</text>
  43. <text class="time">{{ memberInfo[0].endTime.split(' ')[0] }}</text>
  44. </view>
  45. <view class="border"></view>
  46. <view class="project">{{ memberInfo[0].memberTitle }}</view>
  47. <text class="res-time">{{ '预计剩余学习' +
  48. $utils.calculateDateDifference(memberInfo[0].endTime.split(' ')[0]) + '天'}}</text>
  49. </view>
  50. </view>
  51. </view>
  52. </view>
  53. <!-- 会员权益 -->
  54. <view class="benefits-section" v-if="!isMember">
  55. <view class="benefits-title">会员权益</view>
  56. <view class="benefits-list">
  57. <!-- 碎片学习 系统掌握 -->
  58. <!-- <view class="benefit-item" v-for="(item, index) in memberBenefits"
  59. :key="index">
  60. <uv-parse :content="item"></uv-parse>
  61. </view> -->
  62. <uv-parse :content="memberBenefits[0]"></uv-parse>
  63. <!-- 匹配水平 -->
  64. <!-- <view class="benefit-item">
  65. <view class="benefit-content">
  66. <view class="benefit-title">匹配水平</view>
  67. <view class="benefit-desc">依据水平精准推课不做无用功快速提升</view>
  68. </view>
  69. <view class="benefit-icon">
  70. <image src="/static/会员图片2.png" mode="aspectFit"></image>
  71. </view>
  72. </view> -->
  73. <!-- 科学闭环测 讲练结合 -->
  74. <!-- <view class="benefit-item">
  75. <view class="benefit-content">
  76. <view class="benefit-title">科学闭环测 讲练结合</view>
  77. <view class="benefit-desc">精心设计科学的学习流程 测试-讲解-练习-检验知识掌握更牢固</view>
  78. </view>
  79. <view class="benefit-icon">
  80. <image src="/static/会员图片3.png" mode="aspectFit"></image>
  81. </view>
  82. </view> -->
  83. </view>
  84. </view>
  85. <!-- 以下内容为成为会员才能看到的 -->
  86. <!-- 学习计划 -->
  87. <view class="study-plan-section" v-else>
  88. <view class="section-title">学习计划</view>
  89. <view class="plan-books">
  90. <view v-for="(book, index) in studyPlanBooks" :key="index" class="plan-book-item"
  91. @click="goBookDetail(book.book.id)" :class="{ 'active-book': index === 1 }">
  92. <view class="plan-book-cover">
  93. <image :src="book.book.booksImg" mode="aspectFill"></image>
  94. <!-- 学习中标识 -->
  95. <view v-if="index === 1" class="studying-badge">
  96. <view class="studying-icon" />
  97. <text>学习中</text>
  98. </view>
  99. </view>
  100. <view class="plan-book-info">
  101. <text class="plan-book-title" :class="{ 'highlight-title': index === 1 }">{{ book.book.booksName
  102. || '暂无课程' }}</text>
  103. <view class="plan-book-meta">
  104. <text class="plan-book-grade" :class="{ 'highlight-title': index === 1 }">{{
  105. book.book.categoryName || '--' }}/</text>
  106. <image v-if="index !== 1" src="/static/play-icon.png" class="plan-book-duration-icon" />
  107. <image v-else src="/static/play-icon-highlight.png" class="plan-book-duration-icon" />
  108. <text class="plan-book-duration" :class="{ 'highlight-title': index === 1 }">{{
  109. book.book.duration }}</text>
  110. </view>
  111. </view>
  112. </view>
  113. </view>
  114. </view>
  115. <!-- 学习推荐 -->
  116. <view class="study-recommend-section" v-if="isMember">
  117. <view class="section-header" @click="goRecommend">
  118. <text class="section-title">学习推荐</text>
  119. <view class="section-more">
  120. <text>更多</text>
  121. <uv-icon name="arrow-right" size="14" color="#8B8B8B"></uv-icon>
  122. </view>
  123. </view>
  124. <view class="recommend-grid">
  125. <view v-for="(book, index) in recommendBooks" :key="index" @click="goBookDetail(book.id)"
  126. class="recommend-grid-item">
  127. <view class="recommend-grid-cover">
  128. <image :src="book.booksImg" mode="aspectFill"></image>
  129. </view>
  130. <view class="recommend-grid-info">
  131. <text class="recommend-grid-title">{{ book.booksName }}</text>
  132. <view class="recommend-grid-meta">
  133. <text class="recommend-grid-grade">{{ book.categoryName }}/</text>
  134. <image src="/static/播放图标.png" class="recommend-grid-duration-icon" />
  135. <text class="recommend-grid-duration">{{ book.duration }}</text>
  136. </view>
  137. </view>
  138. </view>
  139. </view>
  140. </view>
  141. </view>
  142. </template>
  143. <script>
  144. export default {
  145. data() {
  146. return {
  147. isLogin: uni.getStorageSync('token') ? true : false,
  148. memberInfo: [],
  149. memberBenefits: [],
  150. userInfo: {
  151. name: '战斗世界',
  152. avatar: '/static/默认头像.png'
  153. },
  154. // 学习计划书籍数据
  155. studyPlanBooks: [
  156. ],
  157. // 学习推荐书籍数据
  158. recommendBooks: [
  159. ]
  160. }
  161. },
  162. computed: {
  163. isMember() {
  164. return this.memberInfo.length > 0
  165. }
  166. },
  167. methods: {
  168. // 跳转学习推荐
  169. goRecommend() {
  170. uni.navigateTo({
  171. url: '/subPages/home/search'
  172. })
  173. },
  174. // 跳转书籍详情
  175. goBookDetail(bookId) {
  176. uni.navigateTo({
  177. url: `/subPages/home/directory?id=${bookId}`
  178. })
  179. },
  180. goRecharge() {
  181. if (!this.isLogin) {
  182. uni.navigateTo({
  183. url: '/subPages/login/login'
  184. })
  185. return
  186. }
  187. uni.navigateTo({
  188. url: '/subPages/member/recharge'
  189. })
  190. },
  191. // 获取会员信息
  192. async getUserMemberInfo() {
  193. const memberRes = await this.$api.member.getUserMemberInfo()
  194. if (memberRes.code === 200) {
  195. this.memberInfo = [...memberRes.result]
  196. }
  197. if (!this.memberInfo.length) {
  198. // 如果不是会员 获取会员部分信息
  199. this.getMemberBenefits()
  200. }
  201. },
  202. // 获取会员权益
  203. async getMemberBenefits() {
  204. const benefitsRes = await this.$api.member.getMemberList()
  205. if (benefitsRes.code === 200) {
  206. this.memberBenefits = benefitsRes.result.map(item => item.content)
  207. }
  208. },
  209. // 获取用户信息
  210. async getUserInfo() {
  211. const userRes = await this.$api.login.getUserInfo()
  212. if (userRes.code === 200) {
  213. this.userInfo = userRes.result
  214. }
  215. },
  216. // 获取3个学习计划书籍
  217. async getStudyPlanBook() {
  218. const bookRes = await this.$api.book.stand({
  219. pageNo: 1,
  220. pageSize: 3
  221. })
  222. if (bookRes.code === 200) {
  223. const oneBook = bookRes.result.records[1]
  224. const twoBook = bookRes.result.records[0]
  225. const threeBook = bookRes.result.records[2]
  226. this.studyPlanBooks = [oneBook, twoBook, threeBook]
  227. }
  228. },
  229. async getRecommendBook() {
  230. const bookRes = await this.$api.book.list({
  231. pageNo: 1,
  232. pageSize: 6,
  233. member: 1
  234. }, false)
  235. if (bookRes.code === 200) {
  236. this.recommendBooks = bookRes.result.records
  237. }
  238. },
  239. },
  240. async onShow() {
  241. // 如果登录了就查询会员情况 如果没有登录就不查询
  242. if (uni.getStorageSync('token')) {
  243. this.isLogin = true
  244. Promise.all([this.getUserMemberInfo(), this.getUserInfo(), this.getStudyPlanBook(), this
  245. .getRecommendBook()
  246. ])
  247. } else {
  248. this.isLogin = false
  249. this.userInfo = {
  250. name: '登录后查看会员情况',
  251. avatar: '/static/默认头像.png'
  252. }
  253. }
  254. }
  255. }
  256. </script>
  257. <style lang="scss" scoped>
  258. .container {
  259. min-height: 100%;
  260. padding-bottom: 50rpx;
  261. }
  262. .header {
  263. width: 100%;
  264. .header-bg {
  265. position: relative;
  266. width: 100%;
  267. height: 400rpx;
  268. // background: red;
  269. .header-img {
  270. width: 100%;
  271. height: 400rpx;
  272. }
  273. .header-title {
  274. font-size: 32rpx;
  275. color: black;
  276. position: absolute;
  277. top: 100rpx;
  278. font-weight: 500;
  279. left: 50%;
  280. transform: translateX(-50%);
  281. }
  282. }
  283. .header-content {
  284. margin: 0 18rpx;
  285. /* #ifndef H5 */
  286. margin-top: -150rpx;
  287. /* #endif */
  288. /* #ifdef H5 */
  289. margin-top: 100rpx;
  290. /* #endif */
  291. // height: 256rpx;
  292. border-radius: 32rpx;
  293. border-width: 2rpx;
  294. padding: 40rpx;
  295. background: linear-gradient(180deg, #DEFFFF 0%, #FBFEFF 22.65%, #F0FBFF 100%);
  296. border: 2rpx solid #06DADC12;
  297. display: flex;
  298. flex-direction: column;
  299. gap: 28rpx;
  300. position: relative;
  301. .vip-container {
  302. padding: 20rpx 0;
  303. display: flex;
  304. flex-direction: column;
  305. gap: 18rpx;
  306. .project {
  307. font-size: 36rpx;
  308. color: #191919;
  309. line-height: 1.4;
  310. font-weight: 500;
  311. }
  312. .res-time {
  313. color: $primary-color;
  314. font-size: 24rpx;
  315. line-height: 36rpx;
  316. }
  317. }
  318. .noVip-container {
  319. display: flex;
  320. flex-direction: column;
  321. // align-items: center;
  322. // justify-content: center;
  323. gap: 28rpx;
  324. }
  325. .zuanshi {
  326. position: absolute;
  327. width: 190rpx;
  328. height: 190rpx;
  329. top: -80rpx;
  330. right: 0;
  331. .zuanshi-img {
  332. width: 190rpx;
  333. height: 190rpx;
  334. }
  335. }
  336. .VIP-img {
  337. width: 80rpx;
  338. height: 50rpx;
  339. }
  340. .border {
  341. width: 100%;
  342. // height: 2rpx;
  343. border: 2rpx solid;
  344. border-image-source: linear-gradient(90deg, rgba(228, 255, 255, 0) 0%, #C3EFEF 50.48%, rgba(228, 255, 255, 0) 100%);
  345. border-image-slice: 1;
  346. }
  347. .intro {
  348. font-size: 28rpx;
  349. line-height: 36rpx;
  350. letter-spacing: 0%;
  351. vertical-align: middle;
  352. color: #09B1B3;
  353. }
  354. .info {
  355. display: flex;
  356. justify-content: space-between;
  357. align-items: center;
  358. }
  359. .avatar-box {
  360. display: flex;
  361. align-items: center;
  362. gap: 16rpx;
  363. .name {
  364. font-weight: 600;
  365. font-size: 36rpx;
  366. line-height: 44rpx;
  367. letter-spacing: 0%;
  368. vertical-align: middle;
  369. color: #252545;
  370. }
  371. .avatar {
  372. width: 60rpx;
  373. height: 60rpx;
  374. border-radius: 50%;
  375. }
  376. .time {
  377. font-size: 30rpx;
  378. color: #8B8B8B;
  379. line-height: 36rpx;
  380. }
  381. }
  382. }
  383. }
  384. /* 立即开通会员按钮样式 */
  385. .member-button-section {
  386. margin: 40rpx 50rpx;
  387. }
  388. /* 会员权益样式 */
  389. .benefits-section {
  390. margin-top: 40rpx;
  391. padding: 0 30rpx;
  392. }
  393. .benefits-title {
  394. font-size: 36rpx;
  395. font-weight: bold;
  396. color: #191919;
  397. margin-bottom: 32rpx;
  398. }
  399. .benefits-list {
  400. display: flex;
  401. flex-direction: column;
  402. gap: 32rpx;
  403. }
  404. .benefit-item {
  405. // background: #F8F8F8;
  406. // border: 1px solid #FFFFFF;
  407. // border-radius: 48rpx;
  408. // padding: 27rpx 40rpx;
  409. display: flex;
  410. align-items: center;
  411. justify-content: space-between;
  412. }
  413. .benefit-content {
  414. flex: 1;
  415. margin-right: 40rpx;
  416. }
  417. .benefit-title {
  418. font-size: 32rpx;
  419. font-weight: 600;
  420. color: #333;
  421. margin-bottom: 16rpx;
  422. }
  423. .benefit-desc {
  424. font-size: 24rpx;
  425. color: #09B1B3;
  426. line-height: 36rpx;
  427. }
  428. .benefit-icon {
  429. // width: 152rpx;
  430. // height: 152rpx;
  431. // flex-shrink: 0;
  432. }
  433. .benefit-icon image {
  434. width: 100%;
  435. height: 100%;
  436. }
  437. /* 学习计划样式 */
  438. .study-plan-section {
  439. margin-top: 40rpx;
  440. padding: 0 30rpx;
  441. }
  442. .section-title {
  443. font-size: 36rpx;
  444. font-weight: 500;
  445. color: #191919;
  446. margin-bottom: 32rpx;
  447. }
  448. .plan-books {
  449. display: flex;
  450. justify-content: center;
  451. align-items: flex-end;
  452. gap: 78rpx;
  453. padding: 20rpx 0;
  454. }
  455. .plan-book-item {
  456. display: flex;
  457. flex-direction: column;
  458. align-items: center;
  459. transition: all 0.3s ease;
  460. &.active-book {
  461. transform: scale(1.15);
  462. .plan-book-cover {
  463. // box-shadow: 0 8rpx 24rpx rgba(6, 218, 220, 0.3);
  464. }
  465. }
  466. }
  467. .plan-book-cover {
  468. width: 172rpx;
  469. height: 230rpx;
  470. border-radius: 16rpx;
  471. overflow: hidden;
  472. margin-bottom: 16rpx;
  473. position: relative;
  474. box-shadow: 0px 4px 4px 0px #C0BCBA75;
  475. image {
  476. width: 100%;
  477. height: 100%;
  478. }
  479. .studying-badge {
  480. position: absolute;
  481. bottom: 0rpx;
  482. right: 0rpx;
  483. background: #00000099;
  484. color: #fff;
  485. padding: 6rpx 10rpx;
  486. border-radius: 20rpx;
  487. font-size: 18rpx;
  488. display: flex;
  489. align-items: center;
  490. justify-content: center;
  491. gap: 6rpx;
  492. .studying-icon {
  493. width: 10rpx;
  494. height: 10rpx;
  495. background: $primary-color;
  496. border-radius: 50%;
  497. }
  498. }
  499. }
  500. .plan-book-info {
  501. text-align: center;
  502. width: 180rpx;
  503. .plan-book-title {
  504. // width: 100%;
  505. font-size: 28rpx;
  506. font-weight: 700;
  507. color: #333;
  508. margin-bottom: 8rpx;
  509. display: block;
  510. overflow: hidden;
  511. text-overflow: ellipsis;
  512. white-space: nowrap;
  513. &.highlight-title {
  514. color: $primary-color;
  515. }
  516. }
  517. .plan-book-meta {
  518. display: flex;
  519. align-items: center;
  520. justify-content: center;
  521. gap: 8rpx;
  522. .plan-book-duration-icon {
  523. width: 20rpx;
  524. height: 20rpx;
  525. }
  526. .plan-book-grade {
  527. font-size: 24rpx;
  528. color: #999;
  529. &.highlight-title {
  530. color: $primary-color;
  531. }
  532. }
  533. .plan-book-duration {
  534. font-size: 24rpx;
  535. color: #999;
  536. &.highlight-title {
  537. color: $primary-color;
  538. }
  539. }
  540. }
  541. }
  542. /* 学习推荐样式 */
  543. .study-recommend-section {
  544. margin-top: 40rpx;
  545. padding: 0 30rpx;
  546. }
  547. .section-header {
  548. display: flex;
  549. align-items: center;
  550. justify-content: space-between;
  551. margin-bottom: 24rpx;
  552. .section-more {
  553. display: flex;
  554. align-items: center;
  555. gap: 4rpx;
  556. text {
  557. font-size: 24rpx;
  558. color: #8B8B8B;
  559. }
  560. }
  561. }
  562. .recommend-grid {
  563. display: flex;
  564. flex-wrap: wrap;
  565. gap: 32rpx;
  566. .recommend-grid-item {
  567. width: 208rpx;
  568. display: flex;
  569. flex-direction: column;
  570. .recommend-grid-cover {
  571. box-shadow: 0px 4px 4px 0px #C0BCBA75;
  572. width: 100%;
  573. height: 278rpx;
  574. border-radius: 16rpx;
  575. overflow: hidden;
  576. margin-bottom: 16rpx;
  577. image {
  578. width: 100%;
  579. height: 100%;
  580. }
  581. }
  582. .recommend-grid-info {
  583. padding: 6rpx;
  584. .recommend-grid-title {
  585. font-size: 28rpx;
  586. font-weight: 700;
  587. color: #333;
  588. margin-bottom: 14rpx;
  589. overflow: hidden;
  590. text-overflow: ellipsis;
  591. white-space: nowrap;
  592. }
  593. .recommend-grid-meta {
  594. display: flex;
  595. align-items: center;
  596. .recommend-grid-duration-icon {
  597. width: 24rpx;
  598. height: 24rpx;
  599. margin-right: 12rpx;
  600. }
  601. .recommend-grid-grade {
  602. font-size: 24rpx;
  603. color: #999;
  604. margin-right: 8rpx;
  605. }
  606. .recommend-grid-duration {
  607. font-size: 24rpx;
  608. color: #999;
  609. }
  610. }
  611. }
  612. }
  613. }
  614. </style>