Parcourir la source

add course page

KaysonCui il y a 5 ans
Parent
commit
40176e4cff
30 fichiers modifiés avec 1569 ajouts et 53 suppressions
  1. 8 0
      front/project/www/app.less
  2. BIN
      front/project/www/assets/s.png
  3. 40 12
      front/project/www/components/Item/index.js
  4. 24 0
      front/project/www/components/Item/index.less
  5. 4 4
      front/project/www/components/Ratio/index.js
  6. 17 0
      front/project/www/components/Ratio/index.less
  7. 38 0
      front/project/www/components/Tabs/index.less
  8. 10 4
      front/project/www/components/UserAction/index.js
  9. 11 0
      front/project/www/routes/course/dDetail/index.js
  10. 80 0
      front/project/www/routes/course/dDetail/index.less
  11. 133 0
      front/project/www/routes/course/dDetail/page.js
  12. 9 0
      front/project/www/routes/course/data/index.js
  13. 95 0
      front/project/www/routes/course/data/index.less
  14. 189 0
      front/project/www/routes/course/data/page.js
  15. 11 0
      front/project/www/routes/course/iDetail/index.js
  16. 29 0
      front/project/www/routes/course/iDetail/index.less
  17. 59 0
      front/project/www/routes/course/iDetail/page.js
  18. 7 1
      front/project/www/routes/course/index.js
  19. 11 0
      front/project/www/routes/course/inside/index.js
  20. 69 0
      front/project/www/routes/course/inside/index.less
  21. 151 0
      front/project/www/routes/course/inside/page.js
  22. 15 1
      front/project/www/routes/course/note/index.less
  23. 54 31
      front/project/www/routes/course/note/page.js
  24. 1 0
      front/project/www/routes/course/online/index.less
  25. 11 0
      front/project/www/routes/course/pDetail/index.js
  26. 74 0
      front/project/www/routes/course/pDetail/index.less
  27. 112 0
      front/project/www/routes/course/pDetail/page.js
  28. 11 0
      front/project/www/routes/course/single/index.js
  29. 125 0
      front/project/www/routes/course/single/index.less
  30. 171 0
      front/project/www/routes/course/single/page.js

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

@@ -298,6 +298,10 @@
   color: #F2B252FF !important;
 }
 
+.t-13 {
+  color: #5E677BFF !important;
+}
+
 .b-c-1 {
   background: #F7F7F7;
 }
@@ -346,6 +350,10 @@
   font-size: 14px;
 }
 
+.t-s-28 {
+  font-size: 28px;
+}
+
 .l-h-20 {
   line-height: 20px;
 }

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


+ 40 - 12
front/project/www/components/Item/index.js

@@ -5,6 +5,7 @@ import Button from '../Button';
 
 export class SingleItem extends Component {
   render() {
+    const { show } = this.props;
     return (
       <div className="single-item">
         <div className="img">
@@ -25,18 +26,20 @@ export class SingleItem extends Component {
           <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" />
+        {!show && (
+          <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>
+        )}
+        {!show && <Assets className="buyed" width={75} height={75} name="Purchased" />}
       </div>
     );
   }
@@ -84,3 +87,28 @@ export class PackageItem extends Component {
     );
   }
 }
+
+export class DataItem extends Component {
+  render() {
+    return (
+      <div className="data-item">
+        <Assets name="" />
+        <div className="m-b-1">
+          <span className="t-7 t-s-24 f-w-b">¥8888</span>
+          <span className="f-r t-8 t-s-20">888人</span>
+        </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>
+    );
+  }
+}

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

@@ -139,4 +139,28 @@
     bottom: 15px;
     left: 15px;
   }
+}
+
+.data-item {
+  display: inline-block;
+  width: 290px;
+  background: rgba(251, 251, 251, 1);
+  border-radius: 4px;
+  border: 1px solid rgba(229, 229, 229, 1);
+  padding: 10px;
+
+  .action {
+    margin-bottom: 10px;
+    overflow: hidden;
+
+    .default.button {
+      color: #4292F0;
+    }
+  }
+
+  .buyed {
+    position: absolute;
+    bottom: 15px;
+    left: 15px;
+  }
 }

+ 4 - 4
front/project/www/components/Ratio/index.js

@@ -30,12 +30,12 @@ function makePie(text, subtext, color, data) {
   };
 }
 export default function Ratio(props) {
-  const { text, subtext, values } = props;
+  const { text, subtext, values, size = 'basic' } = props;
   return (
-    <div className="ratio-pie">
+    <div className={`ratio-pie ${size}`}>
       <PieChart
-        width={110}
-        height={110}
+        width={size === 'small' ? 80 : 110}
+        height={size === 'small' ? 80 : 110}
         option={makePie(text, subtext, values.map(item => item.color), values.map(item => item.value))}
       />
       <div className="label-list">

+ 17 - 0
front/project/www/components/Ratio/index.less

@@ -29,4 +29,21 @@
       }
     }
   }
+}
+
+.ratio-pie.small {
+  .pie-chart {
+    margin-right: 25px;
+  }
+
+  .label-list {
+    width: 110px;
+    padding-top: 5px;
+
+    .item {
+      width: 110px;
+      font-size: 12px;
+      margin-bottom: 0;
+    }
+  }
 }

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

@@ -62,6 +62,44 @@
   }
 }
 
