Browse Source

add h5 page

KaysonCui 5 years ago
parent
commit
c4a6cb6038
100 changed files with 1944 additions and 32 deletions
  1. 4 0
      .vscode/settings.json
  2. 2 1
      front/build/webpack.config.js
  3. 2 2
      front/project/admin/local.json
  4. BIN
      front/project/h5/assets/CAT.png
  5. BIN
      front/project/h5/assets/IDcard.png
  6. BIN
      front/project/h5/assets/IDcard2.png
  7. BIN
      front/project/h5/assets/JiJing.png
  8. BIN
      front/project/h5/assets/NEW.png
  9. BIN
      front/project/h5/assets/VIP.png
  10. BIN
      front/project/h5/assets/banner.png
  11. BIN
      front/project/h5/assets/bg_img1.png
  12. BIN
      front/project/h5/assets/bg_img2.png
  13. BIN
      front/project/h5/assets/bg_img3.png
  14. BIN
      front/project/h5/assets/bg_img4.png
  15. BIN
      front/project/h5/assets/bg_img5.png
  16. BIN
      front/project/h5/assets/c_b.png
  17. BIN
      front/project/h5/assets/clean.png
  18. BIN
      front/project/h5/assets/copy.png
  19. BIN
      front/project/h5/assets/d_b.png
  20. BIN
      front/project/h5/assets/down_down3.png
  21. BIN
      front/project/h5/assets/down_up3.png
  22. BIN
      front/project/h5/assets/drop_down1.png
  23. BIN
      front/project/h5/assets/drop_down2.png
  24. BIN
      front/project/h5/assets/drop_up1.png
  25. BIN
      front/project/h5/assets/drop_up2.png
  26. BIN
      front/project/h5/assets/expert.png
  27. BIN
      front/project/h5/assets/human.png
  28. BIN
      front/project/h5/assets/img1.png
  29. BIN
      front/project/h5/assets/img2.png
  30. BIN
      front/project/h5/assets/img3.png
  31. BIN
      front/project/h5/assets/national_emblem.png
  32. BIN
      front/project/h5/assets/next_blue.png
  33. BIN
      front/project/h5/assets/next_violet.png
  34. BIN
      front/project/h5/assets/p_bg.png
  35. BIN
      front/project/h5/assets/planet.png
  36. BIN
      front/project/h5/assets/scan1.png
  37. BIN
      front/project/h5/assets/scan2.png
  38. BIN
      front/project/h5/assets/screen.png
  39. BIN
      front/project/h5/assets/success.png
  40. BIN
      front/project/h5/assets/sun_blue.png
  41. BIN
      front/project/h5/assets/sun_red.png
  42. BIN
      front/project/h5/assets/sun_yello.png
  43. BIN
      front/project/h5/assets/swich_off_big.png
  44. BIN
      front/project/h5/assets/swich_off_small.png
  45. BIN
      front/project/h5/assets/swich_on_big.png
  46. BIN
      front/project/h5/assets/swich_on_small.png
  47. BIN
      front/project/h5/assets/userfriendly.png
  48. BIN
      front/project/h5/assets/形状结合.png
  49. BIN
      front/project/h5/assets/椭圆形.png
  50. 14 0
      front/project/h5/components/Avatar/index.js
  51. 21 0
      front/project/h5/components/Avatar/index.less
  52. 48 0
      front/project/h5/components/Block/index.js
  53. 116 1
      front/project/h5/components/Block/index.less
  54. 5 2
      front/project/h5/components/Button/index.js
  55. 21 0
      front/project/h5/components/Button/index.less
  56. 2 2
      front/project/h5/components/Icon/index.js
  57. 6 0
      front/project/h5/components/Money/index.less
  58. 2 1
      front/project/h5/routes/index.js
  59. 9 0
      front/project/h5/routes/page/changeHistory/index.js
  60. 68 0
      front/project/h5/routes/page/changeHistory/index.less
  61. 67 0
      front/project/h5/routes/page/changeHistory/page.js
  62. 9 0
      front/project/h5/routes/page/data/index.js
  63. 48 0
      front/project/h5/routes/page/data/index.less
  64. 46 0
      front/project/h5/routes/page/data/page.js
  65. 249 1
      front/project/h5/routes/page/home/index.less
  66. 98 1
      front/project/h5/routes/page/home/page.js
  67. 9 0
      front/project/h5/routes/page/identity/index.js
  68. 27 0
      front/project/h5/routes/page/identity/index.less
  69. 28 0
      front/project/h5/routes/page/identity/page.js
  70. 10 1
      front/project/h5/routes/page/index.js
  71. 9 0
      front/project/h5/routes/page/invitation/index.js
  72. 43 0
      front/project/h5/routes/page/invitation/index.less
  73. 42 0
      front/project/h5/routes/page/invitation/page.js
  74. 9 0
      front/project/h5/routes/page/machine/index.js
  75. 64 0
      front/project/h5/routes/page/machine/index.less
  76. 55 0
      front/project/h5/routes/page/machine/page.js
  77. 56 1
      front/project/h5/routes/page/message/index.less
  78. 28 3
      front/project/h5/routes/page/message/page.js
  79. 9 0
      front/project/h5/routes/page/open/index.js
  80. 45 0
      front/project/h5/routes/page/open/index.less
  81. 28 0
      front/project/h5/routes/page/open/page.js
  82. 9 0
      front/project/h5/routes/page/product/index.js
  83. 52 0
      front/project/h5/routes/page/product/index.less
  84. 58 0
      front/project/h5/routes/page/product/page.js
  85. 9 0
      front/project/h5/routes/page/update/index.js
  86. 63 0
      front/project/h5/routes/page/update/index.less
  87. 60 0
      front/project/h5/routes/page/update/page.js
  88. 2 2
      front/project/h5/routes/product/bought/page.js
  89. 42 1
      front/project/h5/routes/product/courseDetail/index.less
  90. 31 3
      front/project/h5/routes/product/courseDetail/page.js
  91. 64 1
      front/project/h5/routes/product/coursePackage/index.less
  92. 46 3
      front/project/h5/routes/product/coursePackage/page.js
  93. 62 1
      front/project/h5/routes/product/dataDetail/index.less
  94. 44 3
      front/project/h5/routes/product/dataDetail/page.js
  95. 6 0
      front/project/h5/routes/product/index.js
  96. 9 0
      front/project/h5/routes/product/serviceDetail/index.js
  97. 52 0
      front/project/h5/routes/product/serviceDetail/index.less
  98. 34 0
      front/project/h5/routes/product/serviceDetail/page.js
  99. 2 2
      front/src/containers/Async.js
  100. 0 0
      front/src/containers/Touch.js

+ 4 - 0
.vscode/settings.json

@@ -0,0 +1,4 @@
+{
+  "git.autorefresh": false,
+  "eslint.run": "onSave"
+}

+ 2 - 1
front/build/webpack.config.js

@@ -219,7 +219,8 @@ function loaderAnalysis(loaders) {
 }
 
 const theme = {
-  // 'primary-color': '#f54b37'
+  // 'primary-color': '#8573AD',
+  'brand-primary': '#6b43fe',
 };
 
 webpackConfig.module.rules.push({

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

@@ -4,7 +4,7 @@
     "scripts": [],
     "proxy": [
       {
-        "target": "http://127.0.0.1:8888",
+        "target": "http://qianxing-admin.nuliji.com",
         "from": "/api",
         "to": "/admin"
       }
@@ -12,4 +12,4 @@
   },
   "test": {},
   "production": {}
-}
+}

BIN
front/project/h5/assets/CAT.png


BIN
front/project/h5/assets/IDcard.png


BIN
front/project/h5/assets/IDcard2.png


BIN
front/project/h5/assets/JiJing.png


BIN
front/project/h5/assets/NEW.png


BIN
front/project/h5/assets/VIP.png


BIN
front/project/h5/assets/banner.png


BIN
front/project/h5/assets/bg_img1.png


BIN
front/project/h5/assets/bg_img2.png


BIN
front/project/h5/assets/bg_img3.png


BIN
front/project/h5/assets/bg_img4.png


BIN
front/project/h5/assets/bg_img5.png


BIN
front/project/h5/assets/c_b.png


BIN
front/project/h5/assets/clean.png


