浏览代码

Merge branch 'master' of git.proginn.com:zaixianjiaoyu/sourcecode

Go 5 年之前
父节点
当前提交
81a60476e6

+ 8 - 0
front/project/www/app.less

@@ -306,6 +306,10 @@
   color: #5E677BFF !important;
 }
 
+.t-14 {
+  color: #515258FF !important;
+}
+
 .b-c-1 {
   background: #F7F7F7;
 }
@@ -362,6 +366,10 @@
   font-size: 28px;
 }
 
+.t-s-32 {
+  font-size: 32px;
+}
+
 .l-h-20 {
   line-height: 20px;
 }

二进制
front/project/www/assets/textbook_banner.png


+ 138 - 1
front/project/www/components/Date/index.js

@@ -1,6 +1,7 @@
 import React, { Component } from 'react';
+import moment from 'moment';
 import './index.less';
-import { DatePicker } from 'antd';
+import { DatePicker, Calendar, Icon } from 'antd';
 
 export default class extends Component {
   constructor(props) {
@@ -53,3 +54,139 @@ export default class extends Component {
     );
   }
 }
+
+export class TwoDate extends Component {
+  constructor(props) {
+    super(props);
+    const today = moment();
+    this.state = {
+      key: 0,
+      value: today,
+      leftValue: today.clone().subtract(1, 'month'),
+      rightValue: today,
+    };
+  }
+
+  dateRender(date) {
+    const { checkRefresh } = this.props;
+    if (!this.loading && checkRefresh) {
+      if (checkRefresh(date, () => this.needRefresh())) {
+        this.loading = true;
+      }
+    }
+    return this.renderItem(date);
+  }
+
+  needRefresh() {
+    this.setState({ key: this.state.key + 1 });
+    this.loading = false;
+    setTimeout(() => {
+      this.setState({ key: this.state.key + 1 });
+    }, 1);
+  }
+
+  renderItem(date) {
+    const { value } = this.state;
+    const { getType } = this.props;
+    return (
+      <div
+        className={`ant-fullcalendar-date ${getType ? getType(date) : ''} ${value.diff(date) === 0 ? 'selected' : ''}`}
+      >
+        <div className="ant-fullcalendar-value">{date.get('date')}</div>
+      </div>
+    );
+  }
+
+  onLeftSelect(date) {
+    const { onChange } = this.props;
+    this.setState({
+      value: date,
+      leftValue: date,
+      rightValue: date.clone().add(1, 'month'),
+    });
+    if (onChange) onChange(date);
+  }
+
+  onRightSelect(date) {
+    const { onChange } = this.props;
+    this.setState({
+      value: date,
+      rightValue: date,
+      leftValue: date.clone().subtract(1, 'month'),
+    });
+    if (onChange) onChange(date);
+  }
+
+  leftHeadRender() {
+    const { leftValue } = this.state;
+    const { extendInfo } = this.props;
+    return (
+      <div className="t-c">
+        <div style={{ left: 15, top: 0 }} className="p-a">
+          <Icon
+            className="m-r-5"
+            type="double-left"
+            onClick={() => this.onLeftSelect(leftValue.clone().subtract(1, 'year'))}
+          />
+          <Icon type="left" onClick={() => this.onLeftSelect(leftValue.clone().subtract(1, 'month'))} />
+        </div>
+        <span>{leftValue.year()}年 </span>
+        <span>{leftValue.month()}月 </span>
+        <span className="t-4">{extendInfo && extendInfo(leftValue)}</span>
+      </div>
+    );
+  }
+
+  rightHeadRender() {
+    const { rightValue } = this.state;
+    const { extendInfo } = this.props;
+    return (
+      <div className="t-c">
+        <span>{rightValue.year()}年 </span>
+        <span>{rightValue.month()}月 </span>
+        <span className="t-4">{extendInfo && extendInfo(rightValue)}</span>
+        <div style={{ right: 15, top: 0 }} className="p-a">
+          <Icon type="right" onClick={() => this.onRightSelect(rightValue.clone().add(1, 'year'))} />
+          <Icon
+            className="m-l-5"
+            type="double-right"
+            onClick={() => this.onRightSelect(rightValue.clone().add(1, 'month'))}
+          />
+        </div>
+      </div>
+    );
+  }
+
+  render() {
+    const { disabledDate } = this.props;
+    const { leftValue, rightValue } = this.state;
+    return (
+      <div className="g-two-date">
+        <div className="g-two-head">
+          {this.leftHeadRender()}
+          {this.rightHeadRender()}
+        </div>
+        <div className="g-two-body">
+          <Calendar
+            fullscreen={false}
+            headerRender={data => this.leftHeadRender(data)}
+            value={leftValue}
+            disabledDate={disabledDate}
+            dateFullCellRender={date => this.dateRender(date)}
+            onSelect={date => this.onLeftSelect(date)}
+            onPanelChange={date => this.onLeftSelect(date)}
+          />
+          <Calendar
+            fullscreen={false}
+            headerRender={data => this.rightHeadRender(data)}
+            value={rightValue}
+            disabledDate={disabledDate}
+            dateFullCellRender={date => this.dateRender(date)}
+            onSelect={date => this.onRightSelect(date)}
+            onPanelChange={date => this.onRightSelect(date)}
+          />
+        </div>
+      </div>
+    );
+  }
+}

