page.js 27 KB

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