KaysonCui 5 lat temu
rodzic
commit
85f5a5d2d8
61 zmienionych plików z 1551 dodań i 158 usunięć
  1. 16 0
      front/project/www/app.less
  2. BIN
      front/project/www/assets/Purchased.png
  3. BIN
      front/project/www/assets/VIP_1.png
  4. BIN
      front/project/www/assets/add.png
  5. BIN
      front/project/www/assets/answer.png
  6. BIN
      front/project/www/assets/call.png
  7. BIN
      front/project/www/assets/cart.png
  8. BIN
      front/project/www/assets/dayi.png
  9. BIN
      front/project/www/assets/excitation.png
  10. BIN
      front/project/www/assets/footer_next_highlight_1.png
  11. BIN
      front/project/www/assets/footer_previous_highlight_1.png
  12. BIN
      front/project/www/assets/full2.png
  13. BIN
      front/project/www/assets/jijing.png
  14. BIN
      front/project/www/assets/kf.png
  15. BIN
      front/project/www/assets/mail.png
  16. BIN
      front/project/www/assets/mokao.png
  17. BIN
      front/project/www/assets/next2.png
  18. BIN
      front/project/www/assets/noviciate.png
  19. BIN
      front/project/www/assets/play.png
  20. BIN
      front/project/www/assets/play2.png
  21. BIN
      front/project/www/assets/question.png
  22. BIN
      front/project/www/assets/question_off.png
  23. BIN
      front/project/www/assets/question_on.png
  24. BIN
      front/project/www/assets/reduction2.png
  25. BIN
      front/project/www/assets/self_paced.png
  26. BIN
      front/project/www/assets/stop.png
  27. BIN
      front/project/www/assets/stop2.png
  28. BIN
      front/project/www/assets/teacher.png
  29. BIN
      front/project/www/assets/wechat_1.png
  30. BIN
      front/project/www/assets/xinshoufudao.png
  31. BIN
      front/project/www/assets/xitongshouke.png
  32. BIN
      front/project/www/assets/zhenduanfudao.png
  33. 29 0
      front/project/www/components/Filter/index.js
  34. 22 0
      front/project/www/components/Filter/index.less
  35. 2 1
      front/project/www/components/Header/index.less
  36. 86 0
      front/project/www/components/Item/index.js
  37. 142 0
      front/project/www/components/Item/index.less
  38. 167 0
      front/project/www/components/Other/index.js
  39. 175 0
      front/project/www/components/Other/index.less
  40. 4 0
      front/project/www/components/Tabs/index.less
  41. 2 2
      front/project/www/local.json
  42. 9 0
      front/project/www/routes/course/answer/index.js
  43. 37 0
      front/project/www/routes/course/answer/index.less
  44. 161 0
      front/project/www/routes/course/answer/page.js
  45. 6 0
      front/project/www/routes/course/index.js
  46. 4 2
      front/project/www/routes/room/main/index.js
  47. 128 0
      front/project/www/routes/course/main/index.less
  48. 172 0
      front/project/www/routes/course/main/page.js
  49. 9 0
      front/project/www/routes/course/note/index.js
  50. 41 0
      front/project/www/routes/course/note/index.less
  51. 121 0
      front/project/www/routes/course/note/page.js
  52. 11 0
      front/project/www/routes/course/online/index.js
  53. 54 0
      front/project/www/routes/course/online/index.less
  54. 146 0
      front/project/www/routes/course/online/page.js
  55. 2 2
      front/project/www/routes/index.js
  56. 0 76
      front/project/www/routes/page/home/index.less
  57. 3 51
      front/project/www/routes/page/home/page.js
  58. 0 3
      front/project/www/routes/room/index.js
  59. 0 3
      front/project/www/routes/room/main/index.less
  60. 0 18
      front/project/www/routes/room/main/page.js
  61. 2 0
      front/src/containers/App.js

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

@@ -290,10 +290,22 @@
   color: #A2AAB5FF !important;
 }
 
+.t-11 {
+  color: #F36565FF !important;
+}
+
+.t-12 {
+  color: #F2B252FF !important;
+}
+
 .b-c-1 {
   background: #F7F7F7;
 }
 
+.b-c-2 {
+  background: #EAEEF4FF;
+}
+
 .f-s-16 {
   font-size: 16px;
 }
@@ -322,6 +334,10 @@
   font-size: 20px;
 }
 
+.t-s-22 {
+  font-size: 22px;
+}
+
 .t-s-24 {
   font-size: 24px;
 }

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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


+ 29 - 0
front/project/www/components/Filter/index.js

@@ -0,0 +1,29 @@
+import React from 'react';
+import './index.less';
+
+function Filter(props) {
+  const { list = [], filter = {}, onFilter } = props;
+  return (
+    <div className="filter">
+      {list.map(item => {
+        return (
+          <div className="list">
+            {item.children &&
+              item.children.map(child => {
+                return (
+                  <div
+                    className={`item ${filter[item.key] === child.key ? 'active' : ''}`}
+                    onClick={() => onFilter(item.key, child.key)}
+                  >
+                    {child.title}
+                  </div>
+                );
+              })}
+          </div>
+        );
+      })}
+    </div>
+  );
+}
+Filter.propTypes = {};
+export default Filter;

+ 22 - 0
front/project/www/components/Filter/index.less

@@ -0,0 +1,22 @@
+@import '../../app.less';
+
+.filter {
+  color: #5E677BFF;
+  font-size: 12px;
+  padding: 15px 0 10px;
+  border-bottom: 1px solid #eee;
+
+  .list {
+    margin-bottom: 5px;
+
+    .item {
+      display: inline-block;
+      margin: 0 15px;
+      cursor: pointer;
+    }
+
+    .item.active {
+      color: #4292F0;
+    }
+  }
+}

+ 2 - 1
front/project/www/components/Header/index.less

@@ -92,7 +92,8 @@
   }
 }
 
-.main #header {
+.main #header,
+.course #header {
   .body {
     width: 1200px;
   }

+ 86 - 0
front/project/www/components/Item/index.js