BIN
front/project/h5/assets/copy.png


BIN
front/project/h5/assets/d_b.png


BIN
front/project/h5/assets/down_down3.png


BIN
front/project/h5/assets/down_up3.png


BIN
front/project/h5/assets/drop_down1.png


BIN
front/project/h5/assets/drop_down2.png


BIN
front/project/h5/assets/drop_up1.png


BIN
front/project/h5/assets/drop_up2.png


BIN
front/project/h5/assets/expert.png


BIN
front/project/h5/assets/human.png


BIN
front/project/h5/assets/img1.png


BIN
front/project/h5/assets/img2.png


BIN
front/project/h5/assets/img3.png


BIN
front/project/h5/assets/national_emblem.png


BIN
front/project/h5/assets/next_blue.png


BIN
front/project/h5/assets/next_violet.png


BIN
front/project/h5/assets/p_bg.png


BIN
front/project/h5/assets/planet.png


BIN
front/project/h5/assets/scan1.png


BIN
front/project/h5/assets/scan2.png


BIN
front/project/h5/assets/screen.png


BIN
front/project/h5/assets/success.png


BIN
front/project/h5/assets/sun_blue.png


BIN
front/project/h5/assets/sun_red.png


BIN
front/project/h5/assets/sun_yello.png


BIN
front/project/h5/assets/swich_off_big.png


BIN
front/project/h5/assets/swich_off_small.png


BIN
front/project/h5/assets/swich_on_big.png


BIN
front/project/h5/assets/swich_on_small.png


BIN
front/project/h5/assets/userfriendly.png


BIN
front/project/h5/assets/形状结合.png


BIN
front/project/h5/assets/椭圆形.png


+ 14 - 0
front/project/h5/components/Avatar/index.js

@@ -0,0 +1,14 @@
+import React, { Component } from 'react';
+import './index.less';
+import Assets from '@src/components/Assets';
+
+export default class Avatar extends Component {
+  render() {
+    const { className = '', name = '', src = '', size = 'basic', radius = true } = this.props;
+    return (
+      <div className={`g-avatar-wrapper ${className} ${size} ${radius ? 'radius' : ''}`}>
+        <Assets name={name} src={src} />
+      </div>
+    );
+  }
+}

+ 21 - 0
front/project/h5/components/Avatar/index.less

@@ -0,0 +1,21 @@
+@import '../../app.less';
+
+.g-avatar-wrapper {
+  display: inline-block;
+
+  .assets {}
+}
+
+.g-avatar-wrapper.radius {
+  border-radius: 50%;
+}
+
+.g-avatar-wrapper.small {
+  width: 32px;
+  height: 32px;
+}
+
+.g-avatar-wrapper.basic {
+  width: 50px;
+  height: 50px;
+}

+ 48 - 0
front/project/h5/components/Block/index.js

@@ -1,6 +1,9 @@
 import React, { Component } from 'react';
 import './index.less';
 import { Icon } from 'antd-mobile';
+import Assets from '@src/components/Assets';
+import Tag from '../Tag';
+import Money from '../Money';
 
 export class Block extends Component {
   render() {
@@ -41,3 +44,48 @@ export class LinkBlock extends Component {
     );
   }
 }
+
+export class CourseBlock extends Component {
+  render() {
+    return (
+      <Block className="course-block">
+        <div className="title">OG20整合刷题-语法SC</div>
+        <div className="block-body">
+          <Assets name="c_b" />
+          <div className="info">
+            <div className="teacher">
+              授课老师<span>李小小</span>
+            </div>
+            <div className="desc">老师特别特别特别好,上课特别认真…</div>
+            <div className="division" />
+            <div className="data">
+              <Tag size="small">适合新手</Tag>
+              <div className="result">
+                优质回答<span>89</span>
+              </div>
+            </div>
+          </div>
+        </div>
+      </Block>
+    );
+  }
+}
+
+export class DataBlock extends Component {
+  render() {
+    return (
+      <Block className="data-block">
+        <Assets name="d_b" />
+        <div className="info">
+          <div className="title">OG16/17/18/19语法千行</div>
+          <div className="desc">资料非常好,帮助复习。</div>
+          <div className="division" />
+          <div className="data">
+            <div className="people">888人已购</div>
+            <Money value="200" />
+          </div>
+        </div>
+      </Block>
+    );
+  }
+}

+ 116 - 1
front/project/h5/components/Block/index.less

@@ -85,7 +85,7 @@
     display: inline-block;
     color: #303036;
     font-size: 16px;
-    margin-right: 10px;
+    font-weight: 600;
   }
 
   .g-link-block-sub {
@@ -94,6 +94,7 @@
     font-size: 12px;
     text-align: center;
     flex: 1;
+    margin-right: 10px;
   }
 
   .g-link-block-icon {
@@ -123,4 +124,118 @@
   .g-link-block-icon {
     background: #A7A7B7;
   }
+}
+
+.course-block {
+  padding: 15px 20px;
+
+  .title {
+    color: #1A1A1F;
+    font-size: 16px;
+    margin-bottom: 15px;
+    line-height: 16px;
+  }
+
+  .block-body {
+    position: relative;
+
+    .assets {
+      width: 120px;
+      height: 75px;
+      position: absolute;
+    }
+
+    .info {
+      padding-left: 130px;
+
+      .teacher {
+        font-size: 12px;
+        color: #A7A7B7;
+        margin-bottom: 5px;
+        line-height: 12px;
+
+        span {
+          color: #1A1A1F;
+          margin-left: 5px;
+        }
+      }
+
+      .desc {
+        font-size: 10px;
+        color: #A7A7B7;
+        white-space: nowrap;
+        text-overflow: ellipsis;
+        overflow: hidden;
+        margin-bottom: 5px;
+      }
+
+      .division {
+        height: 1px;
+        background: #D8D8D8;
+        margin-bottom: 5px;
+      }
+
+      .data {
+        .result {
+          float: right;
+          font-size: 12px;
+          color: #A7A7B7;
+
+          span {
+            color: #7660A4;
+            margin-left: 7px;
+          }
+        }
+      }
+    }
+  }
+}
+
+.data-block {
+  padding: 10px 15px;
+  position: relative;
+
+  .assets {
+    position: absolute;
+    width: 75px;
+    height: 80px;
+  }
+
+  .info {
+    padding-left: 85px;
+
+    .title {
+      color: #1A1A1F;
+      font-size: 16px;
+      line-height: 16px;
+      margin-bottom: 10px;
+    }
+
+    .desc {
+      font-size: 10px;
+      color: #A7A7B7;
+      white-space: nowrap;
+      text-overflow: ellipsis;
+      overflow: hidden;
+      margin-bottom: 5px;
+    }
+
+    .division {
+      height: 1px;
+      background: #D8D8D8;
+      margin-bottom: 5px;
+    }
+
+    .data {
+      .people {
+        display: inline-block;
+        font-size: 10px;
+        color: #A7A7B7;
+      }
+
+      .g-money {
+        float: right;
+      }
+    }
+  }
 }

+ 5 - 2
front/project/h5/components/Button/index.js

@@ -14,13 +14,16 @@ export default class Button extends Component {
       onClick,
       radius,
       block,
+      disabled,
     } = this.props;
     return (
       <div
-        className={`g-button-wrapper ${className} ${size} ${theme} ${radius ? 'radius' : ''} ${block ? 'block' : ''}`}
+        className={`g-button-wrapper ${className} ${size} ${theme} ${radius ? 'radius' : ''} ${block ? 'block' : ''} ${
+          disabled ? 'disabled' : ''
+        }`}
       >
         <Touch
-          style={{ width: width || 'auto', margin: margin ? `0 ${margin}px` : '' }}
+          style={{ width: width || 'auto', margin: margin ? `0 ${margin}px` : '0 auto' }}
           className="g-button"
           onClick={() => onClick && onClick()}
         >

+ 21 - 0
front/project/h5/components/Button/index.less

@@ -6,6 +6,7 @@
   .g-button {
     display: inline-block;
     text-align: center;
+    padding: 0 10px;
   }
 }
 
@@ -24,6 +25,19 @@
   }
 }
 
