浏览代码

fix style

KaysonCui 5 年之前
父节点
当前提交
947e436ab7

文件差异内容过多而无法显示
+ 2327 - 2349
front/package-lock.json


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

@@ -58,6 +58,10 @@
   font-weight: bold;
 }
 
+.f-w-d {
+  font-weight: 500;
+}
+
 .t-l {
   text-align: left;
 }

+ 3 - 3
front/project/www/components/Date/index.js

@@ -17,7 +17,7 @@ export default class extends Component {
       }
     }
     if (dateRender) return dateRender(date);
-    return date.get('date');
+    return <div className="ant-calendar-date">{date.get('date')}</div>;
   }
 
   needRefresh() {
@@ -29,12 +29,12 @@ export default class extends Component {
   }
 
   render() {
-    const { hideInput, disabledDate } = this.props;
+    const { hideInput, disabledDate, theme = '' } = this.props;
     return (
       <div className={`g-date-block ${hideInput ? 'hide-input' : ''}`}>
         <DatePicker
           open
-          dropdownClassName={`g-date ${hideInput ? 'hide-input' : ''}`}
+          dropdownClassName={`g-date ${theme} ${hideInput ? 'hide-input' : ''}`}
           disabledDate={disabledDate}
           dateRender={date => this.dateRender(date)}
         />

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

@@ -66,9 +66,12 @@
 
       .ant-calendar-today .ant-calendar-date {
         border-color: #fff;
+        color: rgba(0, 0, 0, .65);
+        font-weight: 400;
       }
 
       .ant-calendar-selected-date .ant-calendar-date,
+      .ant-calendar-selected-day .ant-calendar-date,
       .ant-calendar-selected-date.ant-calendar-today .ant-calendar-date {
         color: #1890ff;
         font-weight: 700;
@@ -87,6 +90,23 @@
   }
 }
 
+.g-date.filled {
+
+  .ant-calendar {
+
+    .ant-calendar-body {
+
+      .ant-calendar-selected-date .ant-calendar-date,
+      .ant-calendar-selected-day .ant-calendar-date,
+      .ant-calendar-selected-date.ant-calendar-today .ant-calendar-date {
+        color: #fff;
+        background: #4299FF;
+      }
+    }
+  }
+
+}
+
 .g-date.hide-input {
 
   .ant-calendar-input-wrap {

+ 21 - 17
front/project/www/components/Examination/index.js

@@ -39,10 +39,9 @@ export default class extends Component {
       },
     };
     this.state = { step: 0, data: {} };
-    My.getPrepare()
-      .then(result => {
-        this.setState({ data: result, first: !result.prepareStatus });
-      });
+    My.getPrepare().then(result => {
+      this.setState({ data: result, first: !result.prepareStatus });
+    });
   }
 
   onChange(type, key) {
@@ -63,11 +62,10 @@ export default class extends Component {
 
   submitPrepare() {
     const { data } = this.state;
-    My.editPrepare(data)
-      .then(result => {
-        this.setState({ result });
-        this.onNext();
-      });
+    My.editPrepare(data).then(result => {
+      this.setState({ result });
+      this.onNext();
+    });
   }
 
   render() {
@@ -155,15 +153,19 @@ export default class extends Component {
   renderStep3() {
     return (
       <div className="step-3-layout">
-        <Date />
+        <Date theme="filled" />
         <div className="action-layout">
           <div className="prev" onClick={() => this.onPrev()}>
             <Icon type="left-circle" theme="filled" />
             上一题
           </div>
-          <Button size="lager" radius onClick={() => {
-            this.submitPrepare();
-          }}>
+          <Button
+            size="lager"
+            radius
+            onClick={() => {
+              this.submitPrepare();
+            }}
+          >
             提交
           </Button>
         </div>
@@ -175,10 +177,12 @@ export default class extends Component {
     const { first, data } = this.state;
     return (
       <div className="step-4-layout">
-        {first && <div className="tip">
-          <Icon type="check" />
-          7天VIP权限已赠送至您的账户。
-        </div>}
+        {first && (
+          <div className="tip">
+            <Icon type="check" />
+            7天VIP权限已赠送至您的账户。
+          </div>
+        )}
         <Ratio
           text="身份"
           subtext={PrepareStatusMap[data.prepareStatus]}

+ 10 - 0
front/project/www/components/UserTable/index.less

@@ -90,6 +90,16 @@
   }
 }
 
+.user-table.odd {
+  tbody {
+    overflow-y: auto;
+
+    tr:nth-of-type(odd) {
+      background: #FBFBFB;
+    }
+  }
+}
+
 .user-table.dark {
   tr {
     background: #ECEDEE;

+ 2 - 2
front/project/www/local.json

@@ -8,7 +8,7 @@
     ],
     "proxy": [
       {
-        "target": "http://127.0.0.1:8888",
+        "target": "http://qianxing.nuliji.com",
         "from": "/api",
         "to": "/api"
       }
@@ -30,4 +30,4 @@
       "http://res.wx.qq.com/connect/zh_CN/htmledition/js/wxLogin.js"
     ]
   }
-}
+}

+ 339 - 1
front/project/www/routes/my/collect/page.js

@@ -1,9 +1,347 @@
 import React from 'react';
 import './index.less';
+import { Icon, Checkbox } from 'antd';
 import Page from '@src/containers/Page';
+import UserLayout from '../../../layouts/User';
+import UserTable from '../../../components/UserTable';
+import UserAction from '../../../components/UserAction';
+import menu from '../index';
+import Tabs from '../../../components/Tabs';
+import Modal from '../../../components/Modal';
+import Select from '../../../components/Select';
+import GIcon from '../../../components/Icon';
+
+const columns = [
+  { key: '', title: '题型', fixSort: true },
+  { key: '', title: '题目ID', fixSort: true },
+  { key: '', title: '内容' },
+  { key: '', title: '耗时', sort: true },
+  { key: '', title: '错误率', sort: true },
+  { key: '', title: '最近做题' },
+  {
+    key: '',
+    title: '',
+    render() {
+      return [<GIcon name="star" className="m-r-5" />, <GIcon name="note" />];
+    },
+  },
+];
+
+const exportType = [
+  { key: '1', title: '题目' },
+  { key: '2', title: '官方解析' },
+  { key: '3', title: '我的笔记' },
+  { key: '4', title: '千行解析', auth: true },
+  { key: '5', title: '题源联想', auth: true },
+  { key: '6', title: '相关问答', auth: true },
+];
 
 export default class extends Page {
+  initState() {
+    return {
+      tab: '1',
+      filterMap: {},
+      sortMap: {},
+      data: [{}, {}],
+      selectList: [],
+      allChecked: false,
+      page: 1,
+      total: 1,
+    };
+  }
+
+  onChangeTab(tab) {
+    this.setState({ tab });
+  }
+
+  onFilter(value) {
+    this.setState({ filterMap: value });
+  }
+
+  onSort(value) {
+    this.setState({ sortMap: value });
+  }
+
+  onDataChange(page) {
+    this.setState({ page, allChecked: false, selectList: [] });
+  }
+
+  onAll(checked) {
+    if (checked) {
+      const { data = [] } = this.state;
+      const list = [];
+      data.forEach(item => {
+        list.push(item.key);
+      });
+      this.setState({ selectList: list, allChecked: true });
+    } else {
+      this.setState({ selectList: [], allChecked: false });
+    }
+  }
+
+  onAction() {}
+
+  onSelect(selectList) {
+    this.setState({ selectList });
+  }
+
   renderView() {
-    return <div />;
+    const { config } = this.props;
+    return <UserLayout active={config.key} menu={menu} center={this.renderTable()} />;
+  }
+
+  renderTable() {
+    const { tab } = this.state;
+    return (
+      <div className="table-layout">
+        <Tabs
+          border
+          type="division"
+          theme="theme"
+          size="small"
+          space={2.5}
+          width={100}
+          active={tab}
+          tabs={[{ key: '1', title: '题目' }, { key: '2', title: '文章' }]}
+          onChange={key => this.onChangeTab(key)}
+        />
+        {this[`renderTab${tab}`]()}
+        {this.renderModal()}
+      </div>
+    );
+  }
+
+  renderTab1() {
+    const { filterMap = {}, sortMap = {}, selectList = [], data = [], allChecked, page, total } = this.state;
+    return (
+      <div className="tab-1-layout">
+        <UserAction
+          search
+          selectList={[
+            {
+              label: '123',
+              key: 'one',
+              select: [{ title: '123', key: '1' }, { title: '123', key: '2' }, { title: '123', key: '2' }],
+            },
+            {
+              label: '123',
+              children: [
+                {
+                  key: '3',
+                  default: '1',
+                  select: [{ title: '123', key: '1' }, { title: '123', key: '2' }, { title: '123', key: '2' }],
+                },
+                {
+                  key: 'two',
+                  be: 'one',
+                  placeholder: '全部',
+                  selectMap: {
+                    1: [{ title: '123', key: '1' }, { title: '123', key: '2' }, { title: '123', key: '2' }],
+                  },
+                },
+              ],
+            },
+          ]}
+          filterMap={filterMap}
+          onFilter={value => this.onFilter(value)}
+        />
+        <UserAction
+          allCheckbox
+          allChecked={allChecked}
+          help
+          btnList={[
+            { title: '移除', key: 'remove' },
+            { title: '组卷', key: 'group', tag: 'vip' },
+            { title: '导出', key: 'export', tag: 'vip', disabled: true },
+          ]}
+          right={
+            <div className="tip">
+              2019-06-03 15:30 组卷50题,做对30题。<span>移除正确题目</span>
+              <Icon type="close-circle" theme="filled" />
+            </div>
+          }
+          onAll={checked => this.onAll(checked)}
+          onAction={key => this.onAction(key)}
+        />
+        <UserTable
+          select
+          columns={columns}
+          sortMap={sortMap}
+          data={data}
+          current={page}
+          total={total}
+          selectList={selectList}
+          onSelect={l => this.onSelect(l)}
+          onSort={v => this.onSort(v)}
+          onChange={p => this.onDataChange(p)}
+        />
+      </div>
+    );
+  }
+
+  renderTab2() {
+    const { filterMap = {}, sortMap = {}, selectList = [], data = [], allChecked, page, total } = this.state;
+    return (
+      <div className="tab-1-layout">
+        <UserAction
+          search
+          selectList={[
+            {
+              label: '123',
+              key: 'one',
+              select: [{ title: '123', key: '1' }, { title: '123', key: '2' }, { title: '123', key: '2' }],
+            },
+            {
+              label: '123',
+              children: [
+                {
+                  key: '3',
+                  default: '1',
+                  select: [{ title: '123', key: '1' }, { title: '123', key: '2' }, { title: '123', key: '2' }],
+                },
+                {
+                  key: 'two',
+                  be: 'one',
+                  placeholder: '全部',
+                  selectMap: {
+                    1: [{ title: '123', key: '1' }, { title: '123', key: '2' }, { title: '123', key: '2' }],
+                  },
+                },
+              ],
+            },
+          ]}
+          filterMap={filterMap}
+          onFilter={value => this.onFilter(value)}
+        />
+        <UserAction
+          allCheckbox
+          allChecked={allChecked}
+          help
+          btnList={[
+            { title: '移除', key: 'remove' },
+            { title: '组卷', key: 'group', tag: 'vip' },
+            { title: '导出', key: 'export', tag: 'vip', disabled: true },
+          ]}
+          right={
+            <div className="tip">
+              2019-06-03 15:30 组卷50题,做对30题。<span>移除正确题目</span>
+              <Icon type="close-circle" theme="filled" />
+            </div>
+          }
+          onAll={checked => this.onAll(checked)}
+          onAction={key => this.onAction(key)}
+        />
+        <UserTable
+          select
+          columns={columns}
+          sortMap={sortMap}
+          data={data}
+          current={page}
+          total={total}
+          selectList={selectList}
+          onSelect={l => this.onSelect(l)}
+          onSort={v => this.onSort(v)}
+          onChange={p => this.onDataChange(p)}
+        />
+      </div>
+    );
+  }
+
+  renderModal() {
+    return [
+      <Modal title="操作提示" confirmText="好的,知道了" btnAlign="center" onConfirm={() => {}}>
+        <div className="flex-layout m-b-2">
+          <div className="flex-block">
+            <div className="t-1 t-s-18">组卷功能</div>
+            <div className="t-2">操作数量:10-50;</div>
+            <div className="t-2">注意事项:可跨题型、不可跨学科。</div>
+          </div>
+          <div className="flex-block">
+            <div className="t-1 t-s-18">导出功能</div>
+            <div className="t-2">操作数量:1-100;</div>
+            <div className="t-2">注意事项:“综合推理IR”暂时无法导出。</div>
+          </div>
+        </div>
+
+        <div className="t-3">
+          *您可点击
+          <Icon type="question-circle" theme="filled" />
+          查阅以上信息。
+        </div>
+      </Modal>,
+      <Modal title="组卷练习" confirmText="好的,知道了" btnAlign="center" onConfirm={() => {}}>
+        <div className="t-2 t-s-18">不可同时选中语文题和数学题,请重新选择。</div>
+      </Modal>,
+      <Modal title="组卷练习" confirmText="开始练习" onConfirm={() => {}} onCancel={() => {}}>
+        <div className="t-2 t-s-18">
+          您共选择了 <span className="t-4">50</span> 道题目,是否开始练习?
+        </div>
+        <div className="t-2 t-s-16">
+          <Checkbox checked className="m-r-5" />
+          剔除已组卷练习 <Select
+            theme="white"
+            value="1"
+            list={[{ key: '1', title: '2' }, { key: '2', title: '3' }]}
+          />{' '}
+          次以上的错题
+        </div>
+      </Modal>,
+      <Modal title="移出" onConfirm={() => {}} onCancel={() => {}}>
+        <div className="t-2 t-s-18">
+          当前选中的 <span className="t-4">50</span> 道题即将被移出错题本,移出后无法恢复,是否继续?
+        </div>
+      </Modal>,
+      <Modal title="导出" confirmText="好的,知道了" btnAlign="center" onConfirm={() => {}}>
+        <div className="t-2 t-s-18">正在下载中,请不要关闭当前页面!</div>
+      </Modal>,
+      <Modal title="导出" confirmText="导出" onConfirm={() => {}} onCancel={() => {}}>
+        <div className="t-2 t-s-18 m-b-5">
+          当前共选中 <span className="t-4">50</span> 道题,请确认需要导出的内容:
+        </div>
+        <div className="t-2 t-s-16">
+          {exportType.map(item => {
+            return (
+              <div className="d-i-b m-b-5" style={{ width: 135 }}>
+                <Checkbox checked className="m-r-5" />
+                {item.title}
+              </div>
+            );
+          })}
+        </div>
+      </Modal>,
+      <Modal title="导出" confirmText="导出" onConfirm={() => {}} onCancel={() => {}}>
+        <div className="t-2 t-s-18 m-b-5">
+          当前共选中 <span className="t-4">50</span> 道题,请确认需要导出的内容:
+        </div>
+        <div className="t-2 t-s-16 m-b-2">
+          {exportType
+            .filter(item => !item.auth)
+            .map(item => {
+              return (
+                <div className="d-i-b m-b-2" style={{ width: 135 }}>
+                  <Checkbox checked className="m-r-5" />
+                  {item.title}
+                </div>
+              );
+            })}
+        </div>
+        <div className="b-b m-b-2 m-t-2" />
+        <div className="t-3 m-b-1">
+          以下内容需实名认证后才可导出: <a className="f-r">去认证 ></a>
+        </div>
+        <div className="t-2 t-s-16 m-b-2">
+          {exportType
+            .filter(item => item.auth)
+            .map(item => {
+              return (
+                <div className="d-i-b" style={{ width: 135 }}>
+                  <Checkbox disabled className="m-r-5" />
+                  {item.title}
+                </div>
+              );
+            })}
+        </div>
+      </Modal>,
+    ];
   }
 }

+ 1 - 1
front/project/www/routes/my/course/page.js

@@ -99,7 +99,7 @@ export default class extends Page {
           onChange={key => this.refresh(tab1, key)}
         />
         {this[`renderTab${tab1}`]()}
-        <Modal show className="clock-modal" title="打卡表" width={460} onClose={() => {}}>
+        <Modal className="clock-modal" title="打卡表" width={460} onClose={() => {}}>
           <div>
             <div className="d-i-b w-3">
               <div className="t-2 t-s-14">听课频率</div>

+ 9 - 0
front/project/www/routes/my/main/index.less

@@ -99,9 +99,18 @@
         top: 30px;
       }
 
+      .title {
+        border-left: 5px solid #8D65FD;
+        line-height: 16px;
+      }
+
       .table {
         padding-top: 4px;
         padding-bottom: 24px;
+
+        td {
+          font-size: 12px;
+        }
       }
     }
   }

+ 275 - 109
front/project/www/routes/my/main/page.js

@@ -55,23 +55,77 @@ class LogItem extends Component {
   }
 
   renderExercise() {
-    const { data = {} } = this.props;
-    const { detail = [] } = data;
     const { open } = this.state;
-    return <div hidden={!open} className="table">
-      <UserTable size="small" columns={this.columns} data={detail} />
-      <div className="t-r">
-        <Link to="/exercise">继续练习></Link>
+    return (
+      <div hidden={!open} className="table">
+        <UserTable size="small" columns={this.columns} data={[{ title: '123' }]} />
+        <div className="t-r">
+          <Link to="/exercise">继续练习></Link>
+        </div>
       </div>
-    </div>;
+    );
   }
 
   renderExamination() {
-
+    const { open } = this.state;
+    return (
+      <div hidden={!open} className="table">
+        <div className="title p-l-5 m-b-1 t-1 t-s-18 f-w-b">
+          千行-CAT01<div className="f-r t-3 t-s-12 f-w-d">2019-05-16 16:21:06</div>
+        </div>
+        <UserTable
+          size="small"
+          columns={[
+            { key: '1', title: '' },
+            { key: '2', title: 'Tobal' },
+            { key: '3', title: 'IR' },
+            { key: '4', title: 'Verbal' },
+            { key: '5', title: 'Quant' },
+          ]}
+          data={[{ title: '123' }]}
+        />
+        <div className="title p-l-5 m-b-1 t-1 t-s-18 f-w-b m-t-2">
+          净化版GWD-CAT01 <div className="f-r t-3 t-s-12 f-w-d">2019-05-16 16:21:06</div>
+        </div>
+        <UserTable
+          size="small"
+          columns={[
+            { key: '1', title: '' },
+            { key: '2', title: 'Tobal' },
+            { key: '3', title: 'IR' },
+            { key: '4', title: 'Verbal' },
+            { key: '5', title: 'Quant' },
+          ]}
+          data={[{ title: '123' }]}
+        />
+        <div className="t-r">
+          <Link to="/exercise">继续练习></Link>
+        </div>
+      </div>
+    );
   }
 
   renderCourse() {
-
+    const { open } = this.state;
+    return (
+      <div hidden={!open} className="table">
+        <UserTable
+          header={false}
+          size="small"
+          even="odd"
+          columns={[{ key: '1', width: 100 }, { key: '2', width: 310 }, { key: '3', width: 120 }]}
+          data={[
+            { 1: '语法SC', 2: '课时3:代词的指代', 3: '2019-04-27\n 15:14:29' },
+            { 1: '逻辑 RC', 2: '课时3:代词的指代', 3: '2019-04-27\n 15:14:29' },
+            { 1: '阅读CR', 2: '课时3:代词的指代', 3: '2019-04-27\n 15:14:29' },
+            { 1: '逻辑 RC', 2: '课时3:代词的指代', 3: '2019-04-27\n 15:14:29' },
+          ]}
+        />
+        <div className="t-r">
+          <Link to="/exercise">继续练习></Link>
+        </div>
+      </div>
+    );
   }
 }
 
@@ -142,32 +196,35 @@ export default class extends Page {
     });
     My.getStudyWeek(0).then(latest => {
       const diff = latest.time - latest.avgTime;
-      const diffPercent = diff > 0 ? formatPercent(latest.time - latest.avgTime, latest.avgTime, true) : formatPercent(latest.avgTime - latest.time, latest.avgTime, true);
+      const diffPercent =
+        diff > 0
+          ? formatPercent(latest.time - latest.avgTime, latest.avgTime, true)
+          : formatPercent(latest.avgTime - latest.time, latest.avgTime, true);
       this.setState({ latest, diff, diffPercent });
       My.getStudyWeek(1).then(last => {
         const diffLast = latest.time - last.time;
-        const diffLastPercent = diffLast > 0 ? formatPercent(latest.time - last.time, last.time, true) : formatPercent(last.time - latest.time, last.time, true);
+        const diffLastPercent =
+          diffLast > 0
+            ? formatPercent(latest.time - last.time, last.time, true)
+            : formatPercent(last.time - latest.time, last.time, true);
         this.setState({ last, diffLast, diffLastPercent });
       });
     });
     // 获取广告
-    Main.getAd('my-self')
-      .then(result => {
-        this.setState({ ads: result });
-      });
+    Main.getAd('my-self').then(result => {
+      this.setState({ ads: result });
+    });
     // 获取未读消息
-    My.message({ page: 1, size: 2, read: 0 })
-      .then(result => {
-        this.setState({ messages: result.list });
-      });
+    My.message({ page: 1, size: 2, read: 0 }).then(result => {
+      this.setState({ messages: result.list });
+    });
     this.refreshDay(this.state.day);
   }
 
   readAllMessage() {
-    My.readAllMessage()
-      .then(() => {
-        asyncSMessage('操作成功');
-      });
+    My.readAllMessage().then(() => {
+      asyncSMessage('操作成功');
+    });
   }
 
   refreshDay(value) {
@@ -177,10 +234,14 @@ export default class extends Page {
         time = moment().format('YYYY-MM-DD');
         break;
       case 'yesterday':
-        time = moment().add(-1, 'days').format('YYYY-MM-DD');
+        time = moment()
+          .add(-1, 'days')
+          .format('YYYY-MM-DD');
         break;
       case 'before':
-        time = moment().add(-2, 'days').format('YYYY-MM-DD');
+        time = moment()
+          .add(-2, 'days')
+          .format('YYYY-MM-DD');
         break;
       default:
         time = value.format('YYYY-MM-DD');
@@ -196,14 +257,38 @@ export default class extends Page {
         type: 'exercise',
         total: [
           { title: '<span>练习和订正</span>', width: 130 },
-          { title: result.exerciseTime ? formatSeconds(result.exerciseTime).replace(/([0-9]+)(m|min|h|hour|s)/g, '<b>$1</b>$2') : '<b>-</b>', width: 90 },
+          {
+            title: result.exerciseTime
+              ? formatSeconds(result.exerciseTime).replace(/([0-9]+)(m|min|h|hour|s)/g, '<b>$1</b>$2')
+              : '<b>-</b>',
+            width: 90,
+          },
           { title: `<b>${result.exerciseQuestion || '-'}</b>题`, width: 80 },
-          { title: `超过了<b>${result.exerciseExceed ? formatPercent(result.exerciseExceed.rank, result.exerciseExceed.total) : '-%'}</b>的用户` },
+          {
+            title: `超过了<b>${
+              result.exerciseExceed ? formatPercent(result.exerciseExceed.rank, result.exerciseExceed.total) : '-%'
+            }</b>的用户`,
+          },
         ],
         detail: [
-          { title: '做题数', sc: exerciseMap.sc ? exerciseMap.sc.number : '-', cr: exerciseMap.cr ? exerciseMap.cr.number : '-', rc: exerciseMap.rc ? exerciseMap.rc.number : '-' },
-          { title: '平均正确率', sc: exerciseMap.sc ? formatPercent(exerciseMap.sc.correct, exerciseMap.sc.number) : '-%', cr: exerciseMap.cr ? formatPercent(exerciseMap.cr.correct, exerciseMap.cr.number) : '-%', rc: exerciseMap.rc ? formatPercent(exerciseMap.rc.correct, exerciseMap.rc.number) : '-%' },
-          { title: '平均用时', sc: exerciseMap.sc ? exerciseMap.sc.time / exerciseMap.sc.number : '-', cr: exerciseMap.cr ? exerciseMap.cr.time / exerciseMap.cr.number : '-', rc: exerciseMap.rc ? exerciseMap.rc.time / exerciseMap.rc.number : '-' },
+          {
+            title: '做题数',
+            sc: exerciseMap.sc ? exerciseMap.sc.number : '-',
+            cr: exerciseMap.cr ? exerciseMap.cr.number : '-',
+            rc: exerciseMap.rc ? exerciseMap.rc.number : '-',
+          },
+          {
+            title: '平均正确率',
+            sc: exerciseMap.sc ? formatPercent(exerciseMap.sc.correct, exerciseMap.sc.number) : '-%',
+            cr: exerciseMap.cr ? formatPercent(exerciseMap.cr.correct, exerciseMap.cr.number) : '-%',
+            rc: exerciseMap.rc ? formatPercent(exerciseMap.rc.correct, exerciseMap.rc.number) : '-%',
+          },
+          {
+            title: '平均用时',
+            sc: exerciseMap.sc ? exerciseMap.sc.time / exerciseMap.sc.number : '-',
+            cr: exerciseMap.cr ? exerciseMap.cr.time / exerciseMap.cr.number : '-',
+            rc: exerciseMap.rc ? exerciseMap.rc.time / exerciseMap.rc.number : '-',
+          },
         ],
       });
       this.setState({ study });
@@ -220,7 +305,11 @@ export default class extends Page {
         center={[this.renderTop(), this.renderLog(), this.renderTime()]}
         right={[this.renderInfo(), this.renderMessage()]}
         ads={(this.state.ads || []).map(row => {
-          return <a href={row.link} target="_blank"><Assets src={row.image} /></a>;
+          return (
+            <a href={row.link} target="_blank">
+              <Assets src={row.image} />
+            </a>
+          );
         })}
       />
     );
@@ -231,14 +320,27 @@ export default class extends Page {
   }
 
   renderLog() {
-    const { study = [] } = this.state;
-    const { latest = {}, diff = 0, diffPercent = 0, diffLast = 0, diffLastPercent = 0, day, time, showCal } = this.state;
+    const { study = [{}, { type: 'examination' }, { type: 'course' }] } = this.state;
+    const {
+      latest = {},
+      diff = 0,
+      diffPercent = 0,
+      diffLast = 0,
+      diffLastPercent = 0,
+      day,
+      time,
+      showCal,
+    } = this.state;
     return (
       <div className="log-layout">
         <div className="header">
           <div className="title">学习记录</div>
           <div className="right">
-            <span dangerouslySetInnerHTML={{ __html: `本周学习时间${formatSeconds(latest.time).replace(/([0-9]+)(m|min|h|hour|s)/g, '<b>$1</b>$2')}` }} />
+            <span
+              dangerouslySetInnerHTML={{
+                __html: `本周学习时间${formatSeconds(latest.time).replace(/([0-9]+)(m|min|h|hour|s)/g, '<b>$1</b>$2')}`,
+              }}
+            />
             <span>
               同比上周<b>{diffLastPercent}</b>% <Assets name={diffLast > 0 ? 'up' : 'down'} />
             </span>
@@ -254,19 +356,34 @@ export default class extends Page {
             width={54}
             space={5}
             active={day}
-            tabs={[{ title: '今天', key: 'today' }, { title: '昨天', key: 'yesterday' }, { title: '前天', key: 'before' }]}
-            onChange={(value) => {
+            tabs={[
+              { title: '今天', key: 'today' },
+              { title: '昨天', key: 'yesterday' },
+              { title: '前天', key: 'before' },
+            ]}
+            onChange={value => {
               this.refreshDay(value);
             }}
           />
           <div className="right">
             {day === 'other' && formatDate(time, 'YYYY-MM-DD')}
-            <Assets className="right" name="calendar" onClick={() => {
-              this.setState({ showCal: true });
-            }} />
-            {showCal && <Calendar className="cal" fullscreen={false} disabledDate={date => date.unix() <= moment.unix()} onSelect={(date) => {
-              this.refreshDay(date);
-            }} />}
+            <Assets
+              className="right"
+              name="calendar"
+              onClick={() => {
+                this.setState({ showCal: true });
+              }}
+            />
+            {showCal && (
+              <Calendar
+                className="cal"
+                fullscreen={false}
+                disabledDate={date => date.unix() <= moment.unix()}
+                onSelect={date => {
+                  this.refreshDay(date);
+                }}
+              />
+            )}
           </div>
         </div>
         {study.map((log, index) => {
@@ -288,7 +405,13 @@ export default class extends Page {
             </Tooltip>
           </div>
           <div className="right">
-            自 {total.createTIme && formatDate(total.createTime, 'YYYY-MM-DD')} ,您已在千行学习<b>{total.days}</b>天,累计<span dangerouslySetInnerHTML={{ __html: formatSeconds(total.time).replace(/([0-9]+)(m|min|h|hour|s)/g, '<b>$1</b>$2') }} />
+            自 {total.createTIme && formatDate(total.createTime, 'YYYY-MM-DD')} ,您已在千行学习<b>{total.days}</b>
+            天,累计
+            <span
+              dangerouslySetInnerHTML={{
+                __html: formatSeconds(total.time).replace(/([0-9]+)(m|min|h|hour|s)/g, '<b>$1</b>$2'),
+              }}
+            />
           </div>
         </div>
         <div className="body">
@@ -324,46 +447,81 @@ export default class extends Page {
       <div className="info-layout">
         <div className="body">
           <div className="info">
-            <Assets name="sun_blue" src={info.avatar} onClick={() => {
-              this.setState({ showEdit: true });
-            }} />
-            <div className="detail">
-              <div className="name" onClick={() => {
+            <Assets
+              name="sun_blue"
+              src={info.avatar}
+              onClick={() => {
                 this.setState({ showEdit: true });
-              }}>{info.nickname} </div>
+              }}
+            />
+            <div className="detail">
+              <div
+                className="name"
+                onClick={() => {
+                  this.setState({ showEdit: true });
+                }}
+              >
+                {info.nickname}{' '}
+              </div>
               <div className="id">ID: {info.id} </div>
             </div>
           </div>
           <div className="auth">
             <span className="invite">
-              <Button radius size="small" onClick={() => {
-                this.setState({ showInvite: true });
-              }}>
+              <Button
+                radius
+                size="small"
+                onClick={() => {
+                  this.setState({ showInvite: true });
+                }}
+              >
                 邀请
               </Button>
             </span>
             <Assets name="wechat" active={info.bindWechat} />
-            <Assets name="phone_1" active={info.bindMobile} onClick={() => {
-              this.setState({ showPhone: true });
-            }} />
-            <Assets name="realname" active={info.bindReal} onClick={() => {
-              this.setState({ showReal: true });
-            }} />
-            <Assets name="email" active={!!info.email} onClick={() => {
-              this.setState({ showEmail: true });
-            }} />
-            <Assets name="information" active={info.bindPrepare} onClick={() => {
-              this.setState({ showExamination: true });
-            }} />
+            <Assets
+              name="phone_1"
+              active={info.bindMobile}
+              onClick={() => {
+                this.setState({ showPhone: true });
+              }}
+            />
+            <Assets
+              name="realname"
+              active={info.bindReal}
+              onClick={() => {
+                this.setState({ showReal: true });
+              }}
+            />
+            <Assets
+              name="email"
+              active={!!info.email}
+              onClick={() => {
+                this.setState({ showEmail: true });
+              }}
+            />
+            <Assets
+              name="information"
+              active={info.bindPrepare}
+              onClick={() => {
+                this.setState({ showExamination: true });
+              }}
+            />
           </div>
         </div>
-        {<div className="footer">
-          <Assets className="m-r-5" name="VIP" />
-          {info.vip && <span className="date">{formatDate(info.vip, 'YYYY-MM-DD')}到期</span>}
-          <a onClick={() => {
-            this.setState({ showVip: true });
-          }}>续费</a>
-        </div>}
+        {
+          <div className="footer">
+            <Assets className="m-r-5" name="VIP" />
+            {info.vip && <span className="date">{formatDate(info.vip, 'YYYY-MM-DD')}到期</span>}
+            <a
+              onClick={() => {
+                this.setState({ showVip: true });
+              }}
+            >
+              续费
+            </a>
+          </div>
+        }
         <Examination
           show={showExamination}
           data={info}
@@ -387,28 +545,20 @@ export default class extends Page {
           show={showEdit}
           data={info}
           image={this.state.avatarFile}
-          onSelectImage={(file) => this.setState({ showEdit: false, showAvatar: true, avatarImage: file })}
+          onSelectImage={file => this.setState({ showEdit: false, showAvatar: true, avatarImage: file })}
           onConfirm={() => this.setState({ showEdit: false, avatarFile: null })}
           onCancel={() => this.setState({ showEdit: false, avatarFile: null })}
         />
-        <RealAuth
-          show={showReal}
-          data={info}
-          onConfirm={() => this.setState({ showReal: false })}
-        />
+        <RealAuth show={showReal} data={info} onConfirm={() => this.setState({ showReal: false })} />
         <EditAvatar
           show={showAvatar}
           data={info}
           crop={{ width: 200, height: 200 }}
           image={this.state.avatarImage}
-          onConfirm={(file) => this.setState({ showAvatar: false, showEdit: true, avatarFile: file, avatarImage: null })}
+          onConfirm={file => this.setState({ showAvatar: false, showEdit: true, avatarFile: file, avatarImage: null })}
           onCancel={() => this.setState({ showAvatar: false, showEdit: true, avatarImage: null })}
         />
-        <InviteModal
-          show={showInvite}
-          data={info}
-          onClose={() => this.setState({ showInvite: false })}
-        />
+        <InviteModal show={showInvite} data={info} onClose={() => this.setState({ showInvite: false })} />
         <VipRenew
           show={showVip}
           data={info}
@@ -423,33 +573,49 @@ export default class extends Page {
   renderMessage() {
     const { messages = [] } = this.state;
     const number = (messages || []).length;
-    return (number > 0 &&
-      <div className="message-layout">
-        <div className="header">
-          <Assets name="all" onCancel={() => {
-            this.readAllMessage();
-          }} />
-          全部已读
-        </div>
-        <div className="body">
-          {(messages || []).map(row => {
-            return <div className="item">
-              <div className="title dot">老师回答了您的提问</div>
-              <div className="date">{formatDate(row.createTime, 'YYYY-MM-DD HH:mm:ss')}</div>
-              {row.link && <GIcon name="arrow-right-small" onClick={() => {
-                openLink(row.link);
-              }} />}
-            </div>;
-          })}
-        </div>
-        <div className="footer">
-          <Button radius size="small" onClick={() => {
-            linkTo('/my/message');
-          }}>
-            全部消息
-          </Button>
+    return (
+      number > 0 && (
+        <div className="message-layout">
+          <div className="header">
+            <Assets
+              name="all"
+              onCancel={() => {
+                this.readAllMessage();
+              }}
+            />
+            全部已读
+          </div>
+          <div className="body">
+            {(messages || []).map(row => {
+              return (
+                <div className="item">
+                  <div className="title dot">老师回答了您的提问</div>
+                  <div className="date">{formatDate(row.createTime, 'YYYY-MM-DD HH:mm:ss')}</div>
+                  {row.link && (
+                    <GIcon
+                      name="arrow-right-small"
+                      onClick={() => {
+                        openLink(row.link);
+                      }}
+                    />
+                  )}
+                </div>
+              );
+            })}
+          </div>
+          <div className="footer">
+            <Button
+              radius
+              size="small"
+              onClick={() => {
+                linkTo('/my/message');
+              }}
+            >
+              全部消息
+            </Button>
+          </div>
         </div>
-      </div>
+      )
     );
   }
 }