index.tsx 11 KB

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