+.g-button-wrapper.lager {
+  .g-button {
+    line-height: 44px;
+    font-size: 16px;
+  }
+}
+
+.g-button-wrapper.lager.radius {
+  .g-button {
+    border-radius: 22px;
+  }
+}
+
 .g-button-wrapper.basic.radius {
   .g-button {
     border-radius: 18px;
@@ -39,4 +53,11 @@
   .g-button.touch {
     background: darken(#41A6F3, 10)
   }
+}
+
+.g-button-wrapper.disabled {
+  .g-button {
+    background: #C0C0C0 !important;
+    color: #fff;
+  }
 }

+ 2 - 2
front/project/h5/components/Icon/index.js

@@ -2,7 +2,7 @@ import React from 'react';
 import { Icon as AIcon } from 'antd';
 
 function Icon(props) {
-  const { type, onClick, color = '000' } = props;
-  return <AIcon type={type} style={{ color }} onClick={() => onClick && onClick()} />;
+  const { type, theme = 'outlined', onClick, color = '000' } = props;
+  return <AIcon type={type} theme={theme} style={{ color }} onClick={() => onClick && onClick()} />;
 }
 export default Icon;

+ 6 - 0
front/project/h5/components/Money/index.less

@@ -23,6 +23,12 @@
   }
 }
 
+.g-money.small {
+  span {
+    font-size: 12px;
+  }
+}
+
 .g-money.lager {
   span {
     font-size: 16px;

+ 2 - 1
front/project/h5/routes/index.js

@@ -1,5 +1,6 @@
 // We only need to import the modules necessary for initial render
 
 import Page from './page';
+import Product from './product';
 
-export default [...Page];
+export default [...Page, ...Product];

+ 9 - 0
front/project/h5/routes/page/changeHistory/index.js

@@ -0,0 +1,9 @@
+export default {
+  path: '/change/history',
+  key: 'change-history',
+  title: '资料更新',
+  needLogin: false,
+  component() {
+    return import('./page');
+  },
+};

+ 68 - 0
front/project/h5/routes/page/changeHistory/index.less

@@ -0,0 +1,68 @@
+@charset "utf-8";
+
+#change-history {
+  padding: 15px;
+
+  .title {
+    font-size: 16px;
+    color: #303036;
+    margin-bottom: 15px;
+
+    .date {
+      color: #686872;
+      float: right;
+
+      .assets {
+        width: 15px;
+        height: 15px;
+        margin-left: 5px;
+      }
+    }
+  }
+
+  .main {
+    text-align: center;
+    font-size: 24px;
+    font-weight: 600;
+    padding-top: 15px;
+    padding-bottom: 40px;
+    border-bottom: 1px solid #eee;
+    margin-bottom: 25px;
+  }
+
+  .list {
+    .item:nth-child(odd) {
+      background: #FBFBFB;
+    }
+
+    .item {
+      border-bottom: 1px solid #eee;
+
+      .d {
+        color: #686872;
+        display: inline-block;
+        width: 60px;
+        height: 60px;
+        line-height: 60px;
+        text-align: center;
+      }
+
+      .v {
+        display: inline-block;
+        padding: 15px 20px;
+
+        span {
+          display: inline-block;
+          width: 30px;
+          height: 30px;
+          line-height: 30px;
+          color: #fff;
+          margin: 0 5px;
+          background: #7660A4;
+          border-radius: 50%;
+          text-align: center;
+        }
+      }
+    }
+  }
+}

+ 67 - 0
front/project/h5/routes/page/changeHistory/page.js

@@ -0,0 +1,67 @@
+import React from 'react';
+import './index.less';
+import { DatePicker } from 'antd-mobile';
+import Page from '@src/containers/Page';
+import Assets from '@src/components/Assets';
+
+export default class extends Page {
+  init() {}
+
+  renderView() {
+    return (
+      <div>
+        <div className="title">最新换库</div>
+        <div className="main">2019年05月22日</div>
+        <div className="title">
+          历史记录
+          <div className="date">
+            <DatePicker mode="year" onChange={date => this.setState({ date })}>
+              <div>
+                2019年
+                <Assets name="down_down3" />
+              </div>
+            </DatePicker>
+          </div>
+        </div>
+        <div className="list">
+          <div className="item">
+            <div className="d">4月</div>
+            <div className="v">
+              <span>12</span>
+              <span>12</span>
+              <span>12</span>
+              <span>12</span>
+            </div>
+          </div>
+          <div className="item">
+            <div className="d">4月</div>
+            <div className="v">
+              <span>12</span>
+              <span>12</span>
+              <span>12</span>
+              <span>12</span>
+            </div>
+          </div>
+          <div className="item">
+            <div className="d">4月</div>
+            <div className="v">
+              <span>12</span>
+              <span>12</span>
+              <span>12</span>
+              <span>12</span>
+            </div>
+          </div>
+          <div className="item">
+            <div className="d">4月</div>
+            <div className="v">
+              <span>12</span>
+              <span>12</span>
+              <span>12</span>
+              <span>12</span>
+            </div>
+          </div>
+        </div>
+      </div>
+    );
+  }
+}

+ 9 - 0
front/project/h5/routes/page/data/index.js

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

+ 48 - 0
front/project/h5/routes/page/data/index.less

@@ -0,0 +1,48 @@
+@charset "utf-8";
+
+#data {
+  padding: 15px;
+
+  .block {
+    box-shadow: 0px 10px 20px 0px rgba(0, 0, 0, 0.02);
+    border-radius: 8px;
+    border: 1px solid rgba(227, 227, 227, 1);
+    text-align: center;
+    padding: 30px 0;
+    margin-bottom: 35px;
+
+    span {
+      font-size: 24px;
+      color: #7660A4;
+      margin: 0 5px;
+      font-weight: 600;
+    }
+  }
+
+  .title {
+    color: #686872;
+    font-size: 16px;
+    margin-bottom: 25px;
+  }
+
+  .item {
+    width: 90px;
+    display: inline-block;
+
+    .text {
+      color: #303036;
+      margin-bottom: 10px;
+    }
+
+    .value {
+      color: #686872;
+
+      span {
+        color: #303036;
+        font-size: 32px;
+        font-weight: 600;
+        margin: 0 2px;
+      }
+    }
+  }
+}

+ 46 - 0
front/project/h5/routes/page/data/page.js

@@ -0,0 +1,46 @@
+import React from 'react';
+import './index.less';
+import Page from '@src/containers/Page';
+import Icon from '../../../components/Icon';
+
+export default class extends Page {
+  init() {}
+
+  renderView() {
+    return (
+      <div>
+        <div className="block">
+          <div className="text">
+            自2019-05-26,您已在千行学习<span>88</span>天
+          </div>
+          <div className="text">
+            累积<span>88</span>H<span>30</span>Min
+          </div>
+        </div>
+        <div className="title">本周数据</div>
+        <div className="t-c">
+          <div className="item">
+            <div className="text">学习时间</div>
+            <div className="value">
+              <span>23</span>Hour
+            </div>
+          </div>
+          <div className="item">
+            <div className="text">同比上周</div>
+            <div className="value">
+              <Icon type="caret-up" theme="filled" color="#6EC64B" />
+              <span>15</span>%
+            </div>
+          </div>
+          <div className="item">
+            <div className="text">同比全站</div>
+            <div className="value">
+              <Icon type="caret-down" theme="filled" color="#F36565" />
+              <span>15</span>%
+            </div>
+          </div>
+        </div>
+      </div>
+    );
+  }
+}

+ 249 - 1
front/project/h5/routes/page/home/index.less

@@ -1,3 +1,251 @@
 @charset "utf-8";
 