+.tabs.full {
+  text-align: center;
+
+  .tabs-warpper {
+    display: flex;
+  }
+
+  .tab {
+    display: inline-block;
+    flex: 1;
+    position: relative;
+    text-align: center;
+    cursor: pointer;
+    color: #686872FF;
+  }
+
+  .tab::after {
+    content: '';
+    width: 0;
+    height: 3px;
+    background: @theme_color;
+    transform: translateX(-50%);
+    transition: all 0.25s;
+    position: absolute;
+    bottom: 5px;
+    left: 50%;
+  }
+
+  .tab.active {
+    color: #303139FF;
+  }
+
+  .tab:hover::after,
+  .tab.active::after {
+    width: 40px;
+  }
+}
+
 .tabs.card {
   text-align: center;
   background: @theme_bg_color;

+ 10 - 4
front/project/www/components/UserAction/index.js

@@ -102,13 +102,17 @@ export default class UserAction extends Component {
                 {item.fixed ? (
                   sortMap[item.key] ? (
                     <GIcon active name="arrow-down" onClick={() => this.onSort(item.key, '')} />
-                  ) : (<GIcon name="arrow-up" onClick={() => this.onSort(item.key, 'desc')} />)
+                  ) : (
+                    <GIcon name="arrow-up" onClick={() => this.onSort(item.key, 'desc')} />
+                  )
                 ) : sortMap[item.key] ? (
                   <Assets
                     name={sortMap[item.key] === 'asc' ? 'seqencing2_up_select' : 'seqencing2_down_select'}
                     onClick={() => this.onSort(item.key, sortMap[item.key] === 'asc' ? 'desc' : '')}
                   />
-                ) : (<Assets name="seqencing2_normal" onClick={() => this.onSort(item.key, 'asc')} />)}
+                ) : (
+                  <Assets name="seqencing2_normal" onClick={() => this.onSort(item.key, 'asc')} />
+                )}
               </div>
             );
           })}
@@ -124,12 +128,14 @@ export default class UserAction extends Component {
                 onKeyUp={e => this.onSearchKey(e)}
               />
             )}
-            {(!showInput && !defaultSearch) && <Icon type="search" onClick={() => this.setState({ showInput: true })} />}
+            {!showInput && !defaultSearch && <Icon type="search" onClick={() => this.setState({ showInput: true })} />}
           </div>
         )}
         {right && (
           <div
-            className={`right ${btnList.length === 0 && selectList.length === 0 && sortList.length === 0 ? 'only' : ''}`}
+            className={`right ${
+              btnList.length === 0 && selectList.length === 0 && sortList.length === 0 ? 'only' : ''
+            }`}
           >
             {right}
           </div>

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

@@ -0,0 +1,11 @@
+export default {
+  path: '/course/d-detail',
+  key: 'course-d-detail',
+  title: '课堂-资料详情',
+  needLogin: false,
+  repeat: true,
+  tab: 'course',
+  component() {
+    return import('./page');
+  },
+};

+ 80 - 0
front/project/www/routes/course/dDetail/index.less

@@ -0,0 +1,80 @@
+@charset "utf-8";
+
+#course-d-detail {
+  background: #fff;
+
+  .content {
+    width: 1200px !important;
+  }
+
+  .top {
+    padding: 8px 30px;
+    height: 60px;
+    line-height: 44px;
+  }
+
+  .center {
+    background: #fff;
+
+    .content {
+      width: 1140px !important;
+
+      .item-detail {
+        overflow: hidden;
+        padding-bottom: 20px;
+
+        .left {
+          float: left;
+          width: 290px;
+          height: 335px;
+          background: rgba(251, 251, 251, 1);
+          border-radius: 4px;
+          border: 1px solid rgba(229, 229, 229, 1);
+          position: relative;
+          padding: 10px;
+
+          .tag-list {
+            position: absolute;
+            top: 20px;
+            left: 20px;
+
+            .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;
+            }
+          }
+        }
+
+        .right {
+          padding-left: 310px;
+
+          .action {
+            margin-bottom: 10px;
+            overflow: hidden;
+
+            .button {}
+
+            .default.button {
+              color: #4292F0;
+            }
+          }
+        }
+      }
+    }
+  }
+
+  .bottom {
+    background: #FAFAFAFF;
+
+    .content {
+      padding: 20px 0;
+    }
+  }
+}

+ 133 - 0
front/project/www/routes/course/dDetail/page.js

