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

528 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)
  191. }
  192. }
  193. },
  194. goBack(){
  195. uni.navigateBack()
  196. },
  197. // 截取价格的整数与小数部分
  198. getInt(pri){
  199. const price = String(pri)
  200. if (price.indexOf('.') === -1) {
  201. return price
  202. }
  203. if (price === null) {
  204. return '0'
  205. }
  206. return String(price).split('.')[0]
  207. },
  208. getDecimal(pri){
  209. const price = String(pri)
  210. if (price === null) return '00'
  211. const parts = price.split('.')
  212. return parts[1] ? parts[1].padEnd(2, '0') : '00'
  213. },
  214. selectPackage(index) {
  215. this.selectedPackage = index
  216. },
  217. selectCoupon() {
  218. uni.navigateTo({
  219. url: '/subPages/user/discount?from=recharge'
  220. })
  221. },
  222. async getMemberList(){
  223. const memberRes = await this.$api.member.getMemberList()
  224. if (memberRes.code === 200){
  225. this.list = memberRes.result
  226. }
  227. },
  228. changeSwiper(e){
  229. this.selectedMember = e.current
  230. this.selectedPackage = 0
  231. }
  232. },
  233. onShow(){
  234. // 监听优惠券选择事件
  235. uni.$on('couponSelected', this.handleCouponSelected)
  236. this.getMemberList()
  237. },
  238. onUnload() {
  239. // 移除事件监听
  240. uni.$off('couponSelected', this.handleCouponSelected)
  241. console.log('接触监听');
  242. },
  243. }
  244. </script>
  245. <style lang="scss" scoped>
  246. .container {
  247. min-height: 100%;
  248. }
  249. .header{
  250. width: 100%;
  251. .header-bg{
  252. position: relative;
  253. width: 100%;
  254. height: 500rpx;
  255. // background: red;
  256. .header-img{
  257. width: 100%;
  258. height: 500rpx;
  259. }
  260. .header-title{
  261. font-size: 32rpx;
  262. color: black;
  263. position: absolute;
  264. top: 100rpx;
  265. font-weight: 500;
  266. left: 50%;
  267. transform: translateX(-50%);
  268. }
  269. .header-icon{
  270. position: absolute;
  271. top: 100rpx;
  272. left: 30rpx;
  273. }
  274. .swiper-container{
  275. margin-top: -300rpx;
  276. .swiper-arrow{
  277. width: 100%;
  278. height: 22rpx;
  279. }
  280. .swiper-btn{
  281. margin: 35rpx auto 15rpx;
  282. width: 150rpx;
  283. height: 52rpx;
  284. border-radius: 999px;
  285. background: #06DADC;
  286. color: white;
  287. font-size: 28rpx;
  288. font-weight: 500;
  289. text-align: center;
  290. line-height: 52rpx;
  291. }
  292. }
  293. }
  294. }
  295. /* 立即开通会员按钮样式 */
  296. .member-button-section {
  297. margin: 0 50rpx 40rpx;
  298. }
  299. // 会员套餐选择容器
  300. .membership-container {
  301. background: linear-gradient(180deg, #DEFFFF 0%, #FBFEFF 22.65%, #FFFFFF 100%);
  302. padding: 40rpx 30rpx;
  303. margin-top: 20rpx;
  304. .package-list {
  305. display: flex;
  306. justify-content: space-between;
  307. gap: 16rpx;
  308. margin-bottom: 20rpx;
  309. .package-item {
  310. position: relative;
  311. flex: 1;
  312. background: #fff;
  313. border-radius: 20rpx;
  314. text-align: center;
  315. border: 2rpx solid #EEEEEE;
  316. transition: all 0.3s;
  317. // width: 119;
  318. height: 210rpx;
  319. // width: 238rpx;
  320. .info{
  321. padding: 16rpx 16rpx 0 16rpx ;
  322. }
  323. &.active {
  324. border-color: $primary-color;
  325. // box-shadow: 0 4rpx 20rpx rgba(34, 242, 235, 0.2);
  326. }
  327. .gift-tag {
  328. position: absolute;
  329. top: -10rpx;
  330. left: 0%;
  331. // transform: translateX(-50%);
  332. background: #FF6B6B;
  333. color: #fff;
  334. font-size: 20rpx;
  335. padding: 8rpx 16rpx;
  336. border-radius: 20rpx 20rpx 20rpx 0;
  337. white-space: nowrap;
  338. }
  339. .package-title {
  340. font-size: 28rpx;
  341. color: #000;
  342. margin-bottom: 16rpx;
  343. font-weight: 500;
  344. }
  345. .package-price {
  346. font-size: 36rpx;
  347. color: #FF4800;
  348. font-weight: 500;
  349. margin-bottom: 8rpx;
  350. .package-decimal{
  351. font-size: 24rpx;
  352. }
  353. }
  354. .package-original {
  355. font-size: 24rpx;
  356. color: #8B8B8B;
  357. line-height: 1.4;
  358. text-decoration: line-through;
  359. margin-bottom: 8rpx;
  360. }
  361. .package-btn {
  362. background: #E4E7EB;
  363. color: #191919;
  364. font-size: 28rpx;
  365. // padding: 12rpx 20rpx;
  366. width: 100%;
  367. // border-radius: 30rpx;
  368. transition: all 0.3s;
  369. height: 52rpx;
  370. line-height: 52rpx;
  371. border-radius: 0 0 24rpx 24rpx;
  372. &.active {
  373. background: $primary-color;
  374. color: #fff;
  375. }
  376. }
  377. }
  378. }
  379. .coupon-section {
  380. .coupon-title {
  381. font-size: 26rpx;
  382. color: #181818;
  383. margin-bottom: 10rpx;
  384. // font-weight: 500;
  385. }
  386. .coupon-selector {
  387. background: #fff;
  388. border-radius: 16rpx;
  389. padding: 10rpx 0;
  390. display: flex;
  391. justify-content: space-between;
  392. align-items: center;
  393. border-bottom: 2rpx solid #f0f0f0;
  394. .coupon-placeholder {
  395. display: flex;
  396. justify-content: space-between;
  397. align-items: center;
  398. width: 100%;
  399. .coupon-text {
  400. font-size: 32rpx;
  401. color: #C6C6C6;
  402. }
  403. }
  404. .coupon-selected {
  405. display: flex;
  406. justify-content: space-between;
  407. align-items: center;
  408. width: 100%;
  409. .coupon-info {
  410. display: flex;
  411. // flex-direction: column;
  412. align-items: center;
  413. justify-content: space-between;
  414. .coupon-name {
  415. font-size: 28rpx;
  416. color: #181818;
  417. margin-bottom: 4rpx;
  418. }
  419. .coupon-amount {
  420. font-size: 28rpx;
  421. color: red;
  422. font-weight: 500;
  423. }
  424. }
  425. }
  426. }
  427. }
  428. }
  429. /* 会员权益样式 */
  430. .benefits-section {
  431. margin-top: 40rpx;
  432. padding: 0 30rpx;
  433. }
  434. .benefits-title {
  435. font-size: 36rpx;
  436. font-weight: bold;
  437. color: #191919;
  438. margin-bottom: 32rpx;
  439. }
  440. .benefits-list {
  441. display: flex;
  442. flex-direction: column;
  443. gap: 32rpx;
  444. }
  445. .benefit-item {
  446. background: #F8F8F8;
  447. border: 1px solid #FFFFFF;
  448. border-radius: 48rpx;
  449. padding: 27rpx 40rpx;
  450. display: flex;
  451. align-items: center;
  452. justify-content: space-between;
  453. }
  454. .benefit-content {
  455. flex: 1;
  456. margin-right: 40rpx;
  457. }
  458. .benefit-title {
  459. font-size: 32rpx;
  460. font-weight: 600;
  461. color: #333;
  462. margin-bottom: 16rpx;
  463. }
  464. .benefit-desc {
  465. font-size: 24rpx;
  466. color: #09B1B3;
  467. line-height: 36rpx;
  468. }
  469. .benefit-icon {
  470. width: 152rpx;
  471. height: 152rpx;
  472. // flex-shrink: 0;
  473. }
  474. .benefit-icon image {
  475. width: 100%;
  476. height: 100%;
  477. }
  478. </style>