@@ -0,0 +1,86 @@
+import React, { Component } from 'react';
+import './index.less';
+import Assets from '@src/components/Assets';
+import Button from '../Button';
+
+export class SingleItem extends Component {
+  render() {
+    return (
+      <div className="single-item">
+        <div className="img">
+          <div className="title">
+            <div className="tag">新手</div>OG20整合刷题-语法SC
+          </div>
+          <div className="left">
+            <span>课时数: 20</span>
+            <span>133h32min</span>
+          </div>
+          <div className="right">
+            <span>234234次观看</span>
+          </div>
+        </div>
+        <div className="name">
+          <span>授课老师:李小小</span>
+          <span>优质问答: 999</span>
+          <span>有效期: 3个月</span>
+        </div>
+        <div className="money">¥ 15000</div>
+        <div className="action">
+          <Button radius size="lager">
+            立即购买
+          </Button>
+          <Button className="f-r" theme="default" radius size="lager">
+            查看课程
+          </Button>
+          <Button className="f-r" theme="default" radius size="lager">
+            <Assets name="add" />
+          </Button>
+        </div>
+        <Assets className="buyed" width={75} height={75} name="Purchased" />
+      </div>
+    );
+  }
+}
+
+export class PackageItem extends Component {
+  render() {
+    return (
+      <div className="package-item">
+        <div className="block m-b-1">
+          <div className="title t-1 m-b-5 f-w-b">
+            <div className="tag f-w-d">新手</div>OG20整合刷题-语法SC
+          </div>
+          <div className="t-1 t-s-12 m-b-5">授课老师 李小小</div>
+          <div className="t-1 t-s-12 m-b-2">包含最新 XXXXXXX 的全部课程XXXXX;机经券×1+VIP×3 月+模考×1</div>
+          <div className="t-1 t-s-12">包含课程</div>
+          <div className="p-t-5">
+            <div className="t m-b-1 t-4 m-r-5 t-s-12 d-i-b p-5">OG20阅读刷题(7课时)</div>
+          </div>
+          <div className="t-1 t-s-12">配套服务</div>
+          <div className="p-t-5">
+            <div className="t m-b-1 t-4 m-r-5 t-s-12 d-i-b p-5">OG20阅读刷题(7课时)</div>
+          </div>
+          <div className="t-1 t-s-12">赠送服务</div>
+          <div className="p-t-5">
+            <div className="t m-b-1 t-4 m-r-5 t-s-12 d-i-b p-5">OG20阅读刷题(7课时)</div>
+          </div>
+        </div>
+        <div className="t-1 t-s-12">
+          原价: <span className="t-d-l-t">¥18888</span>
+        </div>
+        <div className="t-7 t-s-18 f-w-b m-b-1">套餐价: ¥8888</div>
+        <div className="action">
+          <Button radius size="lager">
+            立即购买
+          </Button>
+          <Button className="f-r" theme="default" radius size="lager">
+            查看课程
+          </Button>
+          <Button className="f-r" theme="default" radius size="lager">
+            <Assets name="add" />
+          </Button>
+        </div>
+      </div>
+    );
+  }
+}

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

@@ -0,0 +1,142 @@
+.single-item {
+  display: inline-block;
+  width: 350px;
+  position: relative;
+  border: 1px solid #E5E5E5FF;
+  border-radius: 4px;
+  background: #FBFBFBFF;
+
+  .img {
+    width: 100%;
+    height: 250px;
+    position: relative;
+    background: #eee;
+    padding-top: 10px;
+    margin-bottom: 10px;
+
+    .title {
+      font-weight: 500;
+      color: rgba(255, 255, 255, 1);
+      line-height: 24px;
+      font-size: 16px;
+      margin-left: 15px;
+
+      .tag {
+        display: inline-block;
+        font-size: 12px;
+        color: #fff;
+        width: 44px;
+        height: 24px;
+        background: rgba(104, 101, 253, 1);
+        border-radius: 2px;
+        text-align: center;
+        margin-right: 5px;
+      }
+    }
+
+    .left {
+      position: absolute;
+      bottom: 10px;
+      left: 20px;
+      color: #fff;
+      font-size: 12px;
+
+      span {
+        margin-right: 10px;
+      }
+    }
+
+    .right {
+      position: absolute;
+      right: 20px;
+      bottom: 10px;
+      color: #fff;
+      font-size: 12px;
+    }
+  }
+
+  .name {
+    margin-bottom: 5px;
+    padding-left: 15px;
+
+    span {
+      margin-right: 20px;
+      color: #5E677BFF;
+    }
+  }
+
+  .money {
+    padding-left: 15px;
+    color: #F09842FF;
+    font-weight: 600;
+    font-size: 20px;
+    margin-bottom: 5px;
+  }
+
+  .action {
+    padding: 0 15px;
+    margin-bottom: 20px;
+    overflow: hidden;
+
+    .default.button {
+      color: #4292F0;
+    }
+  }
+
+  .buyed {
+    position: absolute;
+    bottom: 15px;
+    left: 15px;
+  }
+}
+
+.package-item {
+  display: inline-block;
+  width: 350px;
+  position: relative;
+
+  .block {
+    background: rgba(251, 251, 251, 1);
+    border-radius: 4px;
+    border: 1px solid rgba(229, 229, 229, 1);
+    padding: 15px;
+
+    .title {
+      font-weight: 500;
+      line-height: 24px;
+      font-size: 16px;
+
+      .tag {
+        display: inline-block;
+        font-size: 12px;
+        color: #fff;
+        width: 44px;
+        height: 24px;
+        background: rgba(104, 101, 253, 1);
+        border-radius: 2px;
+        text-align: center;
+        margin-right: 5px;
+      }
+    }
+
+    .t {
+      border-radius: 3px;
+      border: 1px solid rgba(65, 166, 243, 1);
+    }
+  }
+
+  .action {
+    margin-bottom: 20px;
+    overflow: hidden;
+
+    .default.button {
+      color: #4292F0;
+    }
+  }
+
+  .buyed {
+    position: absolute;
+    bottom: 15px;
+    left: 15px;
+  }
+}

+ 167 - 0
front/project/www/components/Other/index.js