@@ -0,0 +1,133 @@
+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 { Contact } from '../../../components/Other';
+import Tabs from '../../../components/Tabs';
+import Button from '../../../components/Button';
+
+export default class extends Page {
+  initState() {
+    return {
+      tab: '1',
+      key: '1',
+    };
+  }
+
+  onChangeTab(tab) {
+    this.setState({ tab });
+  }
+
+  onChangeItem(key) {
+    this.setState({ key });
+  }
+
+  renderView() {
+    return (
+      <div>
+        <div className="top content t-8">
+          千行课堂 > 全部课程 > OG20综合刷题 > 课时3 > <span className="t-1">套餐详情</span>
+        </div>
+        {this.renderDetail()}
+        <Contact />
+        <Footer />
+      </div>
+    );
+  }
+
+  renderDetail() {
+    const { tab } = this.state;
+    return [
+      <div className="center">
+        <div className="content">
+          <div className="item-detail">
+            <div className="left">
+              <Assets name="" />
+              <div className="tag-list">
+                <div className="tag">新手</div>
+                <div className="tag">原创</div>
+              </div>
+            </div>
+            <div style={{ width: 760 }} className="right">
+              <div className="t-1 t-s-20">OG20基础刷题套餐 </div>
+              <div className="t-7 m-b-2">
+                对“忽略有效考点”的解析进行补充,同时讲解OG不够精准的解析,帮助考生明确重点、避开误区,节省大量的时间和精力,刷OG必备。
+              </div>
+              <div className="">
+                <div className="d-i-b t-1">最近更新:</div>
+                <div className="d-i-b t-8">2019-06-20 10:21:04</div>
+              </div>
+              <div className="">
+                <div className="d-i-b t-1">页数:</div>
+                <div className="d-i-b t-8">30页</div>
+              </div>
+              <div className="">
+                <div className="d-i-b t-1">格式:</div>
+                <div className="d-i-b t-8">PDF</div>
+              </div>
+              <div className="m-b-1">
+                <div className="d-i-b t-1">获取方式:</div>
+                <div className="d-i-b t-8">发送至邮箱</div>
+              </div>
+              <div className="m-b-1">
+                <div style={{ marginTop: 12 }} className="d-i-b t-1 t-s-16 v-a-t">
+                  价格:
+                </div>
+                <div className="d-i-b t-7 t-s-28 f-w-b"> ¥ 15000</div>
+              </div>
+              <div className="action">
+                <Button className="m-r-1" radius size="lager">
+                  立即购买
+                </Button>
+                <Button className="m-r-1" theme="default" radius size="lager">
+                  <Assets name="add" />
+                </Button>
+                <Button theme="default" radius size="lager">
+                  预览
+                </Button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>,
+      <div className="bottom">
+        <div className="content">
+          <Tabs
+            type="full"
+            border
+            active={tab}
+            tabs={[
+              { title: '资料介绍', key: '1' },
+              { title: '作者介绍', key: '2' },
+              { title: '获取方式', key: '3' },
+              { title: 'FAQs', key: '4' },
+              { title: '学员评价', key: '5' },
+            ]}
+          />
+          {this[`renderTab${tab}`]()}
+        </div>
+      </div>,
+    ];
+  }
+
+  renderTab1() {
+    return <div />;
+  }
+
+  renderTab2() {
+    return <div />;
+  }
+
+  renderTab3() {
+    return <div />;
+  }
+
+  renderTab4() {
+    return <div />;
+  }
+
+  renderTab5() {
+    return <div />;
+  }
+}

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

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

+ 95 - 0
front/project/www/routes/course/data/index.less

@@ -0,0 +1,95 @@
+@charset "utf-8";
+
+#course-data {
+  .top {
+    height: 60px;
+    line-height: 60px;
+  }
+
+  .center {
+    background: #fff;
+    border-radius: 14px;
+    padding: 20px;
+    position: relative;
+
+    .data-list {
+      margin: 0 -20px;
+      padding-top: 20px;
+
+      .data-item {
+        margin: 0 20px;
+      }
+    }
+
+    .update-search {
+      display: inline-block;
+      position: absolute;
+
+      .user-action {
+        border-bottom: none;
+      }
+
+      top: 10px;
+      right: 20px;
+    }
+
+    .update-log {
+      padding-top: 20px;
+      position: relative;
+      overflow: hidden;
+
+      .left {
+        float: left;
+        width: 240px;
+        background: rgba(251, 251, 251, 1);
+        border-radius: 4px;
+        border: 1px solid rgba(229, 229, 229, 1);
+        padding: 0 20px;
+
+        .block {
+          border-bottom: 1px solid #D8D8D8FF;
+          padding: 30px 0;
+
+          .title {
+            color: #919FAEFF;
+            cursor: pointer;
+          }
+
+          .list {
+            display: none;
+            padding-top: 20px;
+
+            .item {
+              cursor: pointer;
+              color: #303139FF;
+            }
+
+            .item.active {
+              color: #4299FFFF;
+            }
+          }
+
+          .list.open {
+            display: block;
+          }
+        }
+
+        .block:last-child {
+          border-bottom: none;
+        }
+      }
+
+      .right {
+        padding-left: 260px;
+
+        .user-table {
+          font-size: 12px;
+        }
+
+        .item {
+          margin-bottom: 20px;
+        }
+      }
+    }
+  }
+}

+ 189 - 0
front/project/www/routes/course/data/page.js

