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

534 lines
13 KiB

1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
  1. <template>
  2. <view class="container">
  3. <view class="header">
  4. <view class="header-bg">
  5. <image
  6. src="/static/member-background.png"
  7. class="header-img"
  8. mode="scaleToFill"
  9. />
  10. <!-- #ifndef H5 -->
  11. <text class="header-title">会员开通</text>
  12. <!-- 加一个推出箭头 -->
  13. <view class="header-icon" @click="goBack">
  14. <uv-icon name="arrow-left" color="#000" size="20" />
  15. </view>
  16. <!-- #endif -->
  17. <!-- 轮播容器 -->
  18. <view class="uv-demo-block swiper-container">
  19. <uv-swiper
  20. bgColor="transparent"
  21. :list="list"
  22. :loading="!list.length"
  23. @change="changeSwiper"
  24. keyName="img"
  25. previousMargin="70"
  26. nextMargin="70"
  27. acceleration
  28. height="75"
  29. circular
  30. :autoplay="false"
  31. radius="5"
  32. >
  33. </uv-swiper>
  34. <button class="swiper-btn">
  35. 已选择
  36. </button>
  37. <image
  38. class="swiper-arrow"
  39. src="/static/decorative-arrow.png"
  40. mode="aspectFill"
  41. />
  42. </view>
  43. </view>
  44. </view>
  45. <!-- 会员套餐选择容器 -->
  46. <view class="membership-container">
  47. <!-- 套餐选择 -->
  48. <view class="package-list">
  49. <view
  50. class="package-item"
  51. :class="{ 'active': selectedPackage === index }"
  52. v-for="(item, index) in packageList"
  53. :key="index"
  54. @click="selectPackage(index)"
  55. >
  56. <view class="info">
  57. <!-- 赠送标识 -->
  58. <view class="gift-tag" v-if="item.content">
  59. {{ item.content }}
  60. </view>
  61. <view class="package-title">{{ item.title }}</view>
  62. <view class="package-price">¥{{ getInt(item.discountedprice) }}.<text class="package-decimal">{{ getDecimal(item.discountedprice) }}</text></view>
  63. <view class="package-original">¥{{ item.originalprice }}</view>
  64. </view>
  65. <view class="package-btn" :class="{ 'active': selectedPackage === index }">
  66. {{ selectedPackage === index ? '已选择' : '点击选择' }}
  67. </view>
  68. </view>
  69. </view>
  70. <!-- 优惠券选择 -->
  71. <view class="coupon-section">
  72. <view class="coupon-title">选择优惠券</view>
  73. <view class="coupon-selector" @click="selectCoupon">
  74. <view v-if="!selectedCoupon" class="coupon-placeholder">
  75. <text class="coupon-text">请选择</text>
  76. <uv-icon name="arrow-right" color="#999" size="16" />
  77. </view>
  78. <view v-else class="coupon-selected">
  79. <view class="coupon-info">
  80. <text class="coupon-name">{{ selectedCoupon.name }}</text>
  81. <text class="coupon-amount">-¥{{ selectedCoupon.money }}</text>
  82. </view>
  83. <uv-icon name="arrow-right" color="#999" size="16" />
  84. </view>
  85. </view>
  86. </view>
  87. </view>
  88. <!-- 立即开通会员按钮 -->
  89. <view class="member-button-section">
  90. <uv-button
  91. type="primary"
  92. text="立即开通会员"
  93. :custom-style="{
  94. width: '100%',
  95. height: '82rpx',
  96. borderRadius: '44rpx',
  97. backgroundColor: '#06DADC',
  98. fontSize: '36rpx',
  99. fontWeight: '500',
  100. border: '1px solid #06DADC'
  101. }"
  102. @click="handleRecharge"
  103. ></uv-button>
  104. </view>
  105. <!-- 会员权益 -->
  106. <view class="benefits-section">
  107. <view class="benefits-title">会员权益</view>
  108. <view class="benefits-list">
  109. <!-- 碎片学习 系统掌握 -->
  110. <view class="benefit-item" v-for="item in packageList" :key="item.id">
  111. <uv-parse :content="item.content" />
  112. </view>
  113. <!-- 匹配水平 -->
  114. <!-- <view class="benefit-item">
  115. <view class="benefit-content">
  116. <view class="benefit-title">匹配水平</view>
  117. <view class="benefit-desc">依据水平精准推课不做无用功快速提升</view>
  118. </view>
  119. <view class="benefit-icon">
  120. <image src="/static/member-image-2.png" mode="aspectFit"></image>
  121. </view>
  122. </view>
  123. 科学闭环测 讲练结合
  124. <view class="benefit-item">
  125. <view class="benefit-content">
  126. <view class="benefit-title">科学闭环测 讲练结合</view>
  127. <view class="benefit-desc">精心设计科学的学习流程 测试-讲解-练习-检验知识掌握更牢固</view>
  128. </view>
  129. <view class="benefit-icon">
  130. <image src="/static/member-image-3.png" mode="aspectFit"></image>
  131. </view>
  132. </view> -->
  133. </view>
  134. </view>
  135. </view>
  136. </template>
  137. <script>
  138. export default {
  139. data() {
  140. return {
  141. list: [
  142. ],
  143. selectedPackage: 0, // 默认选择第一个套餐
  144. selectedMember: 0, // 默认选择第一个会员
  145. defaultPackageList: [
  146. ],
  147. couponId: '',
  148. selectedCoupon: null // 选中的优惠券信息
  149. }
  150. },
  151. computed:{
  152. packageList(){
  153. return this.list[this.selectedMember].setmeals.length ? this.list[this.selectedMember].setmeals : this.defaultPackageList
  154. }
  155. },
  156. methods: {
  157. handleCouponSelected(coupon) {
  158. // 处理选中的优惠券
  159. this.selectedCoupon = coupon
  160. this.couponId = coupon.id
  161. uni.showToast({
  162. title: `已选择优惠券:¥${coupon.money}`,
  163. icon: 'success'
  164. })
  165. },
  166. async handleRecharge(){
  167. // console.log('选中的会员id是:', this.packageList[this.selectedPackage]);
  168. const object = {
  169. // #ifdef H5
  170. type : 'official',
  171. // #endif
  172. memberId: this.list[this.selectedMember].id,
  173. setmealId: this.packageList[this.selectedPackage].id
  174. }
  175. if (this.couponId) {
  176. object.couponId = this.couponId
  177. }
  178. const res = await this.$api.member.openMember({...object})
  179. if (res.code === 200){
  180. if (res.result === 0){
  181. // 零元购
  182. uni.showToast({
  183. title: '充值成功',
  184. icon: 'success'
  185. })
  186. this.goBack()
  187. }else {
  188. // 调起微信支付
  189. this.$utils.wxPay(res.result, (res) => {
  190. setTimeout(() => {
  191. this.goBack()
  192. }, 1000)
  193. })
  194. }
  195. }
  196. },
  197. goBack(){
  198. uni.navigateBack()
  199. },
  200. // 截取价格的整数与小数部分
  201. getInt(pri){
  202. const price = String(pri)
  203. if (price.indexOf('.') === -1) {
  204. return price
  205. }
  206. if (price === null) {
  207. return '0'
  208. }
  209. return String(price).split('.')[0]
  210. },
  211. getDecimal(pri){
  212. const price = String(pri)
  213. if (price === null) return '00'
  214. const parts = price.split('.')
  215. return parts[1] ? parts[1].padEnd(2, '0') : '00'
  216. },
  217. selectPackage(index) {
  218. this.selectedPackage = index
  219. },
  220. selectCoupon() {
  221. uni.navigateTo({
  222. url: '/subPages/user/discount?from=recharge'
  223. })
  224. },
  225. async getMemberList(){
  226. const memberRes = await this.$api.member.getMemberList()
  227. if (memberRes.code === 200){
  228. this.list = memberRes.result
  229. }
  230. },
  231. changeSwiper(e){
  232. this.selectedMember = e.current
  233. this.selectedPackage = 0
  234. }
  235. },
  236. onShow(){
  237. // 监听优惠券选择事件
  238. uni.$on('couponSelected', this.handleCouponSelected)
  239. this.getMemberList()
  240. },
  241. onUnload() {
  242. // 移除事件监听
  243. uni.$off('couponSelected', this.handleCouponSelected)
  244. console.log('接触监听');
  245. },
  246. }
  247. </script>
  248. <style lang="scss" scoped>
  249. .container {
  250. min-height: 100%;
  251. }
  252. .header{
  253. width: 100%;
  254. .header-bg{
  255. position: relative;
  256. width: 100%;
  257. height: 500rpx;
  258. /* #ifdef H5 */
  259. margin-top: -100rpx;
  260. /* #endif */
  261. // background: red;
  262. .header-img{
  263. width: 100%;
  264. height: 500rpx;
  265. }
  266. .header-title{
  267. font-size: 32rpx;
  268. color: black;
  269. position: absolute;
  270. top: 100rpx;
  271. font-weight: 500;
  272. left: 50%;
  273. transform: translateX(-50%);
  274. }
  275. .header-icon{
  276. position: absolute;
  277. top: 100rpx;
  278. left: 30rpx;
  279. }
  280. .swiper-container{
  281. margin-top: -300rpx;
  282. .swiper-arrow{
  283. width: 100%;
  284. height: 22rpx;
  285. }
  286. .swiper-btn{
  287. margin: 35rpx auto 15rpx;
  288. width: 150rpx;
  289. height: 52rpx;
  290. border-radius: 999px;
  291. background: #06DADC;
  292. color: white;
  293. font-size: 28rpx;
  294. font-weight: 500;
  295. text-align: center;
  296. line-height: 52rpx;
  297. }
  298. }
  299. }
  300. }
  301. /* 立即开通会员按钮样式 */
  302. .member-button-section {
  303. margin: 0 50rpx 40rpx;
  304. }
  305. // 会员套餐选择容器
  306. .membership-container {
  307. background: linear-gradient(180deg, #DEFFFF 0%, #FBFEFF 22.65%, #FFFFFF 100%);
  308. padding: 40rpx 30rpx;
  309. margin-top: 20rpx;
  310. .package-list {
  311. display: flex;
  312. justify-content: space-between;
  313. gap: 16rpx;
  314. margin-bottom: 20rpx;
  315. .package-item {
  316. position: relative;
  317. flex: 1;
  318. background: #fff;
  319. border-radius: 20rpx;
  320. text-align: center;
  321. border: 2rpx solid #EEEEEE;
  322. transition: all 0.3s;
  323. // width: 119;
  324. height: 210rpx;
  325. // width: 238rpx;
  326. .info{
  327. padding: 16rpx 16rpx 0 16rpx ;
  328. }
  329. &.active {
  330. border-color: $primary-color;
  331. // box-shadow: 0 4rpx 20rpx rgba(34, 242, 235, 0.2);
  332. }
  333. .gift-tag {
  334. position: absolute;
  335. top: -10rpx;
  336. left: 0%;
  337. // transform: translateX(-50%);
  338. background: #FF6B6B;
  339. color: #fff;
  340. font-size: 20rpx;
  341. padding: 8rpx 16rpx;
  342. border-radius: 20rpx 20rpx 20rpx 0;
  343. white-space: nowrap;
  344. }
  345. .package-title {
  346. font-size: 28rpx;
  347. color: #000;
  348. margin-bottom: 16rpx;
  349. font-weight: 500;
  350. }
  351. .package-price {
  352. font-size: 36rpx;
  353. color: #FF4800;
  354. font-weight: 500;
  355. margin-bottom: 8rpx;
  356. .package-decimal{
  357. font-size: 24rpx;
  358. }
  359. }
  360. .package-original {
  361. font-size: 24rpx;
  362. color: #8B8B8B;
  363. line-height: 1.4;
  364. text-decoration: line-through;
  365. margin-bottom: 8rpx;
  366. }
  367. .package-btn {
  368. background: #E4E7EB;
  369. color: #191919;
  370. font-size: 28rpx;
  371. // padding: 12rpx 20rpx;
  372. width: 100%;
  373. // border-radius: 30rpx;
  374. transition: all 0.3s;
  375. height: 52rpx;
  376. line-height: 52rpx;
  377. border-radius: 0 0 24rpx 24rpx;
  378. &.active {
  379. background: $primary-color;
  380. color: #fff;
  381. }
  382. }
  383. }
  384. }
  385. .coupon-section {
  386. .coupon-title {
  387. font-size: 26rpx;
  388. color: #181818;
  389. margin-bottom: 10rpx;
  390. // font-weight: 500;
  391. }
  392. .coupon-selector {
  393. background: #fff;
  394. border-radius: 16rpx;
  395. padding: 10rpx 0;
  396. display: flex;
  397. justify-content: space-between;
  398. align-items: center;
  399. border-bottom: 2rpx solid #f0f0f0;
  400. .coupon-placeholder {
  401. display: flex;
  402. justify-content: space-between;
  403. align-items: center;
  404. width: 100%;
  405. .coupon-text {
  406. font-size: 32rpx;
  407. color: #C6C6C6;
  408. }
  409. }
  410. .coupon-selected {
  411. display: flex;
  412. justify-content: space-between;
  413. align-items: center;
  414. width: 100%;
  415. .coupon-info {
  416. display: flex;
  417. // flex-direction: column;
  418. align-items: center;
  419. justify-content: space-between;
  420. .coupon-name {
  421. font-size: 28rpx;
  422. color: #181818;
  423. margin-bottom: 4rpx;
  424. }
  425. .coupon-amount {
  426. font-size: 28rpx;
  427. color: red;
  428. font-weight: 500;
  429. }
  430. }
  431. }
  432. }
  433. }
  434. }
  435. /* 会员权益样式 */
  436. .benefits-section {
  437. margin-top: 40rpx;
  438. padding: 0 30rpx;
  439. }
  440. .benefits-title {
  441. font-size: 36rpx;
  442. font-weight: bold;
  443. color: #191919;
  444. margin-bottom: 32rpx;
  445. }
  446. .benefits-list {
  447. display: flex;
  448. flex-direction: column;
  449. gap: 32rpx;
  450. }
  451. .benefit-item {
  452. background: #F8F8F8;
  453. border: 1px solid #FFFFFF;
  454. border-radius: 48rpx;
  455. padding: 27rpx 40rpx;
  456. display: flex;
  457. align-items: center;
  458. justify-content: space-between;
  459. }
  460. .benefit-content {
  461. flex: 1;
  462. margin-right: 40rpx;
  463. }
  464. .benefit-title {
  465. font-size: 32rpx;
  466. font-weight: 600;
  467. color: #333;
  468. margin-bottom: 16rpx;
  469. }
  470. .benefit-desc {
  471. font-size: 24rpx;
  472. color: #09B1B3;
  473. line-height: 36rpx;
  474. }
  475. .benefit-icon {
  476. width: 152rpx;
  477. height: 152rpx;
  478. // flex-shrink: 0;
  479. }
  480. .benefit-icon image {
  481. width: 100%;
  482. height: 100%;
  483. }
  484. </style>