-#index {}
+#index {
+  .block-1 {
+    padding: 15px;
+    position: relative;
+
+    .line {
+      position: absolute;
+      width: 30px;
+      height: 5px;
+      background: #7660A4;
+      top: 80px;
+    }
+
+    .title {
+      color: #303036;
+      margin-bottom: 5px;
+    }
+
+    .sub {
+      font-size: 12px;
+      color: #303036;
+      margin-bottom: 30px;
+    }
+
+    .line {}
+
+    .copy-title {
+      font-size: 12px;
+      color: #686872;
+      margin-bottom: 5px;
+    }
+
+    .input {
+      height: 44px;
+      line-height: 44px;
+      background: rgba(255, 255, 255, 1);
+      border: 2px solid rgba(229, 229, 229, 1);
+      font-size: 12px;
+      display: flex;
+
+      .prefix {
+        background: rgba(247, 247, 247, 1);
+        padding: 0 6px;
+        display: inline-block;
+        height: 40px;
+        line-height: 40px;
+        vertical-align: top;
+      }
+
+      .value {
+        color: #40A8E2;
+        padding: 0 10px;
+        display: inline-block;
+        height: 40px;
+        line-height: 40px;
+        vertical-align: top;
+        flex: 1;
+      }
+
+      .assets {
+        vertical-align: top;
+      }
+    }
+
+  }
+
+  .block-2 {
+    background: #fefefe;
+    position: relative;
+    max-width: 750px;
+    margin: 0 auto;
+
+    .bg {
+      .bg-1 {
+        background-image: url('/assets/bg_img1.png');
+        background-repeat: no-repeat;
+        background-position: left;
+        background-size: 485px 128px;
+        height: 128px;
+      }
+
+      .bg-2 {
+        background-image: url('/assets/bg_img2.png');
+        background-repeat: no-repeat;
+        background-position: center;
+        background-size: 750px 300px;
+        height: 300px;
+      }
+
+      .bg-3 {
+        background-image: url('/assets/bg_img3.png');
+        background-repeat: no-repeat;
+        background-position: center;
+        background-size: 750px 300px;
+        height: 300px;
+      }
+
+      .bg-4 {
+        background-image: url('/assets/bg_img4.png');
+        background-repeat: no-repeat;
+        background-position: center;
+        background-size: 750px 300px;
+        height: 300px;
+      }
+
+      .bg-5 {
+        background-image: url('/assets/bg_img5.png');
+        background-repeat: no-repeat;
+        background-position: center;
+        background-size: 750px 240px;
+        height: 240px;
+      }
+    }
+
+    .fixed {
+      position: absolute;
+      top: 0;
+      left: 0;
+      right: 0;
+      padding-top: 35px;
+      padding-left: 15px;
+      padding-right: 15px;
+
+      .h-title {
+        color: #050930;
+        font-size: 18px;
+        font-weight: 600;
+        text-align: center;
+        margin-bottom: 30px;
+      }
+
+      .line {
+        height: 3px;
+        width: 15px;
+        background: #7660A4;
+        position: absolute;
+        top: 75px;
+      }
+
+      .title {
+        color: #303139;
+        font-size: 16px;
+        font-weight: 600;
+        margin-bottom: 10px;
+      }
+
+      .block-2-1 {
+        background: rgba(255, 255, 255, 1);
+        box-shadow: 0px 14px 24px 0px rgba(156, 183, 223, 0.14), 0px 10px 20px 0px rgba(0, 0, 0, 0.01);
+        border-radius: 4px;
+        border: 1px solid rgba(240, 240, 240, 1);
+        margin-bottom: 15px;
+        padding: 20px 18px;
+
+        .block-2-1-h {
+          .assets {
+            margin-right: 7px;
+            width: 20px;
+            height: 20px;
+            transform: translateY(-2px)
+          }
+
+          .block-2-1-h-t {
+            font-size: 16px;
+            color: #303139;
+            font-weight: 600;
+            margin-right: 5px;
+            display: inline-block;
+          }
+
+          .block-2-1-h-s {
+            font-size: 12px;
+            color: #5E677B;
+            display: inline-block;
+          }
+        }
+
+        .block-2-1-d {
+          font-size: 12px;
+          color: #8897A8;
+        }
+      }
+
+      .block-2-2 {
+        display: flex;
+        margin: 30px -7px;
+
+        .block-2-2-i {
+          flex: 1;
+          margin: 0 7px;
+          background: rgba(255, 255, 255, 1);
+          box-shadow: 0px 14px 24px 0px rgba(156, 183, 223, 0.14), 0px 10px 20px 0px rgba(0, 0, 0, 0.01);
+          border-radius: 2px;
+          border: 1px solid rgba(240, 240, 240, 1);
+          padding: 10px 15px;
+
+          .block-2-2-i-t {
+            font-size: 18px;
+            font-weight: 600;
+            margin-bottom: 25px;
+          }
+
+          .block-2-2-i-d {
+            font-size: 10px;
+          }
+        }
+      }
+
+
+      .block-2-3 {
+        background: rgba(255, 255, 255, 1);
+        box-shadow: 0px 20px 30px 0px rgba(156, 183, 223, 0.03), 0px 15px 20px 0px rgba(0, 0, 0, 0.02);
+        border-radius: 4px;
+        border: 1px solid rgba(246, 250, 255, 1);
+        margin-bottom: 15px;
+        padding: 20px 15px;
+        position: relative;
+
+        .block-2-3-t {
+          font-weight: 600;
+          margin-bottom: 10px;
+        }
+
+        .block-2-3-d {
+          font-size: 12px;
+          color: #8897A8;
+        }
+
+        .assets {
+          position: absolute;
+          right: 0;
+          top: 0;
+        }
+      }
+    }
+  }
+
+  .blue {
+    color: #4292F0;
+  }
+
+  .red {
+    color: #F36565;
+  }
+
+  .yellow {
+    color: #F2B252;
+  }
+}

+ 98 - 1
front/project/h5/routes/page/home/page.js

@@ -1,9 +1,106 @@
 import React from 'react';
 import './index.less';
 import Page from '@src/containers/Page';
+import Assets from '@src/components/Assets';
 
 export default class extends Page {
   renderView() {
-    return <div />;
+    return (
+      <div>
+        <div className="block-1">
+          <div className="title">加入“千行GMAT”</div>
+          <div className="sub">一起Waste Less,Learn More.</div>
+          <div className="line" />
+          <div className="copy-title">复制下方地址至浏览器打开</div>
+          <div className="input">
+            <div className="prefix">http://</div>
+            <div className="value">qianhanggmat.com/id123134341431</div>
+            <Assets name="copy" />
+          </div>
+        </div>
+        <div className="block-2">
+          <div className="bg">
+            <div className="bg-1" />
+            <div className="bg-2" />
+            <div className="bg-3" />
+            <div className="bg-4" />
+            <div className="bg-5" />
+          </div>
+          <div className="fixed">
+            <div className="h-title">PREPARE THE GMAT LIKE A PRO.</div>
+            <div className="line" />
+            <div className="title">Why 千行</div>
+            <div className="block-2-1">
+              <div className="block-2-1-h">
+                <Assets name="planet" />
+                <div className="block-2-1-h-t">内容全⾯</div>
+                <div className="block-2-1-h-s">360° Support</div>
+              </div>
+              <div className="block-2-1-d">
+                网站涵盖考试介绍、方法引导、技巧点拨、练习、课程、机经、模考、心经分享等,从入门到出分,一应俱全,满足各阶段考生的备考需求。
+              </div>
+            </div>
+            <div className="block-2-1">
+              <div className="block-2-1-h">
+                <Assets name="expert" />
+                <div className="block-2-1-h-t">指导专业</div>
+                <div className="block-2-1-h-s">We are Pro.</div>
+              </div>
+              <div className="block-2-1-d">
+                专注GMAT备考8年
+                <br /> 出分周期高于行业平均水平26%
+                <br /> 学员均分高于行业18%
+              </div>
+            </div>
+            <div className="block-2-1">
+              <div className="block-2-1-h">
+                <Assets name="userfriendly" />
+                <div className="block-2-1-h-t">⼈⼈会⽤</div>
+                <div className="block-2-1-h-s">User-frriendly</div>
+              </div>
+              <div className="block-2-1-d">
+                除提供有用的数据信息外,网站多处设置信息导,提供必要的解释和原理说明,从源头规避误区,协助考生做出更加明智的决策,提高备考效率。
+              </div>
+            </div>
+            <div className="block-2-2">
+              <div className="block-2-2-i">
+                <div className="block-2-2-i-t blue">123342</div>
+                <div className="block-2-2-i-d">注册用户</div>
+              </div>
+              <div className="block-2-2-i">
+                <div className="block-2-2-i-t yellow">2234</div>
+                <div className="block-2-2-i-d">700+分学员</div>
+              </div>
+              <div className="block-2-2-i">
+                <div className="block-2-2-i-t red">680</div>
+                <div className="block-2-2-i-d">学员均分</div>
+              </div>
+            </div>
+            <div className="title">独家服务</div>
+            <div className="block-2-3">
+              <Assets name="sun_blue" />
+              <div className="block-2-3-t blue">千⾏CAT模考</div>
+              <div className="block-2-3-d">采⽤CAT出题机制、排名制算分⽅法</div>
+              <div className="block-2-3-d">独家题源,排除重题⼲扰</div>
+              <div className="block-2-3-d">模考报告提供具体考点分析,明确提升⽅向。</div>
+            </div>
+            <div className="block-2-3">
+              <Assets name="sun_red" />
+              <div className="block-2-3-t red">机经服务</div>
+              <div className="block-2-3-d">⾼效整理:梳理逻辑结构,⽆“反吞噬”⻛险</div>
+              <div className="block-2-3-d">轻松获取:⾃动更新⾄邮箱代替⼿动领取</div>
+              <div className="block-2-3-d">随时查阅:⼿机查看、在线浏览、在线做题</div>
+            </div>
+            <div className="block-2-3">
+              <Assets name="sun_yello" />
+              <div className="block-2-3-t yellow">VIP服务</div>
+              <div className="block-2-3-d">⾃由组卷,练你想练</div>
+              <div className="block-2-3-d">独家解析,专业报告</div>
+              <div className="block-2-3-d">提问特权,1VS1答疑</div>
+            </div>
+          </div>
+        </div>
+      </div>
+    );
   }
 }

