index.tsx 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. import { Button, Cell, Icon, Image, showConfirmDialog } from 'vant';
  2. import { defineComponent } from 'vue';
  3. import styles from './index.module.less';
  4. import request from '@/helpers/request';
  5. import iconStudent from '@common/images/icon-student.png';
  6. import iconMemberLogo from './images/member_logo.png';
  7. import iconGift from '../student-register/images/icon-gift.png';
  8. import { moneyFormat } from '@/helpers/utils';
  9. import OHeader from '@/components/m-header';
  10. import member1 from './images/member-1.png';
  11. import member2 from './images/member-2.png';
  12. import ODialog from '@/components/m-dialog';
  13. import { useEventListener, useWindowScroll } from '@vueuse/core';
  14. import dayjs from 'dayjs';
  15. export default defineComponent({
  16. name: 'MemberCenter',
  17. data() {
  18. return {
  19. functionList: [] as any,
  20. selectMember: {} as any,
  21. users: {} as any,
  22. memberStatus: false,
  23. background: 'transparent',
  24. color: '#fff'
  25. };
  26. },
  27. computed: {
  28. userInfo() {
  29. const users: any = this.users;
  30. return {
  31. username: users?.nickname || '',
  32. phone: users?.phone || '',
  33. avatar: users?.avatar,
  34. id: users?.id,
  35. isVip: users?.vipMember,
  36. membershipGiftDays: users?.membershipGiftDays,
  37. membershipDays: users?.membershipDays,
  38. membershipEndTime: dayjs(users?.membershipEndTime).format('YYYY-MM-DD')
  39. };
  40. }
  41. },
  42. async mounted() {
  43. useEventListener(document, 'scroll', () => {
  44. const { y } = useWindowScroll();
  45. if (y.value > 52) {
  46. this.background = '#fff';
  47. this.color = '#323333';
  48. } else {
  49. this.background = 'transparent';
  50. this.color = '#fff';
  51. }
  52. });
  53. try {
  54. const userInfo = await request.get('/edu-app/student/member');
  55. this.users = userInfo.data || {};
  56. const { data } = await request.post(`/edu-app/cityFeeSetting/member`);
  57. this.selectMember = data;
  58. this.paymentOrderUnpaid();
  59. } catch {
  60. //
  61. }
  62. //
  63. },
  64. methods: {
  65. // 查询未支付订单
  66. async paymentOrderUnpaid() {
  67. try {
  68. const { data } = await request.get('/edu-app/userPaymentOrder/unpaid', {
  69. requestType: 'form',
  70. params: {
  71. paymentType: 'VIP'
  72. }
  73. });
  74. // 判断是否有待支付订单
  75. if (data.id) {
  76. showConfirmDialog({
  77. message: '您有待支付的订单,是否继续支付',
  78. cancelButtonText: '取消订单',
  79. confirmButtonText: '继续支付'
  80. })
  81. .then(() => {
  82. const paymentConfig = data.paymentConfig;
  83. this.$router.push({
  84. path: '/order-detail',
  85. query: {
  86. config: JSON.stringify(paymentConfig.paymentConfig),
  87. orderNo: paymentConfig.orderNo
  88. }
  89. });
  90. })
  91. .catch(async () => {
  92. try {
  93. await request.post(
  94. '/edu-app/userPaymentOrder/cancelPayment/' + data.orderNo
  95. );
  96. } catch {
  97. //
  98. }
  99. });
  100. }
  101. } catch {
  102. //
  103. }
  104. },
  105. calcSalePrice(item: any) {
  106. // discount
  107. if (item.discount === 1) {
  108. const tempPrice = Number(
  109. (item.salePrice - item.discountPrice).toFixed(2)
  110. );
  111. return tempPrice >= 0 ? tempPrice : 0;
  112. }
  113. return item.salePrice;
  114. },
  115. // 购买
  116. async onSubmit() {
  117. try {
  118. const selectMember = this.selectMember;
  119. const params: any = [
  120. {
  121. goodsId: selectMember.id,
  122. goodsNum: 1,
  123. goodsType: 'VIP',
  124. paymentCashAmount: selectMember.salePrice, // 现金支付金额
  125. paymentCouponAmount: 0 // 优惠券金额
  126. }
  127. ]; // 支付参数
  128. // 创建订单
  129. const { data } = await request.post(
  130. '/edu-app/userPaymentOrder/executeOrder',
  131. {
  132. data: {
  133. orderType: 'VIP',
  134. paymentCashAmount: this.selectMember.salePrice || 0,
  135. paymentCouponAmount: 0,
  136. goodsInfos: params,
  137. orderName: '数字化器乐学练工具',
  138. orderDesc: '数字化器乐学练工具'
  139. }
  140. }
  141. );
  142. const res = await request.get(
  143. '/edu-app/userPaymentOrder/detail/' + data.orderNo
  144. );
  145. if (res.data.status !== 'WAIT_PAY' && res.data.status !== 'PAYING') {
  146. this.$router.push({
  147. path: '/payment-result',
  148. query: {
  149. orderNo: data.orderNo
  150. }
  151. });
  152. } else {
  153. this.$router.push({
  154. path: '/order-detail',
  155. query: {
  156. config: JSON.stringify(data.paymentConfig),
  157. orderNo: data.orderNo
  158. }
  159. });
  160. }
  161. } catch (e: any) {
  162. //
  163. console.log(e);
  164. }
  165. }
  166. },
  167. render() {
  168. return (
  169. <div class={styles['member-center']}>
  170. <OHeader
  171. background={this.background}
  172. color={this.color}
  173. border={false}
  174. />
  175. <div class={styles.member_container}>
  176. <Cell
  177. class={[styles.userMember]}
  178. labelClass={styles.timeRemaining}
  179. center
  180. v-slots={{
  181. icon: () => (
  182. <div class={styles.userImgSection}>
  183. <Image
  184. class={styles.userImg}
  185. src={this.userInfo.avatar || iconStudent}
  186. fit="cover"
  187. />
  188. </div>
  189. ),
  190. title: () => (
  191. <div class={styles.userInfo}>
  192. <span class={styles.name}>{this.userInfo.username}</span>
  193. {!!this.userInfo.isVip && (
  194. <Image class={styles.level} src={iconMemberLogo} />
  195. )}
  196. {this.userInfo.phone && (
  197. <span
  198. class={styles.phone}
  199. v-html={`(${this.userInfo.phone})`}></span>
  200. )}
  201. </div>
  202. ),
  203. label: () => (
  204. <div class={styles.member_time}>
  205. <>
  206. {this.userInfo.isVip ? (
  207. <div>
  208. {/* 使用有效期剩余
  209. <span class={styles.remaining}>
  210. {this.userInfo.membershipDays}
  211. </span>
  212. 天 */}
  213. 有效期至
  214. <span class={styles.remaining}>
  215. {this.userInfo.membershipEndTime}
  216. </span>
  217. </div>
  218. ) : (
  219. <div>您还未领取器乐学练工具哟</div>
  220. )}
  221. </>
  222. </div>
  223. )
  224. }}></Cell>
  225. </div>
  226. <div class={[styles.memberContainer]}>
  227. <div
  228. class={[
  229. styles.memberItem,
  230. this.users.membershipGiftDays > 0 ? styles.memberGift : ''
  231. ]}>
  232. <p class={[styles.title]}>
  233. <strong>数字化</strong>器乐学练工具
  234. <span>12个月</span>
  235. </p>
  236. <div class={styles.priceGroup}>
  237. <p class={styles.price}>
  238. <span>¥</span>
  239. {moneyFormat(this.selectMember.salePrice)}
  240. </p>
  241. {this.selectMember.salePrice <
  242. this.selectMember.originalPrice && (
  243. <del class={styles.originalPrice}>
  244. ¥{moneyFormat(this.selectMember.originalPrice)}
  245. </del>
  246. )}
  247. </div>
  248. {this.users.membershipGiftDays > 0 && (
  249. <Cell border={false} class={styles.giftCell}>
  250. {{
  251. title: () => (
  252. <div class={styles.gift}>
  253. <img src={iconGift} class={styles.iconGift} />
  254. 现在领取赠送{' '}
  255. <span>{this.users.membershipGiftDays || 0}</span>
  256. 天有效期
  257. </div>
  258. )
  259. }}
  260. </Cell>
  261. )}
  262. </div>
  263. <div class={styles.memberImgs}>
  264. <img src={member1} />
  265. <img src={member2} />
  266. </div>
  267. </div>
  268. <div class={styles.btnGroup}>
  269. <div class={styles.priceSection}>
  270. 工具领取:
  271. <div class={styles.price}>
  272. <span class={styles.priceUnit}>¥</span>
  273. <span class={styles.priceNum}>
  274. {moneyFormat(this.calcSalePrice(this.selectMember) || 0)}
  275. </span>
  276. </div>
  277. </div>
  278. {this.userInfo.id ? (
  279. <Button round class={styles.btn} onClick={this.onSubmit}>
  280. 立即领取
  281. </Button>
  282. ) : (
  283. ''
  284. )}
  285. </div>
  286. <ODialog
  287. v-model:show={this.memberStatus}
  288. title="待激活团练宝"
  289. message="为让团员有效使用乐团学习工具,首次加入乐团且购买团练宝的团员,团练宝的生效时间为乐团首次训练之日,具体训练时间可查看课表。"
  290. messageAlign="left"
  291. dialogMarginTop="env(safe-area-inset-top)"
  292. confirmButtonText="我知道了"
  293. />
  294. </div>
  295. );
  296. }
  297. });