@@ -0,0 +1,189 @@
+import React from 'react';
+import './index.less';
+import { Switch } from 'antd';
+import Page from '@src/containers/Page';
+import UserAction from '../../../components/UserAction';
+import Tabs from '../../../components/Tabs';
+import Filter from '../../../components/Filter';
+import Icon from '../../../components/Icon';
+import { DataItem } from '../../../components/Item';
+import UserTable from '../../../components/UserTable';
+
+const columns = [
+  {
+    key: '',
+    title: '更新时间',
+  },
+  {
+    key: '',
+    title: '位置',
+  },
+  {
+    key: '',
+    title: '原内容',
+  },
+  {
+    key: '',
+    title: '更改为',
+  },
+  {
+    key: '',
+    title: '更新至',
+  },
+];
+
+export default class extends Page {
+  initState() {
+    return {
+      tab: '2',
+      filterMap: { one: '1', two: '1' },
+      sortMap: {},
+      list: [],
+      type: [
+        { title: '长难句', key: '1', open: true, children: [{ key: '1', title: 'OG19 语法千行' }] },
+        { title: '语文 Verbal', key: '2', open: true, children: [{ key: '1', title: 'OG19 语法千行' }] },
+        { title: '数学 Quant', key: '3', open: true, children: [{ key: '1', title: 'OG19 语法千行' }] },
+      ],
+    };
+  }
+
+  initData() {}
+
+  onChangeTab(tab) {
+    this.setState({ tab });
+  }
+
+  onFilter(value) {
+    this.search(value, false);
+    this.initData();
+  }
+
+  onChangePage(page) {
+    this.search({ page }, false);
+    this.initData();
+  }
+
+  onOpen(index) {
+    const { type } = this.state;
+    type[index].open = !type[index].open;
+    this.setState({ type });
+  }
+
+  renderView() {
+    const { tab } = 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">
+          <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>
+    );
+  }
+
+  renderTab1() {
+    const { list = [], sortMap, filterMap } = this.state;
+    return [
+      <Filter
+        filter={filterMap}
+        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(key, value)}
+      />,
+      <UserAction
+        search
+        defaultSearch={filterMap.keyword}
+        sortList={[
+          { label: '更新时间', key: 'ask_time', fixed: true },
+          { label: '销量', key: 'create_time', fixed: true },
+        ]}
+        sortMap={sortMap}
+        onSort={value => this.onSort(value)}
+      />,
+      <div className="data-list">
+        {list.map(item => {
+          return <DataItem data={item} />;
+        })}
+      </div>,
+    ];
+  }
+
+  renderTab2() {
+    const { type = [], list = [], filterMap } = this.state;
+    return [
+      <div className="update-search">
+        <UserAction search defaultSearch={filterMap.keyword} />
+      </div>,
+      <div className="update-log">
+        <div className="left">
+          {type.map((item, index) => {
+            return (
+              <div className="block">
+                <div className="title" onClick={() => this.onOpen(index)}>
+                  {item.title}
+                  <div className="f-r">
+                    {item.open ? <Icon name="arrow-up" noHover /> : <Icon name="arrow-down" noHover />}
+                  </div>
+                </div>
+                <div className={`list ${item.open ? 'open' : ''}`}>
+                  {item.children.map(child => {
+                    return <div className="item">{child.title}</div>;
+                  })}
+                </div>
+              </div>
+            );
+          })}
+        </div>
+        <div className="right">
+          {list.map(item => {
+            return (
+              <div className="item">
+                <div className="m-b-5">
+                  <span className="t-1 t-s-18 f-w-b">{item.title}</span>
+                  <div className="f-r">
+                    <span className="m-r-5">邮箱订阅</span>
+                    <Switch />
+                    <span className="m-l-5 t-4">纠错</span>
+                  </div>
+                </div>
+                <UserTable size="small" columns={columns} />
+              </div>
+            );
+          })}
+        </div>
+      </div>,
+    ];
+  }
+}

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

@@ -0,0 +1,11 @@
+export default {
+  path: '/course/i-detail',
+  key: 'course-i-detail',
+  title: '课堂-心经详情',
+  needLogin: false,
+  repeat: true,
+  tab: 'course',
+  component() {
+    return import('./page');
+  },
+};

+ 29 - 0
front/project/www/routes/course/iDetail/index.less

@@ -0,0 +1,29 @@
+@charset "utf-8";
+
+#course-i-detail {
+  background: #fff;
+  min-height: 100%;
+
+  .content {
+    width: 1200px !important;
+  }
+
+  .top {
+    padding: 8px 30px;
+    height: 60px;
+    line-height: 44px;
+  }
+
+  .center {
+    background: #fff;
+    padding-top: 60px;
+
+    .content {
+      width: 1140px !important;
+
+      .detail {
+        padding-top: 60px;
+      }
+    }
+  }
+}

+ 59 - 0
front/project/www/routes/course/iDetail/page.js

@@ -0,0 +1,59 @@
+import React from 'react';
+import './index.less';
+import Page from '@src/containers/Page';
+
+export default class extends Page {
+  initState() {
+    return {
+      data: {},
+    };
+  }
+
+  renderView() {
+    return (
+      <div>
+        <div className="center">
+          <div className="content">
+            <div className="t-1 t-s-28">GMAT:掉进坑里多少次才能真正懂得“学习” </div>
+            <div className="t-6 m-b-2">
+              <span className="m-r-2">2019-04-27 15:13:31</span>
+              <span className="m-r-2 m-l-1">阅读 8990</span>
+              <span className="m-l-1">收藏</span>
+            </div>
+            <div className="t-1">
+              <span className="m-r-2">翻翻le</span>
+              <span className="m-r-2 m-l-1">学生-D</span>
+              <span className="m-r-2 m-l-1">备考:2个月</span>
+              <span className="m-r-2 m-l-1">考试时间:2019-06-27</span>
+              <span className="m-r-2 m-l-1">750分 /提分 150+</span>
+              <span className="m-l-1 t-4">更多信息</span>
+            </div>
+            <div className="detail t-1">
+              楼主双非财经大学会计专业 2015 年毕业,毕业之后在一家跨国民营企业战略部工作。雅思两次就刷到了 7.5,Gmat
+              考了5次才勉强出坑,考完就写了一篇总结,过了一个月,思考了更多,及时填坑。 匆匆准备 2 个月的一战:2018 年 3
+              月 10 号,580 分 临时抱佛脚准备半个月的二战:2018 年 5 月,560 分 端正态度准备 2 个月的三站:2018 年 10
+              月,580 分 没有留后路准备 1 个月的四站:2018 年 11 月,560 分 劫后逢生准备 3 个月的五站:2019 年 3 月 23
+              号,710 分 这篇文章主要分享给屡战屡败,屡败屡战的考友们;一边上班一遍申请一遍考 Gmat 的在职党;
+              失败多次,但不愿意面试现实,将失败归因于运气 、心态的考友们。 这篇文章想说的话很多,有些是脱离了 Gmat
+              的内容,但是主题都是关于一点 ——“什么才是真正的读书,什么才是真正的学习”?
+              1.真正的学习,一定是有效的,无效的学习就是意淫。
+              在学习的时候,我们往往会陷入“无效学习的陷阱”,肉体的疲惫和精神的麻痹,让我们“误以为”自己将读到的每一个知识点,做的每一套题目,学习某一个方法都吃透了。
+              但是,真的是这样吗?真的学会了吗?你确定吗?
+              这一点也是我五站中体会比较深刻的一点,看书不要机械式看书,譬如看《曼哈顿语法》,没看完一句话都要
+              countable,联想之前遇到哪些题目考察这一点的?或者如果你是出题人的话,你会从这个考点发散出来什么题目?简单的题目会是什么样子?难的题目会是什么样子?
+              这样子的看书和学习才是有效的,因为你是从目的/终点(也就是考试、做题)出发来进行学习,以终为始,始终带着清晰的目的性,而不要陷入盲目忙碌的状态。
+              2.真正的学习,不是某一个动作,而是一连串的环节和动作。而学习是否有效,不是取决于某个动作的质量,而是这一套连贯动作的质量。
+              这一节会具体说一下我在 5
+              次考试中的学习方式的改变,从只聚焦在一个环节(刷题、看书)到全环节打通(明确考点、现状认知、学习、联系、巩固、复习)
+              3.真正的学习,绝对不是痛苦的,而应该是轻松愉悦的。改变你对Gmat的认知态度,会改变你的学习状态和效率。
+              这一节会分享一下心态的变化,以及心态变化所带来的情绪、状态、学习效率的变化。
+              4.真正的学习,绝对不是忙碌的眉毛鼻子一把抓,而是有侧重。将二八原则应用到 Gmat
+              学习中,抓住自己的核心问题,集中攻破。
+              (但是如果你像我一样,V的每一部分都很差的话,可能需要比其他人努力更多。) 第一次备考(580):
+            </div>
+          </div>
+        </div>
+      </div>
+    );
+  }
+}

