page.js 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862
  1. import React from 'react';
  2. import './index.less';
  3. import { Icon } from 'antd';
  4. import Page from '@src/containers/Page';
  5. import Assets from '@src/components/Assets';
  6. import { asyncSMessage } from '@src/services/AsyncTools';
  7. import { formatDate, getMap } from '@src/services/Tools';
  8. import UserLayout from '../../../layouts/User';
  9. import UserAction from '../../../components/UserAction';
  10. import menu from '../index';
  11. import Tabs from '../../../components/Tabs';
  12. import More from '../../../components/More';
  13. import Button from '../../../components/Button';
  14. import Switch from '../../../components/Switch';
  15. import TotalSort from '../../../components/TotalSort';
  16. import { RealAuth } from '../../../components/OtherModal';
  17. import Examination from '../../../components/Examination';
  18. import VipRenew from '../../../components/VipRenew';
  19. import Modal from '../../../components/Modal';
  20. import UserTable from '../../../components/UserTable';
  21. import UserPagination from '../../../components/UserPagination';
  22. import { My } from '../../../stores/my';
  23. import { User } from '../../../stores/user';
  24. import { Order } from '../../../stores/order';
  25. import { Textbook } from '../../../stores/textbook';
  26. import { DataType, ServiceKey, RecordSource, TextbookFeedbackTarget } from '../../../../Constant';
  27. import { Main } from '../../../stores/main';
  28. import { Question } from '../../../stores/question';
  29. import Select from '../../../components/Select';
  30. const ServiceKeyMap = getMap(ServiceKey, 'value', 'label');
  31. const RecordSourceMap = getMap(RecordSource, 'value', 'label');
  32. const TextbookFeedbackTargetMap = getMap(TextbookFeedbackTarget, 'value', 'tips');
  33. const dataHistoryColumns = [
  34. { title: '更新时间', key: 'time', width: 120 },
  35. { title: '位置', key: 'position', width: 120 },
  36. { title: '原内容', key: 'originContent', width: 120 },
  37. { title: '更改为', key: 'content', width: 120 },
  38. { title: '更新至', key: 'version', width: 90 },
  39. ];
  40. const textbookHistoryColumns = [
  41. {
  42. title: '更新时间',
  43. key: 'createTime',
  44. width: 120,
  45. render: (text) => {
  46. return <div className="sub">
  47. <div className="t-2 t-s-12">{text.split(' ')[0]}</div>
  48. <div className="t-6 t-s-12">{text.split(' ')[1]}</div>
  49. </div>;
  50. },
  51. },
  52. { title: '版本', key: 'version', width: 120 },
  53. { title: '更新内容', key: 'content', width: 330 },
  54. ];
  55. const openColumns = [
  56. { title: '商品名称', key: 'title', width: 240 },
  57. { title: '获取方式', key: 'source', width: 240 },
  58. { title: '开通期限', key: 'endTime', width: 240 },
  59. { title: '操作', key: 'handler', width: 90 },
  60. ];
  61. export default class extends Page {
  62. constructor(props) {
  63. props.size = 10;
  64. super(props);
  65. }
  66. initState() {
  67. return {
  68. tab: 'data',
  69. sortMap: {},
  70. filterMap: {},
  71. feedbackError: { position: ['', '', ''] },
  72. };
  73. }
  74. initData() {
  75. const data = Object.assign(this.state, this.state.search);
  76. if (data.order) {
  77. data.sortMap = { [data.order]: data.direction };
  78. }
  79. data.filterMap = this.state.search;
  80. this.setState(data);
  81. const { tab } = this.state;
  82. switch (tab) {
  83. case 'textbook':
  84. this.refreshTextbook();
  85. break;
  86. case 'examination':
  87. this.refreshExamination();
  88. break;
  89. case 'vip':
  90. this.refreshVip();
  91. break;
  92. case 'cal':
  93. break;
  94. case 'data':
  95. default:
  96. this.refreshData();
  97. break;
  98. }
  99. }
  100. refreshTextbook() {
  101. Main.getService('textbook').then(result => {
  102. this.setState({ service: result });
  103. });
  104. Textbook.getInfo().then(result => {
  105. const { latest } = result;
  106. result.day = parseInt((new Date().getTime() - new Date(result.latest.startDate).getTime()) / 86400000, 10);
  107. result.expireDay =
  108. result.expireTime && parseInt((new Date(result.expireTime).getTime() - new Date().getTime()) / 86400000, 10);
  109. const list = [];
  110. list.push({ subject: 'quant', number: latest.quantNumber, time: latest.quantTime, version: latest.quantVersion });
  111. list.push({ subject: 'rc', number: latest.rcNumber, time: latest.rcTime, version: latest.rcVersion });
  112. list.push({ subject: 'ir', number: latest.irNumber, time: latest.irTime, version: latest.irVersion });
  113. this.setState({ data: result, list });
  114. });
  115. }
  116. textbookHistory({ page, size, subject }) {
  117. Textbook.allHistory(subject).then(result => {
  118. this.setState({
  119. showUpdate: true,
  120. updateList: result.map(row => {
  121. row.version = row[`${subject}Version`];
  122. row.content = row[`${subject}Content`];
  123. row.createTime = formatDate(row.createTime, 'YYYY-MM-DD HH:mm:ss');
  124. return row;
  125. }),
  126. // 不显示分页
  127. updateTotal: 0,
  128. maxHeight: 730,
  129. updatePage: page,
  130. updateData: { page, size, subject, columns: textbookHistoryColumns, type: 'textbook' },
  131. });
  132. });
  133. }
  134. refreshExamination() {
  135. Main.getService('qx_cat').then(result => {
  136. this.setState({ service: result });
  137. });
  138. Question.getExaminationInfo(result => {
  139. result.expireDay =
  140. result.expireTime && parseInt((new Date().getTime() - new Date(result.expireTime).getTime()) / 86400000, 10);
  141. this.setState({ data: result });
  142. });
  143. }
  144. refreshVip() {
  145. Main.getService('vip').then(result => {
  146. this.setState({ service: result });
  147. });
  148. My.getVipInfo().then(result => {
  149. this.setState({ data: result });
  150. });
  151. }
  152. recordList({ page, size, service, isUse, isExpire }) {
  153. Order.listRecord({ page, size, productType: 'service', service, isUse, isExpire }).then(result => {
  154. this.setState({
  155. showUpdate: true,
  156. updateList: result.list.map(row => {
  157. row.title = ServiceKeyMap[service];
  158. row.source = RecordSourceMap[row.source];
  159. row.handler = (
  160. <a
  161. onClick={() => {
  162. this.open(row.id);
  163. }}
  164. >
  165. 立即开通
  166. </a>
  167. );
  168. row.endTime = `${formatDate(row.endTime, 'YYYY-MM-DD')} 前`;
  169. return row;
  170. }),
  171. updateTotal: result.list.length,
  172. updatePage: page,
  173. updateData: { page, size, service, isUse, columns: isUse ? [] : openColumns, type: 'record' },
  174. });
  175. });
  176. }
  177. refreshData() {
  178. const dataTypeSelect = DataType.map(row => {
  179. row.title = row.label;
  180. row.key = row.value;
  181. return row;
  182. });
  183. dataTypeSelect.unshift({
  184. title: '全部',
  185. key: '',
  186. });
  187. this.setState({ dataTypeSelect });
  188. Main.dataStruct().then(result => {
  189. const structs = result
  190. .filter(row => row.level === 1)
  191. .map(row => {
  192. row.title = `${row.titleZh}${row.titleEn}`;
  193. row.key = `${row.id}`;
  194. return row;
  195. });
  196. structs.unshift({
  197. title: '全部',
  198. key: '',
  199. });
  200. this.setState({
  201. structs,
  202. });
  203. });
  204. My.listData(Object.assign({}, this.state.search)).then(result => {
  205. // result = {
  206. // list: [
  207. // {
  208. // title: '123123',
  209. // latestTime: '',
  210. // id: 1,
  211. // number: 10,
  212. // version: '1231',
  213. // },
  214. // ],
  215. // };
  216. this.setState({
  217. list: result.list.map(row => {
  218. row.time = formatDate(row.time, 'YYYY-MM-DD HH:mm:ss');
  219. return row;
  220. }),
  221. total: result.total,
  222. page: this.state.search.page,
  223. });
  224. });
  225. }
  226. dataHistory({ dataId, page, size }) {
  227. My.listDataHistory({ page, size: 10000, dataId }).then(result => {
  228. result.list = result.list.map(row => {
  229. row.time = formatDate(row.time, 'YYYY-MM-DD\nHH:mm:ss');
  230. return row;
  231. });
  232. this.setState({
  233. showUpdate: true,
  234. // 不显示分页
  235. updateTotal: 0,
  236. maxHeight: 730,
  237. updateList: result.list,
  238. updatePage: page,
  239. updateData: { page, size, dataId, columns: dataHistoryColumns, type: 'data' },
  240. });
  241. });
  242. }
  243. onFilter(value) {
  244. this.search(value);
  245. }
  246. onSort(value) {
  247. const { sortMap } = this.state;
  248. const keys = Object.keys(value);
  249. const index = keys.length > 1 && sortMap[keys[0]] ? 1 : 0;
  250. this.search({ order: keys.length ? keys[index] : null, direction: keys.length ? value[keys[index]] : null });
  251. }
  252. onTabChange(tab) {
  253. const data = { tab };
  254. this.refreshQuery(data);
  255. }
  256. submitComment() {
  257. const { comment } = this.state;
  258. if (!comment.content) return;
  259. My.addComment(comment.channel, comment.position, comment.content).then(() => {
  260. this.setState({ showComment: false, showFinish: true, comment: {} });
  261. });
  262. }
  263. submitFeedbackError() {
  264. const { feedbackError } = this.state;
  265. if (!feedbackError.content || !feedbackError.originContent) return;
  266. My.addFeedbackErrorData(
  267. feedbackError.dataId,
  268. feedbackError.title,
  269. feedbackError.position.join(','),
  270. feedbackError.originContent,
  271. feedbackError.content,
  272. ).then(() => {
  273. this.setState({ showFinish: true, showFeedbackError: false, feedbackError: { position: ['', '', ''] } });
  274. });
  275. }
  276. submitFeedback() {
  277. const { feedback } = this.state;
  278. if (!feedback.content) return;
  279. if (feedback.target !== 'new' && !feedback.no) return;
  280. My.addTextbookFeedback(feedback.questionSubject, feedback.target, feedback.no, feedback.content).then(() => {
  281. this.setState({ showFinish: true, showFeedback: false, feedback: {} });
  282. });
  283. }
  284. subscribe(value) {
  285. My.subscribeData(value)
  286. .then(() => {
  287. const { info } = this.props.user;
  288. info.dataEmailSubscribe = value;
  289. User.infoHandle(info);
  290. })
  291. .catch(err => {
  292. asyncSMessage(err.message, 'warn');
  293. });
  294. }
  295. open(recordId) {
  296. Order.useRecord(recordId).then(() => {
  297. this.refresh();
  298. });
  299. }
  300. renderView() {
  301. const { config } = this.props;
  302. return <UserLayout active={config.key} menu={menu} center={this.renderDetail()} />;
  303. }
  304. renderDetail() {
  305. const {
  306. tab,
  307. comment = {},
  308. feedback = {},
  309. feedbackError = {},
  310. showComment,
  311. showFinish,
  312. showUpdate,
  313. showFeedback,
  314. showFeedbackError,
  315. updateList,
  316. updateTotal,
  317. maxHeight,
  318. updateData = {},
  319. showExamination,
  320. showReal,
  321. showVip,
  322. } = this.state;
  323. const { info } = this.props.user;
  324. return (
  325. <div className="table-layout">
  326. <Tabs
  327. border
  328. type="division"
  329. theme="theme"
  330. size="small"
  331. space={2.5}
  332. width={100}
  333. active={tab}
  334. tabs={[
  335. { key: 'data', title: '资料' },
  336. { key: 'textbook', title: '机经' },
  337. { key: 'examination', title: '模考' },
  338. { key: 'vip', title: 'VIP' },
  339. { key: 'cal', title: '考分计算器' },
  340. ]}
  341. onChange={key => this.onTabChange(key)}
  342. />
  343. {this[`renderTab${tab}`]()}
  344. <Modal
  345. show={showUpdate}
  346. maskClosable
  347. close={false}
  348. body={false}
  349. width={630}
  350. onClose={() => this.setState({ showUpdate: false, updateList: [] })}
  351. >
  352. <UserTable
  353. size="small"
  354. theme="top"
  355. columns={updateData.columns}
  356. data={updateList}
  357. current={updateData.page}
  358. pageSize={updateData.size}
  359. onChange={page => {
  360. updateData.page = page;
  361. if (updateData.type === 'data') {
  362. this.dataHistory(updateData);
  363. } else if (updateData.type === 'textbook') {
  364. this.textbookHistory(updateData);
  365. } else if (updateData.type === 'record') {
  366. this.recordList(updateData);
  367. }
  368. }}
  369. total={updateTotal}
  370. maxHeight={maxHeight}
  371. />
  372. </Modal>
  373. <Modal
  374. show={showComment}
  375. title="评价"
  376. onConfirm={() => comment.content && this.submitComment()}
  377. onCancel={() => this.setState({ showComment: false, comment: {} })}
  378. >
  379. <textarea
  380. value={comment.content}
  381. className="b-c-1 w-10 p-10"
  382. rows={6}
  383. placeholder="您的看法对我们来说很重要!"
  384. onChange={e => {
  385. comment.content = e.target.value;
  386. this.setState({ comment });
  387. }}
  388. />
  389. <div className="b-b m-t-2" />
  390. </Modal>
  391. <Modal
  392. show={showFinish}
  393. title="提交成功"
  394. confirmText="好的,知道了"
  395. btnAlign="center"
  396. onConfirm={() => this.setState({ showFinish: false })}
  397. >
  398. <div className="t-2 t-s-18">
  399. <Icon type="check" className="t-5 m-r-5" />
  400. 您的每一次反馈都是千行进步的动力。
  401. </div>
  402. </Modal>
  403. <Modal
  404. show={showFeedbackError}
  405. title="纠错"
  406. btnType="link"
  407. width={630}
  408. onConfirm={() => this.submitFeedbackError()}
  409. onCancel={() => this.setState({ showFeedbackError: false })}
  410. >
  411. <div className="t-2 m-b-1 t-s-16">
  412. 定位:
  413. <input value={feedbackError.position[0]} className="t-c b-c-1 m-r-5" style={{ width: 56 }} onChange={e => {
  414. feedbackError.position[0] = e.target.value;
  415. this.setState({ feedbackError });
  416. }} />
  417. <span className="require">页</span>
  418. <input value={feedbackError.position[1]} className="t-c b-c-1 m-r-5" style={{ width: 56 }} onChange={e => {
  419. feedbackError.position[1] = e.target.value;
  420. this.setState({ feedbackError });
  421. }} />
  422. <span className="require">行</span> , 题号
  423. <input value={feedbackError.position[2]} className="t-c b-c-1" style={{ width: 56 }} onChange={e => {
  424. feedbackError.position[2] = e.target.value;
  425. this.setState({ feedbackError });
  426. }} />
  427. </div>
  428. <div className="t-2 t-s-16">错误内容是:</div>
  429. <textarea
  430. value={feedbackError.originContent}
  431. className="b-c-1 w-10 p-10"
  432. rows={10}
  433. placeholder={'可简单描述您发现的问题'}
  434. onChange={e => {
  435. feedbackError.originContent = e.target.value;
  436. this.setState({ feedbackError });
  437. }}
  438. />
  439. <div className="t-2 t-s-16">应该更改为:</div>
  440. <textarea
  441. value={feedbackError.content}
  442. className="b-c-1 w-10 p-10"
  443. rows={10}
  444. placeholder={'提供您认为正确的内容即可'}
  445. onChange={e => {
  446. feedbackError.content = e.target.value;
  447. this.setState({ feedbackError });
  448. }}
  449. />
  450. <div className="b-b m-t-2" />
  451. </Modal>
  452. <Modal
  453. show={showFeedback}
  454. title="反馈"
  455. width={630}
  456. onConfirm={() => this.submitFeedback()}
  457. onCancel={() => this.setState({ showFeedback: false })}
  458. >
  459. <div className="t-2 t-s-16 m-b-1">
  460. 机经类别:
  461. <Select
  462. value={feedback.questionSubject}
  463. theme="white"
  464. list={[{ title: '数学机经', key: 'quant' }, { title: '逻辑机经', key: 'rc' }, { title: '阅读机经', key: 'ir' }]}
  465. onChange={(value) => {
  466. feedback.questionSubject = value;
  467. this.setState({ feedback });
  468. }}
  469. />
  470. 反馈类型:
  471. <Select
  472. value={feedback.target}
  473. theme="white"
  474. list={TextbookFeedbackTarget}
  475. onChange={(value) => {
  476. feedback.target = value;
  477. this.setState({ feedback });
  478. }}
  479. />
  480. <span hidden={feedback.target === 'new'}>
  481. 题号是
  482. <input value={feedback.no} style={{ width: 80 }} className="m-l-1 b-c-1 t-c" onChange={e => {
  483. feedback.no = e.target.value;
  484. this.setState({ feedback });
  485. }} />
  486. </span>
  487. </div>
  488. <div className="t-2 t-s-16">{TextbookFeedbackTargetMap[feedback.target]}:</div>
  489. <textarea
  490. value={feedback.content}
  491. className="b-c-1 w-10 p-10"
  492. rows={10}
  493. placeholder={TextbookFeedbackTargetMap[feedback.target]}
  494. onChange={e => {
  495. feedback.content = e.target.value;
  496. this.setState({ feedback });
  497. }}
  498. />
  499. <div className="b-b m-t-2" />
  500. </Modal>
  501. <Examination
  502. show={showExamination}
  503. data={info}
  504. onConfirm={() => this.setState({ showExamination: false })}
  505. onCancel={() => this.setState({ showExamination: false })}
  506. onClose={() => this.setState({ showExamination: false })}
  507. />
  508. <RealAuth show={showReal} data={info} onConfirm={() => this.setState({ showReal: false })} />
  509. <VipRenew
  510. show={showVip}
  511. data={info}
  512. onReal={() => this.setState({ showVip: false, showReal: true })}
  513. onPrepare={() => this.setState({ showVip: false, showExamination: true })}
  514. onClose={() => this.setState({ showVip: false })}
  515. />
  516. </div>
  517. );
  518. }
  519. renderTabdata() {
  520. const { list = [], filterMap = {}, sortMap = {}, structs, dataTypeSelect, total, page } = this.state;
  521. const { info } = this.props.user;
  522. return (
  523. <div className="tab-1-layout">
  524. <UserAction
  525. selectList={[
  526. {
  527. label: '学科',
  528. key: 'structId',
  529. select: structs,
  530. },
  531. {
  532. label: '资料形式',
  533. key: 'dataType',
  534. select: dataTypeSelect,
  535. },
  536. ]}
  537. sortList={[
  538. { right: true, label: '销量', key: 'sale_number' },
  539. { right: true, label: '更新时间', key: 'latest_time' },
  540. ]}
  541. sortMap={sortMap}
  542. filterMap={filterMap}
  543. onFilter={value => this.onFilter(value)}
  544. onSort={value => this.onSort(value)}
  545. right={
  546. <div className="email">
  547. 邮箱订阅{' '}
  548. <Switch
  549. checked={info.dataEmailSubscribe}
  550. onChange={() => {
  551. this.subscribe(!info.dataEmailSubscribe);
  552. }}
  553. />
  554. </div>
  555. }
  556. />
  557. <div className="data-layout">
  558. {list.map(item => {
  559. return (
  560. <div className="data-item">
  561. <Assets name="sun_blue" src={item.cover} />
  562. <div className="fixed">
  563. <div className="btns">
  564. <Button
  565. size="small"
  566. radius
  567. onClick={() => {
  568. openLink(item.resource);
  569. }}
  570. >
  571. 阅读
  572. </Button>
  573. <div
  574. className="white"
  575. onClick={() => {
  576. openLink(item.resource);
  577. }}
  578. >
  579. 下载
  580. </div>
  581. </div>
  582. </div>
  583. <div className="title">
  584. <span>版本{item.version}</span>
  585. {item.title}
  586. </div>
  587. <div className="date">{formatDate(item.latestTime, 'YYYY-MM-DD HH:mm:ss')}</div>
  588. <More
  589. menu={[
  590. { label: '纠错', key: 'feedback' },
  591. { label: '评价', key: 'comment' },
  592. { label: '更新', key: 'update' },
  593. ]}
  594. onClick={value => {
  595. const { key } = value;
  596. if (key === 'comment') {
  597. this.setState({ showComment: true, comment: { channel: 'course_data', position: item.id } });
  598. } else if (key === 'update') {
  599. this.dataHistory({ dataId: item.id, page: 1, size: 10 });
  600. } else if (key === 'feedback') {
  601. this.setState({ showFeedbackError: true, feedbackError: { dataId: item.id, title: item.title, position: ['', '', ''] } });
  602. }
  603. }}
  604. />
  605. </div>
  606. );
  607. })}
  608. </div>
  609. {total > 0 && list.length > 0 && (
  610. <UserPagination total={total} current={page} pageSize={this.state.search.size} onChange={p => this.onChangePage(p)} />
  611. )}
  612. </div>
  613. );
  614. }
  615. renderTabtextbook() {
  616. const { data = {}, list = [], service } = this.state;
  617. const { latest = {}, day } = data;
  618. return (
  619. <div className="tab-2-layout">
  620. <UserAction
  621. left={
  622. <div className="total-log">
  623. <span>最新换库</span>
  624. <span>{latest.startDate ? formatDate(latest.startDate, 'YYYY-MM-DD') : ''}</span>
  625. <span>
  626. 已换库<b>{day}</b>天
  627. </span>
  628. </div>
  629. }
  630. right={
  631. !data.hasService &&
  632. data.unUseRecord && (
  633. <div className="email" >
  634. <span onClick={() => {
  635. this.recordList({ page: 1, size: 10, service: 'textbook', isUse: false, isExpire: false });
  636. }} >待开通</span>
  637. </div>
  638. )
  639. }
  640. />
  641. {data.hasService && (
  642. <div className="data-layout">
  643. {list.map(item => {
  644. return (
  645. <div className="data-item">
  646. <Assets name="sun_blue" />
  647. <div className="title">
  648. 已更新至<b>{item.num}</b>题
  649. </div>
  650. <div className="date">{item.date}</div>
  651. <More
  652. menu={[
  653. { label: '更新', key: 'update' },
  654. { label: '反馈', key: 'feedback' },
  655. { label: '评价', key: 'comment' },
  656. ]}
  657. onClick={value => {
  658. const { key } = value;
  659. if (key === 'comment') {
  660. this.setState({ showComment: true, comment: { channel: 'library' } });
  661. } else if (key === 'update') {
  662. this.textbookHistory({ page: 1, size: 100, subject: item.subject });
  663. } else if (key === 'feedback') {
  664. this.setState({ showFeedback: true, feedback: { questionSubject: item.subject, target: TextbookFeedbackTarget[0].value } });
  665. }
  666. }}
  667. />
  668. </div>
  669. );
  670. })}
  671. </div>
  672. )}
  673. {!data.hasService && !data.unUseRecord && (
  674. <div className="tip-layout">
  675. <div className="t1">还未购买本月机经</div>
  676. <div className="desc">¥ {service && service.package && service.package[0].price}</div>
  677. <Button radius size="lager" width={150} onClick={() => {
  678. this.buyTextbook();
  679. }}>
  680. 立即购买
  681. </Button>
  682. </div>
  683. )}
  684. {/* {data.hasService && (
  685. <div className="tip-layout">
  686. <div className="t1">使用中</div>
  687. <div className="t2">距离到期还有 {data.expireDay} 天</div>
  688. </div>
  689. )} */}
  690. {!data.hasService && data.unUseRecord && (
  691. <div className="tip-layout">
  692. <div className="t2">请于{formatDate(data.unUseRecord.endTime, 'YYYY-MM-DD')}前开通</div>
  693. <Button
  694. radius
  695. size="lager"
  696. width={150}
  697. onClick={() => {
  698. this.open(data.unUseRecord.id);
  699. }}
  700. >
  701. 立即开通
  702. </Button>
  703. </div>
  704. )}
  705. </div>
  706. );
  707. }
  708. renderTabexamination() {
  709. const { data = {}, service } = this.state;
  710. return (
  711. <div className="tab-3-layout">
  712. <UserAction
  713. right={
  714. !data.hasService &&
  715. data.unUseRecord && (
  716. <div
  717. className="email"
  718. onClick={() => {
  719. this.recordList({ page: 1, size: 10, service: 'qx_cat', isUse: false, isExpire: false });
  720. }}
  721. >
  722. 待开通
  723. </div>
  724. )
  725. }
  726. />
  727. {!data.hasService && !data.unUseRecord && !data.expireTime && (
  728. <div className="tip-layout">
  729. <div className="t1">未购买</div>
  730. <div className="desc">¥ {service && service.package && service.package[0].price}</div>
  731. <Button radius size="lager" width={150} onClick={() => {
  732. this.buyExamination();
  733. }}>
  734. 立即购买
  735. </Button>
  736. </div>
  737. )}
  738. {!data.hasService && data.unUseRecord && (
  739. <div className="tip-layout">
  740. <div className="t2">请于{formatDate(data.unUseRecord.endTime, 'YYYY-MM-DD')}前开通</div>
  741. <Button
  742. radius
  743. size="lager"
  744. width={150}
  745. onClick={() => {
  746. this.open(data.unUseRecord.id);
  747. }}
  748. >
  749. 立即开通
  750. </Button>
  751. </div>
  752. )}
  753. {data.hasService && (
  754. <div className="tip-layout">
  755. <div className="t1">使用中</div>
  756. <div className="t2">距离到期还有 {data.expireDay} 天</div>
  757. </div>
  758. )}
  759. {!data.hasService && !data.unUseRecord && data.expireTime && (
  760. <div className="tip-layout">
  761. <div className="t3">已过期</div>
  762. <div className="date">
  763. {formatDate(data.startTime, 'YYYY-MM-DD')} ~ {formatDate(data.expireTime, 'YYYY-MM-DD')}
  764. </div>
  765. <div className="desc">¥ {service && service.package && service.package[0].price}</div>
  766. <Button radius size="lager" width={150}>
  767. 立即购买
  768. </Button>
  769. </div>
  770. )}
  771. </div>
  772. );
  773. }
  774. renderTabvip() {
  775. const { data } = this.state;
  776. return (
  777. <div className="tab-4-layout">
  778. {!data.hasService && !data.unUseRecord && !data.expireTime && (
  779. <div className="tip-layout">
  780. <div className="t2">未购买</div>
  781. <Button radius size="lager" width={150} onClick={() => {
  782. this.setState({ showVip: true });
  783. }}>
  784. 立即购买
  785. </Button>
  786. </div>
  787. )}
  788. {data.hasService && (
  789. <div className="tip-layout">
  790. <div className="t1">使用中</div>
  791. <div className="desc">{formatDate(data.expireTime, 'YYYY-MM-DD')} 到期</div>
  792. <Button radius size="lager" width={150} onClick={() => {
  793. this.setState({ showVip: true });
  794. }}>
  795. 续费
  796. </Button>
  797. </div>
  798. )}
  799. {!data.hasService && !data.unUseRecord && data.expireTime && (
  800. <div className="tip-layout">
  801. <div className="t1">已过期</div>
  802. <div className="desc">
  803. {formatDate(data.startTime, 'YYYY-MM-DD')} ~ {formatDate(data.expireTime, 'YYYY-MM-DD')}
  804. </div>
  805. <Button radius size="lager" width={150} onClick={() => {
  806. this.setState({ showVip: true });
  807. }}>
  808. 立即购买
  809. </Button>
  810. </div>
  811. )}
  812. </div>
  813. );
  814. }
  815. renderTabcal() {
  816. const { data = {} } = this.state;
  817. return (
  818. <div className="tab-5-layout">
  819. <TotalSort
  820. value={data.value || 650}
  821. onChange={value => {
  822. data.value = value;
  823. this.setState({ data });
  824. }}
  825. />
  826. </div>
  827. );
  828. }
  829. }