index.tsx 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  1. import { Button, Cell, Icon, Image, Popup, showConfirmDialog, Toast } from 'vant'
  2. import { defineComponent } from 'vue'
  3. import styles from './index.module.less'
  4. import request from '@/helpers/request'
  5. import { setLogin, state } from '@/state'
  6. import iconStudent from '@common/images/icon_student.png'
  7. import iconTeacher from '@common/images/icon_teacher.png'
  8. import iconDiscount from './images/icon_discount.png'
  9. import iconMemberLogo from './images/member_logo.png'
  10. // import { orderStatus } from '@/views/order-detail/orderStatus'
  11. import dayjs from 'dayjs'
  12. import { memberType } from '@/constant'
  13. import { moneyFormat } from '@/helpers/utils'
  14. import OHeader from '@/components/o-header'
  15. import member1 from './images/member-1.png'
  16. import member2 from './images/member-2.png'
  17. import member3 from './images/member-3.png'
  18. import iconQuestion from './images/icon-question.png'
  19. import ODialog from '@/components/o-dialog'
  20. export const getAssetsHomeFile = (fileName: string) => {
  21. const path = `./images/${fileName}`
  22. const modules = import.meta.globEager('./images/*')
  23. return modules[path].default
  24. }
  25. export default defineComponent({
  26. name: 'MemberCenter',
  27. data() {
  28. const query = this.$route.query
  29. return {
  30. functionList: [] as any,
  31. selectMember: {} as any,
  32. users: {} as any,
  33. memberStatus: false
  34. }
  35. },
  36. computed: {
  37. userInfo() {
  38. const users: any = this.users
  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. try {
  52. const userInfo = await request.get('/api-student/student/member')
  53. this.users = userInfo.data || {}
  54. // this.functionList = [
  55. // {
  56. // title: '五线谱<br />跟播',
  57. // icon: getAssetsHomeFile(`1.png`)
  58. // },
  59. // {
  60. // title: '演奏指法<br />跟播',
  61. // icon: getAssetsHomeFile(`2.png`)
  62. // },
  63. // {
  64. // title: '原声/伴奏<br />切换',
  65. // icon: getAssetsHomeFile(`3.png`)
  66. // },
  67. // {
  68. // title: '播放速度<br />调整',
  69. // icon: getAssetsHomeFile(`4.png`)
  70. // },
  71. // {
  72. // title: '五线谱选段<br />播放',
  73. // icon: getAssetsHomeFile(`5.png`)
  74. // },
  75. // {
  76. // title: '智能评测',
  77. // icon: getAssetsHomeFile(`6.png`)
  78. // },
  79. // {
  80. // title: '评测报告',
  81. // icon: getAssetsHomeFile(`7.png`)
  82. // },
  83. // {
  84. // title: '评测音视频<br />云储存',
  85. // icon: getAssetsHomeFile(`8.png`)
  86. // }
  87. // ]
  88. const { data } = await request.post(`/api-student/cityFeeSetting/member`)
  89. this.selectMember = data
  90. this.paymentOrderUnpaid()
  91. } catch {
  92. //
  93. }
  94. //
  95. },
  96. methods: {
  97. // 查询未支付订单
  98. async paymentOrderUnpaid() {
  99. try {
  100. const { data } = await request.get('/api-student/userPaymentOrder/unpaid', {
  101. requestType: 'form',
  102. params: {
  103. paymentType: 'VIP'
  104. }
  105. })
  106. // 判断是否有待支付订单
  107. if (data.id) {
  108. showConfirmDialog({
  109. message: '您有待支付的订单,是否继续支付',
  110. cancelButtonText: '取消订单',
  111. confirmButtonText: '继续支付'
  112. })
  113. .then(() => {
  114. const paymentConfig = data.paymentConfig
  115. this.$router.push({
  116. path: '/orderDetail',
  117. query: {
  118. config: JSON.stringify(paymentConfig.paymentConfig),
  119. orderNo: paymentConfig.orderNo
  120. }
  121. })
  122. })
  123. .catch(async () => {
  124. try {
  125. await request.post('/api-student/userPaymentOrder/cancelPayment/' + data.orderNo)
  126. } catch {
  127. //
  128. }
  129. })
  130. }
  131. } catch {
  132. //
  133. }
  134. },
  135. calcSalePrice(item: any) {
  136. // discount
  137. if (item.discount === 1) {
  138. const tempPrice = Number((item.salePrice - item.discountPrice).toFixed(2))
  139. return tempPrice >= 0 ? tempPrice : 0
  140. }
  141. return item.salePrice
  142. },
  143. // 购买
  144. async onSubmit() {
  145. try {
  146. const selectMember = this.selectMember
  147. const params: any = [
  148. {
  149. goodsId: selectMember.id,
  150. goodsNum: 1,
  151. goodsType: 'VIP',
  152. paymentCashAmount: selectMember.salePrice, // 现金支付金额
  153. paymentCouponAmount: 0 // 优惠券金额
  154. }
  155. ] // 支付参数
  156. // 创建订单
  157. const { data } = await request.post('/api-student/userPaymentOrder/executeOrder', {
  158. data: {
  159. orderType: 'VIP',
  160. paymentCashAmount: this.selectMember.salePrice || 0,
  161. paymentCouponAmount: 0,
  162. goodsInfos: params,
  163. orderName: '团练宝购买',
  164. orderDesc: '团练宝购买'
  165. }
  166. })
  167. console.log(data)
  168. this.$router.push({
  169. path: '/orderDetail',
  170. query: {
  171. config: JSON.stringify(data.paymentConfig),
  172. orderNo: data.orderNo
  173. }
  174. })
  175. } catch (e: any) {
  176. //
  177. console.log(e)
  178. }
  179. }
  180. },
  181. render() {
  182. return (
  183. <div class={styles['member-center']}>
  184. <OHeader background="#ffe5cc" border={false} />
  185. <div class={styles.member_container}>
  186. <Cell
  187. class={[
  188. styles.userMember,
  189. this.users.purchaseMemberRecord ? styles.purchaseMember : ''
  190. ]}
  191. labelClass={styles.timeRemaining}
  192. center
  193. v-slots={{
  194. icon: () => (
  195. <div class={styles.userImgSection}>
  196. <Image
  197. class={styles.userImg}
  198. src={this.userInfo.avatar || iconStudent}
  199. fit="cover"
  200. />
  201. </div>
  202. ),
  203. title: () => (
  204. <div class={styles.userInfo}>
  205. <span class={styles.name}>{this.userInfo.username}</span>
  206. {!!this.userInfo.isVip && (
  207. <Image
  208. class={styles.level}
  209. src="https://daya.ks3-cn-beijing.ksyun.com/202107/ScSTL1D.png"
  210. />
  211. )}
  212. {this.userInfo.phone && (
  213. <span class={styles.phone} v-html={`(${this.userInfo.phone})`}></span>
  214. )}
  215. </div>
  216. ),
  217. label: () => (
  218. <div class={styles.member_time}>
  219. {!this.users.purchaseMemberRecord ? (
  220. <>
  221. {this.userInfo.isVip ? (
  222. <div>
  223. 会员权益有效期剩余
  224. <span class={styles.remaining}>{this.userInfo.membershipDays}</span>天
  225. </div>
  226. ) : (
  227. <div>亲,您还不是会员哟</div>
  228. )}
  229. </>
  230. ) : (
  231. <div class={styles.beforeQuestion}>
  232. <Icon
  233. name={iconQuestion}
  234. class={styles.iconQeustion}
  235. onClick={() => (this.memberStatus = true)}
  236. />
  237. 您有<span>待激活</span>团练宝
  238. </div>
  239. )}
  240. </div>
  241. )
  242. }}
  243. ></Cell>
  244. </div>
  245. <div
  246. class={[
  247. styles.memberContainer,
  248. this.users.purchaseMemberRecord ? styles.beforMemberContainer : ''
  249. ]}
  250. >
  251. <div class={styles.memberItem}>
  252. <div class={styles.title}>
  253. 会员<span>VIP</span>
  254. </div>
  255. {!this.users.purchaseMemberRecord ? (
  256. <div class={styles['system-list']}>
  257. <div class={[styles['system-item'], styles.active]}>
  258. <p class={[styles.title, 'van-hairline--bottom']}>
  259. 半年会员
  260. <span>(6个月)</span>
  261. </p>
  262. <div class={styles.priceGroup}>
  263. <p class={styles.price}>
  264. <span>¥</span>
  265. {moneyFormat(this.selectMember.salePrice)}
  266. </p>
  267. <del class={styles.originalPrice}>
  268. ¥{moneyFormat(this.selectMember.originalPrice)}
  269. </del>
  270. </div>
  271. </div>
  272. </div>
  273. ) : (
  274. ''
  275. )}
  276. </div>
  277. <div class={styles.memberImgs}>
  278. <img src={member1} />
  279. <img src={member2} />
  280. <img src={member3} />
  281. </div>
  282. {/* <div class={[styles.intro]}>
  283. <p>
  284. 团练宝会员使用包括平台提供教材的所有训练乐谱,并专享“乐器练习云教练”八大核心功能,孩子在家就能轻松完成乐器自主规范练习。
  285. </p>
  286. </div>
  287. <div class={styles.memberItem}>
  288. <div class={styles.title}>会员功能</div>
  289. <div class={styles.member_function}>
  290. {this.functionList.map((item: any) => (
  291. <div class={styles.function_item}>
  292. <Icon name={item.icon} size={34} />
  293. <div class={styles.function_text} v-html={item.title}></div>
  294. </div>
  295. ))}
  296. </div>
  297. </div> */}
  298. </div>
  299. {!this.users.purchaseMemberRecord ? (
  300. <div class={styles.btnGroup}>
  301. <div class={styles.priceSection}>
  302. 支付金额:
  303. <div class={styles.price}>
  304. <span class={styles.priceUnit}>¥</span>
  305. <span class={styles.priceNum}>
  306. {moneyFormat(this.calcSalePrice(this.selectMember) || 0)}
  307. </span>
  308. </div>
  309. {this.selectMember?.discount == 1 && (
  310. <div class={[styles.discountItem, styles.discountBuy]}>
  311. <img src={iconDiscount} />
  312. </div>
  313. )}
  314. </div>
  315. {this.userInfo.id ? (
  316. <Button
  317. color="linear-gradient(220deg, #DFA164 0%, #FAC87E 100%)"
  318. round
  319. class={styles.btn}
  320. onClick={this.onSubmit}
  321. >
  322. {this.userInfo.isVip ? '立即续费' : '立即开通'}
  323. </Button>
  324. ) : (
  325. ''
  326. )}
  327. </div>
  328. ) : (
  329. ''
  330. )}
  331. {/* */}
  332. <ODialog
  333. v-model:show={this.memberStatus}
  334. title="待激活团练宝"
  335. message="为让团员有效使用乐团学习工具,首次加入乐团且购买团练宝的团员,团练宝的生效时间为乐团首次训练之日,具体训练时间可查看课表。"
  336. messageAlign="left"
  337. dialogMarginTop="env(safe-area-inset-top)"
  338. confirmButtonText="我知道了"
  339. />
  340. </div>
  341. )
  342. }
  343. })