index.tsx 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401
  1. import ColHeader from '@/components/col-header'
  2. import { Button, Cell, Icon, Image, Popup, Toast } from 'vant'
  3. import { defineComponent } from 'vue'
  4. import styles from './index.module.less'
  5. import request from '@/helpers/request'
  6. import { setLogin, state } from '@/state'
  7. import iconStudent from '@common/images/icon_student.png'
  8. import iconTeacher from '@common/images/icon_teacher.png'
  9. import iconGift from './images/icon_gift.png'
  10. import iconShare from '../music/album/icon_share2.svg'
  11. import iconDiscount from './images/icon_discount.png'
  12. import iconMemberLogo from './images/member_logo.png'
  13. import { orderStatus } from '@/views/order-detail/orderStatus'
  14. import dayjs from 'dayjs'
  15. import { memberType } from '@/constant'
  16. import { moneyFormat } from '@/helpers/utils'
  17. import ColShare from '@/components/col-share'
  18. export const getAssetsHomeFile = (fileName: string) => {
  19. const path = `./images/${fileName}`
  20. const modules = import.meta.globEager('./images/*')
  21. return modules[path].default
  22. }
  23. export default defineComponent({
  24. name: 'MemberCenter',
  25. data() {
  26. const query = this.$route.query
  27. return {
  28. activityId: query.activityId,
  29. recomUserId: query.recomUserId,
  30. apiSuffix:
  31. state.platformType === 'STUDENT' ? '/api-student' : '/api-teacher',
  32. agreeStatus: false,
  33. functionList: [],
  34. memberList: [],
  35. selectMember: {} as any,
  36. params: {
  37. page: 1,
  38. rows: 20
  39. },
  40. discountTeacher: {
  41. avatar: '',
  42. discount: 0,
  43. username: ''
  44. },
  45. shareStatus: false,
  46. shareUrl: '',
  47. shareDiscount: 0 // 是否有优惠活动
  48. }
  49. },
  50. computed: {
  51. userInfo() {
  52. const users = state.user.data
  53. return {
  54. username: users?.username,
  55. phone: users?.phone,
  56. avatar: users?.heardUrl,
  57. id: users?.userId,
  58. memberRankSettingId: users?.memberRankSettingId,
  59. isVip: users?.isVip,
  60. membershipDays: users?.membershipDays,
  61. membershipEndTime: users?.membershipEndTime
  62. }
  63. }
  64. },
  65. async mounted() {
  66. try {
  67. const userInfo = await request.get(
  68. state.platformType === 'TEACHER'
  69. ? '/api-teacher/teacher/queryUserInfo'
  70. : '/api-student/student/queryUserInfo'
  71. )
  72. setLogin(userInfo.data)
  73. const res = await request.post(
  74. `${this.apiSuffix}/memberPriceSettings/vipPermissions`
  75. )
  76. const result = res.data || []
  77. this.functionList = result.map((item: any) => {
  78. return {
  79. title: item.paramName,
  80. icon: getAssetsHomeFile(`${item.paramValue}.png`)
  81. }
  82. })
  83. const setting = await request.post(
  84. `${this.apiSuffix}/memberPriceSettings/list`,
  85. {
  86. data: {
  87. activityId: Number(this.activityId),
  88. userId: this.recomUserId
  89. }
  90. }
  91. )
  92. const { list, ...more } = setting.data
  93. this.discountTeacher = {
  94. ...more
  95. }
  96. const settingResult = list || []
  97. const settingList: any = []
  98. settingResult.forEach((item: any) => {
  99. const tempItem = {
  100. title: '',
  101. salePrice: item.salePrice,
  102. originalPrice: item.originalPrice,
  103. period: item.period,
  104. id: item.id,
  105. discount: item.discount,
  106. discountPrice: item.discountPrice,
  107. status: false
  108. }
  109. tempItem.title = memberType[item.period]
  110. item.period !== 'DAY' && settingList.push(tempItem)
  111. })
  112. if (settingList.length > 0) {
  113. settingList[0].status = true
  114. this.selectMember = settingList[0]
  115. }
  116. console.log(settingList)
  117. this.memberList = settingList
  118. } catch {}
  119. },
  120. methods: {
  121. async onShare() {
  122. try {
  123. const res = await request.post('/api-teacher/open/vipProfit', {
  124. data: {
  125. userId: this.userInfo.id
  126. }
  127. })
  128. this.shareUrl = `${location.origin}/teacher#/shareVip?recomUserId=${this.userInfo.id}&activityId=${res.data.activityId}&userType=${state.platformType}`
  129. this.shareStatus = true
  130. this.shareDiscount = res.data.discount || 0
  131. // let url =
  132. // location.origin +
  133. // `/accompany/colexiu-share.html?id=${moreData.value.id}&recomUserId=${state.user.data?.userId}`
  134. // // 判断是否有活动
  135. // if (res.data.discount === 1) {
  136. // url += `&activityId=${res.data.activityId}`
  137. // }
  138. // shareDiscount.value = res.data.discount || 0
  139. // shareUrl.value = url
  140. // isMore.value = false
  141. // shareStatus.value = true
  142. return
  143. } catch {}
  144. },
  145. calcSalePrice(item: any) {
  146. // discount
  147. if (item.discount === 1) {
  148. const tempPrice = Number(
  149. (item.salePrice - item.discountPrice).toFixed(2)
  150. )
  151. return tempPrice >= 0 ? tempPrice : 0
  152. }
  153. return item.salePrice
  154. },
  155. onSubmit() {
  156. const member: any = this.selectMember
  157. // 判断是否有会员
  158. const startTime = this.userInfo.isVip
  159. ? dayjs(this.userInfo.membershipEndTime).toDate()
  160. : new Date()
  161. let endTime = new Date()
  162. if (member.period === 'MONTH') {
  163. endTime = dayjs(startTime).add(1, 'month').toDate()
  164. } else if (member.period === 'QUARTERLY') {
  165. endTime = dayjs(startTime).add(3, 'month').toDate()
  166. } else if (member.period === 'YEAR_HALF') {
  167. endTime = dayjs(startTime).add(6, 'month').toDate()
  168. } else if (member.period === 'YEAR') {
  169. endTime = dayjs(startTime).add(1, 'year').toDate()
  170. }
  171. orderStatus.orderObject.orderType = 'VIP'
  172. orderStatus.orderObject.orderName = '小酷Ai' + member.title
  173. orderStatus.orderObject.orderDesc = '小酷Ai' + member.title
  174. orderStatus.orderObject.actualPrice = this.calcSalePrice(member)
  175. orderStatus.orderObject.recomUserId = this.recomUserId
  176. orderStatus.orderObject.activityId = this.activityId
  177. orderStatus.orderObject.orderNo = ''
  178. orderStatus.orderObject.orderList = [
  179. {
  180. orderType: 'VIP',
  181. goodsName: '小酷Ai' + member.title,
  182. id: member.id,
  183. title: member.title,
  184. price: this.calcSalePrice(member),
  185. startTime: dayjs(startTime).format('YYYY-MM-DD'),
  186. endTime: dayjs(endTime).format('YYYY-MM-DD'),
  187. recomUserId: this.recomUserId
  188. }
  189. ]
  190. this.$router.push({
  191. path: '/orderDetail',
  192. query: {
  193. orderType: 'VIP'
  194. }
  195. })
  196. }
  197. },
  198. render() {
  199. return (
  200. <div class={styles['member-center']}>
  201. <ColHeader
  202. background="#ffe5cc"
  203. v-slots={{
  204. right: () => (
  205. <div class={styles.shareBtn} onClick={this.onShare}>
  206. <Image src={iconShare} />
  207. 分享
  208. </div>
  209. )
  210. }}
  211. />
  212. <div class={styles.member_container}>
  213. <Cell
  214. class={styles.userMember}
  215. labelClass={styles.timeRemaining}
  216. v-slots={{
  217. icon: () => (
  218. <div class={styles.userImgSection}>
  219. <Image
  220. class={styles.userImg}
  221. src={this.userInfo.avatar || iconStudent}
  222. fit="cover"
  223. />
  224. </div>
  225. ),
  226. title: () => (
  227. <div class={styles.userInfo}>
  228. <span class={styles.name}>{this.userInfo.username}</span>
  229. {!!this.userInfo.isVip && (
  230. <Image
  231. class={styles.level}
  232. src="https://daya.ks3-cn-beijing.ksyun.com/202107/ScSTL1D.png"
  233. />
  234. )}
  235. <span
  236. class={styles.phone}
  237. v-html={`(${this.userInfo.phone})`}
  238. ></span>
  239. </div>
  240. ),
  241. label: () => (
  242. <div class={styles.member_time}>
  243. {this.userInfo.isVip ? (
  244. <div>
  245. 会员权益有效期剩余
  246. <span class={styles.remaining}>
  247. {this.userInfo.membershipDays}
  248. </span>
  249. </div>
  250. ) : (
  251. <div>亲,您还不是会员哟</div>
  252. )}
  253. </div>
  254. )
  255. }}
  256. ></Cell>
  257. </div>
  258. <div class={styles.memberContainer}>
  259. <div class={styles.memberItem}>
  260. <div class={styles.title}>
  261. 会员<span>VIP</span>
  262. </div>
  263. {/* 判断是否有推荐老师 */}
  264. {this.discountTeacher.discount == 1 && (
  265. <div class={styles.memberDiscount}>
  266. <Image
  267. src={this.discountTeacher.avatar || iconTeacher}
  268. class={styles.discountAvatar}
  269. />
  270. <span class={styles.discountName}>
  271. {this.discountTeacher.username}老师的专属优惠~
  272. </span>
  273. <Image src={iconGift} class={styles.discountGift} />
  274. </div>
  275. )}
  276. <div class={styles['system-list']}>
  277. {this.memberList.map((item: any) => (
  278. <div
  279. class={[styles['system-item'], item.status && styles.active]}
  280. onClick={() => {
  281. this.memberList.forEach((item: any) => {
  282. item.status = false
  283. })
  284. item.status = true
  285. this.selectMember = item
  286. }}
  287. >
  288. <div class={styles.discountItem}>
  289. {item.discount == 1 && <img src={iconDiscount} />}
  290. </div>
  291. <p class={styles.title}>{item.title}</p>
  292. <p class={styles.price}>
  293. <span>¥</span>
  294. {moneyFormat(this.calcSalePrice(item), '0,0[.]00')}
  295. </p>
  296. <del class={styles.originalPrice}>
  297. ¥{moneyFormat(item.originalPrice, '0,0[.]00')}
  298. </del>
  299. </div>
  300. ))}
  301. </div>
  302. </div>
  303. <div class={[styles.intro]}>
  304. <p>
  305. 酷乐秀会员可使用包括平台提供的所有训练乐谱,并专享“
  306. <b>小酷Ai</b>
  307. ”八大核心功能,孩子在家就能轻松完成乐器自主规范练习。
  308. </p>
  309. </div>
  310. {this.functionList.length > 0 && (
  311. <div class={styles.memberItem}>
  312. <div class={styles.title}>会员功能</div>
  313. <div class={styles.member_function}>
  314. {this.functionList.map((item: any) => (
  315. <div class={styles.function_item}>
  316. <Icon name={item.icon} size={34} />
  317. <div class={styles.function_text} v-html={item.title}></div>
  318. </div>
  319. ))}
  320. </div>
  321. </div>
  322. )}
  323. {/* <ColProtocol
  324. v-model={this.agreeStatus}
  325. showHeader
  326. style={{ paddingLeft: 0, paddingRight: 0, marginBottom: '64px' }}
  327. /> */}
  328. </div>
  329. <div class={styles.btnGroup}>
  330. <div class={styles.priceSection}>
  331. 支付金额:
  332. <div class={styles.price}>
  333. <span class={styles.priceUnit}>¥</span>
  334. <span class={styles.priceNum}>
  335. {(this as any).$filters.moneyFormat(
  336. this.calcSalePrice(this.selectMember) || 0
  337. )}
  338. </span>
  339. </div>
  340. {this.selectMember?.discount == 1 && (
  341. <div class={[styles.discountItem, styles.discountBuy]}>
  342. <img src={iconDiscount} />
  343. </div>
  344. )}
  345. </div>
  346. <Button
  347. color="linear-gradient(220deg, #DFA164 0%, #FAC87E 100%)"
  348. round
  349. class={styles.btn}
  350. onClick={this.onSubmit}
  351. >
  352. 立即支付
  353. </Button>
  354. </div>
  355. <Popup
  356. v-model:show={this.shareStatus}
  357. style={{ background: 'transparent' }}
  358. >
  359. <ColShare
  360. teacherId={this.userInfo.id}
  361. shareUrl={this.shareUrl}
  362. shareType="vip"
  363. shareLength={2}
  364. >
  365. <div class={styles.shareVip}>
  366. {this.shareDiscount === 1 && (
  367. <div class={styles.tagDiscount}>专属优惠</div>
  368. )}
  369. <img class={styles.icon} src={iconMemberLogo} />
  370. <div class={styles.info}>
  371. <h4 class="van-multi-ellipsis--l2">小酷Ai会员</h4>
  372. <p>海量曲谱、智能评测,专为器乐学习者量身打造</p>
  373. </div>
  374. </div>
  375. </ColShare>
  376. </Popup>
  377. </div>
  378. )
  379. }
  380. })