index.tsx 8.8 KB

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