+ 9 - 0
front/project/h5/routes/page/identity/index.js

@@ -0,0 +1,9 @@
+export default {
+  path: '/identity',
+  key: 'identity',
+  title: '身份认证',
+  needLogin: false,
+  component() {
+    return import('./page');
+  },
+};

+ 27 - 0
front/project/h5/routes/page/identity/index.less

@@ -0,0 +1,27 @@
+@charset "utf-8";
+
+#identity {
+  padding: 25px 0;
+  width: 300px;
+  margin: 0 auto;
+
+  .text {
+    margin-bottom: 25px;
+  }
+
+  .id-card-1 {
+    margin-bottom: 25px;
+    position: relative;
+  }
+
+  .id-card-2 {
+    position: relative;
+  }
+
+  .scan {
+    position: absolute;
+    top: 50%;
+    left: 50%;
+    transform: translate(-50%, -50%);
+  }
+}

+ 28 - 0
front/project/h5/routes/page/identity/page.js

@@ -0,0 +1,28 @@
+import React from 'react';
+import './index.less';
+import Page from '@src/containers/Page';
+import Assets from '@src/components/Assets';
+
+export default class extends Page {
+  init() {}
+
+  renderView() {
+    return (
+      <div>
+        <div className="text">
+          请扫描您的居民身份证原件,领取6个月VIP权限。
+          <br />
+          千行将重视和保护您的隐私。
+        </div>
+        <div className="id-card-1">
+          <Assets name="IDcard" />
+          <Assets className="scan" name="scan1" />
+        </div>
+        <div className="id-card-2">
+          <Assets name="IDcard2" />
+          <Assets className="scan" name="scan2" />
+        </div>
+      </div>
+    );
+  }
+}

+ 10 - 1
front/project/h5/routes/page/index.js

@@ -1,5 +1,14 @@
 import home from './home';
 import login from './login';
 import bind from './bind';
+import identity from './identity';
+import invitation from './invitation';
+import data from './data';
+import product from './product';
+import message from './message';
+import update from './update';
+import changeHistory from './changeHistory';
+import open from './open';
+import machine from './machine';
 
-export default [home, login, bind];
+export default [home, login, bind, identity, invitation, data, product, message, update, changeHistory, open, machine];

+ 9 - 0
front/project/h5/routes/page/invitation/index.js

@@ -0,0 +1,9 @@
+export default {
+  path: '/invitation',
+  key: 'invitation',
+  title: '邀请好友',
+  needLogin: false,
+  component() {
+    return import('./page');
+  },
+};

+ 43 - 0
front/project/h5/routes/page/invitation/index.less

@@ -0,0 +1,43 @@
+@charset "utf-8";
+
+#invitation {
+  padding: 15px;
+  position: relative;
+
+  .line {
+    position: absolute;
+    width: 30px;
+    height: 5px;
+    background: #7660A4;
+    top: 80px;
+  }
+
+  .text {
+    color: #303036;
+    margin-bottom: 50px;
+  }
+
+  .title {
+    margin-bottom: 20px;
+    color: #686872;
+    font-size: 16px;
+  }
+
+  .item {
+    display: inline-block;
+    margin-bottom: 20px;
+    margin-left: 5px;
+    margin-right: 5px;
+    width: 140px;
+
+    .assets {
+      width: 62px;
+      height: 62px;
+      margin-bottom: 5px;
+    }
+  }
+
+  .go {
+    margin-bottom: 25px;
+  }
+}

+ 42 - 0
front/project/h5/routes/page/invitation/page.js

@@ -0,0 +1,42 @@
+import React from 'react';
+import './index.less';
+import Page from '@src/containers/Page';
+import Assets from '@src/components/Assets';
+import Button from '../../../components/Button';
+import Input from '../../../components/Input';
+
+export default class extends Page {
+  init() {}
+
+  renderView() {
+    return (
+      <div>
+        <div className="text">
+          每邀请一位好友注册“千行GMAT”,
+          <br />
+          你的VIP权限会延长7天,可累加无上限。
+        </div>
+        <div className="line" />
+        <div className="title">微信邀请</div>
+        <div className="t-c">
+          <div className="item t-c">
+            <Assets name="img1" />
+            <div>1.点击右上角「 ···」</div>
+          </div>
+          <div className="item t-c">
+            <Assets name="img2" />
+            <div>2.发送给朋友</div>
+          </div>
+        </div>
+        <Button className="go" block width={110} radius>
+          去邀请
+        </Button>
+        <div className="title">邮件邀请</div>
+        <Input placeholder="添加多个邮箱,请用「;」间隔" />
+        <Button block width={110} radius>
+          发送邀请
+        </Button>
+      </div>
+    );
+  }
+}

+ 9 - 0
front/project/h5/routes/page/machine/index.js

@@ -0,0 +1,9 @@
+export default {
+  path: '/machine',
+  key: 'machine',
+  title: '机经',
+  needLogin: false,
+  component() {
+    return import('./page');
+  },
+};

+ 64 - 0
front/project/h5/routes/page/machine/index.less

@@ -0,0 +1,64 @@
+@charset "utf-8";
+
+#machine {
+  .tip {
+    background: #7660A4;
+    color: #fff;
+    line-height: 36px;
+    font-size: 12px;
+  }
+
+  .list {
+    padding: 0 15px;
+
+    .log-title {
+      padding: 10px 0;
+      color: #A7A7B7;
+      font-size: 12px;
+    }
+
+    .item {
+      border-bottom: 1px solid #eee;
+      position: relative;
+      padding-top: 5px;
+      padding-bottom: 10px;
+
+      .title {
+        font-size: 14px;
+        color: #303036;
+        margin-bottom: 10px;
+
+        .date {
+          float: right;
+          color: #686872;
+          font-size: 12px;
+        }
+      }
+
+      .desc {
+        font-size: 12px;
+        color: #686872;
+        margin-bottom: 15px;
+      }
+    }
+  }
+
+  .empty {
+    position: fixed;
+    top: 40%;
+    text-align: center;
+    color: #999999;
+    width: 100%;
+
+    .text {
+      margin-bottom: 20px;
+    }
+  }
+
+  .fixed {
+    position: fixed;
+    bottom: 0;
+    left: 0;
+    right: 0;
+  }
+}

+ 55 - 0
front/project/h5/routes/page/machine/page.js