@@ -0,0 +1,167 @@
+import React, { Component } from 'react';
+import './index.less';
+import { Popover } from 'antd';
+import { Carousel } from 'antd-mobile';
+import Assets from '@src/components/Assets';
+import { formatDate } from '@src/services/Tools';
+import Button from '../Button';
+
+export class CommentFalls extends Component {
+  createLayout() {
+    const msnry = new Masonry('.comment-falls', {
+      itemSelector: '.grid-item',
+    });
+    msnry.layout();
+  }
+
+  render() {
+    const { list = [] } = this.props;
+    return (
+      <div className="comment-falls">
+        {list.map(row => {
+          return (
+            <div className="grid-item">
+              <div className="item">
+                <div className="item-header">
+                  <Assets src={row.avatar} />
+                  <div className="name">{row.nickname}</div>
+                  <div className="date">{formatDate(row.date, 'yyyy年mm月dd日')}</div>
+                </div>
+                <div className="item-body">{row.content}</div>
+              </div>
+            </div>
+          );
+        })}
+      </div>
+    );
+  }
+}
+
+export class AnswerCarousel extends Component {
+  constructor(props) {
+    super(props);
+    this.state = { index: 1 };
+  }
+
+  onNext() {
+    const index = this.state.index + 1;
+    const { list = [] } = this.props;
+    if (index >= list.length - 1) return;
+    this.setState({ index });
+  }
+
+  onPrev() {
+    const index = this.state.index - 1;
+    if (index < 1) return;
+    this.setState({ index });
+  }
+
+  render() {
+    const { index } = this.state;
+    const { list = [], hideBtn = false } = this.props;
+    return (
+      <div className="other-answer-carousel">
+        <div className="body">
+          {list.length > 0 && (
+            <Carousel selectedIndex={index} cellSpacing={40} dots={false} slideWidth={'350px'}>
+              {list.map(item => {
+                return (
+                  <div className="item">
+                    <div className="item-block">
+                      <Assets name="question" />
+                      {item.question}
+                    </div>
+                    <div className="item-block">
+                      <Assets name="answer" />
+                      {item.answer}
+                    </div>
+                  </div>
+                );
+              })}
+            </Carousel>
+          )}
+          <div className="fixed" />
+          <Assets name="footer_next_highlight_1" className="next" onClick={() => this.onNext()} />
+          <Assets name="footer_previous_highlight_1" className="prev" onClick={() => this.onPrev()} />
+        </div>
+        {!hideBtn && (
+          <Button size="lager" radius>
+            <Assets name="kf" className="m-r-5" />
+            立即咨询
+          </Button>
+        )}
+      </div>
+    );
+  }
+}
+
+export class Consultation extends Component {
+  render() {
+    return (
+      <div className="other-consultation">
+        <div className="list">
+          <div className="item">
+            <Assets name="call" />
+          </div>
+          <div className="item">
+            <Assets name="mail" />
+          </div>
+          <div className="item">
+            <Assets name="wechat_1" />
+          </div>
+        </div>
+        <div className="line" />
+        <div className="list">
+          <div className="item">
+            <div className="t-1 t-s-16 m-b-10">电话咨询</div>
+            <div className="t-1 t-s-16 t-w-b">(400)800-8888</div>
+          </div>
+          <div className="item">
+            <div className="t-1 t-s-16 m-b-10">邮件咨询</div>
+            <div className="t-1 t-s-16 t-w-b">service@cat.com</div>
+          </div>
+          <div className="item">
+            <div className="t-1 t-s-16 m-b-10">微信咨询</div>
+            <div className="t-1 t-s-16 t-w-b">
+              <Popover content={<Assets name="qrcode" />}>
+                <span>
+                  <Assets name="erweima" />
+                </span>
+              </Popover>
+            </div>
+          </div>
+        </div>
+      </div>
+    );
+  }
+}
+
+export class Contact extends Component {
+  render() {
+    const { data = {} } = this.props;
+    return (
+      <div className="other-contact">
+        <div className="body">
+          <div className="step-list">
+            <div className="step">
+              <div className="title">工作机会</div>
+              <Assets name="logo2" />
+            </div>
+            <div className="step" style={{ paddingLeft: 80 }}>
+              <div className="title">联系我们</div>
+              <div className="desc">{data.phone}</div>
+              <div className="desc">{data.email}</div>
+              <div className="desc">{data.wechat}</div>
+            </div>
+            <div className="step" style={{ paddingLeft: 140 }}>
+              <div className="title">关注我们</div>
+              <div className="qrcode">
+                <Assets src={data.wechatImage} />
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+    );
+  }
+}

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

@@ -0,0 +1,175 @@
+.comment-falls {
+  height: 530px;
+  overflow-y: auto;
+  padding-top: 20px;
+  padding-bottom: 20px;
+  background: #fff;
+
+  .grid-item {
+    width: 25%;
+    padding: 5px;
+
+    .item {
+      max-height: 260px;
+      background: #FAFAFA;
+      border: 1px solid #F1F4F7;
+      padding: 20px;
+      overflow: hidden;
+
+      .item-header {
+        margin-bottom: 10px;
+
+        .avatar {
+          width: 40px;
+          height: 40px;
+        }
+
+        .name {
+          color: #5E677B;
+          font-size: 16px;
+          vertical-align: middle;
+          display: inline-block;
+        }
+
+        .date {
+          color: #8897A8;
+          font-size: 12px;
+          float: right;
+          vertical-align: middle;
+        }
+      }
+
+      .item-body {
+        color: #8897A8;
+        padding-left: 10px;
+        overflow: hidden;
+      }
+    }
+  }
+}
+
+.other-contact {
+  .body {
+    width: 1200px;
+    margin: 0 auto;
+
+    .m-title {
+      font-size: 32px;
+      font-weight: 600;
+      color: #303139;
+    }
+  }
+
+  height: 420px;
+  padding-top: 80px;
+  background: #6865FD;
+
+  .step-list {}
+
+  .step {
+    width: 33.33%;
+    display: inline-block;
+    box-sizing: border-box;
+    vertical-align: top;
+
+    .title {
+      font-size: 16px;
+      color: #fff;
+      margin-bottom: 30px;
+      font-weight: 600;
+    }
+
+    .desc {
+      font-size: 16px;
+      color: #fff;
+      margin-bottom: 10px;
+    }
+
+    .qrcode {
+      background: #8683fb;
+      padding: 15px;
+      display: inline-block;
+    }
+  }
+}
+
+.other-consultation {
+  width: 1200px;
+  margin: 0 auto;
+  padding: 100px 0;
+
+  .line {
+    border-bottom: 2px dashed #C2C2DFFF;
+    margin: 20px 0;
+  }
+
+  .list {
+    .item {
+      display: inline-block;
+      width: 33.33%;
+      text-align: center;
+    }
+  }
+}
+
+.other-answer-carousel {
+  background: #fafafa;
+  text-align: center;
+  padding: 70px 0;
+
+  .body {
+    width: 1150px;
+    margin: 0 auto;
+    position: relative;
+
+    .fixed {
+      position: absolute;
+      top: 0;
+      left: 0;
+      bottom: 0;
+      right: 0;
+    }
+
+    .next {
+      position: absolute;
+      right: -50px;
+      top: 90px;
+    }
+
+    .prev {
+      position: absolute;
+      left: -50px;
+      top: 90px;
+    }
+
+    .slider-frame {
+      padding: 40px 0 !important;
+    }
+  }
+
+  .item {
+    width: 354px;
+    height: 155px;
+    background: rgba(255, 255, 255, 1);
+    box-shadow: 0px 5px 10px 0px rgba(156, 183, 223, 0.14), 0px 15px 28px 0px rgba(0, 0, 0, 0.01);
+    border-radius: 4px;
+    position: relative;
+    padding: 30px;
+    padding-left: 70px;
+
+    .item-block {
+      position: relative;
+      height: 40px;
+      text-align: left;
+      font-size: 12px;
+      line-height: 16px;
+      color: #303139FF;
+      margin-bottom: 10px;
+
+      .assets {
+        position: absolute;
+        left: -40px;
+      }
+    }
+  }
+}

