index.tsx 11 KB

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