page.js 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. import React from 'react';
  2. import { Link } from 'react-router-dom';
  3. import './index.less';
  4. import Page from '@src/containers/Page';
  5. import Assets from '@src/components/Assets';
  6. import { getMap, formatDate, formatMoney } from '@src/services/Tools';
  7. import Footer from '../../../components/Footer';
  8. import { Contact, AnswerCarousel, Comment } from '../../../components/Other';
  9. import { FaqModal, CommentModal, FinishModal } from '../../../components/OtherModal';
  10. import Tabs from '../../../components/Tabs';
  11. import Button from '../../../components/Button';
  12. import { User } from '../../../stores/user';
  13. import { Course } from '../../../stores/course';
  14. import { Order } from '../../../stores/order';
  15. import { Main } from '../../../stores/main';
  16. export default class extends Page {
  17. initState() {
  18. return {
  19. tab: '1',
  20. };
  21. }
  22. init() {
  23. Main.dataStruct().then(result => {
  24. const dataStructSelect = result.map(row => {
  25. return {
  26. title: `${row.titleZh}${row.titleEn}`,
  27. key: row.id,
  28. };
  29. });
  30. const dataStructMap = getMap(dataStructSelect, 'key');
  31. this.setState({ dataStructSelect, dataStructMap });
  32. });
  33. Main.getBase().then(result => {
  34. this.setState({ base: result });
  35. });
  36. }
  37. initData() {
  38. const { id } = this.params;
  39. Course.getData(id).then(result => {
  40. this.setState({ data: result });
  41. });
  42. this.view(id);
  43. Main.listFaq({ page: 1, size: 100, channel: 'course_data', position: id }).then(result => {
  44. this.faqs = result.list;
  45. this.setState({ faqs: result.list });
  46. });
  47. Main.listComment({ page: 1, size: 100, channel: 'course_data', position: id }).then(result => {
  48. this.comments = result.list;
  49. this.setState({ comments: result.list });
  50. });
  51. }
  52. onChangeTab(tab) {
  53. this.setState({ tab });
  54. }
  55. view(id) {
  56. Course.dataView(id);
  57. }
  58. buy() {
  59. const { data } = this.state;
  60. User.needLogin().then(() => {
  61. Order.speedPay({ productType: 'data', productId: data.id }).then(result => {
  62. User.needPay(result).then(() => {
  63. linkTo('/my/tools?tab=data');
  64. });
  65. });
  66. });
  67. }
  68. add() {
  69. const { data } = this.state;
  70. User.needLogin().then(() => {
  71. Order.addCheckout({ productType: 'data', productId: data.id }).then(() => {
  72. this.setState({ add: true });
  73. });
  74. });
  75. }
  76. renderView() {
  77. const { base = {}, data = {}, dataStructMap = {}, showComment, showFinish, comment = {}, showFaq, faq = {} } = this.state;
  78. return (
  79. <div>
  80. <div className="top content t-8">
  81. <Link to="/course">千行课堂</Link> > <Link to={'/course/data'}>全部资料</Link> > {data.parentStructId > 0 ? <Link to={`/course/online?tab=single&parentStructId=${(dataStructMap[data.parentStructId] || {}).key}`}>{(dataStructMap[data.parentStructId] || {}).title}</Link> : null}{data.parentStructId > 0 ? '> ' : ''}
  82. <Link to={`/course/online?tab=single&parentStructId=${(dataStructMap[data.parentStructId] || {}).key}&structId=${(dataStructMap[data.structId] || {}).key}`}>{(dataStructMap[data.structId] || {}).title}</Link> > <Link to={`/course/data/detail/${data.id}`}>{data.title}</Link> > <span className="t-1">资料详情</span>
  83. </div>
  84. {this.renderDetail()}
  85. <Contact data={base.contact} />
  86. <Footer />
  87. <CommentModal
  88. show={showComment}
  89. defaultData={comment}
  90. onConfirm={() => this.setState({ showComment: false, comment: {}, showFinish: true })}
  91. onCancel={() => this.setState({ showComment: false, comment: {} })}
  92. onClose={() => this.setState({ showComment: false, comment: {} })}
  93. />
  94. <FaqModal show={showFaq} defaultData={faq} onCancel={() => this.setState({ showFaq: false, faq: {} })} onConfirm={() => this.setState({ showFaq: false, faq: {}, showFinish: true })} />
  95. <FinishModal
  96. show={showFinish}
  97. onConfirm={() => this.setState({ showFinish: false })}
  98. />
  99. </div>
  100. );
  101. }
  102. renderDetail() {
  103. const { tab, data = {}, add } = this.state;
  104. return [
  105. <div className="center">
  106. <div className="content">
  107. <div className="item-detail">
  108. <div className="left">
  109. <Assets name="" src={data.cover} />
  110. <div className="tag-list">
  111. {data.isNovice > 0 && <div className="tag">新手</div>}
  112. {data.isOriginal > 0 && <div className="tag">原创</div>}
  113. </div>
  114. </div>
  115. <div style={{ width: 760 }} className="right">
  116. <div className="t-1 t-s-20">{data.title}</div>
  117. <div className="t-7 m-b-2" dangerouslySetInnerHTML={{ __html: data.content }} />
  118. <div className="">
  119. <div className="d-i-b t-1">最近更新:</div>
  120. <div className="d-i-b t-8">{data.latestTime && formatDate(data.latestTime, 'YYYY-MM-DD HH:mm:ss')}</div>
  121. </div>
  122. <div className="">
  123. <div className="d-i-b t-1">页数:</div>
  124. <div className="d-i-b t-8">{data.pages}页</div>
  125. </div>
  126. <div className="">
  127. <div className="d-i-b t-1">格式:</div>
  128. <div className="d-i-b t-8">{data.dataType === 'paper' ? '纸质' : 'PDF'}</div>
  129. </div>
  130. <div className="m-b-1">
  131. <div style={{ marginTop: 12 }} className="d-i-b t-1 t-s-16 v-a-t">
  132. 价格:
  133. </div>
  134. <div className="d-i-b t-7 t-s-28 f-w-b"> ¥ {formatMoney(data.price)}</div>
  135. </div>
  136. <div className="action">
  137. {!data.have && (
  138. <Button
  139. className="m-r-1"
  140. radius
  141. size="lager"
  142. onClick={() => {
  143. if (data.dataType === 'paper') {
  144. openLink(data.link);
  145. } else {
  146. this.buy();
  147. }
  148. }}
  149. >
  150. 立即购买
  151. </Button>
  152. )}
  153. {!data.have && (
  154. <Button
  155. className="m-r-1"
  156. theme="default"
  157. disabled={data.add || add}
  158. radius
  159. size="lager"
  160. onClick={() => this.add()}
  161. >
  162. <Assets name="add" />
  163. </Button>
  164. )}
  165. {!data.have && (
  166. <Button theme="default" radius size="lager" onClick={() => openLink(data.resource)}>
  167. 预览
  168. </Button>
  169. )}
  170. {data.have && (
  171. <Button className="f-r" theme="default" radius size="lager" onClick={() => openLink(data.resource)}>
  172. 查看资料
  173. </Button>
  174. )}
  175. </div>
  176. {data.have && <Assets className="buyed" width={75} height={75} name="Purchased" />}
  177. </div>
  178. </div>
  179. </div>
  180. </div>,
  181. <div className="bottom">
  182. <div className="content">
  183. <Tabs
  184. type="full"
  185. border
  186. active={tab}
  187. tabs={[
  188. { title: '资料介绍', key: '1' },
  189. { title: '作者介绍', key: '2' },
  190. { title: '获取方式', key: '3' },
  191. { title: 'FAQs', key: '4' },
  192. { title: '学员评价', key: '5' },
  193. ]}
  194. onChange={key => this.onChangeTab(key)}
  195. />
  196. {this[`renderTab${tab}`]()}
  197. </div>
  198. </div>,
  199. ];
  200. }
  201. renderTab1() {
  202. const { data } = this.state;
  203. return (
  204. <div className="tab-layout">
  205. <div className="tab-desc" dangerouslySetInnerHTML={{ __html: data.content }} />
  206. </div>
  207. );
  208. }
  209. renderTab2() {
  210. const { data } = this.state;
  211. return (
  212. <div className="tab-layout">
  213. <div className="tab-desc" dangerouslySetInnerHTML={{ __html: data.authorContent }} />
  214. </div>
  215. );
  216. }
  217. renderTab3() {
  218. const { data } = this.state;
  219. return (
  220. <div className="tab-layout">
  221. <div className="tab-desc" dangerouslySetInnerHTML={{ __html: data.methodContent }} />
  222. </div>
  223. );
  224. }
  225. renderTab4() {
  226. const { faqs, data = {} } = this.state;
  227. return (
  228. <div className="tab-layout">
  229. <AnswerCarousel
  230. hideBtn
  231. list={faqs}
  232. onFaq={() => User.needLogin().then(() => this.setState({ showFaq: true, faq: { channel: 'course_data', position: data.id } }))}
  233. />
  234. </div>
  235. );
  236. }
  237. renderTab5() {
  238. const { data, comments } = this.state;
  239. return (
  240. <div className="tab-layout">
  241. {data.have && <div className="m-b-1 t-r">
  242. <Button width={100} radius onClick={() => User.needLogin().then(() => this.setState({ showComment: true, comment: { channel: 'course_data', position: data.id } }))}>
  243. 写评论
  244. </Button>
  245. </div>}
  246. {(comments || []).map(item => {
  247. return <Comment data={item} />;
  248. })}
  249. </div>
  250. );
  251. }
  252. }