+ 4 - 0
front/project/www/components/Tabs/index.less

@@ -188,6 +188,10 @@
     right: -13px;
   }
 
+  .tab:last-child::after {
+    display: none;
+  }
+
   .tab:hover,
   .tab.active {
     color: @theme_color;

+ 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"
     ]
   }
-}
+}

+ 9 - 0
front/project/www/routes/course/answer/index.js

@@ -0,0 +1,9 @@
+export default {
+  path: '/course/answer',
+  key: 'course-answer',
+  title: '课堂-问答',
+  needLogin: false,
+  component() {
+    return import('./page');
+  },
+};

+ 37 - 0
front/project/www/routes/course/answer/index.less

@@ -0,0 +1,37 @@
+@charset "utf-8";
+
+#course-answer {
+
+  .top {
+    height: 60px;
+    line-height: 60px;
+  }
+
+  .center {
+    background: #fff;
+    border-radius: 14px;
+    padding: 20px;
+
+    .answer-layout {
+      border-bottom: 1px solid #eee;
+      padding-top: 20px;
+      padding-left: 15px;
+
+      .small-tag {
+        display: inline-block;
+        height: 16px;
+        background: rgba(163, 207, 255, 1);
+        border-radius: 2px;
+        color: #fff;
+        line-height: 16px;
+        font-size: 10px;
+        padding: 0 9px;
+      }
+
+      .desc {
+        color: #303139;
+        margin-bottom: 20px;
+      }
+    }
+  }
+}

+ 161 - 0
front/project/www/routes/course/answer/page.js

@@ -0,0 +1,161 @@
+import React from 'react';
+import './index.less';
+import Page from '@src/containers/Page';
+import { formatDate } from '@src/services/Tools';
+import UserAction from '../../../components/UserAction';
+import UserPagination from '../../../components/UserPagination';
+import Tabs from '../../../components/Tabs';
+import { OpenText } from '../../../components/Open';
+import { Button } from '../../../components/Button';
+
+export default class extends Page {
+  constructor(props) {
+    props.size = 10;
+    super(props);
+  }
+
+  initState() {
+    return {
+      filterMap: {},
+      list: [],
+      tab: '1',
+    };
+  }
+
+  onTabChange(tab) {
+    const data = { tab };
+    this.refreshQuery(data);
+  }
+
+  onFilter(value) {
+    this.search(value, false);
+    this.initData();
+  }
+
+  onSearch(value) {
+    this.search({ keyword: value }, false);
+    this.initData();
+  }
+
+  onAction() {}
+
+  delAsk(id) {
+    console.log(id);
+  }
+
+  renderView() {
+    const {
+      tab,
+      questionSubjectSelect,
+      questionSubjectMap = {},
+      oneSelect,
+      twoSelectMap = {},
+      filterMap = {},
+      list = [],
+    } = this.state;
+    const { total, page } = this.state;
+    return (
+      <div>
+        <div className="top content t-8">
+          千行课堂 > 全部课程 > OG20综合刷题 > 课时3 > <span className="t-1">全部问答</span>
+          <div className="f-r">返回课程</div>
+        </div>
+        <div className="center content">
+          <div className="t-1 t-s-20 m-b-2">OG20综合刷题——第3课时:XXXXXXX</div>
+          <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.onTabChange(key)}
+          />
+          <UserAction
+            search
+            defaultSearch={filterMap.keyword}
+            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,
+                  },
+                ],
+              },
+            ]}
+            filterMap={filterMap}
+            onFilter={value => this.onFilter(value)}
+            onSearch={value => this.onSearch(value)}
+          />
+          {list.map(item => {
+            return (
+              <div className="answer-layout">
+                <div className="t-2">课时1 01:00~05:00</div>
+                <div className="t-2">课程内容: 单词 avoid 的使用场景应该出现在这些地方</div>
+                {item.answerStatus === 0 && (
+                  <div className="f-r">
+                    <Button radius size="small" onClick={() => this.delAsk(item.id)}>
+                      删除
+                    </Button>
+                  </div>
+                )}
+                <div>
+                  <div className="small-tag">提问</div>
+                  <div className="f-r t-2 t-s-12">{formatDate(item.createTime, 'YYYY-MM-DD HH:mm:ss')}</div>
+                </div>
+                <div className="desc">
+                  <OpenText>{item.content}</OpenText>
+                </div>
+                {item.answerStatus > 0 && (
+                  <div>
+                    <div className="small-tag">回答</div>
+                    <div className="f-r t-2 t-s-12">{formatDate(item.answerTime, 'YYYY-MM-DD HH:mm:ss')}</div>
+                  </div>
+                )}
+                {item.answerStatus > 0 && (
+                  <div className="desc">
+                    <OpenText>{item.answer}</OpenText>
+                  </div>
+                )}
+              </div>
+            );
+          })}
+          {total > 0 && list.length > 0 && (
+            <UserPagination
+              total={total}
+              pageSize={this.state.search.size}
+              current={page}
+              onChange={p => this.onChangePage(p)}
+            />
+          )}
+        </div>
+      </div>
+    );
+  }
+}

+ 6 - 0
front/project/www/routes/course/index.js

@@ -0,0 +1,6 @@
+import main from './main';
+import online from './online';
+import answer from './answer';
+import note from './note';
+
+export default [main, online, answer, note];

+ 4 - 2
front/project/www/routes/room/main/index.js

