You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dolphinscheduler.apache.org by ki...@apache.org on 2021/12/12 13:37:25 UTC

[dolphinscheduler-website] branch master updated: [Feature] Mobile adaptaion (#568)

This is an automated email from the ASF dual-hosted git repository.

kirs pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/dolphinscheduler-website.git


The following commit(s) were added to refs/heads/master by this push:
     new c6f5c11  [Feature] Mobile adaptaion (#568)
c6f5c11 is described below

commit c6f5c115f9ddfe88bd44e0731afe2a34bf010ff0
Author: wangyizhi <wa...@cmss.chinamobile.com>
AuthorDate: Sun Dec 12 21:37:17 2021 +0800

    [Feature] Mobile adaptaion (#568)
    
    * [Feature] Mobile adaptation
    
    * [Feature] Mobile menu && Repair build error
    
    Co-authored-by: wangyizhi1 <wa...@cmss.chinamobile.com>
---
 docs/en-us/dev/user_doc/guide/quick-start.md |  17 +-
 img/banner-mobile.png                        | Bin 0 -> 342943 bytes
 img/menu_black.png                           | Bin 0 -> 141 bytes
 img/menu_white.png                           | Bin 0 -> 141 bytes
 package.json                                 |   2 +
 site_config/docs2-0-0.js                     |   2 +-
 src/components/footer/index.jsx              |  26 +--
 src/components/footer/index.scss             | 136 +++++++-----
 src/components/header/index.jsx              | 200 +++++++++++------
 src/components/header/index.scss             | 239 ++++++++++++++-------
 src/markdown.scss                            |   6 +
 src/pages/blog/index.md.scss                 |  12 ++
 src/pages/home/index.jsx                     | 101 +++++----
 src/pages/home/index.scss                    | 301 ++++++++++++--------------
 src/pages/user/index.jsx                     |  82 ++++---
 src/pages/user/user.scss                     | 310 ++++++++-------------------
 src/variables.scss                           |   5 +
 17 files changed, 760 insertions(+), 679 deletions(-)

diff --git a/docs/en-us/dev/user_doc/guide/quick-start.md b/docs/en-us/dev/user_doc/guide/quick-start.md
index 418248a..9410ada 100644
--- a/docs/en-us/dev/user_doc/guide/quick-start.md
+++ b/docs/en-us/dev/user_doc/guide/quick-start.md
@@ -14,10 +14,11 @@
    <img src="/img/create-queue-en.png" width="60%" />
  </p>
 
-  * Create tenant
-      <p align="center">
-    <img src="/img/create-tenant-en.png" width="60%" />
-  </p>
+* Create tenant
+
+<p align="center">
+  <img src="/img/create-tenant-en.png" width="60%" />
+</p>
 
   * Creating Ordinary Users
 <p align="center">
@@ -43,11 +44,11 @@
     <img src="/img/create-environment.png" width="60%" />
    </p>
     
- * Create a token
+* Create a token
   
-   <p align="center">
-      <img src="/img/token-en.png" width="60%" />
-    </p>
+<p align="center">
+  <img src="/img/token-en.png" width="60%" />
+</p>
      
   
   * Login with regular users
diff --git a/img/banner-mobile.png b/img/banner-mobile.png
new file mode 100644
index 0000000..80095dd
Binary files /dev/null and b/img/banner-mobile.png differ
diff --git a/img/menu_black.png b/img/menu_black.png
new file mode 100644
index 0000000..e84ad37
Binary files /dev/null and b/img/menu_black.png differ
diff --git a/img/menu_white.png b/img/menu_white.png
new file mode 100644
index 0000000..83bc00c
Binary files /dev/null and b/img/menu_white.png differ
diff --git a/package.json b/package.json
index 6a249e3..f95a6ad 100644
--- a/package.json
+++ b/package.json
@@ -14,10 +14,12 @@
     "classnames": "^2.2.6",
     "core-decorators": "^0.20.0",
     "js-cookie": "^2.2.1",
+    "lodash": "^4.17.21",
     "react": "^16.13.1",
     "react-dom": "^16.13.1",
     "react-scroll": "^1.8.1",
     "react-tilt": "^0.1.4",
+    "swiper": "^6.8.4",
     "whatwg-fetch": "^2.0.4"
   },
   "devDependencies": {
diff --git a/site_config/docs2-0-0.js b/site_config/docs2-0-0.js
index 1ba10c2..c02ab09 100644
--- a/site_config/docs2-0-0.js
+++ b/site_config/docs2-0-0.js
@@ -2,7 +2,7 @@ export default {
   'en-us': {
     sidemenu: [
       {
-        title: 'About Apache DolphinScheduler',
+        title: 'About',
         children: [
           {
             title: 'Introduction',
diff --git a/src/components/footer/index.jsx b/src/components/footer/index.jsx
index b21d14f..0c0cec7 100644
--- a/src/components/footer/index.jsx
+++ b/src/components/footer/index.jsx
@@ -22,17 +22,17 @@ class Footer extends React.Component {
           </div>
           <div className="contact-container">
             <ul>
-            {
-              dataSource.contact.list.map((contact, i) => (
-                <li key={i}>
-                  <img className="img-base" src={contact.img1} />
-                  <img className="img-change" src={contact.img2} />
-                  <a href={getLink(contact.link)}>
-                    <p>{contact.name}</p>
-                  </a>
-                </li>
-              ))
-            }
+              {
+                dataSource.contact.list.map((contact, i) => (
+                  <li key={i}>
+                    <a href={getLink(contact.link)}>
+                      <img className="img-base" src={contact.img1} />
+                      <img className="img-change" src={contact.img2} />
+                      <p>{contact.name}</p>
+                    </a>
+                  </li>
+                ))
+              }
             </ul>
           </div>
           <div className="cols-container">
@@ -43,7 +43,7 @@ class Footer extends React.Component {
                   dataSource.documentation.list.map((docu, i) => (
                     <li key={i}>
                       <a href={getLink(docu.link)}>
-                      <p>{docu.text}</p>
+                        <p>{docu.text}</p>
                       </a>
                     </li>
                   ))
@@ -58,7 +58,7 @@ class Footer extends React.Component {
                   dataSource.asf.list.map((asf, i) => (
                     <li key={i}>
                       <a href={getLink(asf.link)}>
-                      <p>{asf.text}</p>
+                        <p>{asf.text}</p>
                       </a>
                     </li>
                   ))
diff --git a/src/components/footer/index.scss b/src/components/footer/index.scss
index fc42a12..df58057 100644
--- a/src/components/footer/index.scss
+++ b/src/components/footer/index.scss
@@ -1,16 +1,12 @@
-@import '../../variables.scss';
+@import "../../variables.scss";
 
 .footer-container {
-  background: #F8F8F8;
+  background: #f8f8f8;
   .footer-body {
     max-width: $contentWidth;
     margin: 0 auto;
     box-sizing: border-box;
     padding: 40px 40px 0;
-    @media screen and (max-width: $mobileWidth) {
-      padding-left: 20px;
-      padding-right: 20px;
-    }
     img {
       // display: block;
       width: 125px;
@@ -22,7 +18,7 @@
       font-family: Avenir-Heavy;
       text-align: center;
       font-size: 36px;
-      color: #000F20;
+      color: #000f20;
       margin-bottom: 20px;
       word-break: break-word;
       height: 54px;
@@ -36,112 +32,109 @@
       word-break: break-word;
       height: 32px;
     }
-    .contact-container{
-      ul{
+    .contact-container {
+      ul {
         display: flex;
-        margin-top:80px;
+        margin-top: 80px;
         margin-bottom: 40px;
         flex-direction: row;
         align-items: center;
         justify-content: center;
         align-content: center;
-        // margin-left: 200px;
-        // margin-right: 200px;
         li {
           list-style: none;
-          display:flex;
-          flex-direction: column;
-          align-items: center;
-          p{
+          a {
+            display: flex;
+            flex-direction: column;
+            align-items: center;
+            justify-self: center;
+          }
+          p {
             font-family: Avenir-Heavy;
             font-size: 22px;
-            color: #000F20;
+            color: #000f20;
             width: 280px;
             text-align: center;
           }
-          &:hover p{
-            color: #288FFF;
+          &:hover p {
+            color: #288fff;
           }
-          img{
+          img {
             width: 80px;
             height: 80px;
           }
-          .img-base{
+          .img-base {
             display: block;
           }
-          .img-change{
+          .img-change {
             display: none;
           }
-          &:hover .img-base{
+          &:hover .img-base {
             display: none;
           }
-          &:hover .img-change{
+          &:hover .img-change {
             display: block;
           }
         }
       }
-      
     }
     .cols-container {
-      margin-top: 100px;
-      margin-bottom: 60px;
+      margin: 100px 0px 60px 0px;
       display: flex;
       flex-direction: row;
-      justify-content: center;
-      .docu-container{
-        margin-left: 100px;
-        h4{
-          color: #000F20;
+      justify-content: space-around;
+      .docu-container {
+        margin-left: 0px;
+        h4 {
+          color: #000f20;
           font-family: Avenir-Heavy;
           font-size: 22px;
           text-align: left;
           margin-bottom: 10px;
-          
         }
-        ul{
+        ul {
           display: flex;
           flex-direction: row;
           border-top: 1px solid #ccc;
-          li{
+          li {
             margin-top: 10px;
             list-style: none;
             margin-right: 35px;
-            p{
+            p {
               font-family: Avenir-Heavy;
               font-size: 16px;
-              color: #000F20;
+              color: #000f20;
             }
-            &:hover p{
-              color: #288FFF;
+            &:hover p {
+              color: #288fff;
             }
           }
         }
       }
-      .asf-container{
+      .asf-container {
         margin-left: 200px;
-        h4{
-          color: #000F20;
+        h4 {
+          color: #000f20;
           font-family: Avenir-Heavy;
           font-size: 22px;
           text-align: left;
           margin-bottom: 10px;
-          
         }
-        ul{
+        ul {
           display: flex;
           flex-direction: row;
           border-top: 1px solid #ccc;
-          li{
+          li {
             margin-top: 10px;
             list-style: none;
             margin-right: 30px;
-            p{
+            p {
               font-family: Avenir-Heavy;
               font-size: 16px;
-              color: #000F20;
+              color: #000f20;
             }
-            &:hover p{
-              color: #288FFF;
+            &:hover p {
+              color: #288fff;
             }
           }
         }
@@ -168,13 +161,50 @@
 @media screen and (max-width: $mobileWidth) {
   .footer-container {
     .footer-body {
+      padding: 40px 20px;
+      h3 {
+        font-size: 28px;
+        height: auto;
+      }
+      h4 {
+        font-size: 20px;
+        height: auto;
+      }
+      .contact-container {
+        ul {
+          margin-top: 20px;
+          flex-wrap: wrap;
+          justify-content: center;
+          li {
+            margin-bottom: 20px;
+            width: 50%;
+            p {
+              width: auto;
+            }
+          }
+        }
+      }
       .cols-container {
-        .col {
-          width: 100%;
-          text-align: center;
-          padding: 0;
+        margin: 60px 0 20px 0;
+        flex-direction: column;
+        .docu-container,.asf-container {
+          margin: 0 0 50px 0;
+          ul {
+            flex-wrap: wrap;
+            padding-top: 10px;
+            justify-content: center;
+            li {
+              margin: 8px 15px;
+            }
+          }
+          h4 {
+            text-align: center;
+          }
         }
       }
+      .copyright {
+        padding-top: 20px;
+      }
     }
   }
 }
diff --git a/src/components/header/index.jsx b/src/components/header/index.jsx
index 4e58b41..1ac364c 100644
--- a/src/components/header/index.jsx
+++ b/src/components/header/index.jsx
@@ -29,7 +29,7 @@ const searchSwitch = {
     url: 'https://www.google.com/search?q=',
   },
 };
-const noop = () => {};
+const noop = () => { };
 const propTypes = {
   currentKey: PropTypes.string,
   logo: PropTypes.string.isRequired,
@@ -49,10 +49,11 @@ class Header extends React.Component {
     super(props);
     this.state = {
       current: props.currentKey,
-      menuBodyVisible: false,
+      mobileMemuVisible: false,
       language: props.language,
       search: siteConfig.defaultSearch,
       searchValue: '',
+      submenuVisibleMap: {},
     };
   }
 
@@ -69,6 +70,17 @@ class Header extends React.Component {
     } else if (localStorage.getItem('currents')) {
       this.setCurrent(localStorage.getItem('currents'));
     }
+    if (siteConfig[this.state.language].pageMenu) {
+      const map = {};
+      siteConfig[this.state.language].pageMenu.forEach((menu) => {
+        if (menu.children && menu.children.length > 0) {
+          map[menu.key] = false;
+        }
+      });
+      this.setState({
+        submenuVisibleMap: map,
+      });
+    }
   }
 
   componentWillReceiveProps(nextProps) {
@@ -137,9 +149,37 @@ class Header extends React.Component {
     }
   }
 
+  preventScroll(e) {
+    e.preventDefault();
+    e.stopPropagation();
+  }
+
+  toggleMenu() {
+    this.setState({
+      mobileMemuVisible: !this.state.mobileMemuVisible,
+    }, () => {
+      if (this.state.mobileMemuVisible) {
+        document.body.addEventListener('touchmove', this.preventScroll, { passive: false });
+      } else {
+        document.body.removeEventListener('touchmove', this.preventScroll);
+      }
+    });
+  }
+
+  toggoleSubMenu(key) {
+    const { submenuVisibleMap } = this.state;
+    if (!submenuVisibleMap.hasOwnProperty(key)) return;
+    this.setState({
+      submenuVisibleMap: {
+        ...submenuVisibleMap,
+        [key]: !submenuVisibleMap[key],
+      },
+    });
+  }
+
   render() {
     const { type, logo, onLanguageChange } = this.props;
-    const { menuBodyVisible, language, search, searchVisible } = this.state;
+    const { mobileMemuVisible, language, search, searchVisible, submenuVisibleMap } = this.state;
     return (
       <header
         className={
@@ -150,91 +190,117 @@ class Header extends React.Component {
         }
       >
         <div className="header-body">
+          <span
+            className={classnames({
+              'mobile-menu-btn': true,
+              [`mobile-menu-btn-${type}`]: true,
+            })}
+            onClick={this.toggleMenu}
+          />
           <a href={getLink(`/${language}/index.html`)}>
             <img className="logo" alt={siteConfig.name} title={siteConfig.name} src={getLink(logo)} />
           </a>
           {
             siteConfig.defaultSearch ?
               (
-              <div
-                className={classnames({
-                  search: true,
-                  [`search-${type}`]: true,
-                })}
-              >
-                <span className="icon-search" onClick={this.toggleSearch} />
-                {
-                  searchVisible ?
-                    (
-                    <div className="search-input">
-                      <img src={searchSwitch[search].logo} onClick={this.switchSearch} />
-                      <input autoFocus onChange={this.onInputChange} onKeyDown={this.onKeyDown} />
-                    </div>
-                    ) : null
-                }
-              </div>
+                <div
+                  className={classnames({
+                    search: true,
+                    [`search-${type}`]: true,
+                  })}
+                >
+                  <span className="icon-search" onClick={this.toggleSearch} />
+                  {
+                    searchVisible ?
+                      (
+                        <div className="search-input">
+                          <img src={searchSwitch[search].logo} onClick={this.switchSearch} />
+                          <input autoFocus onChange={this.onInputChange} onKeyDown={this.onKeyDown} />
+                        </div>
+                      ) : null
+                  }
+                </div>
               ) : null
           }
           {
             onLanguageChange !== noop ?
-              (<span
-              className={
-                classnames({
-                  'language-switch': true,
-                  [`language-switch-${type}`]: true,
-                })
-              }
-              onClick={this.switchLang}
-              >
-              {languageSwitch.find(lang => lang.value === language).text}
-               </span>)
+              (
+                <span
+                  className={
+                    classnames({
+                      'language-switch': true,
+                      [`language-switch-${type}`]: true,
+                    })
+                  }
+                  onClick={this.switchLang}
+                >
+                  {languageSwitch.find(lang => lang.value === language).text}
+                </span>
+              )
               :
               null
           }
           <div
-            className={
-              classnames({
-                'header-menu': true,
-                'header-menu-open': menuBodyVisible,
-              })
-            }
+            className="header-menu"
           >
-            <img
-              className="header-menu-toggle"
-              onClick={this.toggleMenu}
-              src={type === 'normal' ? getLink('/img/system/menu_gray.png') : getLink('/img/system/menu_white.png')}
-            />
             <div>
               <Menu className={type === 'normal' ? 'blackClass' : 'whiteClass'} onClick={this.handleClick} selectedKeys={[this.state.current]} mode="horizontal" forceSubMenuRender>
-              {siteConfig[language].pageMenu.map(item => (
-                item.children ?
-                <SubMenu
-                  key={item.key}
-                  className={this.state.current === item.key ? 'ant-menu-item-selected' : ''}
-                  title={
-                    <span className="submenu-title-wrapper">
+                {siteConfig[language].pageMenu.map(item => (
+                  item.children ?
+                    <SubMenu
+                      key={item.key}
+                      className={this.state.current === item.key ? 'ant-menu-item-selected' : ''}
+                      title={
+                        <span className="submenu-title-wrapper">
+                          <a href={getLink(item.link)} target={item.target || '_self'}>{item.text}</a>
+                        </span>
+                      }
+                    >
+                      <Menu.ItemGroup className="showUL">
+                        {item.children.map(items => (
+                          <Menu.Item key={items.key} ><a href={getLink(items.link)} target={items.target || '_self'}>{items.text}</a></Menu.Item>
+                        ))}
+                      </Menu.ItemGroup>
+                    </SubMenu> :
+                    <Menu.Item key={item.key}>
                       <a href={getLink(item.link)} target={item.target || '_self'}>{item.text}</a>
-                      <ul style={{ display: 'none' }}>
-                      {item.children.map(items => (
-                        <li key={items.key} ><a href={getLink(items.link)} target={items.target || '_self'}>{items.text}</a></li>
-                      ))}
-                      </ul>
-                    </span>
-                  }
-                >
-                  <Menu.ItemGroup className="showUL">
-                  {item.children.map(items => (
-                    <Menu.Item key={items.key} ><a href={getLink(items.link)} target={items.target || '_self'}>{items.text}</a></Menu.Item>
-                  ))}
-                  </Menu.ItemGroup>
-                </SubMenu> :
-                <Menu.Item key={item.key}>
-                  <a href={getLink(item.link)} target={item.target || '_self'}>{item.text}</a>
-                </Menu.Item>
-              ))}
+                    </Menu.Item>
+                ))}
               </Menu>
             </div>
           </div>
+          <div className={mobileMemuVisible ? 'mobile-menu visible' : 'mobile-menu'} onScroll={this.preventScroll}>
+            <div className="mobile-menu-content">
+              <div className="mobile-menu-list">
+                {
+                  siteConfig[language].pageMenu.map(item => (
+                    <div className="mobile-menu-item" onClick={() => this.toggoleSubMenu(item.key)} >
+                      <a className="mobile-menu-title" href={getLink(item.link)} target={item.target || '_self'}>{item.text}</a>
+                      {
+                        item.children && item.children.length > 0 ?
+                          <em className={submenuVisibleMap[item.key] ? 'mobile-menu-icon open' : 'mobile-menu-icon'} /> :
+                          null
+                      }
+                      {
+                        item.children && item.children.length > 0 ?
+                          <div className={submenuVisibleMap[item.key] ? 'mobile-sub-menus open' : 'mobile-sub-menus'}>
+                            {
+                              item.children && item.children.map(sub => (
+                                <div className="mobile-sub-menu-item"><a href={getLink(sub.link)} target={sub.target || '_self'}>{sub.text}</a></div>
+                              ))
+                            }
+                          </div>
+                          :
+                          null
+                      }
+                    </div>
+                  ))
+                }
+              </div>
+            </div>
+            <div className="mobile-menu-dummy" onClick={this.toggleMenu} />
+          </div>
+          }
         </div>
       </header>
     );
diff --git a/src/components/header/index.scss b/src/components/header/index.scss
index f550732..49d3b16 100644
--- a/src/components/header/index.scss
+++ b/src/components/header/index.scss
@@ -1,16 +1,93 @@
-@import '../../variables.scss';
-.ant-menu { 
+@import "../../variables.scss";
+.ant-menu {
   background: none;
 }
 .ant-menu-horizontal {
   border-bottom: 0;
 }
-.ant-menu-submenu-title {
-  padding: 0 15px !important;
-}
 .ant-menu-submenu-hidden {
   display: none;
 }
+.mobile-menu {
+  display: block;
+  position: fixed;
+  top: 66px;
+  left: 0;
+  width: 0;
+  height: calc(100vh - 66px);
+  font-size: 13px;
+  box-sizing: border-box;
+  z-index: 9999;
+  background-color: rgba(0, 0, 0, 0.4);
+  overflow: hidden;
+  display: flex;
+  .mobile-menu-content {
+    position: relative;
+    width: 75%;
+    height: 100%;
+    padding-top: 10px;
+    padding-bottom: 20px;
+    background-color: #fff;
+    overflow-y: auto;
+    box-sizing: border-box;
+    transform: translateX(-120%);
+    transition: transform 0.3s;
+    .mobile-menu-item {
+      padding: 10px 20px;
+      
+      align-items: center;
+      position: relative;
+      .mobile-menu-icon {
+        display: block;
+        width: 12px;
+        height: 8px;
+        background-image: url(/img/system/arrow_down.png);
+        background-size: 100% 100%;
+        position: absolute;
+        right: 20px;
+        top: 14px;
+        &.open {
+          transform: rotate(180deg);
+          transition: all 0.2s;
+        }
+      }
+      .mobile-menu-title {
+        display: block;
+        line-height: 20px;
+        color: #2c3e50;
+        width: 120px;
+      }
+      .mobile-sub-menus {
+        display: none;
+        flex-direction: column;
+        margin-top: 10px;
+        padding-left: 20px;
+        .mobile-sub-menu-item {
+          display: flex;
+          line-height: 32px;
+          a {
+            display: block;
+            width: 100%;
+            color: #999;
+          }
+        }
+        &.open {
+          display: flex;
+        }
+      }
+    }
+  }
+  .mobile-menu-dummy {
+    flex: 1;
+    height: 100%;
+  }
+  &.visible {
+    width: 100%;
+    .mobile-menu-content {
+      transform: translateX(0);
+    }
+  }
+}
 .header-container {
   position: fixed;
   left: 0;
@@ -22,11 +99,11 @@
     background-color: transparent;
   }
   &-dark {
-    background-color:#000F20;
+    background-color: #000f20;
   }
   &-normal {
     background-color: #fff;
-    box-shadow: 0 2px 10px 0 rgba(0,0,0,0.08);
+    box-shadow: 0 2px 10px 0 rgba(0, 0, 0, 0.08);
   }
   .header-body {
     max-width: $contentWidth;
@@ -34,21 +111,15 @@
     height: $headerHeight;
     line-height: $headerHeight;
     .logo {
-      margin-top: 10px;
-      margin-left: 40px;
+      margin-top: 12px;
+      margin-left: 30px;
       width: 156px;
       vertical-align: sub;
     }
     .header-menu {
       margin-top: 10px;
+      margin-right: 20px;
       float: right;
-      .header-menu-toggle {
-        display: none;
-        width: 19px;
-        margin-right: 20px;
-        margin-top: $headerHeight / 2 - 15px;
-        cursor: pointer;
-      }
     }
     ul {
       padding: 0;
@@ -56,14 +127,14 @@
     }
     li {
       display: inline-block;
-      margin-right: 20px;
+      margin-right: 10px;
     }
     .menu-item {
       font-family: Avenir-Heavy;
       font-size: 14px;
       vertical-align: bottom;
     }
-    .whiteClass{
+    .whiteClass {
       .ant-menu-item {
         a {
           color: #fff;
@@ -90,10 +161,10 @@
         .submenu-title-wrapper {
           a {
             color: #fff;
-            opacity:0.6;
+            opacity: 0.6;
             font-family: Avenir-Medium;
           }
-        } 
+        }
       }
     }
     .blackClass {
@@ -182,12 +253,12 @@
       }
     }
     .language-switch-primary {
-      border: 1px solid #FFF;
-      color: #FFF;
+      border: 1px solid #fff;
+      color: #fff;
     }
     .language-switch-dark {
-      border: 1px solid #FFF;
-      color: #FFF;
+      border: 1px solid #fff;
+      color: #fff;
     }
     .language-switch-normal {
       border: 1px solid #333;
@@ -207,16 +278,16 @@
         width: 12px;
         height: 12px;
         border-radius: 50%;
-        border:2px solid;
+        border: 2px solid;
         position: relative;
         &::before {
-          content: '';
+          content: "";
           transform: rotate(45deg);
-          width:8px;
+          width: 8px;
           height: 2px;
           position: absolute;
-          top:13px;
-          left:11px;
+          top: 13px;
+          left: 11px;
         }
       }
       &-primary {
@@ -282,58 +353,63 @@
   }
 }
 
-
-@media screen and (max-width: $mobileWidth) {
+@media screen and (max-width: $navMiddle) {
   .header-container {
     .header-body {
-      .logo {
-        margin-left: 20px;
+      li {
+        margin-right: 10px;
+        padding: 0 10px;
       }
-      .language-switch {
-        margin-right: 20px;
+      .ant-menu-submenu-title {
+        padding: 0;
+      }
+    }
+  }
+}
+
+@media screen and (max-width: $navSmall) {
+  .header-container {
+    .header-body {
+      li {
+        font-size: 12px;
+        margin-right: 5px;
       }
+    }
+  }
+}
+
+@media screen and (max-width: $navMini) {
+  .header-container {
+    .header-body {
       .header-menu {
-        ul {
-          display: none;
-        }
-        .header-menu-toggle {
-          display: inline-block;
-          margin-right: 20px;
-        }
+        display: none;
       }
-      .header-menu-open {
-        ul {
-          background-color: $headerMenuBgColor;
-          display: inline-block;
-          position: absolute;
-          right: 0;
-          top: $headerHeight;
-          z-index: 100;
-        }
-        li {
-          width: 200px;
-          display: list-item;
-          padding-left: 30px;
-          list-style: none;
-          line-height: 40px;
-          margin-right: 20px;
-          a {
-            color: #333;
-            display: inline-block;
-            width: 100%;
-          }
+      .search {
+        margin-right: 20px;
+      }
+      .mobile-menu-btn {
+        display: block;
+        width: 24px;
+        height: 24px;
+        background-size: 100% 100%;
+        margin-top: 21px;
+        margin-left: 20px;
+        cursor: pointer;
+        opacity: 0.6;
+        float: left;
+        margin-right: 20px;
+        &-primary,
+        &-dark {
+          background-image: url("/img/menu_white.png");
+          opacity: 0.6;
           &:hover {
-            background: $endColor;
-            a {
-              color: #fff;
-              opacity: 1;
-            }
+            opacity: 1;
           }
         }
-        .menu-item-primary-active, .menu-item-normal-active, .menu-item-dark-active {
-          background: $endColor;
-          a {
-            color: #fff;
+        &-normal {
+          background-image: url("/img/menu_black.png");
+          opacity: 0.6;
+          &:hover {
             opacity: 1;
           }
         }
@@ -341,3 +417,22 @@
     }
   }
 }
+
+@media screen and (max-width: $mobileWidth) {
+  .header-container {
+    &-primary {
+      background-color: #000f20;
+    }
+    .header-body {
+      .logo {
+        margin-left: 0px;
+      }
+      .search {
+        margin-right: 20px;
+      }
+      .language-switch {
+        margin-right: 20px;
+      }
+    }
+  }
+}
diff --git a/src/markdown.scss b/src/markdown.scss
index 7dfc83c..cc2fe94 100644
--- a/src/markdown.scss
+++ b/src/markdown.scss
@@ -1553,3 +1553,9 @@ $katexPath: 'https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.5.1/';
 .katex .mtable .col-align-r>.vlist {
   text-align:right
 }
+
+@media screen and (max-width: $mobileWidth) { 
+  .markdown-body img {
+    width: 100%;
+  }
+}
diff --git a/src/pages/blog/index.md.scss b/src/pages/blog/index.md.scss
index 7e83c19..3dcb5e2 100644
--- a/src/pages/blog/index.md.scss
+++ b/src/pages/blog/index.md.scss
@@ -5,4 +5,16 @@
     margin: $headerHeight auto 0;
     min-width: 735px;
   }
+}
+
+@media screen and (max-width: $mobileWidth) {
+  .blog-detail-page {
+    .blog-content {
+      min-width: auto;
+      width: 100%;
+      padding: 40px 20px;
+      box-sizing: border-box;
+      margin: $headerHeight auto 0;
+    }
+  }
 }
\ No newline at end of file
diff --git a/src/pages/home/index.jsx b/src/pages/home/index.jsx
index 9c06057..b57de68 100644
--- a/src/pages/home/index.jsx
+++ b/src/pages/home/index.jsx
@@ -8,8 +8,16 @@ import Language from '../../components/language';
 import Item from './featureItem';
 import homeConfig from '../../../site_config/home';
 import './index.scss';
-import Slider from '../../components/slider';
 import EventCard from '../community/eventCard';
+import debounce from 'lodash/debounce';
+import Swiper, { Navigation, Pagination } from 'swiper/core';
+import 'swiper/swiper.scss';
+import 'swiper/components/navigation/navigation.scss';
+import 'swiper/components/pagination/pagination.scss';
+
+Swiper.use([Navigation, Pagination]);
+
+const MOBILE_WIDTH = 640;
 
 class Home extends Language {
   constructor(props) {
@@ -19,18 +27,16 @@ class Home extends Language {
       starCount: 0,
       forkCount: 0,
       index: 0,
+      isMobile: document.body.clientWidth <= MOBILE_WIDTH,
     };
+    this.swiper = null;
+    this.calculateLayout = null;
   }
 
   componentDidMount() {
     window.addEventListener('scroll', () => {
       const scrollTop = getScrollTop();
-      const offsetHeight = document.querySelector('.top-section').offsetHeight - 66;
-      if (scrollTop > 66 && scrollTop <= offsetHeight) {
-        this.setState({
-          headerType: 'normal',
-        });
-      } else if (scrollTop > offsetHeight) {
+      if (scrollTop > 66) {
         this.setState({
           headerType: 'dark',
         });
@@ -40,6 +46,12 @@ class Home extends Language {
         });
       }
     });
+    this.calculateLayout = debounce(() => {
+      this.setState({
+        isMobile: document.body.clientWidth <= MOBILE_WIDTH,
+      });
+    }, 200);
+    window.addEventListener('resize', this.calculateLayout);
     // 写死协议,因github会做协议跳转,这种跳转会被Safari拦截
     fetch('https://api.github.com/repos/apache/dolphinscheduler')
       .then(res => res.json())
@@ -50,36 +62,41 @@ class Home extends Language {
           forkCount: data.forks_count,
         });
       });
+    this.initSwiper();
+    window._debug = this;
   }
 
-  addClick = (length) => {
-    if (this.state.index < length - 1) {
-      this.setState({
-        ...this.state,
-        index: this.state.index + 1,
-      });
-    } else {
-      this.setState({
-        ...this.state,
-        index: 0,
-      });
+  componentDidUpdate(prevProps, prevState) {
+    if (prevState.isMobile !== this.state.isMobile) {
+      this.initSwiper();
     }
   }
 
-  minusClick = (length) => {
-    if (this.state.index > 0) {
-      this.setState({
-        ...this.state,
-        index: this.state.index - 1,
-      });
-    } else {
-      this.setState({
-        ...this.state,
-        index: length - 1,
-      });
+  componentWillUnmount() {
+    if (this.calculateLayout) {
+      window.removeEventListener('resize', this.calculateLayout);
     }
   }
 
+  initSwiper() {
+    const { isMobile } = this.state;
+    // Events swiper
+    if (this.swiper) this.swiper.destroy();
+    this.swiper = new Swiper('.swiper-container', {
+      loop: true,
+      slidesPerView: isMobile ? 1 : 3,
+      spaceBetween: 30,
+      slidesPerGroup: isMobile ? 1 : 3,
+      navigation: {
+        nextEl: '.swiper-button-next',
+        prevEl: '.swiper-button-prev',
+      },
+      pagination: {
+        el: '.swiper-pagination',
+        clickable: true,
+      },
+    });
+  }
 
   addClick = (length) => {
     if (this.state.index < length - 1) {
@@ -110,7 +127,7 @@ class Home extends Language {
   }
 
   render() {
-    const { starCount, forkCount } = this.state;
+    const { starCount, forkCount, isMobile } = this.state;
     const language = this.getLanguage();
     const dataSource = homeConfig[language];
     const { headerType } = this.state;
@@ -118,7 +135,9 @@ class Home extends Language {
     return (
       <div className="home-page">
         <section className="top-section">
-          <img src="/img/banner.jpg" />
+          {
+            isMobile ? null : <img className="pc-bg" src="/img/banner.jpg" />
+          }
           <Header
             currentKey="home"
             type={headerType}
@@ -180,14 +199,22 @@ class Home extends Language {
             }
           </ul>
         </section>
-
         <section className="events-section">
           <h3>{dataSource.events.title}</h3>
-          <Slider>
-            {dataSource.events.list.map((event, i) => (
-              <EventCard event={event} key={i} />
-            ))}
-          </Slider>
+          <div className="swiper-container">
+            <div className="swiper-wrapper">
+              {
+                dataSource.events.list.map((event, i) => (
+                  <div key={i} className="swiper-slide">
+                    <EventCard event={event} key={i} />
+                  </div>
+                ))
+              }
+            </div>
+          </div>
+          <div className="swiper-button-next" />
+          <div className="swiper-button-prev" />
+          <div className="swiper-pagination" />
         </section>
         <Footer logo="/img/ds_gray.svg" language={language} />
       </div>
diff --git a/src/pages/home/index.scss b/src/pages/home/index.scss
index cf83b3a..c33403c 100644
--- a/src/pages/home/index.scss
+++ b/src/pages/home/index.scss
@@ -1,17 +1,22 @@
-@import '../../variables.scss';
-@import '../../reset.scss';
+@import "../../variables.scss";
+@import "../../reset.scss";
 
 @keyframes slashStar {
   0% {
-    opacity: 1; }
+    opacity: 1;
+  }
   100% {
-    opacity: 0; }
+    opacity: 0;
+  }
 }
 
 .home-page {
+  min-width: 1100px;
   .top-section {
+    width: 100%;
     position: relative;
-    img {
+    height: auto;
+    .pc-bg {
       width: 100%;
     }
     .animation {
@@ -19,13 +24,13 @@
       width: 6px;
       height: 6px;
       border-radius: 50%;
-      background-color: #1BE1F6;
-     }
+      background-color: #1be1f6;
+    }
     .animation1 {
       left: 15%;
       top: 70%;
       animation: slashStar 2s ease-in-out 0.3s infinite;
-      }
+    }
     .animation2 {
       left: 34%;
       top: 35%;
@@ -62,7 +67,7 @@
       h2 {
         font-family: Avenir-Heavy;
         font-size: 46px;
-        color: #FFF;
+        color: #fff;
         text-align: center;
         word-break: break-word;
         margin: 0;
@@ -72,7 +77,7 @@
       opacity: 0.6;
       font-family: Avenir-Medium;
       font-size: 24px;
-      color: #FFF;
+      color: #fff;
       text-align: center;
       margin: 12px auto 0;
       max-width: 730px;
@@ -129,9 +134,9 @@
         display: inline-block;
         font-family: Avenir-Heavy;
         font-size: 14px;
-        color: #FFF;
+        color: #fff;
         text-align: center;
-        background: #46484B;
+        background: #46484b;
         border-radius: 2px;
         line-height: 24px;
         padding: 0 6px;
@@ -149,7 +154,7 @@
     }
   }
   .introduction-section {
-    background: #F9FAFA;
+    background: #f9fafa;
     .introduction-body {
       max-width: $contentWidth;
       box-sizing: border-box;
@@ -162,7 +167,7 @@
       justify-content: center;
       flex-direction: column;
       &::before {
-        content: '';
+        content: "";
         position: relative;
         top: 102px;
         left: 40px;
@@ -170,7 +175,7 @@
         border-right: 1px solid #666;
       }
       &::after {
-        content: '';
+        content: "";
         position: relative;
         left: 39px;
         top: 165px;
@@ -196,7 +201,7 @@
           font-size: 22px;
           width: 940px;
           height: 64px;
-          color:#130e0e;
+          color: #130e0e;
         }
       }
       img {
@@ -206,16 +211,6 @@
         max-width: 100%;
         // box-shadow: 0 8px 16px 0 rgba(0, 0, 0, 0.05);
       }
-      @media screen and (max-width: 1106px){
-        .introduction {
-          display: inline-block;
-          width: 100%;
-          max-width: 100%;
-        }
-        img {
-          margin: 0;
-        }
-      }
     }
   }
   .feature-section {
@@ -225,7 +220,7 @@
     position: relative;
     padding: 80px 40px 40px;
     &::before {
-      content: '';
+      content: "";
       position: absolute;
       top: 0;
       left: 50%;
@@ -235,7 +230,7 @@
       border-right: 1px solid #666;
     }
     &::after {
-      content: '';
+      content: "";
       position: absolute;
       top: 66px;
       left: 50%;
@@ -254,13 +249,11 @@
       list-style: none;
       padding: 0;
       margin: 0;
+      display: flex;
       li {
-        width: 240px;
-        height: 360px;
         text-align: center;
-        vertical-align: top;
-        display: inline-block;
-        margin-bottom: 40px;
+        display: block;
+        padding-bottom: 40px;
         width: 25%;
         cursor: pointer;
         &:hover {
@@ -283,7 +276,7 @@
             height: 32px;
             font-weight: 400;
             color: #333333;
-            line-height: 32px
+            line-height: 32px;
           }
           p {
             width: 200px;
@@ -297,20 +290,33 @@
           }
         }
       }
-      @media screen and (max-width: 768px){
-        li {
-          width: 100%;
-        }
-      }
     }
   }
   .events-section {
-    // background: #F9FAFA;
     max-width: $contentWidth;
-    margin: 0px auto 50px;
+    margin: 0px auto 70px;
+    padding: 0 50px;
     box-sizing: border-box;
-    @media screen and (max-width: $mobileWidth) {
-      padding: 0px;
+    position: relative;
+    .swiper-container {
+      overflow: hidden;
+    }
+    .swiper-button-next {
+      position: absolute;
+      right: 10px;
+    }
+    .swiper-pagination {
+      position: absolute;
+      bottom: -30px;
+      left: 50%;
+      transform: translateX(-50%);
+      .swiper-pagination-bullet:not(:last-child){
+        margin-right: 10px;
+      }
+    }
+    .swiper-button-prev {
+      position: absolute;
+      left: 10px;
     }
     h3 {
       font-family: Avenir-Heavy;
@@ -320,19 +326,12 @@
       margin: 40px 0 60px;
     }
     .event-card {
-      width: 373px;
+      width: 100%;
       font-size: 0;
       img {
-        width: 373px;
+        width: 100%;
         height: 209px;
       }
-      @media screen and (max-width: $mobileWidth / 2) {
-        width: 320px;
-        img {
-          width: 320px;
-          height: 179px;
-        }
-      }
       .event-introduction {
         padding: 20px;
         h4 {
@@ -363,7 +362,7 @@
       }
     }
   }
-  .ourusers-section{
+  .ourusers-section {
     display: flex;
     flex-direction: column;
     align-items: center;
@@ -376,33 +375,33 @@
       margin-top: 40px;
       margin-bottom: 60px;
     }
-    .button1-section{
+    .button1-section {
       display: flex;
       flex-direction: row;
       align-items: center;
       justify-content: center;
       width: 100%;
-      img{
+      img {
         width: 80px;
         height: 80px;
         &:hover {
           box-shadow: 0px 0px 12px 0px rgba(9, 97, 197, 0.1);
         }
       }
-      button{
+      button {
         border: hidden;
         background-color: transparent;
       }
-      .overflow-section{
+      .overflow-section {
         display: flex;
         width: 70%;
-        ul{
+        ul {
           display: inline-flex;
           flex-wrap: wrap;
-          li{
+          li {
             list-style: none;
             margin: 5px 5px 5px 5px;
-            img{
+            img {
               width: 100px;
               height: 100px;
               &:hover {
@@ -414,7 +413,7 @@
       }
     }
   }
-  .review-section{
+  .review-section {
     display: flex;
     flex-direction: column;
     align-items: center;
@@ -426,60 +425,60 @@
       text-align: center;
       margin-top: 40px;
     }
-    .button-section{
+    .button-section {
       display: flex;
       flex-direction: row;
       align-items: center;
       justify-content: center;
       width: 100%;
-      img{
+      img {
         width: 80px;
         height: 80px;
         &:hover {
           box-shadow: 0px 0px 12px 0px rgba(9, 97, 197, 0.1);
         }
       }
-      button{
+      button {
         border: hidden;
         background-color: transparent;
       }
-      .overflow-section{
+      .overflow-section {
         overflow: hidden;
         width: 65%;
         height: 350px;
         margin: 40px 0px 20px 0px;
-        background: #F9FAFA;
+        background: #f9fafa;
         display: flex;
         align-items: center;
-        ul{
+        ul {
           display: -webkit-box;
           align-items: center;
           flex-direction: row;
           width: 100%;
-          li{
+          li {
             display: flex;
             flex-direction: row;
             align-items: center;
             list-style: none;
             width: 100%;
-            img{
+            img {
               width: 150px;
               height: 150px;
               margin: 0 40px 0 50px;
             }
-            .name-section{
+            .name-section {
               display: flex;
               flex-direction: column;
               margin-left: 20px;
             }
-            p{
+            p {
               font-family: Avenir-Heavy;
             }
-            .pr{
+            .pr {
               font-size: 20px;
               margin-right: 20px;
             }
-            .pn{
+            .pn {
               font-size: 18px;
               text-align: right;
               margin-top: 40px;
@@ -490,91 +489,6 @@
       }
     }
   }
-  .start-section {
-    background-image: linear-gradient(0deg, $startColor 0%, $intermediateColor 51%, $endColor 100%);
-    .start-body {
-      max-width: $contentWidth;
-      margin: 0 auto;
-      box-sizing: border-box;
-      height: 260px;
-      padding: 35px 40px;
-      position: relative;
-      &::before {
-        content: '';
-        position: absolute;
-        top: 0;
-        left: 20px;
-        height: 100%;
-        opacity: 0.3;
-        border-right: 1px solid #fff;
-      }
-      &::after {
-        content: '';
-        position: absolute;
-        left: 19px;
-        top: 48px;
-        height: 17px;
-        background: #fff;
-      }
-      .left-part {
-        display: inline-block;
-        width: 50%;
-        vertical-align: top;
-        h3 {
-          font-family: Avenir-Heavy;
-          font-size: 36px;
-          color: #FFF;
-          margin: 0;
-        }
-        p {
-          opacity: 0.8;
-          font-family: Avenir-Medium;
-          font-size: 18px;
-          color: #FFF;
-          line-height: 24px;
-          margin: 6px 0 12px;
-        }
-        a {
-          font-family: Avenir-Heavy;
-          font-size: 14px;
-          color: $brandColor;
-          text-align: center;
-          display: inline-block;
-          width: 140px;
-          height: 48px;
-          line-height: 48px;
-          background: #FFF;
-          border-radius: 4px;
-        }
-      }
-      .right-part {
-        display: inline-block;
-        width: 50%;
-        font-size: 0;
-        margin-top: 15px;
-        img {
-          margin-left: 5%;
-          width: 500px;
-        }
-      }
-      @media screen and (max-width: 1050px){
-        & {
-          height: 474px;
-        }
-        .left-part {
-          width: 100%;
-        }
-        .right-part {
-          width: 100%;
-          margin-top: 38px;
-          img {
-            max-width: 100%;
-            margin-left: 0;
-          }
-        }
-      }
-    }
-  }
   .users-section {
     box-sizing: border-box;
     max-width: $contentWidth;
@@ -582,7 +496,7 @@
     padding: 80px 40px 40px;
     position: relative;
     &::before {
-      content: '';
+      content: "";
       position: absolute;
       top: 0;
       left: 50%;
@@ -592,7 +506,7 @@
       border-right: 1px solid #666;
     }
     &::after {
-      content: '';
+      content: "";
       position: absolute;
       top: 66px;
       left: 50%;
@@ -636,6 +550,25 @@
     }
   }
   @media screen and (max-width: $mobileWidth) {
+    min-width: auto;
+    .top-section {
+      height: 100vh;
+      max-height: 1335px;
+      background-image: url("/img/banner-mobile.png");
+      background-position: right 50% bottom 0%;
+      background-size: cover;
+      .pc-bg {
+        display: none;
+      }
+      .product-name {
+        h2 {
+          font-size: 36px;
+        }
+      }
+      .product-desc {
+        font-size: 18px;
+      }
+    }
     .introduction-section {
       padding: 0 20px;
       &::before {
@@ -644,10 +577,52 @@
       &::after {
         left: 19px;
       }
+      .introduction-body {
+        min-height: auto;
+        .introduction {
+          margin: 40px auto 0 auto;
+          h3 {
+            width: 100%;
+            font-size: 28px;
+          }
+          p {
+            font-size: 18px;
+            width: 100%;
+            height: auto;
+            text-align: center;
+          }
+        }
+        img {
+          width: 100%;
+          margin: 40px 0;
+          height: auto;
+        }
+      }
     }
-    .feature-section, .users-section {
-      padding-left: 20px;
-      padding-right: 20px;
+    .feature-section {
+      padding: 40px 20px;
+      h3 {
+        font-size: 28px;
+        margin: 0 0 20px 0;
+      }
+      ul {
+        width: 100%;
+        flex-direction: column;
+        li {
+          width: 100%;
+        }
+      }
+    }
+    .events-section {
+      h3 {
+        font-size: 28px;
+        margin: 20px 0 40px 0;
+      }
+      padding: 0 10px;
+      .swiper-button-next,
+      .swiper-button-prev {
+        display: none;
+      }
     }
   }
 }
diff --git a/src/pages/user/index.jsx b/src/pages/user/index.jsx
index 1bd983f..1be6165 100644
--- a/src/pages/user/index.jsx
+++ b/src/pages/user/index.jsx
@@ -4,7 +4,13 @@ import Header from '../../components/header';
 import Language from '../../components/language';
 import homeConfig from '../../../site_config/home';
 import './user.scss';
+import Footer from '../../components/footer';
+import Swiper, { Navigation, Pagination } from 'swiper/core';
+import 'swiper/swiper.scss';
+import 'swiper/components/navigation/navigation.scss';
+import 'swiper/components/pagination/pagination.scss';
 
+Swiper.use([Navigation, Pagination]);
 class User extends Language {
   constructor(props) {
     super(props);
@@ -13,39 +19,25 @@ class User extends Language {
       starCount: 0,
       forkCount: 0,
       index: 0,
+      swiper: null,
     };
   }
 
-  addClick = (length) => {
-    if (this.state.index < length - 1) {
-      this.setState({
-        ...this.state,
-        index: this.state.index + 1,
-      });
-    } else {
-      this.setState({
-        ...this.state,
-        index: 0,
-      });
-    }
-  }
-
-  minusClick = (length) => {
-    if (this.state.index > 0) {
-      this.setState({
-        ...this.state,
-        index: this.state.index - 1,
-      });
-    } else {
-      this.setState({
-        ...this.state,
-        index: length - 1,
-      });
-    }
+  componentDidMount() {
+    this.swiper = new Swiper('.swiper-container', {
+      loop: true,
+      navigation: {
+        nextEl: '.swiper-button-next',
+        prevEl: '.swiper-button-prev',
+      },
+      pagination: {
+        el: '.swiper-pagination',
+        clickable: true,
+      },
+    });
   }
 
   render() {
-    const { index } = this.state;
     const language = this.getLanguage();
     const { headerType } = this.state;
     const headerLogo = headerType === 'normal' ? '/img/hlogo_colorful.svg' : '/img/hlogo_white.svg';
@@ -65,7 +57,7 @@ class User extends Language {
           <h3>
             {dataSource.ourusers.title}
           </h3>
-          <div className="button1-section" id="buttonleft">
+          <div className="button1-section">
             <div className="overflow-section">
               <ul>
                 {
@@ -81,30 +73,30 @@ class User extends Language {
         </section>
         <section className="review-section">
           <h3>{dataSource.userreview.title}</h3>
-          <div className="button-section" id="buttonleft">
-            <button onClick={() => this.minusClick(dataSource.userreview.list.length)} >
-              <img src="/img/gotoleft.png" />
-            </button>
-            <div className="overflow-section">
-              <ul>
-                {
-                  dataSource.userreview.list.map((ureview, i) => (
-                    <li key={i}>
-                      <img src={ureview.img} />
+          <div className="swiper-container">
+            <div className="swiper-wrapper">
+              {
+                dataSource.userreview.list.map((ureview, i) => (
+                  <div key={i} className="swiper-slide">
+                    <div className="slide-content">
+                      <div className="img-box">
+                        <img src={ureview.img} />
+                      </div>
                       <div className="name-section">
                         <p className="pr">{ureview.review} </p>
                         <p className="pn">{ureview.name} </p>
                       </div>
-                    </li>
-                  ))[index]
-                }
-              </ul>
+                    </div>
+                  </div>
+                ))
+              }
             </div>
-            <button onClick={() => this.addClick(dataSource.userreview.list.length)}>
-              <img src="/img/gotoright.png" />
-            </button>
+            <div className="swiper-button-next" />
+            <div className="swiper-button-prev" />
+            <div className="swiper-pagination" />
           </div>
         </section>
+        <Footer logo="/img/ds_gray.svg" language={language} />
       </div>
     );
   }
diff --git a/src/pages/user/user.scss b/src/pages/user/user.scss
index 22c89f4..067e4bc 100644
--- a/src/pages/user/user.scss
+++ b/src/pages/user/user.scss
@@ -1,161 +1,21 @@
-@import '../../variables.scss';
-@import '../../reset.scss';
+@import "../../variables.scss";
+@import "../../reset.scss";
 
 @keyframes slashStar {
   0% {
-    opacity: 1; }
+    opacity: 1;
+  }
   100% {
-    opacity: 0; }
+    opacity: 0;
+  }
 }
 
 .user-page {
-  .top-section {
-    position: relative;
- 
-    img {
-      width: 100%;
-    }
-    .animation {
-      position: absolute;
-      width: 6px;
-      height: 6px;
-      border-radius: 50%;
-      background-color: #1BE1F6;
-     }
-    .animation1 {
-      left: 15%;
-      top: 70%;
-      animation: slashStar 2s ease-in-out 0.3s infinite;
-      }
-    .animation2 {
-      left: 34%;
-      top: 35%;
-      animation: slashStar 2s ease-in-out 1.2s infinite;
-    }
-    .animation3 {
-      left: 53%;
-      top: 20%;
-      animation: slashStar 2s ease-in-out 0.5s infinite;
-    }
-    .animation4 {
-      left: 72%;
-      top: 64%;
-      animation: slashStar 2s ease-in-out 0.8s infinite;
-    }
-    .animation5 {
-      left: 87%;
-      top: 30%;
-      animation: slashStar 2s ease-in-out 1.5s infinite;
-    }
-    .vertical-middle {
-      position: absolute;
-      left: 0;
-      top: 40%;
-      transform: translateY(-50%);
-      box-sizing: border-box;
-      width: 100%;
-      text-align: center;
-      padding: 0 20px;
-    }
-    .product-name {
-      position: relative;
-      display: inline-block;
-      h2 {
-        font-family: Avenir-Heavy;
-        font-size: 46px;
-        color: #FFF;
-        text-align: center;
-        word-break: break-word;
-        margin: 0;
-      }
-    }
-    .product-desc {
-      opacity: 0.6;
-      font-family: Avenir-Medium;
-      font-size: 24px;
-      color: #FFF;
-      text-align: center;
-      margin: 12px auto 0;
-      max-width: 730px;
-    }
-    .button-area {
-      text-align: center;
-      margin-top: 40px;
-      .button {
-        margin-right: 20px;
-      }
-      .button:last-child {
-        margin-right: 0;
-      }
-    }
-    .github-buttons {
-      margin-top: 20px;
-      text-align: center;
-      a {
-        margin-right: 12px;
-        &:last-child {
-          margin-right: 0;
-        }
-        div {
-          border-radius: 2px;
-          display: inline-block;
-          height: 24px;
-          line-height: 24px;
-          font-size: 12px;
-          padding: 0 8px;
-          color: #fff;
-          background: rgba(255, 255, 255, 0.2);
-          img {
-            width: 16px;
-            height: 16px;
-            vertical-align: middle;
-            margin-top: -6px;
-          }
-          .count {
-            font-family: TXD_D_Medium;
-            font-size: 16px;
-            padding-left: 4px;
-            display: inline-block;
-            height: 100%;
-            min-width: 30px;
-          }
-        }
-      }
-    }
-    .version-note {
-      text-align: center;
-      margin: 22px 0 10px;
-      a {
-        text-decoration: none;
-        display: inline-block;
-        font-family: Avenir-Heavy;
-        font-size: 14px;
-        color: #FFF;
-        text-align: center;
-        background: #46484B;
-        border-radius: 2px;
-        line-height: 24px;
-        padding: 0 6px;
-        margin-right: 10px;
-        &:last-child {
-          margin-right: 0;
-        }
-      }
-    }
-    .release-date {
-      font-family: Avenir-Medium;
-      font-size: 12px;
-      color: #999;
-      text-align: center;
-    }
-  }
-
-  .ourusers-section{
+  .ourusers-section {
     display: flex;
     flex-direction: column;
     align-items: center;
-    margin-bottom: 40px;
-    margin:110px auto;
+    margin: 110px auto 80px auto;
     h3 {
       font-family: Avenir-Heavy;
       font-size: 36px;
@@ -164,33 +24,33 @@
       margin-top: 40px;
       margin-bottom: 60px;
     }
-    .button1-section{
+    .button1-section {
       display: flex;
       flex-direction: row;
       align-items: center;
       justify-content: center;
       width: 100%;
-      img{
+      img {
         width: 80px;
         height: 80px;
         &:hover {
           box-shadow: 0px 0px 12px 0px rgba(9, 97, 197, 0.1);
         }
       }
-      button{
+      button {
         border: hidden;
         background-color: transparent;
       }
-      .overflow-section{
+      .overflow-section {
         display: flex;
         width: 70%;
-        ul{
+        ul {
           display: inline-flex;
           flex-wrap: wrap;
-          li{
+          li {
             list-style: none;
             margin: 5px 5px 5px 5px;
-            img{
+            img {
               width: 100px;
               height: 100px;
               &:hover {
@@ -202,11 +62,11 @@
       }
     }
   }
-  .review-section{
+  .review-section {
     display: flex;
     flex-direction: column;
     align-items: center;
-    margin-bottom: 40px;
+    margin-bottom: 80px;
     h3 {
       font-family: Avenir-Heavy;
       font-size: 36px;
@@ -214,84 +74,94 @@
       text-align: center;
       margin-top: 40px;
     }
-    .button-section{
-      display: flex;
-      flex-direction: row;
-      align-items: center;
-      justify-content: center;
-      width: 100%;
-      img{
-        width: 80px;
-        height: 80px;
-        &:hover {
-          box-shadow: 0px 0px 12px 0px rgba(9, 97, 197, 0.1);
-        }
-      }
-      button{
-        border: hidden;
-        background-color: transparent;
+    .swiper-container {
+      width: 80%;
+      overflow: hidden;
+      position: relative;
+      margin: 20px 40px;
+      .swiper-wrapper {
+        align-items: center;
       }
-      .overflow-section{
-        overflow: hidden;
-        width: 65%;
-        height: 350px;
-        margin: 40px 0px 20px 0px;
-        background: #F9FAFA;
+      .slide-content {
         display: flex;
         align-items: center;
-        ul{
-          display: -webkit-box;
+        justify-content: center;
+        width: calc(100% - 120px);
+        background-color: #f9fafa;
+        margin: 40px 60px;
+        padding: 20px;
+        box-sizing: border-box;
+        min-height: 300px;
+        .img-box {
+          width: 150px;
+          height: 150px;
+          margin: 0 40px 0 50px;
+          display: flex;
           align-items: center;
-          flex-direction: row;
-          width: 100%;
-          li{
-            display: flex;
-            flex-direction: row;
-            align-items: center;
-            list-style: none;
+          img {
             width: 100%;
-            img{
-              width: 150px;
-              height: 150px;
-              margin: 0 40px 0 50px;
-            }
-            .name-section{
-              display: flex;
-              flex-direction: column;
-              margin-left: 20px;
-            }
-            p{
-              font-family: Avenir-Heavy;
-            }
-            .pr{
-              font-size: 20px;
-              margin-right: 20px;
-            }
-            .pn{
-              font-size: 18px;
-              text-align: right;
-              margin-top: 40px;
-              margin-right: 20px;
-            }
           }
         }
+        .name-section {
+          flex: 1;
+        }
       }
     }
   }
 
   @media screen and (max-width: $mobileWidth) {
-    .introduction-section {
-      padding: 0 20px;
-      &::before {
-        left: 20px;
+    .ourusers-section {
+      margin: 70px auto 40px auto;
+      h3 {
+        font-size: 28px;
+        margin-bottom: 40px;
       }
-      &::after {
-        left: 19px;
+      .button1-section {
+        .overflow-section {
+          width: 100%;
+          ul {
+            justify-content: center;
+          }
+        }
       }
     }
-    .feature-section, .users-section {
-      padding-left: 20px;
-      padding-right: 20px;
+    .review-section {
+      h3 {
+        font-size: 28px;
+        margin: 0 0 20px 0;
+      }
+      .swiper-container {
+        width: 100%;
+        overflow: hidden;
+        position: relative;
+        .swiper-wrapper {
+          align-items: stretch;
+        }
+        .swiper-slide {
+          background-color: #f9fafa;
+          height: auto;
+        }
+        .slide-content {
+          width: 100%;
+          margin: 30px 0;
+          flex-direction: column;
+          .img-box {
+            width: 150px;
+            height: 150px;
+            background-color: #fff;
+            display: flex;
+            align-items: center;
+            margin-bottom: 20px;
+            img {
+              width: 100%;
+            }
+          }
+        }
+        .swiper-button-prev,
+        .swiper-button-next {
+          display: none;
+        }
+      }
     }
   }
 }
diff --git a/src/variables.scss b/src/variables.scss
index 6eaf859..9d13a21 100644
--- a/src/variables.scss
+++ b/src/variables.scss
@@ -22,3 +22,8 @@ $barHeight: 200px;
 $mobileWidth: 640px;
 // 页面主体最大宽度
 $contentWidth: 1280px;
+
+
+$navMiddle: $contentWidth;
+$navSmall: 1050px;
+$navMini: 968px;
\ No newline at end of file