+ 7 - 1
front/project/www/routes/course/index.js

@@ -2,5 +2,11 @@ import main from './main';
 import online from './online';
 import answer from './answer';
 import note from './note';
+import data from './data';
+import single from './single';
+import pDetail from './pDetail';
+import dDetail from './dDetail';
+import inside from './inside';
+import iDetail from './iDetail';
 
-export default [main, online, answer, note];
+export default [main, online, answer, note, data, single, pDetail, dDetail, inside, iDetail];

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

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

+ 69 - 0
front/project/www/routes/course/inside/index.less

@@ -0,0 +1,69 @@
+@charset "utf-8";
+
+#course-inside {
+  background: #fff;
+
+  .content {
+    width: 1200px !important;
+  }
+
+  .top {
+    padding: 8px 30px;
+    height: 60px;
+    line-height: 44px;
+  }
+
+  .center {
+    background: #fff;
+    padding-top: 20px;
+
+    .content {
+      width: 1140px !important;
+
+      .total-list {
+        margin: 0 -20px;
+        margin-bottom: 30px;
+
+        .total-item {
+          margin: 0 20px;
+          width: 254px;
+          display: inline-block;
+          padding: 20px;
+          padding-right: 10px;
+          background: #F7F7F7FF;
+          height: 150px;
+          vertical-align: top;
+
+          .title {
+            line-height: 16px;
+            font-size: 16px;
+            color: #5E677BFF;
+            margin-bottom: 10px;
+          }
+
+          .label {
+            color: #5E677BFF;
+            font-size: 32px;
+            text-align: center;
+            padding-right: 10px;
+            font-weight: bold;
+          }
+        }
+      }
+
+      .user-action {
+        border-top: 1px solid #eee;
+      }
+
+      .article-item {
+        .detail {
+          max-height: 140px;
+          overflow: hidden;
+          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;
+        }
+      }
+    }
+  }
+}

+ 151 - 0
front/project/www/routes/course/inside/page.js

