Browse Source

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

Go 5 years ago
parent
commit
333a60da16

+ 36 - 6
front/project/www/app.less

@@ -234,24 +234,44 @@
   flex: 1;
 }
 
+.p-a {
+  position: absolute;
+}
+
+.v-a-t {
+  vertical-align: top;
+}
+
+.v-a-m {
+  vertical-align: middle;
+}
+
+.v-a-b {
+  vertical-align: bottom;
+}
+
 .t-1 {
-  color: #303036;
+  color: #303036 !important;
 }
 
 .t-2 {
-  color: #686872;
+  color: #686872 !important;
 }
 
 .t-3 {
-  color: #B5B5BA;
+  color: #B5B5BA !important;
 }
 
 .t-4 {
-  color: #4292F0;
+  color: #4292F0 !important;
 }
 
 .t-5 {
-  color: #6EC64B;
+  color: #6EC64B !important;
+}
+
+.t-6 {
+  color: #A7A7A7 !important;
 }
 
 .b-c-1 {
@@ -290,7 +310,7 @@ textarea {
 
 input::-webkit-input-placeholder,
 textarea::-webkit-input-placeholder {
-  color: @holder_color;
+  color: #A7A7A7;
 }
 
 .d-i-b {
@@ -363,6 +383,16 @@ body,
       display: block;
     }
   }
+
+  .input-layout {
+    display: flex;
+
+    .label {}
+
+    .input-block {
+      flex: 1;
+    }
+  }
 }
 
 #root {}

BIN
front/project/www/assets/erweima.png


+ 26 - 0
front/project/www/components/Icon/index.less

@@ -467,4 +467,30 @@
 .icon.user-info.no.active,
 .icon.user-info:hover {
   background-image: url('/assets/info.png');
+}
+
+.icon.more,
+.icon.more.no:hover {
+  width: 24px;
+  height: 24px;
+  background: url('/assets/more1_normal.png') no-repeat center;
+}
+
+.icon.more.active,
+.icon.more.no.active,
+.icon.more:hover {
+  background-image: url('/assets/more1_hover.png');
+}
+
+.icon.more-small,
+.icon.more-small.no:hover {
+  width: 20px;
+  height: 20px;
+  background: url('/assets/more2_normal.png') no-repeat center;
+}
+
+.icon.more-small.active,
+.icon.more-small.no.active,
+.icon.more-small:hover {
+  background-image: url('/assets/more2_hover.png');
 }

+ 0 - 1
front/project/www/components/Invite/index.less

@@ -2,7 +2,6 @@
 
 .invite-block {
 
-
   .title-block {
     font-size: 18px;
     color: #686872;

+ 3 - 2
front/project/www/components/Modal/index.js

@@ -20,6 +20,7 @@ export default class extends Component {
       close = true,
       maskClosable = false,
       body = true,
+      btnType,
       center,
       height,
     } = this.props;
@@ -46,12 +47,12 @@ export default class extends Component {
           )}
           <div className={`g-modal-btns ${btnAlign}`}>
             {onCancel && (
-              <Button size="lager" theme="link" onClick={() => onCancel()}>
+              <Button size="lager" theme={btnType === 'link' ? 'link t-6' : 'link'} onClick={() => onCancel()}>
                 {cancelText}
               </Button>
             )}
             {onConfirm && (
-              <Button size="lager" radius onClick={() => onConfirm()}>
+              <Button size="lager" theme={btnType === 'link' ? 'link' : 'theme'} radius onClick={() => onConfirm()}>
                 {confirmText}
               </Button>
             )}

+ 0 - 141
front/project/www/components/Modal/index.less

@@ -44,145 +44,4 @@
       text-align: center;
     }
   }
-}
-
-.g-modal.bind-phone-modal {
-  .step-0-layout {
-    margin-bottom: 70px;
-    font-size: 18px;
-
-    a {
-      margin-right: 20px;
-      float: right;
-    }
-  }
-
-  .step-1-layout {
-    display: flex;
-
-    .label {
-      font-size: 18px;
-      line-height: 40px;
-      margin-right: 20px;
-    }
-
-    .input-layout {
-      flex: 1;
-    }
-  }
-}
-
-.g-modal.bind-email-modal {
-  .step-0-layout {
-    margin-bottom: 70px;
-    font-size: 18px;
-
-    a {
-      margin-right: 20px;
-      float: right;
-    }
-  }
-
-  .step-1-layout {
-    display: flex;
-
-    .label {
-      font-size: 18px;
-      line-height: 40px;
-      margin-right: 10px;
-    }
-
-    .input-layout {
-      flex: 1;
-    }
-  }
-}
-
-.g-modal.edit-info-modal {
-  .edit-info-modal-block {
-    display: flex;
-
-    .label {
-      font-size: 18px;
-      line-height: 40px;
-      margin-right: 10px;
-    }
-
-    .input-layout {
-      flex: 1;
-    }
-
-    .file-upload {
-      background: #F7F7F7;
-      border: none;
-    }
-  }
-}
-
-.g-modal.real-auth-modal {
-  .real-auth-modal-wrapper {
-    position: relative;
-  }
-
-  .real-auth-text {
-    font-size: 18px;
-
-    .t2 {
-      margin-bottom: 30px;
-    }
-
-    .t3 {
-      margin-bottom: 20px;
-    }
-  }
-
-  .real-auth-qrcode {
-    position: absolute;
-    right: 0;
-    top: 0;
-  }
-}
-
-.g-modal.edit-avatar-modal {
-  .edit-avatar-modal-wrapper {
-    position: relative;
-  }
-
-  .edit-avatar-o {
-    vertical-align: top;
-    display: inline-block;
-    padding-right: 35px;
-    border-right: 1px solid #d8d8d8;
-
-    .assets {
-      width: 360px;
-    }
-  }
-
-  .edit-avatar-r {
-    display: inline-block;
-    padding-left: 30px;
-
-    .text {
-      font-size: 18px;
-      margin-bottom: 20px;
-    }
-
-    .assets {
-      border-radius: 50%;
-      width: 100px;
-    }
-  }
-}
-
-.g-modal.invite-modal {
-  .invite-modal-wrapper {
-    position: relative;
-
-    .tip {
-      font-size: 18px;
-      color: #686872;
-      margin-bottom: 30px;
-    }
-  }
 }

+ 4 - 3
front/project/www/components/More/index.js

@@ -1,9 +1,10 @@
 import React from 'react';
 import './index.less';