@@ -1,8 +1,10 @@
 export default {
-  path: '/room',
-  key: 'room-main',
+  path: '/course',
+  key: 'course-main',
   title: '课堂',
   needLogin: false,
+  repeat: true,
+  tab: 'course',
   component() {
     return import('./page');
   },

+ 128 - 0
front/project/www/routes/course/main/index.less

@@ -0,0 +1,128 @@
+@charset "utf-8";
+
+#course-main {
+  .block-1 {
+    height: 400px;
+    background: #fff;
+
+    .body {
+      width: 1200px;
+      height: 480px;
+      margin: 0 auto;
+      transform: translateY(100px);
+      text-align: center;
+      padding-top: 135px;
+      background: #eee;
+
+      .main-title {
+        font-size: 70px;
+        font-weight: 600;
+        margin-bottom: 80px;
+        color: #fff;
+      }
+
+      .btn-list {
+        .button {
+          margin: 0 20px;
+          font-weight: 600;
+          font-size: 16px;
+        }
+      }
+    }
+  }
+
+  .block-2 {
+    text-align: center;
+    padding-top: 250px;
+    background: #6865FDFF;
+    overflow: hidden;
+
+    .main-title {
+      color: #fff;
+      font-size: 56px;
+      font-weight: 600;
+      margin-bottom: 40px;
+    }
+
+    .video-list {
+      margin-bottom: 80px;
+
+      .video-item {
+        display: inline-block;
+        width: 580px;
+        height: 360px;
+        margin: 0 20px;
+        position: relative;
+        background: #eee;
+
+        .play {
+          position: absolute;
+          top: 50%;
+          left: 50%;
+          transform: translate(-50%, -50%);
+        }
+
+        .name {
+          position: absolute;
+          bottom: 10px;
+          right: 20px;
+          color: #fff;
+          font-size: 20px;
+          font-weight: 600;
+        }
+      }
+    }
+
+    .class-list {
+      margin-bottom: 80px;
+
+      .class-item {
+        vertical-align: top;
+        display: inline-block;
+        width: 380px;
+        margin: 0 15px;
+        padding: 30px;
+        background: #fff;
+        position: relative;
+        text-align: left;
+
+        .new {
+          position: absolute;
+          right: 0;
+          top: 0;
+        }
+      }
+    }
+  }
+
+  .block-4 {
+    background: #fff;
+    text-align: center;
+    padding-top: 100px;
+
+    .main-title {
+      font-size: 48px;
+      font-weight: 600;
+      color: #303139FF;
+      margin-bottom: 40px;
+    }
+
+    .list {
+      .item {
+        width: 380px;
+        background: rgba(255, 255, 255, 1);
+        box-shadow: 0px 32px 44px 0px rgba(156, 183, 223, 0.14), 0px 15px 28px 0px rgba(0, 0, 0, 0.01);
+        border-radius: 2px;
+        padding: 30px;
+        display: inline-block;
+        margin: 0 15px;
+        text-align: left;
+        vertical-align: top;
+      }
+    }
+  }
+
+  .block-5 {}
+
+  .block-6 {}
+}

+ 172 - 0
front/project/www/routes/course/main/page.js

@@ -0,0 +1,172 @@
+import React from 'react';
+import './index.less';
+import Assets from '@src/components/Assets';
+import Page from '@src/containers/Page';
+import Footer from '../../../components/Footer';
+import { CommentFalls, AnswerCarousel, Consultation, Contact } from '../../../components/Other';
+import Button from '../../../components/Button';
+
+export default class extends Page {
+  initState() {
+    return {};
+  }
+
+  renderView() {
+    return (
+      <div>
+        <div className="block-1">
+          <div className="body">
+            <Assets name="" />
+            <div className="main-title">Waste Less, Learn More.</div>
+            <div className="btn-list">
+              <Button width={100} size="lager">
+                查看套餐
+              </Button>
+              <Button className="t-4" width={100} theme="default" size="lager">
+                试听课程
+              </Button>
+            </div>
+          </div>
+        </div>
+        <div className="block-2">
+          <div className="main-title">找到你的Style</div>
+          <div className="video-list">
+            <div className="video-item">
+              <Assets width={70} height={70} name="play" className="play" />
+              <div className="name">在线课程 ></div>
+            </div>
+            <div className="video-item">
+              <Assets width={70} height={70} name="play" className="play" />
+              <div className="name">1v1私教 ></div>
+            </div>
+          </div>
+          <div className="class-list">
+            <div className="class-item">
+              <Assets width={55} height={52} className="new" name="noviciate" />
+              <div className="t-s-22 t-4 m-b-5 f-w-b">基础刷题 </div>
+              <div className="t-8 m-b-1">包含最新 XXXXXXX 的全部课程XXXXX;机经券×1+VIP×3 月+模考×1</div>
+              <div className="t-1 t-s-12">包含课程</div>
+              <div className="m-b-5">
+                <div className="m-b-1 m-r-5 t-9 t-s-12 d-i-b b-c-2 p-5">OG20阅读刷题(7课时)</div>
+              </div>
+              <div className="t-1 t-s-12">配套服务</div>
+              <div className="m-b-5">
+                <div className="m-b-1 m-r-5 t-9 t-s-12 d-i-b b-c-2 p-5">OG20阅读刷题(7课时)</div>
+              </div>
+              <div className="t-1 t-s-12">赠送服务</div>
+              <div className="m-b-2">
+                <div className="m-b-1 m-r-5 t-9 t-s-12 d-i-b b-c-2 p-5">OG20阅读刷题(7课时)</div>
+              </div>
+              <div className="t-8">
+                总价值: <span className="t-d-l-t">¥18888</span>
+              </div>
+              <div className="t-1 t-s-18 f-w-b m-b-1">套餐价: ¥8888</div>
+              <div className="m-b-5">
+                <Button size="lager">立即购买</Button>
+              </div>
+            </div>
+            <div className="class-item">
+              <div className="t-s-22 t-11 m-b-5 f-w-b">系统授课 </div>
+              <div className="t-8 m-b-1">包含最新 XXXXXXX 的全部课程XXXXX;机经券×1+VIP×3 月+模考×1</div>
+              <div className="t-1 t-s-12">包含课程</div>
+              <div className="m-b-5">
+                <div className="m-b-1 m-r-5 t-9 t-s-12 d-i-b b-c-2 p-5">OG20阅读刷题(7课时)</div>
+                <div className="m-b-1 m-r-5 t-9 t-s-12 d-i-b b-c-2 p-5">OG20阅读刷题(7课时)</div>
+              </div>
+              <div className="t-1 t-s-12">配套服务</div>
+              <div className="m-b-5">
+                <div className="m-b-1 m-r-5 t-9 t-s-12 d-i-b b-c-2 p-5">OG20阅读刷题(7课时)</div>
+              </div>
+              <div className="t-1 t-s-12">赠送服务</div>
+              <div className="m-b-2">
+                <div className="m-b-1 m-r-5 t-9 t-s-12 d-i-b b-c-2 p-5">OG20阅读刷题(7课时)</div>
+              </div>
+              <div className="t-8">
+                总价值: <span className="t-d-l-t">¥18888</span>
+              </div>
+              <div className="t-1 t-s-18 f-w-b m-b-1">套餐价: ¥8888</div>
+              <div className="m-b-5">
+                <Button size="lager">立即购买</Button>
+              </div>
+            </div>
+            <div className="class-item">
+              <div className="t-s-22 t-12 m-b-5 f-w-b">思维提升 </div>
+              <div className="t-8 m-b-1">包含最新 XXXXXXX 的全部课程XXXXX;机经券×1+VIP×3 月+模考×1</div>
+              <div className="t-1 t-s-12">包含课程</div>
+              <div className="m-b-5">
+                <div className="m-b-1 m-r-5 t-9 t-s-12 d-i-b b-c-2 p-5">OG20阅读刷题(7课时)</div>
+              </div>
+              <div className="t-1 t-s-12">配套服务</div>
+              <div className="m-b-5">
+                <div className="m-b-1 m-r-5 t-9 t-s-12 d-i-b b-c-2 p-5">OG20阅读刷题(7课时)</div>
+              </div>
+              <div className="t-1 t-s-12">赠送服务</div>
+              <div className="m-b-2">
+                <div className="m-b-1 m-r-5 t-9 t-s-12 d-i-b b-c-2 p-5">OG20阅读刷题(7课时)</div>
+              </div>
+              <div className="t-8">
+                总价值: <span className="t-d-l-t">¥18888</span>
+              </div>
+              <div className="t-1 t-s-18 f-w-b m-b-1">套餐价: ¥8888</div>
+              <div className="m-b-5">
+                <Button size="lager">立即购买</Button>
+              </div>
+            </div>
+          </div>
+        </div>
+        <Consultation />
+        <div className="block-4">
+          <div className="main-title">You will always find the answers</div>
+          <Assets name="" />
+          <div className="list">
+            <div className="item">
+              <div className="t-1 t-s-20 m-b-2">
+                <Assets className="m-r-5" name="self_paced" /> Self-Paced
+              </div>
+              <div className="t-8">随时随地学习;不限听课次数;支持停课申请。</div>
+            </div>
+            <div className="item">
+              <div className="t-1 t-s-20 m-b-2">
+                <Assets className="m-r-5" name="teacher" /> 实力导师
+              </div>
+              <div className="t-8">从业8年,考取700+成绩10次。</div>
+              <div className="t-4 ">
+                <div className="link d-i-b">查看成绩单 ></div>
+              </div>
+            </div>
+            <div className="item">
+              <div className="t-1 t-s-20 m-b-2">
+                <Assets className="m-r-5" name="excitation" /> 激励机制
+              </div>
+              <div className="t-8">保持听课频率,赠送课程时效。</div>
+            </div>
+          </div>
+        </div>
+        <CommentFalls />
+        <AnswerCarousel
+          list={[
+            {
+              question: '如果视频课程到期了却没有听完,没听的课程可以退款么',
+              answer: '不可以的,视频课程为虚拟商品,购买成功后不接受退换。',
+            },
+            {
+              question: '学习过程中可以申请停课么?',
+              answer: '每个商品均有1次申请停课的机会,最长停课30天,停课时间不计入使用有效期内。',
+            },
+            {
+              question: '我需要一个整体的GMAT备考计划,报课程的话可以提供么?',
+              answer:
+                '报语文全科“系统授课”的同学会赠送价值900元课前辅导,老师语音一对一与同学交流沟通,为同学提供针对性建议和详细的备考计划。',
+            },
+            {
+              question: '如果视频课程到期了却没有听完,没听的课程可以退款么',
+              answer: '不可以的,视频课程为虚拟商品,购买成功后不接受退换。',
+            },
+          ]}
+        />
+        <Contact />
+        <Footer />
+      </div>
+    );
+  }
+}