@@ -0,0 +1,151 @@
+import React, { Component } from 'react';
+import './index.less';
+import Page from '@src/containers/Page';
+import { formatDate, formatMonth, getMap } from '@src/services/Tools';
+import Ratio from '../../../components/Ratio';
+import UserAction from '../../../components/UserAction';
+import { PrepareStatus, ExperiencePercent } from '../../../../Constant';
+
+const PrepareStatusMap = getMap(PrepareStatus, 'value', 'label');
+const ExperiencePercentMap = getMap(ExperiencePercent, 'value', 'label');
+
+export default class extends Page {
+  initState() {
+    return {
+      tab: '1',
+      key: '1',
+      filterMap: {},
+      list: [{}, {}],
+    };
+  }
+
+  onChangeTab(tab) {
+    this.setState({ tab });
+  }
+
+  onChangeItem(key) {
+    this.setState({ key });
+  }
+
+  renderView() {
+    return (
+      <div>
+        <div className="top content t-8">
+          千行课堂 > 全部课程 > OG20综合刷题 > 课时3 > <span className="t-1">心经首页</span>
+        </div>
+        {this.renderDetail()}
+      </div>
+    );
+  }
+
+  renderDetail() {
+    const { filterMap, list } = this.state;
+    return [
+      <div className="center">
+        <div className="content">
+          <div className="total-list">
+            <div className="total-item">
+              <div className="title">学员人数</div>
+              <div className="label">1231431</div>
+            </div>
+            <div className="total-item">
+              <div className="title">考分分布</div>
+              <Ratio
+                size="small"
+                values={[
+                  { color: '#2754E0', label: '750+  36%  3600人', value: 10 },
+                  { color: '#41A6F3', label: '750+  36%  3600人', value: 10 },
+                  { color: '#9BD4FF', label: '750+  36%  3600人', value: 10 },
+                ]}
+              />
+            </div>
+            <div className="total-item">
+              <div className="title">出分周期</div>
+              <div className="label">35天</div>
+            </div>
+            <div className="total-item">
+              <div className="title">考分分布</div>
+              <Ratio
+                size="small"
+                values={[
+                  { color: '#2754E0', label: '750+  36%  3600人', value: 10 },
+                  { color: '#41A6F3', label: '750+  36%  3600人', value: 10 },
+                  { color: '#9BD4FF', label: '750+  36%  3600人', value: 10 },
+                ]}
+              />
+            </div>
+          </div>
+          <UserAction
+            selectList={[
+              {
+                children: [
+                  {
+                    key: 'subject',
+                    placeholder: '学科',
+                    select: [],
+                  },
+                  {
+                    placeholder: '题型',
+                    key: 'questionType',
+                    be: 'subject',
+                    selectMap: [],
+                  },
+                ],
+              },
+              {
+                label: '范围',
+                children: [
+                  {
+                    key: 'one',
+                    placeholder: '全部',
+                    select: [],
+                  },
+                  {
+                    key: 'two',
+                    be: 'one',
+                    placeholder: '全部',
+                    selectMap: [],
+                  },
+                ],
+              },
+            ]}
+            filterMap={filterMap}
+            onFilter={value => this.onFilter(value)}
+          />
+          {list.map(item => {
+            return <Article data={item} onClick={() => {}} onUnCollect={() => this.collectArticle(item, false)} />;
+          })}
+        </div>
+      </div>,
+    ];
+  }
+}
+
+class Article extends Component {
+  render() {
+    const { data, onClick, onCollect } = 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={() => onCollect()}>
+              收藏
+            </span>
+          </div>
+        </div>
+        <div className="t-1 t-s-12 m-b-2">
+          <span className="m-r-2">{data.user ? data.user.nickname : data.nickname}</span>
+          <span className="m-r-2">{PrepareStatusMap[data.prepareStatus]}</span>
+          <span className="m-r-2">备考:{formatMonth(data.experienceDay, false)}</span>
+          <span className="m-r-2">
+            {data.experienceScore}分 /提分 {ExperiencePercentMap[data.experiencePercent]}
+          </span>
+        </div>
+        <div className="t-2 m-b-2 detail" dangerouslySetInnerHTML={{ __html: data.content }} />
+      </div>
+    );
+  }
+}

+ 15 - 1
front/project/www/routes/course/note/index.less

@@ -10,10 +10,24 @@
     background: #fff;
     border-radius: 14px;
     padding: 20px;
+
+    .user-action {
+      border-top: 1px solid #eee;
+    }
+
+    .list {
+      padding-left: 15px;
+
+      .note-item {
+        .checkbox-item {
+          vertical-align: middle;
+        }
+      }
+    }
   }
 }
 