-import { Icon, Dropdown, Menu } from 'antd';
+import { Dropdown, Menu } from 'antd';
+import Icon from '../Icon';
 
 function More(props) {
-  const { menu = [], node, onClick } = props;
+  const { menu = [], size = '', children, onClick } = props;
   return (
     <Dropdown
       overlay={
@@ -16,7 +17,7 @@ function More(props) {
       }
       trigger={['click']}
     >
-      <div className="more">{node || <Icon type="more" />}</div>
+      <div className="more">{children || <Icon name={size ? `more-${size}` : 'more'} />}</div>
     </Dropdown>
   );
 }

+ 55 - 0
front/project/www/components/Open/index.js

@@ -0,0 +1,55 @@
+import React, { Component } from 'react';
+import './index.less';
+import { Icon } from '../Icon';
+
+export default class Open extends Component {
+  constructor(props) {
+    super(props);
+    this.Text = null;
+    this.state = { show: false, more: false };
+    this.checkHeight();
+  }
+
+  checkHeight() {
+    const { height } = this.props;
+    if (this.Text != null) {
+      if (this.Text.offsetHeight > height) {
+        this.setState({ more: true });
+      }
+    } else {
+      setTimeout(() => {
+        this.checkHeight();
+      }, 1);
+    }
+  }
+
+  render() {
+    const { show, more } = this.state;
+    const { up, down, height, className = '', children } = this.props;
+    return (
+      <div className={`super-open ${className} ${more ? 'more' : ''} ${!show ? 'hide' : ''}`}>
+        <div
+          className="hide-content"
+          ref={ref => {
+            this.Text = ref;
+          }}
+          style={{ height: more && !show ? height : null }}
+        >
+          {children}
+        </div>
+        {more && show && <span onClick={() => this.setState({ show: false })}>{up}</span>}
+        {more && !show && <span onClick={() => this.setState({ show: true })}>{down}</span>}
+      </div>
+    );
+  }
+}
+export class OpenText extends Component {
+  render() {
+    const { children } = this.props;
+    return (
+      <Open className="super-open-text" height={60} up={<Icon name="small-up" />} down={<Icon name="small-down" />}>
+        {children}
+      </Open>
+    );
+  }
+}

+ 21 - 0
front/project/www/components/Open/index.less

@@ -0,0 +1,21 @@
+@import '../../app.less';
+
+.super-open {
+  position: relative;
+
+  .hide-content {
+    overflow: hidden;
+  }
+}
+
+.super-open-text {
+  line-height: 20px;
+  padding-right: 30px;
+
+  span {
+    position: absolute;
+    top: 0;
+    right: 0;
+    background: #fff;
+  }
+}

+ 5 - 30
front/project/www/components/OtherAnswer/index.js

@@ -1,44 +1,19 @@
 import React, { Component } from 'react';
 import './index.less';
 import Icon from '../Icon';
+import Open from '../Open';
 
 export default class OtherAnswer extends Component {
-  constructor(props) {
-    super(props);
-    this.Text = null;
-    this.state = { show: false, more: false };
-    this.checkHeight();
-  }
-
-  checkHeight() {
-    if (this.Text != null) {
-      if (this.Text.offsetHeight > 80) {
-        this.setState({ more: true });
-      }
-    } else {
-      setTimeout(() => {
-        this.checkHeight();
-      }, 1);
-    }
-  }
-
   render() {
     const { data } = this.props;
-    const { show, more } = this.state;
     return (
-      <div className={`other-answer ${more ? 'more' : ''} ${!show ? 'hide' : ''}`}>
+      <div className="other-answer">
         <div className="small-tag">提问</div>
         <div className="title">{data.content}</div>
         <div className="small-tag">回答</div>
-        <div
-          ref={ref => {
-            this.Text = ref;
-          }}
-          className="desc"
-          dangerouslySetInnerHTML={{ __html: data.answer }}
-        />
-        {more && show && <Icon name="up" onClick={() => this.setState({ show: false })} />}
-        {more && !show && <Icon name="down" onClick={() => this.setState({ show: true })} />}
+        <Open height={80} up={<Icon name="up" />} down={<Icon name="down" />}>
+          <div className="desc" dangerouslySetInnerHTML={{ __html: data.answer }} />
+        </Open>
       </div>
     );
   }

+ 11 - 11
front/project/www/components/OtherAnswer/index.less

@@ -24,7 +24,6 @@
     color: #686872;
     font-size: 16px;
     margin-bottom: 20px;
-    overflow: hidden;
   }
 
   .icon {
@@ -34,19 +33,20 @@
     transform: translateX(-50%);
     display: none;
   }
-}
 