+ 9 - 0
front/project/www/routes/course/note/index.js

@@ -0,0 +1,9 @@
+export default {
+  path: '/course/note',
+  key: 'course-note',
+  title: '课堂-笔记',
+  needLogin: false,
+  component() {
+    return import('./page');
+  },
+};

+ 41 - 0
front/project/www/routes/course/note/index.less

@@ -0,0 +1,41 @@
+@charset "utf-8";
+
+#course-note {
+  .top {
+    height: 60px;
+    line-height: 60px;
+  }
+
+  .center {
+    background: #fff;
+    border-radius: 14px;
+    padding: 20px;
+  }
+}
+
+.g-modal.article-detail-modal {
+  .ant-modal-body {
+    .detail {
+      height: 600px;
+      overflow-y: auto;
+    }
+
+    .prev {
+      position: absolute;
+      left: -100px;
+      top: 300px;
+      color: #fff;
+      font-size: 37px;
+      cursor: pointer;
+    }
+
+    .next {
+      position: absolute;
+      right: -100px;
+      top: 300px;
+      color: #fff;
+      font-size: 37px;
+      cursor: pointer;
+    }
+  }
+}

+ 121 - 0
front/project/www/routes/course/note/page.js

@@ -0,0 +1,121 @@
+import React, { Component } from 'react';
+import './index.less';
+import { Icon } from 'antd';
+import Page from '@src/containers/Page';
+import { formatDate } from '@src/services/Tools';
+import Modal from '../../../components/Modal';
+
+export default class extends Page {
+  constructor(props) {
+    props.size = 10;
+    super(props);
+  }
+
+  initState() {
+    return {
+      tab: 'question',
+      module: 'exercise',
+      timerange: 'today',
+      filterMap: {},
+      sortMap: {},
+      list: [],
+      selectList: [],
+      allChecked: false,
+      showDetail: false,
+    };
+  }
+
+  initData() {}
+
+  onFilter(value) {
+    this.search(value, false);
+    this.initData();
+  }
+
+  onChangePage(page) {
+    this.search({ page }, false);
+    this.initData();
+  }
+
+  renderView() {
+    const { list = [] } = this.state;
+    return (
+      <div>
+        <div className="top content t-8">
+          千行课堂 > 全部课程 > OG20综合刷题 > 课时3 > <span className="t-1">我的笔记</span>
+          <div className="f-r">返回课程</div>
+        </div>
+        <div className="center content">
+          <div className="t-1 t-s-20 m-b-2">OG20综合刷题——第3课时:XXXXXXX</div>
+          {list.map(item => {
+            return (
+              <Article
+                data={item}
+                onClick={() => this.setState({ showDetail: true, article: item })}
+                onUnCollect={() => this.collectArticle(item, false)}
+              />
+            );
+          })}
+        </div>
+        {this.renderModal()}
+      </div>
+    );
+  }
+
+  renderModal() {
+    const { article = {} } = this.state;
+    return [
+      <ArticleDetail
+        show={this.state.showDetail}
+        data={article}
+        onClose={() => this.setState({ showDetail: false })}
+        onPrev={() => this.prevArticle()}
+        onNext={() => this.nextArticle()}
+      />,
+    ];
+  }
+}
+
+class ArticleDetail extends Component {
+  render() {
+    const { show, data, onClose, onPrev, onNext } = this.props;
+    return (
+      <Modal
+        className="article-detail-modal"
+        body={false}
+        show={show}
+        width={720}
+        maskClosable
+        close={false}
+        onClose={onClose}
+        center
+      >
+        <Icon type="left" className="prev" onClick={() => onPrev && onPrev()} />
+        <Icon type="right" className="next" onClick={() => onNext && onNext()} />
+        <div className="t-1 t-s-20 m-b-5">{data.title}</div>
+        <div className="t-2 t-s-18 detail" dangerouslySetInnerHTML={{ __html: data.content }} />
+      </Modal>
+    );
+  }
+}
+
+class Article extends Component {
+  render() {
+    const { data, onClick, onUnCollect } = this.props;
+    return (
+      <div className="article-item p-t-2 b-b" onClick={() => onClick && onClick()}>
+        <div className="t-1 t-s-14 f-w-b">
+          {data.title}
+          <div className="f-r t-3 t-s-12 f-w-d">
+            <span>{formatDate(data.updateTime, 'YYYY-MM-DD HH:mm:ss')}</span>
+            <span className="m-l-2">阅读 {data.viewNumber}</span>
+            <span className="m-l-2" onClick={() => onUnCollect()}>
+              取消收藏
+            </span>
+          </div>
+        </div>
+        <div className="t-2 m-b-2 detail" dangerouslySetInnerHTML={{ __html: data.content }} />
+      </div>
+    );
+  }
+}