@@ -0,0 +1,55 @@
+import React from 'react';
+import './index.less';
+import { Tabs } from 'antd-mobile';
+import Page from '@src/containers/Page';
+import Button from '../../../components/Button';
+
+export default class extends Page {
+  renderView() {
+    const { list = [] } = this.state;
+    return (
+      <div>
+        <div className="tip">最近换库时间:2019-07-30,已换库n天。</div>
+        <Tabs tabs={[{ title: '数学', key: 's' }, { title: '阅读RC', key: '1' }, { title: '逻辑CR', key: 'l' }]} />
+        <div>{list.length > 0 ? this.renderList() : this.renderEmpty()}</div>
+        <div className="fixed">
+          <Button block disabled={list.length === 0} size="lager">
+            查阅机经
+          </Button>
+        </div>
+      </div>
+    );
+  }
+
+  renderList() {
+    return (
+      <div className="list">
+        <div className="log-title">更新日志</div>
+        <div className="item">
+          <div className="title">
+            版本7<span className="date">2019-07-21 09:50:26</span>
+          </div>
+          <div className="desc">
+            新增 7 道数学机经;
+            <br /> 补充第 23 题条件;
+            <br /> 更新第 54题解析和答案
+          </div>
+        </div>
+      </div>
+    );
+  }
+
+  renderEmpty() {
+    return (
+      <div className="empty">
+        <div className="text">
+          还未购买本月机经。 <br />
+          您可至千行网站「我的-工具」查看往期机经。
+        </div>
+        <Button block width={120} radius>
+          去购买
+        </Button>
+      </div>
+    );
+  }
+}

+ 56 - 1
front/project/h5/routes/page/message/index.less

@@ -1,3 +1,58 @@
 @charset "utf-8";
 
-#message {}
+#message {
+  padding: 15px;
+
+
+  .all {
+    .assets {
+      width: 25px;
+      height: 25px;
+      margin-right: 8px;
+    }
+  }
+
+  .list {
+    .item {
+      display: flex;
+      padding: 20px 15px;
+      border-bottom: 1px solid #eee;
+
+      .am-badge-dot {
+        transform: translate(5px, -2px);
+      }
+
+      .detail {
+        flex: 1;
+
+        .title {
+          color: #000000;
+          font-size: 16px;
+          margin-bottom: 5px;
+        }
+
+        .desc {
+          color: #999999;
+          white-space: nowrap;
+          text-overflow: ellipsis;
+          overflow: hidden;
+        }
+
+        a {
+          font-size: 10px;
+        }
+      }
+
+      .date-time {
+        color: #999999;
+        font-size: 12px;
+        text-align: right;
+        margin-top: 10px;
+
+        .date {}
+
+        .time {}
+      }
+    }
+  }
+}

+ 28 - 3
front/project/h5/routes/page/message/page.js

@@ -1,12 +1,37 @@
 import React from 'react';
+import { Link } from 'react-router-dom';
+import { Badge } from 'antd-mobile';
 import './index.less';
 import Page from '@src/containers/Page';
+import Assets from '@src/components/Assets';
 
 export default class extends Page {
-  init() {
-  }
+  init() {}
 
   renderView() {
-    return <div />;
+    return (
+      <div>
+        <div className="all">
+          <Assets name="clean" />
+          全部已读
+        </div>
+        <div className="list">
+          <div className="item">
+            <div className="detail">
+              <div className="title">
+                请尽快完成作业
+                <Badge dot />
+              </div>
+              <div className="desc">消息详情消息详情消息详情消息详情</div>
+              <Link to="">请在千行官网查看详情</Link>
+            </div>
+            <div className="date-time">
+              <div className="date">2019-05-20</div>
+              <div className="time">10:22:21</div>
+            </div>
+          </div>
+        </div>
+      </div>
+    );
   }
 }

+ 9 - 0
front/project/h5/routes/page/open/index.js

@@ -0,0 +1,9 @@
+export default {
+  path: '/open',
+  key: 'open',
+  title: '开通',
+  needLogin: false,
+  component() {
+    return import('./page');
+  },
+};

+ 45 - 0
front/project/h5/routes/page/open/index.less

@@ -0,0 +1,45 @@
+@charset "utf-8";
+
+#open {
+  padding: 65px 30px;
+  text-align: center;
+
+  .icon {
+    margin-bottom: 25px;
+    width: 48px;
+    margin-left: auto;
+    margin-right: auto;
+  }
+
+  .title {
+    color: #303036;
+  }
+
+  .tip {
+    font-size: 10px;
+    color: #303036;
+    margin-bottom: 35px;
+  }
+
+  .check {
+    margin-bottom: 10px;
+    text-align: left;
+
+    .g-checkbox-wrapper {
+      margin-right: 10px;
+    }
+
+    span {
+      vertical-align: top;
+      display: inline-block;
+    }
+  }
+
+  .g-button-wrapper {
+    margin-bottom: 20px;
+  }
+
+  .no {
+    color: #A7A7B7;
+  }
+}

+ 28 - 0
front/project/h5/routes/page/open/page.js

@@ -0,0 +1,28 @@
+import React from 'react';
+import './index.less';
+import Page from '@src/containers/Page';
+import Assets from '@src/components/Assets';
+import Checkbox from '../../../components/CheckBox';
+import Button from '../../../components/Button';
+
+export default class extends Page {
+  renderView() {
+    return (
+      <div>
+        <div className="icon">
+          <Assets name="img3" />
+        </div>
+        <div className="title">您正在开通“机经服务”</div>
+        <div className="tip">有效期至:2019-12-03</div>
+        <div className="check">
+          <Checkbox />
+          <span>邮箱订阅机经</span>
+        </div>
+        <Button block radius>
+          立即开通
+        </Button>
+        <div className="no">暂不开通</div>
+      </div>
+    );
+  }
+}

+ 9 - 0
front/project/h5/routes/page/product/index.js

@@ -0,0 +1,9 @@
+export default {
+  path: '/product',
+  key: 'product',
+  title: '全部商品',
+  needLogin: false,
+  component() {
+    return import('./page');
+  },
+};

+ 52 - 0
front/project/h5/routes/page/product/index.less

@@ -0,0 +1,52 @@
+@charset "utf-8";
+
+#product {
+  padding: 0 15px;
+
+  .am-tabs {
+    margin-bottom: 15px;
+  }
+
+  .title {
+    font-size: 16px;
+    color: #1A1A1F;
+    margin-bottom: 15px;
+  }
+
+  .service {
+    display: flex;
+    margin: 0 -4px;
+    margin-bottom: 30px;
+
+    .service-item {
+      flex: 1;
+      margin: 0 4px;
+      background: rgba(247, 247, 247, 1);
+      border-radius: 4px;
+      position: relative;
+      padding: 15px;
+      font-size: 12px;
+      line-height: 16px;
+
+      .assets {
+        width: 32px;
+        height: 32px;
+        position: absolute;
+        top: 15px;
+        right: 15px;
+      }
+    }
+  }
+
+  .banner {
+    margin-bottom: 15px;
+    width: 100%;
+    background: rgba(216, 216, 216, 1);
+    border-radius: 4px;
+    overflow: hidden;
+  }
+
+  .more {
+    color: #A7A7B7;
+  }
+}

+ 58 - 0
front/project/h5/routes/page/product/page.js

@@ -0,0 +1,58 @@
+import React from 'react';
+import './index.less';
+import { Tabs } from 'antd-mobile';
+import Page from '@src/containers/Page';
+import Assets from '@src/components/Assets';
+import Money from '../../../components/Money';
+import { LinkBlock, CourseBlock, DataBlock } from '../../../components/Block';
+
+export default class extends Page {
+  init() {}
+
+  renderView() {
+    return (
+      <div>
+        <Tabs
+          tabs={[
+            { title: '服务', key: 's' },
+            { title: '1V1私教', key: '1' },
+            { title: '在线课程', key: 'l' },
+            { title: '资料', key: 'd' },
+          ]}
+        />
+        <div className="title">服务</div>
+        <div className="service">
+          <div className="service-item">
+            <div className="service-item-t">123342</div>
+            <Money size="small" value="100" />
+            <Assets name="VIP" />
+          </div>
+          <div className="service-item">
+            <div className="service-item-t">123342</div>
+            <Money size="small" value="100" />
+            <Assets name="CAT" />
+          </div>
+          <div className="service-item">
+            <div className="service-item-t">123342</div>
+            <Money size="small" value="100" />
+            <Assets name="JiJing" />
+          </div>
+        </div>
+        <div className="title">1V1私教</div>
+        <Assets name="banner" className="banner" />
+        <LinkBlock title="新手辅导" sub="GMAT 全面了解,定制学习计划" />
+        <LinkBlock title="诊断辅导" sub="复习效果不理想,制定突破计划" theme="not" />
+        <LinkBlock title="系统授课" sub="全面知识体系讲解,提升实战能力" />
+        <LinkBlock title="答疑课" sub="一对一解答疑问,破解所有疑团" theme="not" />
+        <div className="title">在线课程</div>
+        <Assets name="banner" className="banner" />
+        <CourseBlock />
+        <div className="more t-r m-b-2">全部课程 ></div>
+        <div className="title">资料</div>
+        <Assets name="banner" className="banner" />
+        <DataBlock />
+        <div className="more t-r m-b-2">全部资料 ></div>
+      </div>
+    );
+  }
+}