-.g-modal.article-detail-modal {
+.g-modal.note-detail-modal {
   .ant-modal-body {
     .detail {
       height: 600px;

Fichier diff supprimé car celui-ci est trop grand
+ 54 - 31
front/project/www/routes/course/note/page.js


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

@@ -7,6 +7,7 @@
 
   .top {
     padding: 8px 30px;
+    height: 60px;
 
     .tabs.text {
       background: none;

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

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

+ 74 - 0
front/project/www/routes/course/pDetail/index.less

@@ -0,0 +1,74 @@
+@charset "utf-8";
+
+#course-p-detail {
+  background: #fff;
+  min-height: 100%;
+
+  .content {
+    width: 1200px !important;
+  }
+
+  .top {
+    padding: 8px 30px;
+    height: 60px;
+    line-height: 44px;
+  }
+
+  .center {
+    padding-top: 20px;
+    position: relative;
+    overflow: hidden;
+    width: 1140px !important;
+
+    .desc {
+      margin-bottom: 60px;
+    }
+
+    .main-title {
+      border-left: 6px solid #7876FCFF;
+      padding-left: 5px;
+      line-height: 20px;
+      color: #303036FF;
+      font-size: 20px;
+      margin-bottom: 30px;
+    }
+
+    .list {
+      margin: 0 -20px;
+      margin-bottom: 10px;
+
+      .single-item {
+        margin: 0 20px;
+        margin-bottom: 20px;
+      }
+
+      .other-item {
+        margin: 0 20px;
+        margin-bottom: 20px;
+        background: #eee;
+        width: 352px;
+        height: 140px;
+
+        .assets {}
+      }
+
+      .service-item {
+        margin: 0 20px;
+        margin-bottom: 20px;
+        padding: 20px 30px 20px 80px;
+        position: relative;
+        border-radius: 3px;
+        background: #FBFBFBFF;
+
+        .assets {
+          position: absolute;
+          left: 10px;
+        }
+
+        .t {
+          line-height: 25px;
+        }
+      }
+    }
+  }
+}

+ 112 - 0
front/project/www/routes/course/pDetail/page.js

@@ -0,0 +1,112 @@
+import React from 'react';
+import './index.less';
+import Assets from '@src/components/Assets';
+import Page from '@src/containers/Page';
+import Button from '../../../components/Button';
+import { SingleItem } from '../../../components/Item';
+import Footer from '../../../components/Footer';
+import { Contact } from '../../../components/Other';
+
+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() {
+    return (
+      <div>
+        <div className="top content t-8">
+          千行课堂 > 全部课程 > OG20综合刷题 > 课时3 > <span className="t-1">套餐详情</span>
+        </div>
+        <div className="center content">
+          <div className="t-1 t-s-20 m-b-2">
+            OG20综合刷题——第3课时:XXXXXXX
+            <div className="action f-r">
+              <Button className="m-r-1" radius size="lager">
+                立即购买
+              </Button>
+              <Button theme="default" radius size="lager">
+                <Assets name="add" />
+              </Button>
+            </div>
+          </div>
+          <div className="t-7 t-s-18 f-w-b m-b-1">套餐价: ¥ 15000</div>
+          <div className="t-1 t-s-16 desc">
+            针对 0G20 的集中训练针对 0G20 的集中训练针对 0G20 的集中训练针对 0G20 的集中训练。针对 0G20 的集中训练针对
+            0G20 的集中训练针对 0G20 的集,中训练针对 0G20 的集中训练针对 0G20 的集中训练针对。 0G20 的集中训练针对
+            0,G20 的集中训练针对 0G20 的集中训练针对 0G20 的集中训。练针对 0G20 的集中训练针对 0G20 的集中训练针对 0G20
+            的集中训练。针对 0G20 的集中训练针对 0G20 的集中训练针对 0G20 的集中训练针对 0G20 的集中训练。
+          </div>
+          <div className="main-title">包含课程</div>
+          <div className="list">
+            <SingleItem show />
+            <SingleItem show />
+            <SingleItem show />
+          </div>
+          <div className="main-title">配套服务</div>
+          <div className="list">
+            <div className="other-item d-i-b">
+              <Assets name="" />
+            </div>
+            <div className="other-item d-i-b">
+              <Assets name="" />
+            </div>
+            <div className="other-item d-i-b">
+              <Assets name="" />
+            </div>
+          </div>
+          <div className="main-title">赠送服务</div>
+          <div className="list">
+            <div className="service-item d-i-b">
+              <Assets name="mokao" />
+              <div className="t t-13 t-s-20 f-w-b">机经</div>
+              <div className="t-13">1个月</div>
+            </div>
+            <div className="service-item d-i-b">
+              <Assets name="VIP_1" />
+              <div className="t t-13 t-s-20 f-w-b">VIP</div>
+              <div className="t-13">3个月</div>
+            </div>
+            <div className="service-item d-i-b">
+              <Assets name="jijing" />
+              <div className="t t-13 t-s-20 f-w-b">模考</div>
+              <div className="t-13">1个月</div>
+            </div>
+          </div>
+        </div>
+        <Contact />
+        <Footer />
+      </div>
+    );
+  }
+}

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

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

+ 125 - 0
front/project/www/routes/course/single/index.less

@@ -0,0 +1,125 @@
+@charset "utf-8";
+
+#course-single {
+  .content {
+    width: 1200px !important;
+  }
+
+  .top {
+    padding: 8px 30px;
+    height: 60px;
+
+    .tabs.text {
+      background: none;
+      padding: 0;
+      display: inline-block;
+    }
+
+    .f-r {
+      height: 44px;
+      line-height: 44px;
+    }
+  }
+
+  .center {
+    background: #fff;
+
+    .content {
+      width: 1140px !important;
+
+      .item-list {
+        margin: 0 -20px;
+        margin-bottom: 20px;
+
+        .item {
+          display: inline-block;
+          margin: 0 20px;
+          border: 3px solid #F7F7F7FF;
+          background: #F7F7F7FF;
+          border-radius: 4px;
+          width: 254px;
+          padding: 20px 20px 30px 60px;
+          position: relative;
+          cursor: pointer;
+
+          .assets {
+            position: absolute;
+            left: 15px;
+            top: 30px;
+          }
+        }
+
+        .item.active {
+          border: 3px solid rgba(66, 146, 240, 1);
+          background: #fff;
+        }
+      }
+
+      .item-detail {
+        overflow: hidden;
+
+        .left {
+          float: left;
+          width: 450px;
+          height: 500px;
+          background: #eee;
+        }
+
+        .right {
+          padding-left: 490px;
+
+          .input {
+            position: relative;
+            line-height: 32px;
+
+            .up {
+              cursor: pointer;
+              position: absolute;
+              left: 160px;
+              top: 5px;
+              font-size: 10px;
+              color: #D0D8E2;
+              transform: scale(0.8);
+
+            }
+
+            .down {
+              cursor: pointer;
+              position: absolute;
+              left: 160px;
+              top: 15px;
+              font-size: 10px;
+              color: #D0D8E2;
+              transform: scale(0.8);
+            }
+
+            input {
+              line-height: 32px;
+              background: #F7F7F7FF;
+            }
+          }
+
+          .action {
+            margin-bottom: 10px;
+            overflow: hidden;
+            padding-top: 40px;
+
+            .button {}
+
+            .default.button {
+              color: #4292F0;
+            }
+          }
+        }
+      }
+    }
+  }
+
+  .bottom {
+    background: #FAFAFAFF;
+
+    .content {
+      padding: 20px 0;
+    }
+  }
+}

+ 171 - 0
front/project/www/routes/course/single/page.js

@@ -0,0 +1,171 @@
+import React from 'react';
+import './index.less';
+import { Icon } from 'antd';
+import Page from '@src/containers/Page';
+import Assets from '@src/components/Assets';
+import Footer from '../../../components/Footer';
+import { Contact } from '../../../components/Other';
+import Tabs from '../../../components/Tabs';
+import Button from '../../../components/Button';
+
+export default class extends Page {
+  initState() {
+    return {
+      tab: '1',
+      key: '1',
+    };
+  }
+
+  onChangeTab(tab) {
+    this.setState({ tab });
+  }
+
+  onChangeItem(key) {
+    this.setState({ key });
+  }
+
+  renderView() {
+    return (
+      <div>
+        <div className="top content">
+          <Tabs type="text" active={'2'} 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>
+        {this.renderDetail()}
+        <Contact />
+        <Footer />
+      </div>
+    );
+  }
+
+  renderDetail() {
+    const { tab, key } = this.state;
+    return [
+      <div className="center">
+        <div className="content">
+          <Assets className="m-b-2" width={1140} name="s" />
+          <div className="item-list">
+            <div className={`item ${key === '1' ? 'active' : ''}`} onClick={() => this.onChangeItem('1')}>
+              <Assets name="xinshoufudao" />
+              <div className="t-1 t-s-20 f-w-b">新手辅导</div>
+              <div className="t-2">GMAT 全面了解,定制学习计划</div>
+            </div>
+            <div className={`item ${key === '2' ? 'active' : ''}`} onClick={() => this.onChangeItem('2')}>
+              <Assets name="zhenduanfudao" />
+              <div className="t-1 t-s-20 f-w-b">诊断辅导</div>
+              <div className="t-2">复习效果不理想,制定突破计划</div>
+            </div>
+            <div className={`item ${key === '3' ? 'active' : ''}`} onClick={() => this.onChangeItem('3')}>
+              <Assets name="xitongshouke" />
+              <div className="t-1 t-s-20 f-w-b">系统授课</div>
+              <div className="t-2">全面知识体系讲解,提升实战能力</div>
+            </div>
+            <div className={`item ${key === '4' ? 'active' : ''}`} onClick={() => this.onChangeItem('4')}>
+              <Assets name="dayi" />
+              <div className="t-1 t-s-20 f-w-b">答疑课</div>
+              <div className="t-2">GMAT 全面了解,定制学习计划</div>
+            </div>
+          </div>
+          <div className="item-detail">
+            <div className="left">
+              <Assets name="" />
+            </div>
+            <div className="right">
+              <div className="t-1 t-s-16 m-b-2">
+                针对 0G20 的集中训练针对 0G20 的集中训练针对 0G20 的集中训练针对 0G20 的集中训练。针对 0G20
+                的集中训练针对 0G20 的集中训练针对 0G20 的集,中训练针对 0G20 的集中训练针 对 0G20 的集中训练针对。 0G20
+                的集中训练针对 0,G20 的集中训练针对 0G20 的集中训练针对 0G20 的集中训。练针对 0G20 的集中训练针对 0G20
+                的集中训练针对 0G20 的集中训练。针对 0G20 的集中训练针对 0G20 的集中训练针对 0G20 的集中训练针对 0G20
+                的集中训练。
+              </div>
+              <div className="m-b-5">
+                <div style={{ width: 120 }} className="d-i-b t-2">
+                  适合人群
+                </div>
+                <div className="d-i-b t-1">刚接触GMAT考试的考 ⽣生或需要科学备考计划 的考⽣生</div>
+              </div>
+              <div className="m-b-5">
+                <div style={{ width: 120 }} className="d-i-b t-2">
+                  课时数
+                </div>
+                <div className="d-i-b t-1">1课时,时⻓长1-1.5⼩小时</div>
+              </div>
+              <div className="m-b-5">
+                <div style={{ width: 120 }} className="d-i-b t-2">
+                  授课流程
+                </div>
+                <div className="d-i-b t-1">购买课时 → 收集信息 → 预约时间 → 正式辅导</div>
+              </div>
+              <div className="m-b-5">
+                <div style={{ width: 120 }} className="d-i-b t-2">
+                  课程有效期
+                </div>
+                <div className="d-i-b t-1">30天</div>
+              </div>
+              <div className="m-b-5 input">
+                <div style={{ width: 120 }} className="d-i-b t-2">
+                  购买课时
+                </div>
+                <div className="d-i-b t-1">
+                  <input style={{ width: 32 }} className="m-l-5 t-c" />
+                  <Icon className="up" type="caret-up" />
+                  <Icon className="down" type="caret-down" />
+                </div>
+              </div>
+              <div className="m-b-5">
+                <div style={{ width: 120 }} className="d-i-b t-2">
+                  课程总价
+                </div>
+                <div className="d-i-b t-7 t-s-20 f-w-b"> ¥ 15000</div>
+              </div>
+              <div className="action">
+                <Button className="m-r-1" radius size="lager">
+                  立即购买
+                </Button>
+                <Button theme="default" radius size="lager">
+                  <Assets name="add" />
+                </Button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>,
+      <div className="bottom">
+        <div className="content">
+          <Tabs
+            type="full"
+            border
+            active={tab}
+            tabs={[
+              { title: '老师资料', key: '1' },
+              { title: '咨询方式', key: '2' },
+              { title: 'FAQs', key: '3' },
+              { title: '学员评价', key: '4' },
+            ]}
+          />
+          {this[`renderTab${tab}`]()}
+        </div>
+      </div>,
+    ];
+  }
+
+  renderTab1() {
+    return <div />;
+  }
+
+  renderTab2() {
+    return <div />;
+  }
+
+  renderTab3() {
+    return <div />;
+  }
+
+  renderTab4() {
+    return <div />;
+  }
+}