+ 11 - 0
front/project/www/routes/course/online/index.js

@@ -0,0 +1,11 @@
+export default {
+  path: '/course/online',
+  key: 'course-online',
+  title: '课堂-在线课程',
+  needLogin: false,
+  repeat: true,
+  tab: 'course',
+  component() {
+    return import('./page');
+  },
+};

+ 54 - 0
front/project/www/routes/course/online/index.less

@@ -0,0 +1,54 @@
+@charset "utf-8";
+
+#course-online {
+  .content {
+    width: 1200px !important;
+  }
+
+  .top {
+    padding: 8px 30px;
+
+    .tabs.text {
+      background: none;
+      padding: 0;
+      display: inline-block;
+    }
+
+    .f-r {
+      height: 44px;
+      line-height: 44px;
+    }
+  }
+
+  .center {
+    background: #fff;
+
+    .content {
+      padding: 20px 30px;
+    }
+
+    .tab-1-list {
+      padding-top: 30px;
+      padding-bottom: 40px;
+      margin: 0 -20px;
+
+      .single-item {
+        margin-bottom: 20px;
+        margin-left: 20px;
+        margin-right: 20px;
+      }
+    }
+
+    .tab-2-list {
+      padding-top: 30px;
+      padding-bottom: 40px;
+      margin: 0 -20px;
+
+      .package-item {
+        margin-bottom: 20px;
+        margin-left: 20px;
+        margin-right: 20px;
+      }
+    }
+  }
+}

+ 146 - 0
front/project/www/routes/course/online/page.js

@@ -0,0 +1,146 @@
+import React from 'react';
+import './index.less';
+import Page from '@src/containers/Page';
+import Assets from '@src/components/Assets';
+import Footer from '../../../components/Footer';
+import { CommentFalls, AnswerCarousel, Consultation, Contact } from '../../../components/Other';
+import Tabs from '../../../components/Tabs';
+import Filter from '../../../components/Filter';
+import { SingleItem, PackageItem } from '../../../components/Item';
+
+export default class extends Page {
+  initState() {
+    return {
+      list: [{}, {}],
+      tab: '1',
+      tab1Filter: { one: '1', two: '1' },
+      tab2Filter: { one: '1' },
+    };
+  }
+
+  onChangeTab(tab) {
+    this.setState({ tab });
+  }
+
+  onFilter(type, key, value) {
+    this.state[type][key] = value;
+    this.setState(this.state);
+  }
+
+  renderView() {
+    const { tab } = this.state;
+    return (
+      <div>
+        <div className="top content">
+          <Tabs type="text" active={'1'} tabs={[{ title: '在线课程', key: '1' }, { title: '1v1私教', key: '2' }]} />
+          <div className="f-r">
+            <span className="t-2 m-r-1">优惠活动:2门9折,3门88折,4门及以上85折。</span>
+            <Assets name="cart" />
+            <span className="t-2">( 1 )</span>
+          </div>
+        </div>
+        <div className="center">
+          <div className="content">
+            <Tabs
+              type="division"
+              theme="theme"
+              size="small"
+              space={2.5}
+              width={100}
+              border
+              active={tab}
+              tabs={[{ title: '单项购买', key: '1' }, { title: '套餐购买', key: '2' }]}
+              onChange={key => this.onChangeTab(key)}
+            />
+            {this[`renderTab${tab}`]()}
+          </div>
+        </div>
+        <Consultation />
+        <CommentFalls />
+        <AnswerCarousel
+          list={[
+            {
+              question: '如果视频课程到期了却没有听完,没听的课程可以退款么',
+              answer: '不可以的,视频课程为虚拟商品,购买成功后不接受退换。',
+            },
+            {
+              question: '学习过程中可以申请停课么?',
+              answer: '每个商品均有1次申请停课的机会,最长停课30天,停课时间不计入使用有效期内。',
+            },
+            {
+              question: '我需要一个整体的GMAT备考计划,报课程的话可以提供么?',
+              answer:
+                '报语文全科“系统授课”的同学会赠送价值900元课前辅导,老师语音一对一与同学交流沟通,为同学提供针对性建议和详细的备考计划。',
+            },
+            {
+              question: '如果视频课程到期了却没有听完,没听的课程可以退款么',
+              answer: '不可以的,视频课程为虚拟商品,购买成功后不接受退换。',
+            },
+          ]}
+        />
+        <Contact />
+        <Footer />
+      </div>
+    );
+  }
+
+  renderTab1() {
+    const { tab1Filter, list = [] } = this.state;
+    return [
+      <Filter
+        filter={tab1Filter}
+        list={[
+          {
+            key: 'one',
+            children: [
+              { key: '1', title: '全部' },
+              { key: '2', title: '长难句' },
+              { key: '3', title: '语文Verbal' },
+              { key: '4', title: '数学Quant' },
+            ],
+          },
+          {
+            key: 'two',
+            children: [
+              { key: '1', title: '全部' },
+              { key: '2', title: '语法SC' },
+              { key: '3', title: '阅读RC' },
+              { key: '4', title: '逻辑RC' },
+            ],
+          },
+        ]}
+        onFilter={(key, value) => this.onFilter('tab1Filter', key, value)}
+      />,
+      <div className="tab-1-list">
+        {list.map(() => {
+          return <SingleItem />;
+        })}
+      </div>,
+    ];
+  }
+
+  renderTab2() {
+    const { tab2Filter, list = [] } = this.state;
+    return [
+      <Filter
+        filter={tab2Filter}
+        list={[
+          {
+            key: 'one',
+            children: [
+              { key: '1', title: '全部' },
+              { key: '2', title: '语文Verbal' },
+              { key: '3', title: '数学Quant' },
+            ],
+          },
+        ]}
+        onFilter={(key, value) => this.onFilter('tab2Filter', key, value)}
+      />,
+      <div className="tab-2-list">
+        {list.map(() => {
+          return <PackageItem />;
+        })}
+      </div>,
+    ];
+  }
+}