+ 9 - 0
front/project/h5/routes/page/update/index.js

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

+ 63 - 0
front/project/h5/routes/page/update/index.less

@@ -0,0 +1,63 @@
+@charset "utf-8";
+
+#update {
+  padding: 0 15px;
+
+  .list {
+    .item {
+      border-bottom: 1px solid #eee;
+      position: relative;
+      padding-top: 20px;
+      padding-bottom: 15px;
+
+      .title {
+        font-size: 16px;
+        color: #303036;
+        margin-bottom: 10px;
+
+        .date {
+          float: right;
+          color: #686872;
+          font-size: 14px;
+        }
+      }
+
+      .tip {
+        color: #686872;
+        font-size: 12px;
+
+        .new {
+          margin-right: 5px;
+
+          .g-tag {
+            background: #FFC800;
+            border: none;
+          }
+        }
+      }
+
+      .desc {
+        font-size: 12px;
+        color: #686872;
+        margin-top: 10px;
+        margin-bottom: 15px;
+      }
+
+      .drop {
+        width: 22px;
+        height: 22px;
+        position: absolute;
+        bottom: 15px;
+        right: 0;
+      }
+    }
+  }
+
+  .empty {
+    position: fixed;
+    top: 50%;
+    left: 50%;
+    transform: translate(-50%, -50%);
+    color: #999999;
+  }
+}

+ 60 - 0
front/project/h5/routes/page/update/page.js

@@ -0,0 +1,60 @@
+import React, { Component } from 'react';
+import './index.less';
+import Page from '@src/containers/Page';
+import Assets from '@src/components/Assets';
+import Tag from '../../../components/Tag';
+
+class Item extends Component {
+  constructor(props) {
+    super(props);
+    this.state = { show: false };
+  }
+
+  render() {
+    const { show } = this.state;
+    return (
+      <div className="item">
+        <div className="title">
+          OG19 语法千行<span className="date">2019-08-11</span>
+        </div>
+        <div className="tip">
+          <Tag className="new" size="small">
+            NEW
+          </Tag>
+          变更点:版本2
+        </div>
+        <div hidden={!show} className="desc">
+          删除“the number of wolf population 意思重复”删除“the number of wolf population 意思重复”删除“the number of
+          wolf population 意思重复”
+        </div>
+        <Assets
+          className="drop"
+          name={!show ? 'drop_down1' : 'drop_up1'}
+          onClick={() => this.setState({ show: !show })}
+        />
+      </div>
+    );
+  }
+}
+
+export default class extends Page {
+  init() {}
+
+  renderView() {
+    const { list = [] } = this.state;
+    return <div>{list.length > 0 ? this.renderList() : this.renderEmpty()}</div>;
+  }
+
+  renderList() {
+    return (
+      <div className="list">
+        <Item />
+        <Item />
+      </div>
+    );
+  }
+
+  renderEmpty() {
+    return <div className="empty">还未购买或订阅资料</div>;
+  }
+}

+ 2 - 2
front/project/h5/routes/product/bought/page.js

@@ -1,10 +1,10 @@
 import React from 'react';
 import './index.less';
 import Page from '@src/containers/Page';
+import {} from '../../../components/Block';
 
 export default class extends Page {
-  init() {
-  }
+  init() {}
 
   renderView() {
     return <div />;

+ 42 - 1
front/project/h5/routes/product/courseDetail/index.less

@@ -1,3 +1,44 @@
 @charset "utf-8";
 
-#product-course-detail {}
+#product-course-detail {
+  .b-g {
+    padding: 15px;
+    height: 160px;
+    background-size: 100%;
+    background-position: center;
+    background-repeat: no-repeat;
+
+    .title {
+      color: #fff;
+      font-size: 16px;
+    }
+  }
+
+  .tip {
+    background: #8872BC;
+    height: 32px;
+    line-height: 32px;
+    padding: 0 15px;
+    color: #fff;
+  }
+
+  .detail {
+    padding: 0 15px;
+  }
+
+  .fixed {
+    position: fixed;
+    bottom: 0;
+    left: 0;
+    right: 0;
+    height: 64px;
+    line-height: 64px;
+    padding: 0 15px;
+    border-top: 1px solid #eee;
+    background: #fff;
+
+    .fee {
+      display: inline-block;
+    }
+  }
+}

+ 31 - 3
front/project/h5/routes/product/courseDetail/page.js

@@ -1,12 +1,40 @@
 import React from 'react';
 import './index.less';
+import { Tabs } from 'antd-mobile';
 import Page from '@src/containers/Page';
+import Money from '../../../components/Money';
+import Button from '../../../components/Button';
 
 export default class extends Page {
-  init() {
-  }
+  init() {}
 
   renderView() {
-    return <div />;
+    return (
+      <div>
+        <div className="b-g" style={{ backgroundImage: 'url(/assets/p_bg.png)' }}>
+          <div className="title">OG20整合刷题-语法SC</div>
+        </div>
+        <div className="tip">访问WWW.XXXXX,试听该课程</div>
+        <div className="detail">
+          <Tabs
+            tabs={[
+              { title: '资料介绍', key: 'd' },
+              { title: '作者介绍', key: 'a' },
+              { title: '获取方式', key: 'h' },
+              { title: 'FAQs', key: 'f' },
+              { title: '用户评价', key: 'u' },
+            ]}
+          />
+        </div>
+        <div className="fixed">
+          <div className="fee">
+            总额: <Money value="1200" size="lager" />
+          </div>
+          <Button width={110} className="f-r" radius>
+            立即购买
+          </Button>
+        </div>
+      </div>
+    );
   }
 }

+ 64 - 1
front/project/h5/routes/product/coursePackage/index.less

@@ -1,3 +1,66 @@
 @charset "utf-8";
 
-#product-course-package {}
+#product-course-package {
+  padding: 15px;
+
+  .title {
+    font-size: 16px;
+    color: #303036;
+    margin-bottom: 15px;
+    font-weight: 600;
+  }
+
+  .name {
+    line-height: 50px;
+    margin-bottom: 25px;
+
+    span {
+      margin-left: 10px;
+    }
+  }
+
+  .tags {
+    margin-bottom: 30px;
+
+    .g-tag {
+      margin-right: 5px;
+    }
+  }
+
+  .desc {
+    color: #686872;
+    margin-bottom: 15px;
+    font-size: 12px;
+  }
+
+  .detail-title {
+    color: #303036;
+    font-weight: 600;
+    margin-bottom: 10px;
+  }
+
+  .detail-tags {
+    margin-bottom: 15px;
+
+    .g-tag {
+      margin-right: 10px;
+      margin-bottom: 10px;
+    }
+  }
+
+  .fixed {
+    position: fixed;
+    bottom: 0;
+    left: 0;
+    right: 0;
+    height: 64px;
+    line-height: 64px;
+    padding: 0 15px;
+    border-top: 1px solid #eee;
+    background: #fff;
+
+    .fee {
+      display: inline-block;
+    }
+  }
+}

+ 46 - 3
front/project/h5/routes/product/coursePackage/page.js

@@ -1,12 +1,55 @@
 import React from 'react';
 import './index.less';
 import Page from '@src/containers/Page';
