|
@@ -3,42 +3,304 @@ import { Link } from 'react-router-dom';
|
|
|
import './index.less';
|
|
|
import Page from '@src/containers/Page';
|
|
|
import Assets from '@src/components/Assets';
|
|
|
+import { getMap, formatDate } from '@src/services/Tools';
|
|
|
+import { CommentModal, FaqModal, TextbookFeedbackModal, FinishModal } from '../../../components/OtherModal';
|
|
|
import { CommentFalls, AnswerCarousel, Consultation, Contact } from '../../../components/Other';
|
|
|
+import Modal from '../../../components/Modal';
|
|
|
import Footer from '../../../components/Footer';
|
|
|
import Button from '../../../components/Button';
|
|
|
import UserTable from '../../../components/UserTable';
|
|
|
import Tabs from '../../../components/Tabs';
|
|
|
import { TextbookItem } from '../../../components/Item';
|
|
|
import { TwoDate } from '../../../components/Date';
|
|
|
+import { Main } from '../../../stores/main';
|
|
|
+import { Textbook } from '../../../stores/textbook';
|
|
|
+import { Order } from '../../../stores/order';
|
|
|
+import { User } from '../../../stores/user';
|
|
|
+import { TextbookFeedbackTarget } from '../../../../Constant';
|
|
|
+
|
|
|
+const textbookHistoryColumns = [
|
|
|
+ {
|
|
|
+ title: '更新时间',
|
|
|
+ key: 'createTime',
|
|
|
+ width: 120,
|
|
|
+ render: (text) => {
|
|
|
+ return <div className="sub">
|
|
|
+ <div className="t-2 t-s-12">{text.split(' ')[0]}</div>
|
|
|
+ <div className="t-6 t-s-12">{text.split(' ')[1]}</div>
|
|
|
+ </div>;
|
|
|
+ },
|
|
|
+ },
|
|
|
+ { title: '版本', key: 'version', width: 120 },
|
|
|
+ { title: '更新内容', key: 'content', width: 330 },
|
|
|
+];
|
|
|
|
|
|
export default class extends Page {
|
|
|
initState() {
|
|
|
return {
|
|
|
- list: [{}, {}, {}],
|
|
|
+ tab: 'baselibrary',
|
|
|
+ list: [],
|
|
|
+ enroll: {},
|
|
|
+ load: 0,
|
|
|
};
|
|
|
}
|
|
|
|
|
|
+ init() {
|
|
|
+ this.enrollMap = {};
|
|
|
+ this.libraryMap = {};
|
|
|
+ Main.getBase()
|
|
|
+ .then(result => {
|
|
|
+ this.setState({ base: result });
|
|
|
+ });
|
|
|
+
|
|
|
+ Textbook.getInfo().then((result) => {
|
|
|
+ const { latest } = result;
|
|
|
+ result.day = parseInt((new Date().getTime() - new Date(result.latest.startDate).getTime()) / 86400000, 10);
|
|
|
+
|
|
|
+ result.expireDay =
|
|
|
+ result.expireTime && parseInt((new Date(result.expireTime).getTime() - new Date().getTime()) / 86400000, 10);
|
|
|
+
|
|
|
+ const list = [];
|
|
|
+
|
|
|
+ list.push({ subject: 'quant', number: latest.quantNumber, time: latest.quantTime, version: latest.quantVersion });
|
|
|
+ list.push({ subject: 'rc', number: latest.rcNumber, time: latest.rcTime, version: latest.rcVersion });
|
|
|
+ list.push({ subject: 'ir', number: latest.irNumber, time: latest.irTime, version: latest.irVersion });
|
|
|
+ this.setState({ data: result, list });
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ initData() {
|
|
|
+ this.refreshFaqs(this.state.tab);
|
|
|
+ this.refreshComments();
|
|
|
+ const start = new Date();
|
|
|
+ start.setMinutes(0, 0, 0);
|
|
|
+ start.setHours(0);
|
|
|
+ start.setDate(1);
|
|
|
+ start.setMonth(start.getMonth() - 2);
|
|
|
+ const end = new Date();
|
|
|
+ end.setMinutes(0, 0, 0);
|
|
|
+ end.setHours(0);
|
|
|
+ end.setDate(1);
|
|
|
+ end.setMonth(end.getMonth() + 4);
|
|
|
+ const startDate = formatDate(start, 'YYYY-MM-DD');
|
|
|
+ const endDate = formatDate(end, 'YYYY-MM-DD');
|
|
|
+ this.refreshEnroll(startDate, endDate);
|
|
|
+ this.setState({ startDate, endDate });
|
|
|
+
|
|
|
+ const nowYear = new Date().getFullYear();
|
|
|
+ this.refreshYear(nowYear);
|
|
|
+ if (nowYear > start.getFullYear()) {
|
|
|
+ this.refreshYear(nowYear - 1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ refreshFaqs(tab) {
|
|
|
+ Main.listFaq({ page: 1, size: 1000, channel: `library-${tab}` })
|
|
|
+ .then((result => {
|
|
|
+ this.setState({ faqs: result.list });
|
|
|
+ }));
|
|
|
+ }
|
|
|
+
|
|
|
+ refreshComments() {
|
|
|
+ Main.listComment({ page: 1, size: 1000, channel: 'library' })
|
|
|
+ .then(result => {
|
|
|
+ this.setState({ comments: result.list });
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ refreshEnroll(startDate, endDate) {
|
|
|
+ const month = formatDate(new Date(), 'YYYY-MM');
|
|
|
+ Textbook.listEnroll(startDate, endDate)
|
|
|
+ .then(result => {
|
|
|
+ result.times = result.times.map(row => {
|
|
|
+ row.month = formatDate(row.month, 'YYYY-MM');
|
|
|
+ if (row.month === month) {
|
|
|
+ // 本月机经开通人数
|
|
|
+ this.setState({ useNumber: row.useNumber });
|
|
|
+ }
|
|
|
+ return row;
|
|
|
+ });
|
|
|
+ this.enrollMap = getMap(result.times, 'month');
|
|
|
+ if (result.date) {
|
|
|
+ const d = new Date(result.date);
|
|
|
+ result.dateF = formatDate(d, 'YYYY-MM-DD');
|
|
|
+ result.day = parseInt((d.getTime() - new Date().getTime()) / 86400000, 10);
|
|
|
+ }
|
|
|
+ this.setState({ enroll: result, load: this.state.load + 1 });
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ refreshYear(year) {
|
|
|
+ Textbook.listYear(year)
|
|
|
+ .then(result => {
|
|
|
+ result = result.map(row => {
|
|
|
+ row.day = formatDate(row.startDate, 'YYYY-MM-DD');
|
|
|
+ this.libraryMap[row.day] = row;
|
|
|
+ return row;
|
|
|
+ });
|
|
|
+ this.setState({ library: result, load: this.state.load + 1 });
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ textbookHistory({ page, size, subject }) {
|
|
|
+ this.setState({ subject });
|
|
|
+ Textbook.allHistory(subject).then(result => {
|
|
|
+ this.setState({
|
|
|
+ showUpdate: true,
|
|
|
+ updateList: result.map(row => {
|
|
|
+ row.version = row[`${subject}Version`];
|
|
|
+ row.content = row[`${subject}Content`];
|
|
|
+ row.createTime = formatDate(row.createTime, 'YYYY-MM-DD HH:mm:ss');
|
|
|
+ return row;
|
|
|
+ }),
|
|
|
+ // 不显示分页
|
|
|
+ updateTotal: 0,
|
|
|
+ maxHeight: 730,
|
|
|
+ updatePage: page,
|
|
|
+ updateData: { page, size, subject, columns: textbookHistoryColumns, type: 'textbook' },
|
|
|
+ });
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ enroll() {
|
|
|
+ const { date, enroll } = this.state;
|
|
|
+ if (enroll.date) return;
|
|
|
+ if (!date) {
|
|
|
+ this.setState({ showWarn: true, warn: { title: '报名', content: '请先选择报考日期' } });
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ User.needLogin()
|
|
|
+ .then(() => {
|
|
|
+ Textbook.enroll(date.format('YYYY-MM-DD'))
|
|
|
+ .then(() => {
|
|
|
+ enroll.date = new Date(date);
|
|
|
+ enroll.dateF = date.format('YYYY-MM-DD');
|
|
|
+ enroll.day = parseInt((enroll.date.getTime() - new Date().getTime()) / 86400000, 10);
|
|
|
+ this.setState({ showWarn: true, warn: { title: '报名', content: `已报考${formatDate(date, 'YYYY-MM-DD')}` } });
|
|
|
+ this.setState({ enroll });
|
|
|
+ });
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ unEnroll() {
|
|
|
+ const { enroll } = this.state;
|
|
|
+ if (!enroll.date) return;
|
|
|
+ User.needLogin()
|
|
|
+ .then(() => {
|
|
|
+ Textbook.unEnroll()
|
|
|
+ .then(() => {
|
|
|
+ this.setState({ enroll: {} });
|
|
|
+ });
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ onTabChange(key) {
|
|
|
+ this.refreshFaqs(key);
|
|
|
+ this.setState({ tab: key });
|
|
|
+ }
|
|
|
+
|
|
|
+ open(recordId) {
|
|
|
+ User.needLogin()
|
|
|
+ .then(() => {
|
|
|
+ Order.useRecord(recordId)
|
|
|
+ .then(() => {
|
|
|
+ this.refresh();
|
|
|
+ });
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ buy() {
|
|
|
+ User.needLogin()
|
|
|
+ .then(() => {
|
|
|
+ return Order.speedPay({ productType: 'service', service: 'textbook' });
|
|
|
+ })
|
|
|
+ .then((order) => {
|
|
|
+ return User.needPay(order);
|
|
|
+ })
|
|
|
+ .then(() => {
|
|
|
+ this.refresh();
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
renderView() {
|
|
|
+ const { data = {}, base = {}, tab, faqs = [], comments = [], showFaq, faq = {}, showFinish, showComment, comment = {}, showUpdate, updateData = {}, updateList = [], updateTotal, maxHeight, showFeedback, feedback = {}, showWarn, warn = {} } = this.state;
|
|
|
return (
|
|
|
<div>
|
|
|
{this.renderDate()}
|
|
|
- {this.renderLog()}
|
|
|
- {this.renderCompare()}
|
|
|
- {this.renderList()}
|
|
|
+ {!data.hasService && data.unUseRecord && this.renderLog()}
|
|
|
+ {!data.hasService && !data.unUseRecord && this.renderCompare()}
|
|
|
+ {data.hasService && this.renderList()}
|
|
|
<AnswerCarousel
|
|
|
hideBtn
|
|
|
- tabActive={'1'}
|
|
|
- tabs={[{ title: '换库知识', key: '1' }, { title: '机经知识', key: '2' }, { title: '千行机经', key: '3' }]}
|
|
|
+ tabActive={tab}
|
|
|
+ list={faqs}
|
|
|
+ tabs={[{ title: '换库知识', key: 'baselibrary' }, { title: '机经知识', key: 'basetextbook' }, { title: '千行机经', key: 'qxtextbook' }]}
|
|
|
+ onTabChange={(key) => this.onTabChange(key)}
|
|
|
/>
|
|
|
- <CommentFalls />
|
|
|
+ <CommentFalls list={comments} />
|
|
|
<Consultation />
|
|
|
- <Contact />
|
|
|
+ <Contact data={base.contact} />
|
|
|
<Footer />
|
|
|
+
|
|
|
+ <Modal show={showWarn} title={warn.title} confirmText="好的,知道了" btnAlign="center" onConfirm={() => this.setState({ showWarn: false })}>
|
|
|
+ <div className="t-2 t-s-18">{warn.content}</div>
|
|
|
+ </Modal>,
|
|
|
+ <Modal
|
|
|
+ show={showUpdate}
|
|
|
+ maskClosable
|
|
|
+ close={false}
|
|
|
+ body={false}
|
|
|
+ width={630}
|
|
|
+ onClose={() => this.setState({ showUpdate: false, updateList: [] })}
|
|
|
+ >
|
|
|
+ <UserTable
|
|
|
+ size="small"
|
|
|
+ theme="top"
|
|
|
+ columns={updateData.columns}
|
|
|
+ data={updateList}
|
|
|
+ current={updateData.page}
|
|
|
+ pageSize={updateData.size}
|
|
|
+ onChange={page => {
|
|
|
+ updateData.page = page;
|
|
|
+ if (updateData.type === 'data') {
|
|
|
+ this.dataHistory(updateData);
|
|
|
+ } else if (updateData.type === 'textbook') {
|
|
|
+ this.textbookHistory(updateData);
|
|
|
+ } else if (updateData.type === 'record') {
|
|
|
+ this.recordList(updateData);
|
|
|
+ }
|
|
|
+ }}
|
|
|
+ total={updateTotal}
|
|
|
+ maxHeight={maxHeight}
|
|
|
+ />
|
|
|
+ </Modal>
|
|
|
+ <TextbookFeedbackModal
|
|
|
+ show={showFeedback}
|
|
|
+ defaultData={feedback}
|
|
|
+ onConfirm={() => this.setState({ showFeedback: false, showFinish: true })}
|
|
|
+ onCancel={() => this.setState({ showFeedback: false })}
|
|
|
+ onClose={() => this.setState({ showFeedback: false })}
|
|
|
+ />
|
|
|
+ <CommentModal
|
|
|
+ show={showComment}
|
|
|
+ defaultData={comment}
|
|
|
+ onConfirm={() => this.setState({ showComment: false, showFinish: true })}
|
|
|
+ onCancel={() => this.setState({ showComment: false })}
|
|
|
+ onClose={() => this.setState({ showComment: false })}
|
|
|
+ />
|
|
|
+ <FaqModal show={showFaq} defaultData={faq} onCancel={() => this.setState({ showFaq: false })} onConfirm={() => this.setState({ showFaq: false, showFinish: true })} />
|
|
|
+ <FinishModal
|
|
|
+ getContainer={() => document.getElementById(this.video.state.id)}
|
|
|
+ show={showFinish}
|
|
|
+ onConfirm={() => this.setState({ showFinish: false })}
|
|
|
+ />
|
|
|
</div>
|
|
|
);
|
|
|
}
|
|
|
|
|
|
renderDate() {
|
|
|
+ const { data, enroll = {}, useNumber, startDate, endDate, load } = this.state;
|
|
|
+ const { latest = {}, day } = data;
|
|
|
return (
|
|
|
<div className="date-layout">
|
|
|
<div className="content">
|
|
@@ -47,31 +309,55 @@ export default class extends Page {
|
|
|
<span className="today">今日</span>
|
|
|
<span className="type-1">换库</span>
|
|
|
<span className="type-2">考试日</span>
|
|
|
- <Button size="small" radius>
|
|
|
+ {enroll.date && <span>
|
|
|
+ {enroll.day > 0 ? `距离考试还有${enroll.day}天` : `距离考试已过去${enroll.day * -1}天`}
|
|
|
+ </span>}
|
|
|
+ {enroll.date && <Button size="small" radius onClick={() => this.unEnroll()}>
|
|
|
+ 取消报考
|
|
|
+ </Button>}
|
|
|
+ {!enroll.date && <Button size="small" radius onClick={() => this.enroll()}>
|
|
|
我已报考
|
|
|
- </Button>
|
|
|
- <Link to="" className="f-r">
|
|
|
+ </Button>}
|
|
|
+ <Link to="/textbook/year" className="f-r">
|
|
|
按年份查看 >
|
|
|
</Link>
|
|
|
</div>
|
|
|
<TwoDate
|
|
|
- getType={date => (date.date() === 1 ? 'type-1' : 'type-2')}
|
|
|
- extendInfo={date => `${date.month()}人`}
|
|
|
- onChange={() => {}}
|
|
|
+ key={load}
|
|
|
+ startDate={startDate}
|
|
|
+ endDate={endDate}
|
|
|
+ getType={date => {
|
|
|
+ const d = date.format('YYYY-MM-DD');
|
|
|
+ if (enroll.date && d === enroll.dateF) {
|
|
|
+ return 'type-2';
|
|
|
+ }
|
|
|
+ if (this.libraryMap[d]) {
|
|
|
+ return 'type-1';
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }}
|
|
|
+ extendInfo={date => {
|
|
|
+ const d = date.format('YYYY-MM');
|
|
|
+ return `${this.enrollMap[d] ? this.enrollMap[d].enrollNumber : 0}人`;
|
|
|
+ }}
|
|
|
+ onChange={(date) => this.setState({ date })}
|
|
|
/>
|
|
|
</div>
|
|
|
<div style={{ width: 275 }} className="b f-r p-20">
|
|
|
<div className="t-13 t-s-16">最近换库</div>
|
|
|
<Assets name="" />
|
|
|
- <div className="t-13 t-s-32 t-c">2019-07-22</div>
|
|
|
+ <div className="t-13 t-s-32 t-c">{latest.startDate ? formatDate(latest.startDate, 'YYYY-MM-DD') : ''}</div>
|
|
|
<div className="t-13 t-c t-s-16">
|
|
|
- 已换库 <span className="t-4">10</span> 天
|
|
|
+ 已换库 <span className="t-4">{day}</span> 天
|
|
|
</div>
|
|
|
<div className="m-t-2 t-c">
|
|
|
- <Button width={100} radius size="lager">
|
|
|
+ <Button width={100} radius size="lager" onClick={() => User.needLogin().then(() => linkTo('/my/tools?tab=textbook'))}>
|
|
|
我的机经
|
|
|
</Button>
|
|
|
</div>
|
|
|
+ <div className="m-t-2 t-13 t-c t-s-14">
|
|
|
+ 本月共{useNumber || 0}人使用机经
|
|
|
+ </div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
@@ -84,7 +370,24 @@ export default class extends Page {
|
|
|
<div className="list-layout">
|
|
|
<div className="content">
|
|
|
{list.map(item => {
|
|
|
- return <TextbookItem data={item} />;
|
|
|
+ return <TextbookItem
|
|
|
+ data={item}
|
|
|
+ menu={[
|
|
|
+ { label: '更新', key: 'update' },
|
|
|
+ { label: '反馈', key: 'feedback' },
|
|
|
+ { label: '评价', key: 'comment' },
|
|
|
+ ]}
|
|
|
+ onClick={() => linkTo(`/textbook/topic/list/${item.subject}`)}
|
|
|
+ onMenuClick={value => {
|
|
|
+ const { key } = value;
|
|
|
+ if (key === 'comment') {
|
|
|
+ this.setState({ showComment: true, comment: { channel: 'library' } });
|
|
|
+ } else if (key === 'update') {
|
|
|
+ this.textbookHistory({ page: 1, size: 100, subject: item.subject });
|
|
|
+ } else if (key === 'feedback') {
|
|
|
+ this.setState({ showFeedback: true, feedback: { questionSubject: item.subject, target: TextbookFeedbackTarget[0].value } });
|
|
|
+ }
|
|
|
+ }} />;
|
|
|
})}
|
|
|
</div>
|
|
|
</div>
|
|
@@ -92,6 +395,7 @@ export default class extends Page {
|
|
|
}
|
|
|
|
|
|
renderLog() {
|
|
|
+ const { data, subject, updateList } = this.state;
|
|
|
return (
|
|
|
<div className="table-layout">
|
|
|
<div className="content">
|
|
@@ -99,8 +403,9 @@ export default class extends Page {
|
|
|
<span className="d-i-b t-1 t-s-18">更新日志</span>
|
|
|
<Tabs
|
|
|
type="text"
|
|
|
- tabs={[{ title: '数学', key: '1' }, { title: '阅读RC', key: '2' }, { title: '逻辑RC', key: '3' }]}
|
|
|
- active="1"
|
|
|
+ tabs={[{ title: '数学', key: 'quant' }, { title: '阅读RC', key: 'rc' }, { title: '逻辑IR', key: 'ir' }]}
|
|
|
+ active={subject}
|
|
|
+ onTabChange={(key) => this.textbookHistory({ subject: key })}
|
|
|
/>
|
|
|
</div>
|
|
|
<UserTable
|
|
@@ -110,15 +415,9 @@ export default class extends Page {
|
|
|
{ title: '版本', key: 'version' },
|
|
|
{ title: '更新内容', key: 'content' },
|
|
|
]}
|
|
|
- data={[
|
|
|
- {
|
|
|
- date: '2019-07-12 \n 11:38:51',
|
|
|
- version: '数学机经-版本 7',
|
|
|
- content: '新增 7 道数学机经;补充第 23 题条件;\n 更新第 54题解析和答案',
|
|
|
- },
|
|
|
- ]}
|
|
|
+ data={updateList}
|
|
|
/>
|
|
|
- <Assets name="textbook_banner" />
|
|
|
+ <Assets name="textbook_banner" onClick={() => this.open(data.unUseRecord.id)} />
|
|
|
</div>
|
|
|
</div>
|
|
|
);
|
|
@@ -129,10 +428,10 @@ export default class extends Page {
|
|
|
<div className="compare-layout">
|
|
|
<div className="t-14 t-c t-s-32 m-b-2">让机经帮上忙,而不是帮倒忙!</div>
|
|
|
<div className="t-c m-b-2">
|
|
|
- <Button width={100} size="lager" radius className="m-r-2">
|
|
|
+ <Button width={100} size="lager" radius className="m-r-2" onClick={() => this.buy()}>
|
|
|
立刻购买
|
|
|
</Button>
|
|
|
- <Button width={100} size="lager" radius className="m-l-2">
|
|
|
+ <Button width={100} size="lager" radius className="m-l-2" onClick={() => linkTo('/examination?tab1=textbook')}>
|
|
|
试用往期
|
|
|
</Button>
|
|
|
</div>
|