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

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