import React from 'react'; 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, TextbookSubject } 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 { tab: 'baselibrary', list: [], enroll: {}, load: 0, subject: TextbookSubject[0].value, textbookSubject: TextbookSubject.map(row => { return { title: row.label, key: row.value, }; }), }; } 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 }); if (!result.hasService && result.unUseRecord) { this.textbookHistory({ subject: this.state.subject, showUpdate: false }); } }); } 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, showUpdate = true }) { this.setState({ subject }); Textbook.allHistory(subject).then(result => { this.setState({ showUpdate, 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()} {!data.hasService && data.unUseRecord && this.renderLog()} {!data.hasService && !data.unUseRecord && this.renderCompare()} {data.hasService && this.renderList()} <AnswerCarousel hideBtn tabActive={tab} list={faqs} tabs={[{ title: '换库知识', key: 'baselibrary' }, { title: '机经知识', key: 'basetextbook' }, { title: '千行机经', key: 'qxtextbook' }]} onTabChange={(key) => this.onTabChange(key)} /> <CommentFalls list={comments} /> <Consultation data={base.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, feedback: {}, showFinish: true })} onCancel={() => this.setState({ showFeedback: false, feedback: {} })} onClose={() => this.setState({ showFeedback: false, feedback: {} })} /> <CommentModal show={showComment} defaultData={comment} onConfirm={() => this.setState({ showComment: false, comment: {}, showFinish: true })} onCancel={() => this.setState({ showComment: false, comment: {} })} onClose={() => this.setState({ showComment: false, comment: {} })} /> <FaqModal show={showFaq} defaultData={faq} onCancel={() => this.setState({ showFaq: false, faq: {} })} onConfirm={() => this.setState({ showFaq: false, faq: {}, showFinish: true })} /> <FinishModal 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"> <div style={{ width: 845 }} className="b f-l"> <div className="date-info"> <span className="today">今日</span> <span className="type-1">换库</span> <span className="type-2">考试日</span> {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="/textbook/year" className="f-r"> 按年份查看 > </Link> </div> <TwoDate 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">{latest.startDate ? formatDate(latest.startDate, 'YYYY-MM-DD') : ''}</div> <div className="t-13 t-c t-s-16"> 已换库 <span className="t-4">{day}</span> 天 </div> <div className="m-t-2 t-c"> <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> ); } renderList() { const { list } = this.state; return ( <div className="list-layout"> <div className="content"> {list.map(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> ); } renderLog() { const { data, subject, updateList, textbookSubject } = this.state; return ( <div className="table-layout"> <div className="content"> <div className="t"> <span className="d-i-b t-1 t-s-18">更新日志</span> <Tabs type="text" tabs={textbookSubject} active={subject} onChange={(key) => this.textbookHistory({ subject: key, showUpdate: false })} /> </div> <UserTable size="small" columns={textbookHistoryColumns} data={updateList} /> <Assets name="textbook_banner" onClick={() => this.open(data.unUseRecord.id)} /> </div> </div> ); } renderCompare() { return ( <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" onClick={() => this.buy()}> 立刻购买 </Button> <Button width={100} size="lager" radius className="m-l-2" onClick={() => linkTo('/examination?tab1=textbook')}> 试用往期 </Button> </div> <div className="table"> <table> <thead> <tr> <th>千行机经</th> <th>其他机经</th> </tr> </thead> <tbody> <tr> <td>整理内容+梳理逻辑结构</td> <td>只关注内容</td> </tr> <tr> <td>最新版本自动更新至邮箱</td> <td>手动领取</td> </tr> <tr> <td>重视考场一手信息,越准越好</td> <td>越多越好</td> </tr> <tr> <td>独家资源,严格把关</td> <td>市面资源</td> </tr> <tr> <td>一键反馈,随时沟通</td> <td>无售后系统</td> </tr> <tr> <td>下载至本地、在线浏览、在线做题,多种查阅方式</td> <td>下载至本地</td> </tr> </tbody> </table> </div> </div> ); } }