-.other-answer.more.hide {
-  .desc {
-    height: 80px;
-    background: linear-gradient(360deg, rgba(161, 161, 171, 0) 0%, rgba(104, 104, 114, 1) 100%);
-    -webkit-background-clip: text;
-    -webkit-text-fill-color: transparent;
+  .super-open.more.hide {
+    .desc {
+      background: linear-gradient(360deg, rgba(161, 161, 171, 0) 0%, rgba(104, 104, 114, 1) 100%);
+      -webkit-background-clip: text;
+      -webkit-text-fill-color: transparent;
+    }
   }
 }
 
-.other-answer.more:hover {
-  .icon {
-    display: block;
+.other-answer:hover {
+  .super-open.more {
+    .icon {
+      display: block;
+    }
   }
 }

+ 6 - 3
front/project/www/components/ProgressText/index.js

@@ -3,13 +3,16 @@ import './index.less';
 import Progress from '../Progress';
 
 function ProgressText(props) {
-  const { progress, times, size } = props;
+  const { progress, width, times, unit = '遍', size } = props;
   return (
     <div className="progress-text">
-      <div className="p">
+      <div style={{ width }} className="p">
         <Progress progress={progress} size={size} />
       </div>
-      <div className="t">{times > 0 ? `${times}遍+` : ''}{progress}%</div>
+      <div className="t">
+        {times > 0 ? `${times}${unit}+` : ''}
+        {progress}%
+      </div>
     </div>
   );
 }

File diff suppressed because it is too large
+ 20 - 9
front/project/www/routes/my/answer/page.js


+ 87 - 54
front/project/www/routes/my/collect/page.js

@@ -17,7 +17,10 @@ import { My } from '../../../stores/my';
 const columns = [
   { key: 'question_type', title: '题型', fixSort: true },
   { key: 'title', title: '题目ID', fixSort: true },
-  { key: 'description', title: '内容' },
+  {
+    key: 'description',
+    title: '内容',
+  },
   { key: 'time', title: '耗时', sort: true },
   { key: 'correct', title: '错误率', sort: true },
   { key: 'latest_time', title: '最近做题' },
@@ -51,7 +54,7 @@ export default class extends Page {
       timerange: 'today',
       filterMap: {},
       sortMap: {},
-      data: [{}, {}],
+      list: [{}, {}],
       selectList: [],
       allChecked: false,
       showDetail: false,
@@ -79,22 +82,34 @@ export default class extends Page {
 
   refreshQuestion(data) {
     const [startTime, endTime] = timeRange(data.timerange);
-    refreshQuestionType(this, data.subject, data.questionType, { all: true, needSentence: true, allSubject: true })
-      .then(({ questionTypes }) => {
-        return refreshStruct(this, data.tab, data.one, data.two, {
-          all: true, needPreview: false, needTextbook: true,
-        })
-          .then(({ structIds, latest, year }) => {
-            My.listQuestionCollect(Object.assign({ module: data.tab, questionTypes, structIds, latest, year, startTime, endTime }, this.state.search, {
-              order: Object.keys(data.sortMap).map(key => {
-                if (key === 'title') return 'pid desc, no desc';
-                return `${key} ${data.sortMap[key]}`;
-              }).join(','),
-            })).then(result => {
-              this.setState({ list: result.list, total: result.total });
-            });
-          });
+    refreshQuestionType(this, data.subject, data.questionType, {
+      all: true,
+      needSentence: true,
+      allSubject: true,
+    }).then(({ questionTypes }) => {
+      return refreshStruct(this, data.tab, data.one, data.two, {
+        all: true,
+        needPreview: false,
+        needTextbook: true,
+      }).then(({ structIds, latest, year }) => {
+        My.listQuestionCollect(
+          Object.assign(
+            { module: data.tab, questionTypes, structIds, latest, year, startTime, endTime },
+            this.state.search,
+            {
+              order: Object.keys(data.sortMap)
+                .map(key => {
+                  if (key === 'title') return 'pid desc, no desc';
+                  return `${key} ${data.sortMap[key]}`;
+                })
+                .join(','),
+            },
+          ),
+        ).then(result => {
+          this.setState({ list: result.list, total: result.total });
+        });
       });
+    });
   }
 
   refreshArticle(data) {
@@ -138,7 +153,7 @@ export default class extends Page {
     }
   }
 
-  onAction() { }
+  onAction() {}
 
   onSelect(selectList) {
     this.setState({ selectList });
@@ -171,40 +186,58 @@ export default class extends Page {
   }
 
   renderTabquestion() {
-    const { questionSubjectSelect, questionSubjectMap = {}, oneSelect, twoSelectMap = {}, filterMap = {}, sortMap = {}, list = [] } = this.state;
+    const {
+      questionSubjectSelect,
+      questionSubjectMap = {},
+      oneSelect,
+      twoSelectMap = {},
+      filterMap = {},
+      sortMap = {},
+      list = [],
+    } = this.state;
     const { selectList = [], allChecked, page, total } = this.state;
     return (
       <div className="tab-1-layout">
         <UserAction
           search
-          selectList={[{
-            children: [{
-              key: 'subject',
-              placeholder: '学科',
-              select: questionSubjectSelect,
-            }, {
-              placeholder: '题型',
-              key: 'questionType',
-              be: 'subject',
-              selectMap: questionSubjectMap,
-            }],
-          }, {
-            label: '范围',
-            children: [{
-              key: 'one',
-              placeholder: '全部',
-              select: oneSelect,
-            }, {
-              key: 'two',
-              be: 'one',
-              placeholder: '全部',
-              selectMap: twoSelectMap,
-            }],
-          }, {
-            right: true,
-            key: 'timerange',
-            select: TimeRange,
-          }]}
+          selectList={[
+            {
+              children: [
+                {
+                  key: 'subject',
+                  placeholder: '学科',
+                  select: questionSubjectSelect,
+                },
+                {
+                  placeholder: '题型',
+                  key: 'questionType',
+                  be: 'subject',
+                  selectMap: questionSubjectMap,
+                },
+              ],
+            },
+            {
+              label: '范围',
+              children: [
+                {
+                  key: 'one',
+                  placeholder: '全部',
+                  select: oneSelect,
+                },
+                {
+                  key: 'two',
+                  be: 'one',
+                  placeholder: '全部',
+                  selectMap: twoSelectMap,
+                },
+              ],
+            },
+            {
+              right: true,
+              key: 'timerange',
+              select: TimeRange,
+            },
+          ]}
           filterMap={filterMap}
           onFilter={value => this.onFilter(value)}
         />
@@ -278,7 +311,7 @@ export default class extends Page {
   renderModal() {
     return [
       <ArticleDetail show={this.state.showDetail} onClose={() => this.setState({ showDetail: false })} />,
-      <Modal title="操作提示" confirmText="好的,知道了" btnAlign="center" onConfirm={() => { }}>
+      <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>
@@ -298,10 +331,10 @@ export default class extends Page {
           查阅以上信息。
         </div>
       </Modal>,
-      <Modal title="组卷练习" confirmText="好的,知道了" btnAlign="center" onConfirm={() => { }}>
+      <Modal title="组卷练习" confirmText="好的,知道了" btnAlign="center" onConfirm={() => {}}>
         <div className="t-2 t-s-18">不可同时选中语文题和数学题,请重新选择。</div>
       </Modal>,
-      <Modal title="组卷练习" confirmText="开始练习" onConfirm={() => { }} onCancel={() => { }}>
+      <Modal title="组卷练习" confirmText="开始练习" onConfirm={() => {}} onCancel={() => {}}>
         <div className="t-2 t-s-18">
           您共选择了 <span className="t-4">50</span> 道题目,是否开始练习?
         </div>
@@ -315,15 +348,15 @@ export default class extends Page {
           次以上的错题
         </div>
       </Modal>,
-      <Modal title="移出" onConfirm={() => { }} onCancel={() => { }}>
+      <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={() => { }}>
+      <Modal title="导出" confirmText="好的,知道了" btnAlign="center" onConfirm={() => {}}>
         <div className="t-2 t-s-18">正在下载中,请不要关闭当前页面!</div>
       </Modal>,
-      <Modal title="导出" confirmText="导出" onConfirm={() => { }} onCancel={() => { }}>
+      <Modal title="导出" confirmText="导出" onConfirm={() => {}} onCancel={() => {}}>
         <div className="t-2 t-s-18 m-b-5">
           当前共选中 <span className="t-4">50</span> 道题,请确认需要导出的内容:
         </div>
@@ -338,7 +371,7 @@ export default class extends Page {
           })}
         </div>
       </Modal>,
-      <Modal title="导出" confirmText="导出" onConfirm={() => { }} onCancel={() => { }}>
+      <Modal title="导出" confirmText="导出" onConfirm={() => {}} onCancel={() => {}}>
         <div className="t-2 t-s-18 m-b-5">
           当前共选中 <span className="t-4">50</span> 道题,请确认需要导出的内容:
         </div>

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

@@ -1,7 +1,7 @@
 import React, { Component } from 'react';
 import { Link } from 'react-router-dom';
 import './index.less';
-import { Icon } from 'antd';
+import { Icon, Dropdown } from 'antd';
 import FileUpload from '@src/components/FileUpload';
 import Page from '@src/containers/Page';
 import Assets from '@src/components/Assets';
@@ -10,6 +10,7 @@ import { formatDate, formatSeconds, formatPercent } from '@src/services/Tools';
 import UserLayout from '../../../layouts/User';
 import Button from '../../../components/Button';
 import ProgressText from '../../../components/ProgressText';
+import IconButton from '../../../components/IconButton';
 import { Icon as GIcon } from '../../../components/Icon';
 import menu from '../index';
 import Tabs from '../../../components/Tabs';
@@ -148,7 +149,7 @@ export default class extends Page {
       const courseMap = {};
       const previewMap = {};
       const stopMap = {};
-      result.forEach((row) => {
+      result.forEach(row => {
         const date = formatDate(row.day, 'YYYY-MM-DD');
         if (row.type === 'stop') {
           stopMap[date] = true;
@@ -166,24 +167,24 @@ export default class extends Page {
   }
 
   refreshDetail(recordId) {
-    My.detailCourse(recordId)
-      .then(result => {
-        let { list } = this.state;
-        list = list.map(row => {
-          if (row.id === recordId) return this.formatRecord(result);
-          return row;
-        });
-        this.setState({ list });
+    My.detailCourse(recordId).then(result => {
+      let { list } = this.state;
+      list = list.map(row => {
+        if (row.id === recordId) return this.formatRecord(result);
+        return row;
       });
+      this.setState({ list });
+    });
   }
 
   suspend() {
     const { suspend } = this.state;
-    My.suspendCourse(suspend.id).then(() => {
-      asyncSMessage('停课成功');
-      this.setState({ showSuspend: false });
-      this.refreshDetail(suspend.id);
-    })
+    My.suspendCourse(suspend.id)
+      .then(() => {
+        asyncSMessage('停课成功');
+        this.setState({ showSuspend: false });
+        this.refreshDetail(suspend.id);
+      })
       .catch(err => {
         asyncSMessage(err.message, 'error');
       });
@@ -191,11 +192,12 @@ export default class extends Page {
 
   restore() {
     const { restore } = this.state;
-    My.restoreCourse(restore.id).then(() => {
-      asyncSMessage('恢复成功');
-      this.setState({ showRestore: false });
-      this.refreshDetail(restore.id);
-    })
+    My.restoreCourse(restore.id)
+      .then(() => {
+        asyncSMessage('恢复成功');
+        this.setState({ showRestore: false });
+        this.refreshDetail(restore.id);
+      })
       .catch(err => {
         asyncSMessage(err.message, 'error');
       });
@@ -204,15 +206,13 @@ export default class extends Page {
   submitAppointmentComment(data, type) {
     data.type = type;
     if (data.id) {
-      My.editAppointmentComment(data)
-        .then(() => {
-          this.refreshDetail(data.recordId);
-        });
+      My.editAppointmentComment(data).then(() => {
+        this.refreshDetail(data.recordId);
+      });
     } else {
-      My.addAppointmentComment(data)
-        .then(() => {
-          this.refreshDetail(data.recordId);
-        });
+      My.addAppointmentComment(data).then(() => {
+        this.refreshDetail(data.recordId);
+      });
     }
   }
 
@@ -252,18 +252,56 @@ export default class extends Page {
     My.courseCommentTips(recordId);
   }
 
+  uploadNote(file) {
+    const { note = {} } = this.state;
+    Common.uploadImage(file).then(result => {
+      note.file = result.url;
+      note.name = file.name;
+      this.setState({ note });
+    });
+  }
+
+  uploadSupply(file) {
+    const { supply = {} } = this.state;
+    Common.uploadImage(file).then(result => {
+      supply.file = result.url;
+      supply.name = file.name;
+      this.setState({ supply });
+    });
+  }
+
   renderView() {
     const { config } = this.props;
     return <UserLayout active={config.key} menu={menu} center={this.renderDetail()} />;
   }
 
   renderDetail() {
-    const { tab, status, showTips, showTime, showSuspend, showRestore, showUploadNote, showUploadSupply, showSupply, showNote, showComment, showFinish, comment = {}, data = {}, note = {}, supply = {}, appointment = {} } = this.state;
+    const {
+      tab,
+      status,
+      showTips,
+      showTime,
+      showSuspend,
+      showRestore,
+      showUploadNote,
+      showUploadSupply,
+      showSupply,
+      showNote,
+      showComment,
+      showFinish,
+      comment = {},
+      data = {},
+      note = {},
+      supply = {},
+      appointment = {},
+    } = this.state;
     return (
       <div className="detail-layout">
         <div hidden={!showTips} className="tip">
           <div className="text">理清备考思路,避开常见误区,让学习的每一分钟发光发热!</div>
-          <a href="" target="_blank">去填写 ></a>
+          <a href="" target="_blank">
+            去填写 >
+          </a>
           <Icon type="close-circle" theme="filled" onClick={() => this.setState({ showTips: false })} />
         </div>
         <Tabs
@@ -331,7 +369,7 @@ export default class extends Page {
               return (
                 <div className="ant-calendar-date">
                   {current.get('date')}
-                  {data.courseTimeMap[date] && < i className="s1" style={{ background: '#6865FD' }} />}
+                  {data.courseTimeMap[date] && <i className="s1" style={{ background: '#6865FD' }} />}
                   {data.previewTimeMap[date] && <i className="s2" style={{ background: '#4299FF' }} />}
                 </div>
               );
@@ -375,13 +413,32 @@ export default class extends Page {
             您的每一次反馈都是千行进步的动力。
           </div>
         </Modal>
-        <Modal show={showSuspend} title="申请停课" onConfirm={() => this.suspend()} onCancel={() => this.setState({ showSuspend: false })}>
-          <div className="t-2 t-s-18">最长停课时间为1个月,截止日期将顺延。</div>
-          <div className="t-2 t-s-18">停课不影响学习频率计算。</div>
-          <div className="t-2 t-s-18">停课期间可随时恢复学习,</div>
+        <Modal
+          show={showSuspend}
+          title="申请停课"
+          width={630}
+          confirmText="立即停课"
+          onConfirm={() => this.suspend()}
+          onCancel={() => this.setState({ showSuspend: false })}
+        >
+          <div className="t-2 t-s-18">最长停课周期为1个月,到期后系统自动恢复至“学习中”状态。</div>
           <div className="t-2 t-s-18">每门课程只有一次申请机会,是否需要停课?</div>
+          <div style={{ bottom: 20, left: 0 }} className="p-a t-3 t-s-14">
+            *停课不影响听课频率的计算;
+          </div>
+          <div style={{ bottom: 0, left: 0 }} className="p-a t-3 t-s-14">
+            {' '}
+            停课期间可随时恢复学习。
+          </div>
         </Modal>
-        <Modal show={showRestore} title="恢复学习" onConfirm={() => this.restore()} onCancel={() => this.setState({ showRestore: false })}>
+        <Modal
+          show={showRestore}
+          title="恢复学习"
+          width={630}
+          confirmText="立即恢复"
+          onConfirm={() => this.restore()}
+          onCancel={() => this.setState({ showRestore: false })}
+        >
           <div className="t-2 t-s-18">恢复学习后,本课程的停课功能将无法使用。是否恢复学习?</div>
         </Modal>
         <Modal
@@ -421,19 +478,38 @@ export default class extends Page {
           </div>
           <div className="b-b m-t-2" />
         </Modal>
-        <Modal show={showNote} title="课后笔记" width={500} height={500} onClose={() => this.setState({ showNote: false })}>
-          {appointment.noteList && appointment.noteList.map(row => {
-            return <Note user={this.props.user} teacher={data.teacher} data={row} />;
-          })}
+        <Modal
+          show={showNote}
+          title="课后笔记"
+          width={500}
+          height={500}
+          onClose={() => this.setState({ showNote: false })}
+        >
+          {appointment.noteList &&
+            appointment.noteList.map(row => {
+              return <Note user={this.props.user} teacher={data.teacher} data={row} />;
+            })}
         </Modal>
-        <Modal show={showSupply} title="课后留言" width={500} height={500} onClose={() => this.setState({ showSupply: false })}>
-          {appointment.supplyList && appointment.supplyList.map(row => {
-            return <Note user={this.props.user} teacher={data.teacher} data={row} />;
-          })}
+        <Modal
+          show={showSupply}
+          title="课后留言"
+          width={500}
+          height={500}
+          onClose={() => this.setState({ showSupply: false })}
+        >
+          {appointment.supplyList &&
+            appointment.supplyList.map(row => {
+              return <Note user={this.props.user} teacher={data.teacher} data={row} />;
+            })}
         </Modal>
-        <Modal show={showUploadSupply} title="上传留言"
+        <Modal
+          show={showUploadSupply}
+          title="上传留言"
           width={630}
-          confirmText="提交" onConfirm={() => this.submitAppointmentComment(supply, 'supply')} onCancel={() => this.setState({ showUploadSupply: false, supply: {} })}>
+          confirmText="提交"
+          onConfirm={() => this.submitAppointmentComment(supply, 'supply')}
+          onCancel={() => this.setState({ showUploadSupply: false, supply: {} })}
+        >
           <textarea
             className="b-c-1 w-10 p-10 m-b-1"
             rows={6}
@@ -470,17 +546,28 @@ export default class extends Page {
   renderTabonline() {
     const { list = [] } = this.state;
     return list.map(item => {
-      return <CourseOnline data={item} user={this.props.user} refreshDetail={(recordId) => {
-        this.refreshDetail(recordId);
-      }} onRestore={() => {
-        this.setState({ showRestore: true, restore: item });
-      }} onSuspend={() => {
-        this.setState({ showSuspend: true, suspend: item });
-      }} onTime={() => {
-        this.openTime(item);
-      }} onComment={() => {
-        this.setState({ showComment: true, comment: { channel: 'course-video', position: item.course.id } });
-      }} closeCommentTips={() => this.closeCommentTips(item.id)} />;
+      return (
+        <CourseOnline
+          data={item}
+          user={this.props.user}
+          refreshDetail={recordId => {
+            this.refreshDetail(recordId);
+          }}
+          onRestore={() => {
+            this.setState({ showRestore: true, restore: item });
+          }}
+          onSuspend={() => {
+            this.setState({ showSuspend: true, suspend: item });
+          }}
+          onTime={() => {
+            this.openTime(item);
+          }}
+          onComment={() => {
+            this.setState({ showComment: true, comment: { channel: 'course-video', position: item.course.id } });
+          }}
+          closeCommentTips={() => this.closeCommentTips(item.id)}
+        />
+      );
     });
   }
 
@@ -524,14 +611,26 @@ class CourseOnline extends Component {
         key: 'paper',
         render: (text, record) => {
           const { paper = {} } = record;
-          return `${paper.paper && paper.paper.times > 0 ? `${paper.paper.times}次+` : ''}${paper.report ? formatPercent(paper.report.userNumber, paper.report.questionNumber, false) : '0%'}`;
+          return `${paper.paper && paper.paper.times > 0 ? `${paper.paper.times}次+` : ''}${
+            paper.report ? formatPercent(paper.report.userNumber, paper.report.questionNumber, false) : '0%'
+          }`;
         },
       },
       {
         title: '进度',
         key: 'progress',
         render: (text, record) => {
-          return `${record.progress && record.progress.times > 0 ? `${record.progress.times}次+` : ''}${record.progress ? record.progress.progress : 0}%`;
+          return record.progress ? (
+            <div>
+              <div className="v-a-m d-i-b">
+                <ProgressText width={50} size="small" times={1} progress={20} unit="次" />
+              </div>
+              <IconButton className="m-l-2" type="start" />
+              <IconButton className="m-l-5" type="report" />
+            </div>
+          ) : (
+            '-'
+          );
         },
       },
       {
@@ -545,15 +644,18 @@ class CourseOnline extends Component {
       {
         title: '笔记',
         key: 'note',
-        render: (text) => {
-          return text;
+        render: () => {
+          return <GIcon name="note" active />;
         },
       },
       {
         title: '问答',
         key: 'ask',
         render: (text, record) => {
-          return <Link to={`/course/ask/${record.courseId}?no=${record.id}`}>{`${record.answerNumber || 0}/${record.askNumber || 0}`}</Link>;
+          return (
+            <Link to={`/course/ask/${record.courseId}?no=${record.id}`}>{`${record.answerNumber ||
+              0}/${record.askNumber || 0}`}</Link>
+          );
         },
       },
     ];
@@ -585,7 +687,8 @@ class CourseOnline extends Component {
           <div className="tag">学习中</div>
           <div className="text">{data.course.title}</div>
           <div className="right">
-            <More menu={[{ label: '评价', key: 'comment' }, { label: '停课', key: 'suspend' }]}
+            <More
+              menu={[{ label: '评价', key: 'comment' }, { label: '停课', key: 'suspend' }]}
               onClick={value => {
                 const { key } = value;
                 if (key === 'comment') {
@@ -593,15 +696,21 @@ class CourseOnline extends Component {
                 } else if (key === 'suspend') {
                   onSuspend();
                 }
-              }} />
+              }}
+            />
           </div>
         </div>
-        {data.currentCourseNo && <div className="continue" onClick={() => {
-          linkTo(`/course/detail/${data.course.id}`);
-        }}>
-          <Assets name="notice" />
-          继续学习:课时 {data.currentNo}:{data.currentCourseNo.title}
-        </div>}
+        {data.currentCourseNo && (
+          <div
+            className="continue"
+            onClick={() => {
+              linkTo(`/course/detail/${data.course.id}`);
+            }}
+          >
+            <Assets name="notice" />
+            继续学习:课时 {data.currentNo}:{data.currentCourseNo.title}
+          </div>
+        )}
         <div className="detail">
           <div className="left">
             <Assets name="sun_blue" src={data.course.cover} />
@@ -633,9 +742,7 @@ class CourseOnline extends Component {
             </div>
             <div className="item">
               <GIcon name="note-block" active noHover />
-              <div className="text">
-                {data.noteNumber}
-              </div>
+              <div className="text">{data.noteNumber}</div>
             </div>
           </div>
           <div className="open">
@@ -662,22 +769,26 @@ class CourseOnline extends Component {
               <div className="t1">授课老师</div>
               <div className="t2">{data.course.teacher}</div>
               <div>
-                <div className='d-i-b m-r-2'>
-                  <div className='t-2'>课时</div>
-                  <div className='t-1 t-s-16'>{data.courseNos.length}</div>
+                <div className="d-i-b m-r-2">
+                  <div className="t-2">课时</div>
+                  <div className="t-1 t-s-16">{data.courseNos.length}</div>
                 </div>
-                <div className='d-i-b'>
-                  <div className='t-2'>总时长</div>
-                  <div className='t-1 t-s-16'>{formatSeconds(data.courseTime)}</div>
+                <div className="d-i-b">
+                  <div className="t-2">总时长</div>
+                  <div className="t-1 t-s-16">{formatSeconds(data.courseTime)}</div>
                 </div>
               </div>
             </div>
           </div>
           <div className="right t-c">
             <div className="text">请于 {formatDate(data.endTime, 'YYYY-MM-DD')} 前开通</div>
-            <Button size="lager" radius onClick={() => {
-              this.open(data.id);
-            }}>
+            <Button
+              size="lager"
+              radius
+              onClick={() => {
+                this.open(data.id);
+              }}
+            >
               立即开通
             </Button>
           </div>
@@ -695,13 +806,15 @@ class CourseOnline extends Component {
           <div className="tag">已结束</div>
           <div className="text">{data.course.title}</div>
           <div className="right">
-            <More menu={[{ label: '评价', key: 'comment' }]}
+            <More
+              menu={[{ label: '评价', key: 'comment' }]}
               onClick={value => {
                 const { key } = value;
                 if (key === 'comment') {
                   onComment();
                 }
-              }} />
+              }}
+            />
           </div>
         </div>
         <div className="detail">
@@ -729,14 +842,14 @@ class CourseOnline extends Component {
             </div>
             <div className="item">
               <GIcon name="note-block" active noHover />
-              <div className="text">
-                {data.noteNumber}
-              </div>
+              <div className="text">{data.noteNumber}</div>
             </div>
-            {data.courseAward > 0 && <div className="item">
-              <GIcon name="gift-block" active />
-              <div className="text">赠送{data.courseAward}天</div>
-            </div>}
+            {data.courseAward > 0 && (
+              <div className="item">
+                <GIcon name="gift-block" active />
+                <div className="text">赠送{data.courseAward}天</div>
+              </div>
+            )}
           </div>
           <div className="open">
             <GIcon name={open ? 'up' : 'down'} onClick={() => this.setState({ open: !open })} />
@@ -754,16 +867,28 @@ class CourseOnline extends Component {
       <div className="course-item end">
         <div className="title">
           <div className="tag">已停课</div>
-          <div className="text">{data.course.title}<Button size="small" radius onClick={() => onRestore()} >恢复上课</Button></div>
-          <div className='t-s-12'><span className='t-3'>申请时间:</span><span className='t-2 m-r-1'>{formatDate(data.suspendTime, 'YYYY-MM-DD HH:mm:ss')}</span><span className='t-3'>已停课:</span><span>{parseInt((new Date().getTime() - new Date(data.suspendTime).getTime()) / 86400000, 10)}Days/30</span></div>
+          <div className="text">
+            {data.course.title}
+            <Button size="small" radius onClick={() => onRestore()}>
+              恢复上课
+            </Button>
+          </div>
+          <div className="t-s-12">
+            <span className="t-3">申请时间:</span>
+            <span className="t-2 m-r-1">{formatDate(data.suspendTime, 'YYYY-MM-DD HH:mm:ss')}</span>
+            <span className="t-3">已停课:</span>
+            <span>{parseInt((new Date().getTime() - new Date(data.suspendTime).getTime()) / 86400000, 10)}Days/30</span>
+          </div>
           <div className="right">
-            <More menu={[{ label: '评价', key: 'comment' }]}
+            <More
+              menu={[{ label: '评价', key: 'comment' }]}
               onClick={value => {
                 const { key } = value;
                 if (key === 'comment') {
                   onComment();
                 }
-              }} />
+              }}
+            />
           </div>
         </div>
 
@@ -798,9 +923,7 @@ class CourseOnline extends Component {
             </div>
             <div className="item">
               <GIcon name="note-block" active noHover />
-              <div className="text">
-                {data.noteNumber}
-              </div>
+              <div className="text">{data.noteNumber}</div>
             </div>
           </div>
           <div className="open">
@@ -819,7 +942,6 @@ class CourseOnline extends Component {
   }
 }
 
-
 const titleMap = {
   1: '预约时间',
   2: '答疑文档',
@@ -840,11 +962,11 @@ const iconMap = {
 };
 
 const statusMap = {
-  1: (appointment) => {
+  1: appointment => {
     if (!appointment.id) return 'end';
     return '';
   },
-  2: (appointment) => {
+  2: appointment => {
     if (!appointment.questionFile) return 'not';
     return '';
   },
@@ -879,8 +1001,18 @@ class CourseVs extends Component {
         {
           title: '预习作业',
           key: 'paper',
-          render: () => {
-
+          render: (text, record) => {
+            return record.progress ? (
+              <div>
+                <div className="v-a-m d-i-b">
+                  <ProgressText width={50} size="small" times={1} progress={20} unit="次" />
+                </div>
+                <IconButton className="m-l-2" type="start" />
+                <IconButton className="m-l-5" type="report" />
+              </div>
+            ) : (
+              '-'
+            );
           },
         },
         {
@@ -911,7 +1043,11 @@ class CourseVs extends Component {
           title: '答疑文档',
           key: 'questionFile',
           render: (text, record) => {
-            return <a href={text} target="_blank">{record.questionFileName}</a>;
+            return (
+              <a href={text} target="_blank">
+                {record.questionFileName}
+              </a>
+            );
           },
         },
         {
@@ -938,14 +1074,22 @@ class CourseVs extends Component {
       answer: [1, 2, 3],
     };
     const index = props.data.appointments.length - 1;
-    this.state = { open: false, tab: 'ing', index, list: this.listMap[this.props.data.course.vsType], showTips: props.data.commentTips === 0 && (props.data.appointments.length === parseInt(props.data.number / 2, 10) || props.data.appointments.length === props.data.number) };
+    this.state = {
+      open: false,
+      tab: 'ing',
+      index,
+      list: this.listMap[this.props.data.course.vsType],
+      showTips:
+        props.data.commentTips === 0 &&
+        (props.data.appointments.length === parseInt(props.data.number / 2, 10) ||
+          props.data.appointments.length === props.data.number),
+    };
   }
 
   closeCommentTips() {
-    My.courseCommentTips(this.props.data.id)
-      .then(() => {
-        this.setState({ showTips: false });
-      });
+    My.courseCommentTips(this.props.data.id).then(() => {
+      this.setState({ showTips: false });
+    });
   }
 
   render() {
@@ -971,15 +1115,21 @@ class CourseVs extends Component {
       <div className="education-item ing">
         <div className="title">
           <div className="tag">学习中</div>
-          <div className="text">{data.course.title}{data.vsNo > 0 ? `V${data.vsNo}` : ''}{data.number > 0 ? `(${data.number}课时)` : ''}</div>
+          <div className="text">
+            {data.course.title}
+            {data.vsNo > 0 ? `V${data.vsNo}` : ''}
+            {data.number > 0 ? `(${data.number}课时)` : ''}
+          </div>
           <div className="right">
-            <More menu={[{ label: '评价', key: 'comment' }, { label: '停课', key: 'suspend' }]}
+            <More
+              menu={[{ label: '评价', key: 'comment' }, { label: '停课', key: 'suspend' }]}
               onClick={value => {
                 const { key } = value;
                 if (key === 'comment') {
                   onComment();
                 }
-              }} />
+              }}
+            />
           </div>
         </div>
         {showTips && <div className="continue">
@@ -1035,7 +1185,11 @@ class CourseVs extends Component {
       <div className="education-item not">
         <div className="title">
           <div className="tag">未开通</div>
-          <div className="text">{data.course.title}{data.vsNo > 0 ? `V${data.vsNo}` : ''}{data.number > 0 ? `(${data.number}课时)` : ''}</div>
+          <div className="text">
+            {data.course.title}
+            {data.vsNo > 0 ? `V${data.vsNo}` : ''}
+            {data.number > 0 ? `(${data.number}课时)` : ''}
+          </div>
         </div>
         <div className="detail">
           <div className="left">
@@ -1044,13 +1198,13 @@ class CourseVs extends Component {
               <div className="t1">授课老师</div>
               <div className="t2">{data.teacher.realname}</div>
               <div>
-                <div className='d-i-b m-r-2'>
-                  <div className='t-2'>课时</div>
-                  <div className='t-1 t-s-16'>{data.number}</div>
+                <div className="d-i-b m-r-2">
+                  <div className="t-2">课时</div>
+                  <div className="t-1 t-s-16">{data.number}</div>
                 </div>
-                <div className='d-i-b'>
-                  <div className='t-2'>总时长</div>
-                  <div className='t-1 t-s-16'>{data.number}Hours</div>
+                <div className="d-i-b">
+                  <div className="t-2">总时长</div>
+                  <div className="t-1 t-s-16">{data.number}Hours</div>
                 </div>
               </div>
             </div>
@@ -1077,15 +1231,21 @@ class CourseVs extends Component {
       <div className="education-item end">
         <div className="title">
           <div className="tag">已结课</div>
-          <div className="text">{data.course.title}{data.vsNo > 0 ? `V${data.vsNo}` : ''}{data.number > 0 ? `(${data.number}课时)` : ''}</div>
+          <div className="text">
+            {data.course.title}
+            {data.vsNo > 0 ? `V${data.vsNo}` : ''}
+            {data.number > 0 ? `(${data.number}课时)` : ''}
+          </div>
           <div className="right">
-            <More menu={[{ label: '评价', key: 'comment' }]}
+            <More
+              menu={[{ label: '评价', key: 'comment' }]}
               onClick={value => {
                 const { key } = value;
                 if (key === 'comment') {
                   onComment();
                 }
-              }} />
+              }}
+            />
           </div>
         </div>
         {showTips && <div className="continue">
@@ -1141,16 +1301,30 @@ class CourseVs extends Component {
       <div className="education-item end">
         <div className="title">
           <div className="tag">已停课</div>
-          <div className="text">{data.course.title}{data.vsNo > 0 ? `V${data.vsNo}` : ''}{data.number > 0 ? `(${data.number}课时)` : ''}<Button size="small" onClick={() => onRestore()} >恢复上课</Button></div>
-          <div className='t-s-12'><span className='t-3'>申请时间:</span><span className='t-2 m-r-1'>{formatDate(data.suspendTime, 'YYYY-MM-DD HH:mm:ss')}</span><span className='t-3'>已停课:</span><span>{parseInt((new Date().getTime() - new Date(data.suspendTime).getTime()) / 86400000, 10)}Days/30</span></div>
+          <div className="text">
+            {data.course.title}
+            {data.vsNo > 0 ? `V${data.vsNo}` : ''}
+            {data.number > 0 ? `(${data.number}课时)` : ''}
+            <Button size="small" onClick={() => onRestore()}>
+              恢复上课
+            </Button>
+          </div>
+          <div className="t-s-12">
+            <span className="t-3">申请时间:</span>
+            <span className="t-2 m-r-1">{formatDate(data.suspendTime, 'YYYY-MM-DD HH:mm:ss')}</span>
+            <span className="t-3">已停课:</span>
+            <span>{parseInt((new Date().getTime() - new Date(data.suspendTime).getTime()) / 86400000, 10)}Days/30</span>
+          </div>
           <div className="right">
-            <More menu={[{ label: '评价', key: 'comment' }]}
+            <More
+              menu={[{ label: '评价', key: 'comment' }]}
               onClick={value => {
                 const { key } = value;
                 if (key === 'comment') {
                   onComment();
                 }
-              }} />
+              }}
+            />
           </div>
         </div>
         <div className="detail">
@@ -1187,7 +1361,7 @@ class CourseVs extends Component {
     const { list = [], index } = this.state;
     const appointment = data.appointments[index] || {};
     let status = '';
-    return ([
+    return [
       <div className="class-hour">
         {data.number > 1 && <div className="text">课时 {appointment.no}:{appointment.title}</div>}
         {data.number > 1 && <div className="right">
@@ -1209,7 +1383,7 @@ class CourseVs extends Component {
           return <TimeLineItem type={`${item}`} user={this.props.user} appointment={appointment} data={data} status={status} onUploadNote={onUploadNote} onUploadSupply={onUploadSupply} onUploadQuestion={onUploadQuestion} setCCTalkName={setCCTalkName} />;
         })}
       </div>,
-    ]);
+    ];
   }
 
   renderTable() {
@@ -1246,7 +1420,17 @@ class TimeLineItem extends Component {
   }
 
   renderDetail() {
-    const { data = {}, appointment = {}, type, onUploadNote, onUploadSupply, onDeleteNote, onDeleteSupply, onUploadQuestion, setCCTalkName } = this.props;
+    const {
+      data = {},
+      appointment = {},
+      type,
+      onUploadNote,
+      onUploadSupply,
+      onDeleteNote,
+      onDeleteSupply,
+      onUploadQuestion,
+      setCCTalkName,
+    } = this.props;
     const { status } = this.props;
     const { paper } = appointment;
     switch (type) {
@@ -1254,9 +1438,23 @@ class TimeLineItem extends Component {
         switch (status) {
           case 'end':
           case 'not':
-            return <span>请尽快与老师预约上课时间,老师微信:{data.teacher.wechat}扫码加微信</span>;
+            return (
+              <span>
+                请尽快与老师预约上课时间,老师微信:{data.teacher.wechat}扫码加微信{' '}
+                <Dropdown overlay={<Assets name="qrcode" src={data.teacher.qr} />}>
+                  <span>
+                    <Assets className="m-l-1" name="erweima" />
+                  </span>
+                </Dropdown>
+              </span>
+            );
           default:
-            return <span>{formatDate(appointment.startTime, 'YYYY-MM-DD HH:mm:ss')} ~ {formatDate(appointment.endTime, 'HH:mm:ss')}</span>;
+            return (
+              <span>
+                {formatDate(appointment.startTime, 'YYYY-MM-DD HH:mm:ss')} ~{' '}
+                {formatDate(appointment.endTime, 'HH:mm:ss')}
+              </span>
+            );
         }
       case '2':
         switch (status) {
@@ -1267,7 +1465,11 @@ class TimeLineItem extends Component {
               return Common.upload({ file }).then((result => onUploadQuestion(appointment, result.url, file.name)));
             }}><span className="link">点此上传</span></FileUpload>;
           default:
-            return <a href={appointment.questionFile} target="_blank">{appointment.questionFileName || '文件'}</a>;
+            return (
+              <a href={appointment.questionFile} target="_blank">
+                {appointment.questionFileName || '文件'}
+              </a>
+            );
         }
       case '3':
         switch (status) {
@@ -1286,14 +1488,19 @@ class TimeLineItem extends Component {
               if (this.state.cctalkName) setCCTalkName(appointment, this.state.cctalkName);
             }} >提交</Button></div>;
           default:
-            return <span>
-              CCtalk 频道号 :{appointment.cctalkChannel} <a className="link" href="" target="_black">CC talk使用手册</a>
-            </span>;
+            return (
+              <span>
+                CCtalk 频道号 :{appointment.cctalkChannel}{' '}
+                <a className="link" href="" target="_black">
+                  CC talk使用手册
+                </a>
+              </span>
+            );
         }
       case '4':
         switch (status) {
           case 'end':
-            return <span className="link" >点此上传</span>;
+            return <span className="link">点此上传</span>;
           case 'not':
             return <span className="link" onClick={() => onUploadNote(appointment, { appointmentId: appointment.id, recordId: appointment.recordId })}>点此上传</span>;
           default:
@@ -1327,7 +1534,7 @@ class TimeLineItem extends Component {
       case '5':
         switch (status) {
           case 'end':
-            return <span className="link" >写留言</span>;
+            return <span className="link">写留言</span>;
           case 'not':
             return <span className="link" onClick={() => onUploadSupply(appointment, { appointmentId: appointment.id, recordId: appointment.recordId })}>写留言</span>;
           default:
@@ -1361,15 +1568,24 @@ class TimeLineItem extends Component {
         return [
           <div>
             <span>基本情况</span>
-            <a href={status !== 'end' ? '' : ''} className="link">填写</a>
+            <a href={status !== 'end' ? '' : ''} className="link">
+              填写
+            </a>
           </div>,
           <div>
             <span>备考细节</span>
-            <a href={status !== 'end' ? '' : ''} className="link">填写</a>
+            <a href={status !== 'end' ? '' : ''} className="link">
+              填写
+            </a>
           </div>,
         ];
       case '7':
-        return <ProgressText progress={paper ? formatPercent(paper.report.userNumber, paper.report.questionNumber) : 0} size="small" />;
+        return (
+          <ProgressText
+            progress={paper ? formatPercent(paper.report.userNumber, paper.report.questionNumber) : 0}
+            size="small"
+          />
+        );
       default:
         return <div />;
     }

+ 85 - 50
front/project/www/routes/my/note/page.js

@@ -11,6 +11,7 @@ import menu, { refreshQuestionType, refreshStruct } from '../index';
 import Tabs from '../../../components/Tabs';
 import { TimeRange } from '../../../../Constant';
 import { My } from '../../../stores/my';
+import { OpenText } from '../../../components/Open';
 
 const columns = [
   {
@@ -36,10 +37,11 @@ const columns = [
         <div className="group">
           <Link to="">{text}</Link>
         </div>
-      ) : (<div className="sub">
-        <div className="date">{text.split(' ')[0]}</div>
-        <div className="date">{text.split(' ')[1]}</div>
-      </div>
+      ) : (
+        <div className="sub">
+          <div className="date">{text.split(' ')[0]}</div>
+          <div className="date">{text.split(' ')[1]}</div>
+        </div>
       );
     },
   },
@@ -53,7 +55,7 @@ const columns = [
           <Link to="">{text}</Link>
         </div>
       ) : (
-        <div className="sub">{text}</div>
+        <OpenText>{text}</OpenText>
       );
     },
   },
@@ -128,21 +130,33 @@ export default class extends Page {
       data.filterMap.timerange = data.timerange;
     }
     const [startTime, endTime] = timeRange(data.timerange);
-    refreshQuestionType(this, data.subject, data.questionType, { all: true, needSentence: false, allSubject: true })
-      .then(({ questionTypes }) => {
-        return refreshStruct(this, data.tab, data.one, data.two, {
-          all: true, needPreview: false, needTextbook: false,
-        })
-          .then(({ structIds, latest, year }) => {
-            My.listQuestionNote(Object.assign({ module: data.tab, questionTypes, structIds, latest, year, startTime, endTime }, this.state.search, {
-              order: Object.keys(data.sortMap).map(key => {
-                return `${key} ${data.sortMap[key]}`;
-              }).join(','),
-            })).then(result => {
-              this.setState({ list: result.list, total: result.total, page: data.page });
-            });
-          });
+    refreshQuestionType(this, data.subject, data.questionType, {
+      all: true,
+      needSentence: false,
+      allSubject: true,
+    }).then(({ questionTypes }) => {
+      return refreshStruct(this, data.tab, data.one, data.two, {
+        all: true,
+        needPreview: false,
+        needTextbook: false,
+      }).then(({ structIds, latest, year }) => {
+        My.listQuestionNote(
+          Object.assign(
+            { module: data.tab, questionTypes, structIds, latest, year, startTime, endTime },
+            this.state.search,
+            {
+              order: Object.keys(data.sortMap)
+                .map(key => {
+                  return `${key} ${data.sortMap[key]}`;
+                })
+                .join(','),
+            },
+          ),
+        ).then(result => {
+          this.setState({ list: result.list, total: result.total, page: data.page });
+        });
       });
+    });
   }
 
   onTabChange(tab) {
@@ -179,7 +193,7 @@ export default class extends Page {
     }
   }
 
-  onAction() { }
+  onAction() {}
 
   onSelect(selectList) {
     this.setState({ selectList });
@@ -191,7 +205,16 @@ export default class extends Page {
   }
 
   renderTable() {
-    const { tab, questionSubjectSelect, questionSubjectMap = {}, oneSelect, twoSelectMap = {}, filterMap = {}, sortMap = {}, list = [] } = this.state;
+    const {
+      tab,
+      questionSubjectSelect,
+      questionSubjectMap = {},
+      oneSelect,
+      twoSelectMap = {},
+      filterMap = {},
+      sortMap = {},
+      list = [],
+    } = this.state;
     const { selectList = [], allChecked, page, total } = this.state;
     return (
       <div className="table-layout">
@@ -208,34 +231,44 @@ export default class extends Page {
         />
         <UserAction
           search
-          selectList={[{
-            children: [{
-              key: 'subject',
-              placeholder: '学科',
-              select: questionSubjectSelect,
-            }, {
-              placeholder: '题型',
-              key: 'questionType',
-              be: 'subject',
-              selectMap: questionSubjectMap,
-            }],
-          }, {
-            label: '范围',
-            children: [{
-              key: 'one',
-              placeholder: '全部',
-              select: oneSelect,
-            }, {
-              key: 'two',
-              be: 'one',
-              placeholder: '全部',
-              selectMap: twoSelectMap,
-            }],
-          }, {
-            right: true,
-            key: 'timerange',
-            select: TimeRange,
-          }]}
+          selectList={[
+            {
+              children: [
+                {
+                  key: 'subject',
+                  placeholder: '学科',
+                  select: questionSubjectSelect,
+                },
+                {
+                  placeholder: '题型',
+                  key: 'questionType',
+                  be: 'subject',
+                  selectMap: questionSubjectMap,
+                },
+              ],
+            },
+            {
+              label: '范围',
+              children: [
+                {
+                  key: 'one',
+                  placeholder: '全部',
+                  select: oneSelect,
+                },
+                {
+                  key: 'two',
+                  be: 'one',
+                  placeholder: '全部',
+                  selectMap: twoSelectMap,
+                },
+              ],
+            },
+            {
+              right: true,
+              key: 'timerange',
+              select: TimeRange,
+            },
+          ]}
           filterMap={filterMap}
           onFilter={value => this.onFilter(value)}
         />
@@ -276,7 +309,9 @@ export default class extends Page {
             </div>
           );
         })}
-        {total && list.length > 0 && <UserPagination total={total} current={page} onChange={(p) => this.onChangePage(p)} />}
+        {total && list.length > 0 && (
+          <UserPagination total={total} current={page} onChange={p => this.onChangePage(p)} />
+        )}
       </div>
     );
   }

+ 78 - 12
front/project/www/routes/my/order/page.js

@@ -1,14 +1,17 @@
 import React from 'react';
 import './index.less';
+import { Icon, Radio } from 'antd';
 import Page from '@src/containers/Page';
 import { asyncSMessage } from '@src/services/AsyncTools';
 import { getMap, formatMoney, formatDate } from '@src/services/Tools';
 import UserLayout from '../../../layouts/User';
 import menu from '../index';
 import UserTable from '../../../components/UserTable';
+import Modal from '../../../components/Modal';
+import More from '../../../components/More';
+import IconButton from '../../../components/IconButton';
 import { Order } from '../../../stores/order';
 import { RecordSource, ServiceKey } from '../../../../Constant';
-import More from '../../../components/More';
 
 const RecordSourceMap = getMap(RecordSource, 'value', 'label');
 const ServiceKeyMap = getMap(ServiceKey, 'value', 'label');
@@ -49,18 +52,26 @@ const columns = [
           default:
         }
       };
+      let content = '';
       if (record.checkouts.length > 3) {
-        return <span>{formatTitle(record.checkouts[0])}<br />等{record.checkouts.length}个商品<More actionList={actionList} onAction={onAction} /></span>;
+        content = [<div className="flex-block">{formatTitle(record.checkouts[0])}<br />等{record.checkouts.length}个商品</div>];
+      } else {
+        content = record.checkouts.map(row => {
+          return formatTitle(row);
+        }).join(<br />);
       }
-      return record.checkouts.map(row => {
-        return formatTitle(row);
-      });
+      return <div className="t-2">
+        <div className="flex-layout m-b-5">
+          {content}
+          <More actionList={actionList} onAction={onAction} ><IconButton type="more" /></More>
+        </div>
+      </div>;
     },
   },
   {
     title: '购买时间',
     key: 'createTime',
-    render: (text) => {
+    render: text => {
       return formatDate(text, 'YYYY-MM-DD\nHH:mm:ss');
     },
   },
@@ -74,7 +85,7 @@ const columns = [
   {
     title: '付款金额',
     key: 'money',
-    render: (text) => {
+    render: text => {
       return formatMoney(text);
     },
   },
@@ -87,14 +98,15 @@ export default class extends Page {
   }
 
   initState() {
-    return {};
+    return {
+      list: [{}],
+    };
   }
 
   initData() {
-    Order.list(this.state.search)
-      .then(result => {
-        this.setState({ list: result.list, total: result.total, page: this.state.search.page });
-      });
+    Order.list(this.state.search).then(result => {
+      this.setState({ list: result.list, total: result.total, page: this.state.search.page });
+    });
   }
 
   onChangePage(page) {
@@ -129,6 +141,60 @@ export default class extends Page {
           total={total}
           current={page}
         />
+        <Modal title="开发票" width={630} btnType="link" confirmText="申请" onConfirm={() => { }} onCancel={() => { }}>
+          <div className="input-layout m-b-2 t-2 t-s-16">
+            <div className="label m-r-5">发票类型:</div>
+            <div className="input-block">
+              <Radio />
+              普通增值税电子发票
+            </div>
+          </div>
+          <div className="input-layout m-b-2 t-2 t-s-16">
+            <div className="label m-r-5">抬头类型:</div>
+            <div className="input-block">
+              <span className="m-r-2">
+                <Radio />
+                个人
+              </span>
+              <span className="m-l-2">
+                <Radio />
+                公司
+              </span>
+            </div>
+          </div>
+          <div className="input-layout m-b-2 t-2 t-s-16">
+            <div className="label m-r-5">发票抬头:</div>
+            <div className="input-block">
+              <input style={{ width: 330, paddingTop: 3, paddingBottom: 3 }} className="b-c-1 p-l-1 p-r-1 p-l-1" />
+            </div>
+          </div>
+          <div className="input-layout m-b-2 t-2 t-s-16">
+            <div className="label m-r-5">纳税人识别号:</div>
+            <div className="input-block">
+              <input style={{ width: 300, paddingTop: 3, paddingBottom: 3 }} className="b-c-1 p-l-1 p-r-1 p-l-1" />
+            </div>
+          </div>
+          <div className="input-layout m-b-2 t-2 t-s-16">
+            <div className="label m-r-5">发票内容:</div>
+            <div className="input-block">
+              <Radio />
+              商品明细
+            </div>
+          </div>
+          <div className="input-layout t-2 t-s-16">
+            <div className="label m-r-5">发票金额:</div>
+            <div className="input-block">¥ 210010.0</div>
+          </div>
+        </Modal>
+        <Modal title="申请成功" width={630} confirmText="好的,知道了" btnAlign="center" onConfirm={() => { }}>
+          <div className="t-2 t-s-18">
+            <Icon className="t-5 m-r-5" type="check" />
+            我们会在三个工作日内将电子发票发送至您的绑定邮箱:
+          </div>
+          <div className="t-2 t-s-18">201-30-2103@12321.com</div>
+          <div className="m-b-2 t-2 t-s-18">请注意查收。</div>
+          <div className="m-t-2 t-3 t-s-14">我们也会通过站内信的方式通知您</div>
+        </Modal>
       </div>
     );
   }