+ 2 - 2
front/project/www/routes/index.js

@@ -9,7 +9,7 @@ import Preview from './preview';
 import Question from './question';
 import Sentence from './sentence';
 import Textbook from './textbook';
-import Room from './room';
+import Course from './course';
 
 export default [
   ...Page,
@@ -21,5 +21,5 @@ export default [
   ...Question,
   ...Sentence,
   ...Textbook,
-  ...Room,
+  ...Course,
 ];

+ 0 - 76
front/project/www/routes/page/home/index.less

@@ -456,48 +456,6 @@
     padding-top: 20px;
     padding-bottom: 20px;
     background: #fff;
-
-    .grid-item {
-      width: 25%;
-      padding: 5px;
-
-      .item {
-        max-height: 260px;
-        background: #FAFAFA;
-        border: 1px solid #F1F4F7;
-        padding: 20px;
-        overflow: hidden;
-
-        .item-header {
-          margin-bottom: 10px;
-
-          .avatar {
-            width: 40px;
-            height: 40px;
-          }
-
-          .name {
-            color: #5E677B;
-            font-size: 16px;
-            vertical-align: middle;
-            display: inline-block;
-          }
-
-          .date {
-            color: #8897A8;
-            font-size: 12px;
-            float: right;
-            vertical-align: middle;
-          }
-        }
-
-        .item-body {
-          color: #8897A8;
-          padding-left: 10px;
-          overflow: hidden;
-        }
-      }
-    }
   }
 
   .block-6 {
@@ -538,38 +496,4 @@
       }
     }
   }
-
-  .block-7 {
-    height: 420px;
-    padding-top: 80px;
-    background: #6865FD;
-
-    .step-list {}
-
-    .step {
-      width: 33.33%;
-      display: inline-block;
-      box-sizing: border-box;
-      vertical-align: top;
-
-      .title {
-        font-size: 16px;
-        color: #fff;
-        margin-bottom: 30px;
-        font-weight: 600;
-      }
-
-      .desc {
-        font-size: 16px;
-        color: #fff;
-        margin-bottom: 10px;
-      }
-
-      .qrcode {
-        background: #8683fb;
-        padding: 15px;
-        display: inline-block;
-      }
-    }
-  }
 }

+ 3 - 51
front/project/www/routes/page/home/page.js

@@ -3,9 +3,9 @@ import { Carousel } from 'antd';
 import './index.less';
 import Page from '@src/containers/Page';
 import Assets from '@src/components/Assets';
-import { formatDate } from '@src/services/Tools';
 import Button from '../../../components/Button';
 import Footer from '../../../components/Footer';
+import { CommentFalls, Contact } from '../../../components/Other';
 import { Main } from '../../../stores/main';
 import { User } from '../../../stores/user';
 
@@ -21,16 +21,6 @@ export default class extends Page {
     Main.getIndex().then(result => {
       this.setState(result);
     });
-    setTimeout(() => {
-      this.createLayout();
-    }, 1);
-  }
-
-  createLayout() {
-    const msnry = new Masonry('.grid', {
-      itemSelector: '.grid-item',
-    });
-    msnry.layout();
   }
 
   location(url) {
@@ -266,24 +256,7 @@ export default class extends Page {
             );
           })}
         </Carousel>
-        <div className="block block-5">
-          <div className="grid">
-            {evaluation.map(row => {
-              return (
-                <div className="grid-item">
-                  <div className="item">
-                    <div className="item-header">
-                      <Assets src={row.avatar} />
-                      <div className="name">{row.nickname}</div>
-                      <div className="date">{formatDate(row.date, 'yyyy年mm月dd日')}</div>
-                    </div>
-                    <div className="item-body">{row.content}</div>
-                  </div>
-                </div>
-              );
-            })}
-          </div>
-        </div>
+        <CommentFalls list={evaluation} />
         <div className="block block-6">
           <div className="body">
             <div className="m-title">发展历程</div>
@@ -317,28 +290,7 @@ export default class extends Page {
             </div>
           </div>
         </div>
-        <div className="block block-7">
-          <div className="body">
-            <div className="step-list">
-              <div className="step">
-                <div className="title">工作机会</div>
-                <Assets name="logo2" />
-              </div>
-              <div className="step" style={{ paddingLeft: 80 }}>
-                <div className="title">联系我们</div>
-                <div className="desc">{contact.phone}</div>
-                <div className="desc">{contact.email}</div>
-                <div className="desc">{contact.wechat}</div>
-              </div>
-              <div className="step" style={{ paddingLeft: 140 }}>
-                <div className="title">关注我们</div>
-                <div className="qrcode">
-                  <Assets src={contact.wechatImage} />
-                </div>
-              </div>
-            </div>
-          </div>
-        </div>
+        <Contact data={contact} />
         <Footer />
       </div>
     );

+ 0 - 3
front/project/www/routes/room/index.js

@@ -1,3 +0,0 @@
-import main from './main';
-
-export default [main];

+ 0 - 3
front/project/www/routes/room/main/index.less

@@ -1,3 +0,0 @@
-@charset "utf-8";
-
-#room-main {}

+ 0 - 18
front/project/www/routes/room/main/page.js

@@ -1,18 +0,0 @@
-import React from 'react';
-import './index.less';
-import Page from '@src/containers/Page';
-import { NoteModal } from '../../../components/OtherModal';
-
-export default class extends Page {
-  initState() {
-    return {};
-  }
-
-  renderView() {
-    return (
-      <div>
-        <NoteModal selectList={[{ title: '123', key: '123' }]} show onConfirm={() => {}} onCancel={() => {}} />
-      </div>
-    );
-  }
-}

+ 2 - 0
front/src/containers/App.js

@@ -62,6 +62,7 @@ export default class App extends Component {
             </Route>
           )}
           {routes.map(route => {
+            if (!route.path) return '';
             return (
               <Route
                 exact
@@ -97,6 +98,7 @@ export default class App extends Component {
 
   renderMode(route, props) {
     const { project } = this.props;
+    console.log(route);
     let c;
     if (typeof project.mode === 'function') {
       c = project.mode;