+import Money from '../../../components/Money';
+import Button from '../../../components/Button';
+import Tag from '../../../components/Tag';
+import Avatar from '../../../components/Avatar';
 
 export default class extends Page {
-  init() {
-  }
+  init() {}
 
   renderView() {
-    return <div />;
+    return (
+      <div>
+        <div className="title">OG16/17/18/19语法千行OG16/17/18/19语法千 行</div>
+        <div className="tags">
+          <Tag size="small">适合新手</Tag>
+        </div>
+        <div className="detail-title">授课老师</div>
+        <div className="name">
+          <Avatar name="scan1" />
+          <span>李奕都(DUKB24)</span>
+        </div>
+        <div className="detail-title">课程介绍</div>
+        <div className="desc">
+          本商品仅限购买者本人使用,不可商用和传播。 若在购买过程中 遇到问题,请联系千行小助手协助解决。
+        </div>
+        <div className="detail-title">包含课程</div>
+        <div className="detail-tags">
+          <Tag theme="border">OG20阅读刷题(7课时)</Tag>
+          <Tag theme="border">OOG20逻辑刷题(8课时)</Tag>
+          <Tag theme="border">OG20语法SC刷题(10 课时)</Tag>
+        </div>
+        <div className="detail-title">配套服务</div>
+        <div className="detail-tags">
+          <Tag theme="border">预习作业</Tag>
+          <Tag theme="border">课后答疑</Tag>
+        </div>
+        <div className="detail-title">赠送服务</div>
+        <div className="detail-tags">
+          <Tag theme="border">机经对折券×1</Tag>
+          <Tag theme="border">VIP 权限×6个月</Tag>
+        </div>
+        <div className="fixed">
+          <div className="fee">
+            总额: <Money value="1200" size="lager" />
+          </div>
+          <Button width={110} className="f-r" radius>
+            立即购买
+          </Button>
+        </div>
+      </div>
+    );
   }
 }

+ 62 - 1
front/project/h5/routes/product/dataDetail/index.less

@@ -1,3 +1,64 @@
 @charset "utf-8";
 
-#product-data-detail {}
+#product-data-detail {
+  padding: 15px;
+  min-height: 100%;
+
+  .detail {
+    position: relative;
+    margin-bottom: 15px;
+
+    .info-img {
+      position: absolute;
+      left: 0;
+      top: 0;
+      width: 105px;
+    }
+
+    .info {
+      padding-left: 115px;
+      position: relative;
+
+      .title {
+        font-size: 16px;
+        line-height: 24px;
+        color: #303036;
+      }
+
+      .tags {
+
+        .g-tag {
+          margin-right: 5px;
+        }
+      }
+
+      .data {}
+
+      .g-money {
+        position: absolute;
+        bottom: 0;
+        right: 0;
+      }
+    }
+  }
+
+  .desc {
+    margin-bottom: 15px;
+  }
+
+  .fixed {
+    position: fixed;
+    bottom: 0;
+    left: 0;
+    right: 0;
+    height: 64px;
+    line-height: 64px;
+    padding: 0 15px;
+    border-top: 1px solid #eee;
+    background: #fff;
+
+    .fee {
+      display: inline-block;
+    }
+  }
+}

+ 44 - 3
front/project/h5/routes/product/dataDetail/page.js

@@ -1,12 +1,53 @@
 import React from 'react';
 import './index.less';
+import { Tabs } from 'antd-mobile';
 import Page from '@src/containers/Page';
+import Assets from '@src/components/Assets';
+import Money from '../../../components/Money';
+import Button from '../../../components/Button';
+import Tag from '../../../components/Tag';
 
 export default class extends Page {
-  init() {
-  }
+  init() {}
 
   renderView() {
-    return <div />;
+    return (
+      <div>
+        <div className="detail">
+          <Assets className="info-img" name="d_b" />
+          <div className="info">
+            <div className="title">OG16/17/18/19语法千行OG16/ 17/18/19语法千行</div>
+            <div className="tags">
+              <Tag size="small">原创</Tag>
+              <Tag size="small">适合新手</Tag>
+            </div>
+            <div className="data">页数: 30页</div>
+            <div className="data">格式: PDF</div>
+            <div className="data">2019-06-20 10:21 更新</div>
+            <Money value="200" size="lager" theme="sell" />
+          </div>
+        </div>
+        <div className="desc">
+          对“忽略有效考点”的解析进行补充,同时讲解OG不够精准的解析,帮助考生明确重点、避开误区,节省大量的时间和精力,刷OG必备。
+        </div>
+        <Tabs
+          tabs={[
+            { title: '资料介绍', key: 'd' },
+            { title: '作者介绍', key: 'a' },
+            { title: '获取方式', key: 'h' },
+            { title: 'FAQs', key: 'f' },
+            { title: '用户评价', key: 'u' },
+          ]}
+        />
+        <div className="fixed">
+          <div className="fee">
+            总额: <Money value="1200" size="lager" />
+          </div>
+          <Button width={110} className="f-r" radius>
+            立即购买
+          </Button>
+        </div>
+      </div>
+    );
   }
 }

+ 6 - 0
front/project/h5/routes/product/index.js

@@ -0,0 +1,6 @@
+import courseDetail from './courseDetail';
+import serviceDetail from './serviceDetail';
+import dataDetail from './dataDetail';
+import coursePackage from './coursePackage';
+
+export default [courseDetail, serviceDetail, dataDetail, coursePackage];

+ 9 - 0
front/project/h5/routes/product/serviceDetail/index.js

@@ -0,0 +1,9 @@
+export default {
+  path: '/product/service/detail/:id',
+  key: 'product-service-detail',
+  title: '服务详情',
+  needLogin: false,
+  component() {
+    return import('./page');
+  },
+};

+ 52 - 0
front/project/h5/routes/product/serviceDetail/index.less

@@ -0,0 +1,52 @@
+@charset "utf-8";
+
+#product-service-detail {
+  .b-g {
+    padding: 15px;
+    height: 160px;
+    background-size: 100%;
+    background-position: center;
+    background-repeat: no-repeat;
+
+    .title {
+      color: #fff;
+      font-size: 16px;
+    }
+  }
+
+  .detail {
+    padding: 15px;
+
+    .title {
+      font-size: 16px;
+      color: #303036;
+      margin-bottom: 15px;
+    }
+
+    .division {
+      height: 1px;
+      background: #D8D8D8;
+      margin-bottom: 15px;
+    }
+
+    .g-special-radio-group {
+      margin-bottom: 15px;
+    }
+  }
+
+  .fixed {
+    position: fixed;
+    bottom: 0;
+    left: 0;
+    right: 0;
+    height: 64px;
+    line-height: 64px;
+    padding: 0 15px;
+    border-top: 1px solid #eee;
+    background: #fff;
+
+    .fee {
+      display: inline-block;
+    }
+  }
+}

+ 34 - 0
front/project/h5/routes/product/serviceDetail/page.js

@@ -0,0 +1,34 @@
+import React from 'react';
+import './index.less';
+import Page from '@src/containers/Page';
+import Money from '../../../components/Money';
+import Button from '../../../components/Button';
+import { SpecialRadioGroup } from '../../../components/Radio';
+
+export default class extends Page {
+  init() {}
+
+  renderView() {
+    return (
+      <div>
+        <div className="b-g" style={{ backgroundImage: 'url(/assets/p_bg.png)' }}>
+          <div className="title">OG20整合刷题-语法SC</div>
+        </div>
+        <div className="detail">
+          <div className="title">可选套餐</div>
+          <SpecialRadioGroup list={[{ key: '1', label: 1 }, { key: '2', label: 2 }]} value="1" onChange={() => {}} />
+          <div className="division" />
+          <div className="title">服务介绍</div>
+        </div>
+        <div className="fixed">
+          <div className="fee">
+            总额: <Money value="1200" size="lager" />
+          </div>
+          <Button width={110} className="f-r" radius>
+            立即购买
+          </Button>
+        </div>
+      </div>
+    );
+  }
+}

+ 2 - 2
front/src/containers/Async.js

@@ -1,5 +1,5 @@
 import React, { Component } from 'react';
-import { Form } from 'antd';
+import { createForm } from 'rc-form';
 
 export default class extends Component {
   constructor(props) {
@@ -12,7 +12,7 @@ export default class extends Component {
       this.props
         .component()
         .then(({ default: component }) => {
-          this.setState({ C: this.props.isForm ? Form.create()(component) : component });
+          this.setState({ C: this.props.isForm ? createForm()(component) : component });
         })
         .catch(err => {
           console.log('async error: ', err);

+ 0 - 0
front/src/containers/Touch.js


Some files were not shown because too many files changed in this diff