page.js 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. import React from 'react';
  2. import './index.less';
  3. import Assets from '@src/components/Assets';
  4. import Page from '@src/containers/Page';
  5. import { getMap, formatMoney } from '@src/services/Tools';
  6. import Footer from '../../../components/Footer';
  7. import { FaqModal, FinishModal } from '../../../components/OtherModal';
  8. import { CommentFalls, AnswerCarousel, Consultation, Contact } from '../../../components/Other';
  9. import Button from '../../../components/Button';
  10. import { User } from '../../../stores/user';
  11. import { Main } from '../../../stores/main';
  12. import { Course } from '../../../stores/course';
  13. import { ServiceKey, ServiceParamMap } from '../../../../Constant';
  14. import { Order } from '../../../stores/order';
  15. import Video from '../../../components/Video';
  16. export default class extends Page {
  17. initState() {
  18. return {};
  19. }
  20. initData() {
  21. Main.getCourseIndex()
  22. .then(result => {
  23. this.setState({ courseIndex: result });
  24. });
  25. Main.getBase()
  26. .then(result => {
  27. this.setState({ base: result });
  28. });
  29. Course.listPackage({ isSpecial: true, page: 1, size: 3 })
  30. .then(result => {
  31. this.setState({ packages: result.list || [] });
  32. });
  33. Main.listFaq({ page: 1, size: 100, channel: 'course-index' }).then(result => {
  34. this.setState({ faqs: result.list });
  35. });
  36. Main.listComment({ page: 1, size: 100, channel: 'course-index' }).then(result => {
  37. this.setState({ comments: result.list });
  38. });
  39. }
  40. renderView() {
  41. const { courseIndex = {}, base = {}, packages = [], faqs = [], comments = [], showFaq, faq = {}, showFinish } = this.state;
  42. return (
  43. <div>
  44. <div className="block-1">
  45. <div className="body">
  46. <Assets name="course_main_banner" />
  47. <div className="btn-list">
  48. <Button width={100} size="lager" onClick={() => linkTo('/course/online?tab=package')}>
  49. 查看套餐
  50. </Button>
  51. <Button className="t-4" width={100} theme="default" size="lager" onClick={() => linkTo('/course/online?tab=single')}>
  52. 试听课程
  53. </Button>
  54. </div>
  55. </div>
  56. </div>
  57. <div className="block-2">
  58. <div className="main-title">找到你的Style</div>
  59. <div className="video-list">
  60. <div className="video-div">
  61. {courseIndex.onlineVideo ? <Video src={courseIndex.onlineVideo} width={580} height={360} hideAction hideProgress /> : null}
  62. <div className="name" onClick={() => linkTo('/course/online')}>在线课程 ></div>
  63. </div>
  64. <div className="video-div">
  65. {courseIndex.vsVideo ? <Video src={courseIndex.vsVideo} width={580} height={360} hideAction hideProgress /> : null}
  66. <div className="name" onClick={() => linkTo('/course/vs')}>1v1私教 ></div>
  67. </div>
  68. </div>
  69. <div className="class-list">
  70. {packages.map(data => {
  71. const originMoney = data.courses.reduce((a, y) => a + y.price, 0);
  72. const novice = data.courses.filter(row => row.crowd !== 'novice').length === 0;
  73. return <div className="class-item">
  74. {novice && <Assets width={55} height={52} className="new" name="noviciate" />}
  75. <div className="t-s-22 t-4 m-b-5 f-w-b"><a href={`/course/package/detail/${data.id}`}>{data.title}</a></div>
  76. <div className="t-8 m-b-1">{data.description}</div>
  77. <div className="t-1 t-s-12">包含课程</div>
  78. <div className="m-b-5">
  79. {data.courses.map((course => {
  80. return <div className="m-b-1 m-r-5 t-9 t-s-12 d-i-b b-c-2 p-5">{course.title}({course.noNumber}课时)</div>;
  81. }))}
  82. </div>
  83. <div className="t-1 t-s-12">配套服务</div>
  84. <div className="m-b-5">
  85. <div className="m-b-1 m-r-5 t-9 t-s-12 d-i-b b-c-2 p-5">预习作业</div>
  86. <div className="m-b-1 m-r-5 t-9 t-s-12 d-i-b b-c-2 p-5">课后答题</div>
  87. </div>
  88. <div className="t-1 t-s-12">赠送服务</div>
  89. <div className="m-b-2">
  90. {data.gift &&
  91. ServiceKey.map(row => {
  92. if (!data.gift[row.value]) return null;
  93. const list = ServiceParamMap[row.value];
  94. if (list) {
  95. const map = getMap(list, 'value', 'label');
  96. return <div className="m-b-1 m-r-5 t-9 t-s-12 d-i-b b-c-2 p-5">{row.label}×{map[data.gift[row.value]]}</div>;
  97. }
  98. return <div className="m-b-1 m-r-5 t-9 t-s-12 d-i-b b-c-2 p-5">{row.label}×{data.gift[row.value]}</div>;
  99. })}
  100. </div>
  101. <div className="t-8">
  102. 总价值: <span className="t-d-l-t">¥{formatMoney(originMoney)}</span>
  103. </div>
  104. <div className="t-1 t-s-18 f-w-b m-b-1">套餐价: ¥{formatMoney(data.price)}</div>
  105. <div className="m-b-5">
  106. <Button size="lager" onClick={() => User.needLogin().then(() => Order.addCheckout({ productType: 'course_package', productId: data.id }).then(() => linkTo('/cart')))}>立即购买</Button>
  107. </div>
  108. </div>;
  109. })}
  110. </div>
  111. </div>
  112. <Consultation data={base.contact} />
  113. <div className="block-4">
  114. <div className="main-title">You will always find the answers</div>
  115. <Assets name="" />
  116. <div className="list">
  117. <div className="item">
  118. <div className="t-1 t-s-20 m-b-2">
  119. <Assets className="m-r-5" name="self_paced" /> Self-Paced
  120. </div>
  121. <div className="t-8">随时随地学习;不限听课次数;支持停课申请。</div>
  122. </div>
  123. <div className="item">
  124. <div className="t-1 t-s-20 m-b-2">
  125. <Assets className="m-r-5" name="teacher" /> 实力导师
  126. </div>
  127. <div className="t-8">从业8年,考取700+成绩10次。</div>
  128. <div className="t-4 ">
  129. <a className="link d-i-b" href="/course/experience" target="_blank">查看成绩单 ></a>
  130. </div>
  131. </div>
  132. <div className="item">
  133. <div className="t-1 t-s-20 m-b-2">
  134. <Assets className="m-r-5" name="excitation" /> 激励机制
  135. </div>
  136. <div className="t-8">保持听课频率,赠送课程时效。</div>
  137. </div>
  138. </div>
  139. </div>
  140. <CommentFalls list={comments} />
  141. <AnswerCarousel list={faqs} onFaq={() => User.needLogin().then(() => this.setState({ showFaq: true, faq: { channel: 'course-index' } }))} />
  142. <Contact data={base.contact} />
  143. <Footer />
  144. <FaqModal show={showFaq} defaultData={faq} onCancel={() => this.setState({ showFaq: false, faq: {} })} onConfirm={() => this.setState({ showFaq: false, faq: {}, showFinish: true })} />
  145. <FinishModal
  146. show={showFinish}
  147. onConfirm={() => this.setState({ showFinish: false })}
  148. />
  149. </div >
  150. );
  151. }
  152. }