+ 84 - 0
front/project/www/components/Date/index.less

@@ -28,6 +28,7 @@
 
     .ant-calendar-body {
       cursor: pointer;
+
       table {
         th {
           height: 64px;
@@ -125,4 +126,87 @@
 
 .g-date-block.hide-input {
   height: 460px;
+}
+
+.g-two-date {
+  .g-two-head {
+    >div {
+      display: inline-block;
+      width: 50%;
+      height: 40px;
+      line-height: 40px;
+      color: #5E677BFF;
+      position: relative;
+
+      .i {
+        color: #00000073;
+      }
+    }
+  }
+
+  .g-two-body {
+    >div {
+      display: inline-block;
+      width: 50%;
+    }
+
+    >div:first-child {
+      .ant-fullcalendar-calendar-body {
+        border-right: 1px solid #d9d9d9;
+      }
+    }
+  }
+
+  .ant-fullcalendar table,
+  .ant-fullcalendar td,
+  .ant-fullcalendar th {
+    height: 30px;
+  }
+
+  .ant-fullcalendar-header {
+    display: none;
+  }
+
+  .ant-fullcalendar-selected-day .ant-fullcalendar-value {
+    color: rgba(0, 0, 0, .65);
+    background: #fff;
+  }
+
+  .ant-fullcalendar-today .ant-fullcalendar-value {
+    box-shadow: none;
+    border: 1px solid #4299FF;
+    border-radius: 12px;
+  }
+
+  .ant-fullcalendar-today.ant-fullcalendar-last-month-btn-day,
+  .ant-fullcalendar-today.ant-fullcalendar-next-month-btn-day {
+    .ant-fullcalendar-value {
+      border: none;
+    }
+  }
+
+  .ant-fullcalendar-cell {
+    .selected {
+      .ant-fullcalendar-value {
+        background: #4299FF;
+        color: #fff;
+        border-radius: 12px;
+      }
+    }
+  }
+
+  .ant-fullcalendar-value {
+    width: 36px;
+  }
+
+  .ant-fullcalendar-last-month-cell,
+  .ant-fullcalendar-next-month-cell,
+  .ant-fullcalendar-last-month-btn-day,
+  .ant-fullcalendar-next-month-btn-day {
+    .ant-fullcalendar-value {
+      color: rgba(0, 0, 0, .65) !important;
+      background: #fff !important;
+    }
+  }
+
 }

+ 142 - 57
front/project/www/components/Item/index.js

@@ -3,6 +3,7 @@ import './index.less';
 import Assets from '@src/components/Assets';
 import { getMap, formatSeconds } from '@src/services/Tools';
 import Button from '../Button';
+import More from '../More';
 import { Order } from '../../stores/order';
 import { User } from '../../stores/user';
 import { ServiceKey, ServiceParamMap, CrowdList } from '../../../Constant';
@@ -18,13 +19,11 @@ export class SingleItem extends Component {
   buy() {
     const { data } = this.props;
     User.needLogin().then(() => {
-      Order.speedPay({ productType: 'course', productId: data.id })
-        .then(result => {
-          User.needPay(result)
-            .then(() => {
-              linkTo('/my/course');
-            });
+      Order.speedPay({ productType: 'course', productId: data.id }).then(result => {
+        User.needPay(result).then(() => {
+          linkTo('/my/course');
         });
+      });
     });
   }
 
@@ -45,7 +44,8 @@ export class SingleItem extends Component {
       <div className="single-item">
         <div className="img" onClick={() => linkTo(`/course/detail/${data.id}`)}>
           <div className="title">
-            <div className="tag">{CrowdMap[data.crowd]}</div>{data.title}
+            <div className="tag">{CrowdMap[data.crowd]}</div>
+            {data.title}
           </div>
           <div className="left">
             <span>课时数: {data.noNumber}</span>
@@ -61,17 +61,38 @@ export class SingleItem extends Component {
           <span>有效期: {data.useExpireDays}天</span>
         </div>
         <div className="money">¥ {data.price}</div>
-        {!noAction && <div className="action">
-          {!data.have && <Button radius size="lager" onClick={() => this.buy()}>
-            立即购买
-            </Button>}
-          {data.have && <Button className="f-r" theme="default" radius size="lager" onClick={() => linkTo(`/course/detail/${data.id}`)}>
-            查看课程
-            </Button>}
-          {!data.have && <Button className="f-r" theme="default" disabled={data.add || add} radius size="lager" onClick={() => this.add()} >
-            <Assets name="add" />
-          </Button>}
-        </div>}
+        {!noAction && (
+          <div className="action">
+            {!data.have && (
+              <Button radius size="lager" onClick={() => this.buy()}>
+                立即购买
+              </Button>
+            )}
+            {data.have && (
+              <Button
+                className="f-r"
+                theme="default"
+                radius
+                size="lager"
+                onClick={() => linkTo(`/course/detail/${data.id}`)}
+              >
+                查看课程
+              </Button>
+            )}
+            {!data.have && (
+              <Button
+                className="f-r"
+                theme="default"
+                disabled={data.add || add}
+                radius
+                size="lager"
+                onClick={() => this.add()}
+              >
+                <Assets name="add" />
+              </Button>
+            )}
+          </div>
+        )}
         {!noAction && data.have && <Assets className="buyed" width={75} height={75} name="Purchased" />}
       </div>
     );
@@ -87,23 +108,20 @@ export class PackageItem extends Component {
   buy() {
     const { data } = this.props;
     User.needLogin().then(() => {
-      Order.speedPay({ productType: 'course_package', productId: data.id })
-        .then(result => {
-          User.needPay(result)
-            .then(() => {
-              linkTo('/my/course');
-            });
+      Order.speedPay({ productType: 'course_package', productId: data.id }).then(result => {
+        User.needPay(result).then(() => {
+          linkTo('/my/course');
         });
+      });
     });
   }
 
   add() {
     const { data } = this.props;
     User.needLogin().then(() => {
-      Order.addCheckout({ productType: 'course_package', productId: data.id })
-        .then(() => {
-          this.setState({ add: true });
-        });
+      Order.addCheckout({ productType: 'course_package', productId: data.id }).then(() => {
+        this.setState({ add: true });
+      });
     });
   }
 
@@ -121,15 +139,22 @@ export class PackageItem extends Component {
       <div className="package-item">
         <div className="block m-b-1" onClick={() => linkTo(`/course/package/detail/${data.id}`)}>
           <div className="title t-1 m-b-5 f-w-b">
-            <div hidden={!novice} className="tag f-w-d">新手</div>{data.title}
+            <div hidden={!novice} className="tag f-w-d">
+              新手
+            </div>
+            {data.title}
           </div>
           <div className="t-1 t-s-12 m-b-5">授课老师 {teachers.join(' ')}</div>
           <div className="t-1 t-s-12 m-b-2">{data.description}</div>
           <div className="t-1 t-s-12">包含课程</div>
           <div className="p-t-5">
-            {data.courses.map((course => {
-              return <div className="t m-b-1 t-4 m-r-5 t-s-12 d-i-b p-5">{course.title}({course.noNumber}课时)</div>;
-            }))}
+            {data.courses.map(course => {
+              return (
+                <div className="t m-b-1 t-4 m-r-5 t-s-12 d-i-b p-5">
+                  {course.title}({course.noNumber}课时)
+                </div>
+              );
+            })}
           </div>
           <div className="t-1 t-s-12">配套服务</div>
           <div className="p-t-5">
@@ -144,9 +169,17 @@ export class PackageItem extends Component {
                 const list = ServiceParamMap[row.value];
                 if (list) {
                   const map = getMap(list, 'value', 'label');
-                  return <div className="t m-b-1 t-4 m-r-5 t-s-12 d-i-b p-5">{row.label}×{map[data.gift[row.value]]}</div>;
+                  return (
+                    <div className="t m-b-1 t-4 m-r-5 t-s-12 d-i-b p-5">
+                      {row.label}×{map[data.gift[row.value]]}
+                    </div>
+                  );
                 }
-                return <div className="t m-b-1 t-4 m-r-5 t-s-12 d-i-b p-5">{row.label}×{data.gift[row.value]}</div>;
+                return (
+                  <div className="t m-b-1 t-4 m-r-5 t-s-12 d-i-b p-5">
+                    {row.label}×{data.gift[row.value]}
+                  </div>
+                );
               })}
           </div>
         </div>
@@ -158,7 +191,14 @@ export class PackageItem extends Component {
           <Button radius size="lager" onClick={() => this.buy()}>
             立即购买
           </Button>
-          <Button className="f-r" theme="default" radius size="lager" disabled={data.add || add} onClick={() => this.add()}>
+          <Button
+            className="f-r"
+            theme="default"
+            radius
+            size="lager"
+            disabled={data.add || add}
+            onClick={() => this.add()}
+          >
             <Assets name="add" />
           </Button>
         </div>
@@ -176,23 +216,20 @@ export class DataItem extends Component {
   buy() {
     const { data } = this.props;
     User.needLogin().then(() => {
-      Order.speedPay({ productType: 'data', productId: data.id })
-        .then(result => {
-          User.needPay(result)
-            .then(() => {
-              linkTo('/my/tools?tab=data');
-            });
+      Order.speedPay({ productType: 'data', productId: data.id }).then(result => {
+        User.needPay(result).then(() => {
+          linkTo('/my/tools?tab=data');
         });
+      });
     });
   }
 
   add() {
     const { data } = this.props;
     User.needLogin().then(() => {
-      Order.addCheckout({ productType: 'data', productId: data.id })
-        .then(() => {
-          this.setState({ add: true });
-        });
+      Order.addCheckout({ productType: 'data', productId: data.id }).then(() => {
+        this.setState({ add: true });
+      });
     });
   }
 
@@ -201,26 +238,74 @@ export class DataItem extends Component {
     const { add } = this.state;
     return (
       <div className="data-item">
-        <Assets width="309" height="264" name="" src={data.cover} onClick={() => linkTo(`/course/data/detail/${data.id}`)} />
+        <Assets
+          width="309"
+          height="264"
+          name=""
+          src={data.cover}
+          onClick={() => linkTo(`/course/data/detail/${data.id}`)}
+        />
         <div className="m-b-1">
           <span className="t-7 t-s-24 f-w-b">¥{data.price}</span>
           <span className="f-r t-8 t-s-20">{data.saleNumber}人</span>
         </div>
         <div className="action">
-          {!data.have && <Button radius size="lager" onClick={() => {
-            this.buy();
-          }}>
-            立即购买
-          </Button>}
-          {data.have && <Button className="f-r" theme="default" radius size="lager" onClick={() => openLink(data.resource)}>
-            查看资料
-          </Button>}
-          {!data.have && <Button className="f-r" theme="default" disabled={data.add || add} radius size="lager" onClick={() => this.add()}>
-            <Assets name="add" />
-          </Button>}
+          {!data.have && (
+            <Button
+              radius
+              size="lager"
+              onClick={() => {
+                this.buy();
+              }}
+            >
+              立即购买
+            </Button>
+          )}
+          {data.have && (
+            <Button className="f-r" theme="default" radius size="lager" onClick={() => openLink(data.resource)}>
+              查看资料
+            </Button>
+          )}
+          {!data.have && (
+            <Button
+              className="f-r"
+              theme="default"
+              disabled={data.add || add}
+              radius
+              size="lager"
+              onClick={() => this.add()}
+            >
+              <Assets name="add" />
+            </Button>
+          )}
         </div>
         {data.have && <Assets className="buyed" width={75} height={75} name="Purchased" />}
       </div>
     );
   }
 }
+
+export class TextbookItem extends Component {
+  constructor(props) {
+    super(props);
+    this.state = {};
+  }
+
+  render() {
+    const { data = {} } = this.props;
+    return (
+      <div className="textbook-item">
+        <Assets src={data.src} className="m-b-5" />
+        <div className="t-6 t-s-14 m-b-5">
+          已更新至 <span className="t-4">30</span> 题
+        </div>
+        <div className="t-6 t-s-12 m-b-1">
+          2019-08-31 09:26:13{' '}
+          <div className="f-r">
+            <More />
+          </div>
+        </div>
+      </div>
+    );
+  }
+}

+ 9 - 0
front/project/www/components/Item/index.less

@@ -163,4 +163,13 @@
     bottom: 15px;
     left: 15px;
   }
+}
+
+.textbook-item {
+  display: inline-block;
+  width: 350px;
+
+  >.assets {
+    height: 250px;
+  }
 }

+ 13 - 1
front/project/www/components/Other/index.js

@@ -5,6 +5,7 @@ import { Carousel } from 'antd-mobile';
 import Assets from '@src/components/Assets';
 import { formatDate } from '@src/services/Tools';
 import Button from '../Button';
+import Tabs from '../Tabs';
 import { User } from '../../stores/user';
 
 export class CommentFalls extends Component {
@@ -58,12 +59,23 @@ export class AnswerCarousel extends Component {
   }
 
   render() {
-    const { onFaq } = this.props;
+    const { onFaq, tabActive, tabs = [], onTabChange } = this.props;
     const { index } = this.state;
     const { list = [], hideBtn = false } = this.props;
     return (
       <div className="other-answer-carousel">
         <div className="body">
+          {tabs.length > 0 && (
+            <Tabs
+              type="tag"
+              theme="white"
+              tabs={tabs}
+              space={6}
+              width={86}
+              active={tabActive}
+              onChange={key => onTabChange && onTabChange(key)}
+            />
+          )}
           {list.length > 0 && (
             <Carousel selectedIndex={index} cellSpacing={40} dots={false} slideWidth={'350px'}>
               {list.map(item => {

+ 11 - 0
front/project/www/components/Other/index.less

@@ -122,6 +122,16 @@
     margin: 0 auto;
     position: relative;
 
+    .tabs {
+      text-align: left;
+      margin-bottom: 30px;
+
+      .tab {
+        padding-left: 10px;
+        padding-right: 10px;
+      }
+    }
+
     .fixed {
       position: absolute;
       top: 0;
@@ -179,6 +189,7 @@
   padding: 20px 0;
   position: relative;
   border-bottom: 1px solid #eee;
+
   .assets {
     border-radius: 50%;
     width: 60px;

+ 2 - 2
front/project/www/components/Tabs/index.less

@@ -176,8 +176,8 @@
 
   .tab {
     background: #fff;
-    color: #8897A8;
-    border: 1px solid #8897A8;
+    color: #7F8699FF;
+    border: 1px solid #E7EEF1FF;
   }
 
   .tab:hover,

+ 1 - 1
front/project/www/routes/textbook/main/index.js

@@ -1,5 +1,5 @@
 export default {
-  path: '/textbook/list',
+  path: '/textbook',
   key: 'textbook-index',
   title: '机经首页',
   needLogin: false,

+ 185 - 1
front/project/www/routes/textbook/main/index.less

@@ -1,3 +1,187 @@
 @charset "utf-8";
 
-#textbook-index {}
+#textbook-index {
+
+  .content {
+    width: 1140px !important;
+  }
+
+  .date-layout {
+    background: #fff;
+    padding-top: 30px;
+    padding-bottom: 10px;
+    overflow: hidden;
+
+    .b {
+      background: rgba(255, 255, 255, 1);
+      box-shadow: 0px 2px 8px 0px rgba(0, 0, 0, 0.06);
+      border-radius: 4px;
+      height: 315px;
+    }
+
+    .date-info {
+      height: 40px;
+      line-height: 40px;
+      border-bottom: 1px solid #d9d9d9;
+      padding: 0 15px;
+
+      span {
+        margin-right: 20px;
+        display: inline-block;
+        position: relative;
+      }
+
+      .today::before {
+        content: '';
+        width: 10px;
+        height: 10px;
+        display: inline-block;
+        border: 1px solid #4299FF;
+        border-radius: 50%;
+        margin-right: 8px;
+      }
+
+      .type-1::before {
+        content: '';
+        width: 10px;
+        height: 10px;
+        display: inline-block;
+        background: #FFB231FF;
+        border-radius: 50%;
+        margin-right: 8px;
+      }
+
+      .type-2::before {
+        content: '';
+        width: 10px;
+        height: 10px;
+        display: inline-block;
+        background: #4299FF;
+        border-radius: 50%;
+        margin-right: 8px;
+        opacity: 0.59;
+      }
+    }
+
+    .g-two-date {
+      .ant-fullcalendar-cell {
+        .type-1 {
+          .ant-fullcalendar-value {
+            background: #FFB231FF;
+            color: #fff;
+            border-radius: 12px;
+          }
+        }
+
+        .type-2 {
+          .ant-fullcalendar-value {
+            background: #4299FF;
+            color: #fff;
+            border-radius: 12px;
+            opacity: 0.59;
+          }
+        }
+      }
+    }
+
+    .f-r {
+      .button {
+        padding: 6px 0;
+      }
+    }
+  }
+
+  .compare-layout {
+    padding-top: 20px;
+    padding-bottom: 80px;
+    background: #fff;
+
+    .button {
+      padding: 6px 0;
+    }
+
+    .table {
+      width: 1100px;
+      margin: 0 auto;
+      text-align: center;
+
+      table {
+        width: 100%;
+      }
+
+      th {
+        height: 96px;
+        line-height: 96px;
+        width: 555px;
+        font-size: 20px;
+        font-weight: bold;
+        background: #F1F3F7FF;
+      }
+
+      td {
+        height: 64px;
+        line-height: 64px;
+        font-size: 18px;
+      }
+
+      th:first-child,
+      td:first-child {
+        font-weight: bold;
+      }
+
+      th:first-child {
+        background: #D8EEFFFF;
+        color: #637DA3FF;
+      }
+
+      td:first-child {
+        background: #F9FDFFFF;
+        color: #637DA3FF;
+      }
+
+      tr:nth-of-type(even) {
+        background: #FAFAFA;
+
+        td:first-child {
+          background: #F1F9FFFF;
+        }
+      }
+    }
+  }
+
+  .list-layout {
+    margin: 0 -15px;
+    padding-bottom: 70px;
+    padding-top: 20px;
+    background: #fff;
+
+    .textbook-item {
+      margin: 0 15px;
+      margin-bottom: 15px;
+    }
+  }
+
+  .table-layout {
+    background: #fff;
+    padding-top: 20px;
+    padding-bottom: 30px;
+
+    .t {
+      line-height: 44px;
+      height: 44px;
+    }
+
+    .tabs {
+      display: inline-block;
+      padding-left: 20px;
+    }
+
+    .user-table {
+      margin-bottom: 20px;
+    }
+  }
+
+  .other-answer-carousel {
+    padding-top: 40px;
+  }
+}

+ 170 - 1
front/project/www/routes/textbook/main/page.js

@@ -1,9 +1,178 @@
 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 { CommentFalls, AnswerCarousel, Consultation, Contact } from '../../../components/Other';
+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';
 
 export default class extends Page {
+  initState() {
+    return {
+      list: [{}, {}, {}],
+    };
+  }
+
   renderView() {
-    return <div>1</div>;
+    return (
+      <div>
+        {this.renderDate()}
+        {this.renderLog()}
+        {this.renderCompare()}
+        {this.renderList()}
+        <AnswerCarousel
+          hideBtn
+          tabActive={'1'}
+          tabs={[{ title: '换库知识', key: '1' }, { title: '机经知识', key: '2' }, { title: '千行机经', key: '3' }]}
+        />
+        <CommentFalls />
+        <Consultation />
+        <Contact />
+        <Footer />
+      </div>
+    );
+  }
+
+  renderDate() {
+    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>
+              <Button size="small" radius>
+                我已报考
+              </Button>
+              <Link to="" className="f-r">
+                按年份查看 >
+              </Link>
+            </div>
+            <TwoDate
+              getType={date => (date.date() === 1 ? 'type-1' : 'type-2')}
+              extendInfo={date => `${date.month()}人`}
+              onChange={() => {}}
+            />
+          </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-c t-s-16">
+              已换库 <span className="t-4">10</span> 天
+            </div>
+            <div className="m-t-2 t-c">
+              <Button width={100} radius size="lager">
+                我的机经
+              </Button>
+            </div>
+          </div>
+        </div>
+      </div>
+    );
+  }
+
+  renderList() {
+    const { list } = this.state;
+    return (
+      <div className="list-layout">
+        <div className="content">
+          {list.map(item => {
+            return <TextbookItem data={item} />;
+          })}
+        </div>
+      </div>
+    );
+  }
+
+  renderLog() {
+    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={[{ title: '数学', key: '1' }, { title: '阅读RC', key: '2' }, { title: '逻辑RC', key: '3' }]}
+              active="1"
+            />
+          </div>
+          <UserTable
+            size="small"
+            columns={[
+              { title: '更新时间', key: 'date' },
+              { title: '版本', key: 'version' },
+              { title: '更新内容', key: 'content' },
+            ]}
+            data={[
+              {
+                date: '2019-07-12 \n 11:38:51',
+                version: '数学机经-版本 7',
+                content: '新增 7 道数学机经;补充第 23 题条件;\n 更新第 54题解析和答案',
+              },
+            ]}
+          />
+          <Assets name="textbook_banner" />
+        </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">
+            立刻购买
+          </Button>
+          <Button width={100} size="lager" radius className="m-l-2">
+            试用往期
+          </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>
+    );
   }
 }