Selaa lähdekoodia

移动端PC提测

xzh 4 vuotta sitten
vanhempi
commit
c2c1559233
95 muutettua tiedostoa jossa 2723 lisäystä ja 1565 poistoa
  1. BIN
      common/data/images/new-3.png
  2. BIN
      common/data/images/new-3@2x.png
  3. 6 0
      mobile/build/webpack.dev.conf.js
  4. 23 0
      mobile/src/apis/index.js
  5. BIN
      mobile/src/assets/images/refactor/account/forget-img.png
  6. BIN
      mobile/src/assets/images/refactor/conduct/exhibition/banner.png
  7. BIN
      mobile/src/assets/images/refactor/conduct/house/banner.png
  8. BIN
      mobile/src/assets/images/refactor/conduct/secury/banner.png
  9. BIN
      mobile/src/assets/images/refactor/conduct/shop/banner.png
  10. BIN
      mobile/src/assets/images/refactor/conduct/subject/banner.png
  11. BIN
      mobile/src/assets/images/refactor/coreProduct/banner.png
  12. BIN
      mobile/src/assets/images/refactor/home/4case_01@2x.png
  13. BIN
      mobile/src/assets/images/refactor/home/4case_02@2x.png
  14. BIN
      mobile/src/assets/images/refactor/home/4case_03@2x.png
  15. BIN
      mobile/src/assets/images/refactor/home/4case_04@2x.png
  16. BIN
      mobile/src/assets/images/refactor/home/plate03-1.png
  17. BIN
      mobile/src/assets/images/refactor/home/plate03-2.png
  18. BIN
      mobile/src/assets/images/refactor/location/AI AR SLAM 01(剪辑版2).mp4
  19. BIN
      mobile/src/assets/images/refactor/location/banner.png
  20. BIN
      mobile/src/assets/images/refactor/location/show-1.png
  21. BIN
      mobile/src/assets/images/refactor/location/show-2.png
  22. BIN
      mobile/src/assets/images/refactor/location/show-3.png
  23. BIN
      mobile/src/assets/images/refactor/news/banner1.jpg
  24. BIN
      mobile/src/assets/images/refactor/news/banner2.jpg
  25. BIN
      mobile/src/assets/images/refactor/news/banner3.jpg
  26. BIN
      mobile/src/assets/images/refactor/news/news_ban01@2x.jpg
  27. BIN
      mobile/src/assets/images/refactor/usercenter/ali_pay.png
  28. BIN
      mobile/src/assets/images/refactor/usercenter/pay-type.png
  29. BIN
      mobile/src/assets/images/refactor/usercenter/wx_pay.png
  30. 16 7
      mobile/src/assets/style/public.scss
  31. 12 3
      mobile/src/components/browse/index.vue
  32. 2 2
      mobile/src/components/cinvoices/style.scss
  33. 24 33
      mobile/src/components/citySelect/index.vue
  34. 18 6
      mobile/src/components/citySelect/style.scss
  35. 2 2
      mobile/src/components/editInvoice/style.scss
  36. 37 32
      mobile/src/components/priceTable/index.vue
  37. 3 1
      mobile/src/components/shared/Icon.vue
  38. 1 1
      mobile/src/components/shared/MessageBox/MessageBox.vue
  39. 5 2
      mobile/src/lang/_zh/index.js
  40. 13 0
      mobile/src/lang/_zh/modules/account.js
  41. 7 0
      mobile/src/lang/_zh/modules/mall.js
  42. 6 10
      mobile/src/pages/account/codeLogin/index.vue
  43. 40 15
      mobile/src/pages/account/codeLogin/style.scss
  44. 194 0
      mobile/src/pages/account/forget/components/emailForget.vue
  45. 213 0
      mobile/src/pages/account/forget/components/phoneForget.vue
  46. 157 0
      mobile/src/pages/account/forget/components/style.scss
  47. 50 165
      mobile/src/pages/account/forget/index.vue
  48. 8 11
      mobile/src/pages/account/login/index.vue
  49. 28 31
      mobile/src/pages/account/login/style.scss
  50. 190 0
      mobile/src/pages/account/mailRegister/index.vue
  51. 62 48
      mobile/src/pages/account/forget/style.scss
  52. 0 183
      mobile/src/pages/account/manage/confirm/index.vue
  53. 2 2
      mobile/src/pages/account/manage/openInvoice/index.vue
  54. 2 2
      mobile/src/pages/account/manage/orderInvoice/index.vue
  55. 1 1
      mobile/src/pages/account/manage/payselect/style.scss
  56. 0 86
      mobile/src/pages/account/manage/paytype/index.vue
  57. 0 91
      mobile/src/pages/account/manage/paytype/style.scss
  58. 1 1
      mobile/src/pages/account/manage/vieworder/style.scss
  59. 9 14
      mobile/src/pages/account/register/index.vue
  60. 27 34
      mobile/src/pages/account/register/style.scss
  61. 3 1
      mobile/src/pages/coreProduct/index.vue
  62. 25 6
      mobile/src/pages/home/components/plate3.vue
  63. 6 1
      mobile/src/pages/home/components/plate4.vue
  64. 27 10
      mobile/src/pages/home/components/plate5.vue
  65. 34 15
      mobile/src/pages/layout/footer.vue
  66. 17 17
      mobile/src/pages/layout/header.vue
  67. 3 2
      mobile/src/pages/layout/style.scss
  68. 147 85
      mobile/src/pages/location/index.vue
  69. 0 194
      mobile/src/pages/location/style.scss
  70. 32 0
      mobile/src/pages/mall/index.vue
  71. 157 0
      mobile/src/pages/news/index.vue
  72. 1 1
      mobile/src/pages/payresult/index.vue
  73. 35 28
      mobile/src/pages/pricedetail/index.vue
  74. 137 24
      mobile/src/pages/purchase/index.vue
  75. 67 28
      mobile/src/pages/purchase/style.scss
  76. 7 7
      mobile/src/pages/purchasetwo/style.scss
  77. 16 16
      mobile/src/pages/purchasezhijia/index.vue
  78. 73 103
      mobile/src/pages/purchasezhijia/style.scss
  79. 88 0
      mobile/src/pages/userCenter/addressForm/index.vue
  80. 23 10
      mobile/src/pages/account/manage/cart/index.vue
  81. 28 45
      mobile/src/pages/account/manage/cart/style.scss
  82. 287 0
      mobile/src/pages/userCenter/confirm/index.vue
  83. 34 29
      mobile/src/pages/account/manage/confirm/style.scss
  84. 141 0
      mobile/src/pages/userCenter/paytype/index.vue
  85. 0 0
      mobile/src/pages/userCenter/paytype/style.scss
  86. 19 40
      mobile/src/pages/account/manage/submit/index.vue
  87. 36 48
      mobile/src/pages/account/manage/submit/style.scss
  88. 6 4
      mobile/src/pages/video/index.vue
  89. 67 40
      mobile/src/router/index.js
  90. 1 1
      mobile/src/store/language/cn/home.js
  91. 18 19
      mobile/src/store/language/cn/purchase.js
  92. 14 2
      mobile/src/store/user.js
  93. 7 1
      mobile/src/util/http.js
  94. 1 1
      pc/src/config/newsData.js
  95. 7 4
      pc/src/page/home2/index.vue

BIN
common/data/images/new-3.png


BIN
common/data/images/new-3@2x.png


+ 6 - 0
mobile/build/webpack.dev.conf.js

@@ -42,6 +42,12 @@ const devWebpackConfig = merge(baseWebpackConfig, {
     quiet: true, // necessary for FriendlyErrorsPlugin
     watchOptions: {
       poll: config.dev.poll,
+    },
+    proxy: {
+      '/api': {
+        target: 'https://test.4dkankan.com',
+        changeOrigin: true,
+      }
     }
   },
   plugins: [

+ 23 - 0
mobile/src/apis/index.js

@@ -0,0 +1,23 @@
+import axios from '@/util/http'
+
+export default {
+  saveAduit (data) {
+    return axios.post('agentAduit/save', data)
+  },
+  getEmailAuthCode (data) {
+    return axios.post('sso/user/getEmailAuthCode', data)
+  },
+  // 地址模块
+  getReceiverList () {
+    return axios.post('user/getReceiverList')
+  },
+  insertAddress (data) {
+    return axios.post('user/insertAddress', data)
+  },
+  updateAddress (data) {
+    return axios.post('user/updateAddress', data)
+  },
+  deleteAddress (id) {
+    return axios.post('user/deleteAddress', {id})
+  }
+}

BIN
mobile/src/assets/images/refactor/account/forget-img.png


BIN
mobile/src/assets/images/refactor/conduct/exhibition/banner.png


BIN
mobile/src/assets/images/refactor/conduct/house/banner.png


BIN
mobile/src/assets/images/refactor/conduct/secury/banner.png


BIN
mobile/src/assets/images/refactor/conduct/shop/banner.png


BIN
mobile/src/assets/images/refactor/conduct/subject/banner.png


BIN
mobile/src/assets/images/refactor/coreProduct/banner.png


BIN
mobile/src/assets/images/refactor/home/4case_01@2x.png


BIN
mobile/src/assets/images/refactor/home/4case_02@2x.png


BIN
mobile/src/assets/images/refactor/home/4case_03@2x.png


BIN
mobile/src/assets/images/refactor/home/4case_04@2x.png


BIN
mobile/src/assets/images/refactor/home/plate03-1.png


BIN
mobile/src/assets/images/refactor/home/plate03-2.png


BIN
mobile/src/assets/images/refactor/location/AI AR SLAM 01(剪辑版2).mp4


BIN
mobile/src/assets/images/refactor/location/banner.png


BIN
mobile/src/assets/images/refactor/location/show-1.png


BIN
mobile/src/assets/images/refactor/location/show-2.png


BIN
mobile/src/assets/images/refactor/location/show-3.png


BIN
mobile/src/assets/images/refactor/news/banner1.jpg


BIN
mobile/src/assets/images/refactor/news/banner2.jpg


BIN
mobile/src/assets/images/refactor/news/banner3.jpg


BIN
mobile/src/assets/images/refactor/news/news_ban01@2x.jpg


BIN
mobile/src/assets/images/refactor/usercenter/ali_pay.png


BIN
mobile/src/assets/images/refactor/usercenter/pay-type.png


BIN
mobile/src/assets/images/refactor/usercenter/wx_pay.png


+ 16 - 7
mobile/src/assets/style/public.scss

@@ -88,7 +88,7 @@ body{
   line-height: 1.15;
   padding: 0 15px;
   font-size: 12px;
-  border-radius: 4px;
+  border-radius: 2px;
   height: 28px;
   user-select: none;
   transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
@@ -101,7 +101,7 @@ body{
 .ant-btn-primary{
   color: #000 !important;
   border-color: transparent !important;
-  background: linear-gradient(-135deg, #1fe4dc 0%, #1fc3dc 100%) !important;
+  background: #1FE4DC;
   margin: 10px 0;
   span{
     font-size: 14px;
@@ -191,13 +191,13 @@ body{
   display: inline-block;
   line-height: unset;
   cursor: pointer;
-  color: rgba(0,0,0,.65);
+  color: #202020;
   font-size: 12px;
   .check-box {
     box-sizing: border-box;
     margin: 0;
     padding: 0;
-    color: rgba(0, 0, 0, 0.65);
+    color:#202020;
     font-size: 12px;
     font-variant: tabular-nums;
     line-height: 1.5;
@@ -253,12 +253,12 @@ body{
       }
     }
     .checkbox-inner-checked {
-      background-color: #1fe4dc;
-      border-color: #1fe4dc;
+      background-color: #202020;
+      border-color:#202020;
       &::after {
         position: absolute;
         display: table;
-        border: 2px solid #fff;
+        border: 3px solid #fff;
         border-top: 0;
         border-left: 0;
         transform: rotate(45deg) scale(0.8) translate(-50%, -50%);
@@ -325,4 +325,13 @@ body{
   100% {
     transform: rotate(360deg);
   }
+}
+
+.common-header {
+  padding: 27px 20px 17px;
+  border: 1px solid #EBEBEB;
+  color: #202020;
+  font-size: 14px;
+  font-weight: bold;
+  line-height: 21px;
 }

+ 12 - 3
mobile/src/components/browse/index.vue

@@ -3,9 +3,11 @@
     <swiper class="swiper-wrapper swiper-wrapper-n" :options="swiperOption">
       <swiper-slide class="swiper-slide" v-for="(item,index) in idata" :key="index">
         <div class="s-item" :style="{height:wh.width+'px'}" >
-          <video v-if="item.video" controls="controls" playsinline="playsinline" muted="muted" :poster="`${$cdn}images/${floder}/${item.video}.png`" >
-            <source :src="`${$cdn}images/${floder}/${item.big}.mp4`" type="video/mp4">
-          </video>
+          <div v-if="item.video" class="video-bg">
+            <video  controls="controls" playsinline="playsinline" muted="muted" :poster="`${$cdn}images/${floder}/${item.video}.png`" >
+              <source :src="`${$cdn}images/${floder}/${item.big}.mp4`" type="video/mp4">
+            </video>
+          </div>
           <img v-else class="main-img" :src="`${$cdn}images/${floder}/${item.big}.png`">
         </div>
       </swiper-slide>
@@ -100,4 +102,11 @@ export default {
 .swiper-pagination-bullet-active{
   background: #1fe4dc!important;
 }
+.video-bg {
+  width: 100%;
+  height: 100%;
+  background: #202020;
+  display: flex;
+  align-items: center;
+}
 </style>

+ 2 - 2
mobile/src/components/cinvoices/style.scss

@@ -179,7 +179,7 @@
       overflow-wrap: break-word;
       .bc-contact{
         font-size: 12px;
-        color: rgba(0,0,0,.7);
+        color: #202020;
         line-height: 18px;
         
       }
@@ -193,7 +193,7 @@
         top: 16px;
         right: 16px;
         font-size: 12px;
-        color: rgba(0,0,0,.7);
+        color: #202020;
         line-height: 18px;
       }
     }

+ 24 - 33
mobile/src/components/citySelect/index.vue

@@ -3,13 +3,15 @@
     <div class="address-input-con">
       <div class="address-input-item">
         <div class="address-sub address-name">
-          <div class="top-title">{{langAccount.placeholder.name}}</div>
+          <div class="top-title">{{ $t('mall.receiver') }}</div>
           <div class="ant-input">
             <input v-model="tempAddress.shipName" type="text" :placeholder="langAccount.placeholder.name" />
           </div>
         </div>
+      </div>
+      <div class="address-input-item">
         <div class="address-sub address-phone">
-          <div class="top-title">{{langAccount.placeholder.phone}}</div>
+          <div class="top-title">{{ $t('mall.receiverPlaceholder') }}</div>
           <div class="ant-input">
             <input v-model="tempAddress.shipMobile" oninput="value=value.replace(/[^\d]/g,'')" maxlength='11' type="text" :placeholder="langAccount.placeholder.phone" />
           </div>
@@ -17,7 +19,7 @@
       </div>
       <div class="address-input-item">
         <div class="address-sub prov-name">
-          <div class="top-title">{{langAccount.placeholder.prov}}</div>
+          <div class="top-title">{{$t('mall.receiveAddress')}}</div>
           <div class="ant-input prov" @click="handleSelect('prov')">
             {{citylist[currentPID]['p']||'省份'}}
             <ul v-if="prov">
@@ -25,8 +27,8 @@
             </ul>
           </div>
         </div>
-        <div class="address-sub city-phone">
-          <div class="top-title">{{langAccount.placeholder.city}}</div>
+        <div class="address-sub prov-name">
+          <div class="top-title notrequired"></div>
           <div class="ant-input city" @click="handleSelect('city')">
             {{currentProv[currentCID]['n']||'城市'}}
             <ul v-if="city">
@@ -34,28 +36,32 @@
             </ul>
           </div>
         </div>
-      </div>
-      <div class="address-input-item">
-        <div class="address-sub">
-          <div class="top-title">{{langAccount.placeholder.address}}</div>
-          <div class="ant-input dist" @click="handleSelect('dist')">
+        <div class="address-sub prov-name" @click="handleSelect('dist')">
+          <div class="top-title notrequired"></div>
+          <div class="ant-input city" @click="handleSelect('dist')">
             {{currentCity[currentSID]['s']||'区/县'}}
             <ul v-if="dist">
               <li v-for="(item,i) in currentCity" :key="i" @click="handleClick('currentSID',i)">{{item.s}}</li>
             </ul>
           </div>
+        </div>
+      </div>
+      <div class="address-input-item">
+        <div class="address-sub">
+          <!-- <div class="top-title">{{langAccount.placeholder.address}}</div> -->
           <div class="ant-input">
             <input v-model="tempAddress.shipAddress" type="text" :placeholder="langAccount.placeholder.address" />
           </div>
         </div>
       </div>
-      <p class="p-dec">{{langAccount.recaddress}}</p>
-      <button type="submit" class="ant-btn ant-btn-primary" @click="uAddress">
-        <span>{{langAccount.save}}</span>
-      </button>
-      <button type="submit" class="ant-btn ant-btn-primary cancel" @click="$emit('closeSelect', true)">
-        <span>{{langAccount.cancel}}</span>
-      </button>
+      <div class="actions-w">
+        <button type="submit" class="ant-btn ant-btn-primary cancel" @click="$emit('cancle', true)">
+          <span>{{langAccount.cancel}}</span>
+        </button>
+        <button type="submit" class="ant-btn ant-btn-primary" @click="uAddress">
+          <span>{{langAccount.save}}</span>
+        </button>
+      </div>
     </div>
   </div>
 </template>
@@ -171,22 +177,7 @@ export default {
           return this.$toast.show('warn', this.langAccount.fill)
         }
       }
-      this.$http
-        .post('/user/updateAddress', params, {
-          headers: {
-            token: this.token
-          }
-        })
-        .then(data => {
-          let res = data.data
-          if (res.code === 0) {
-            this.$emit('closeSelect', true)
-            this.$store.dispatch('getInfo', {
-              url: '/user/getReceiverInfo',
-              name: 'address'
-            })
-          }
-        })
+      this.$emit('submit', params)
     },
     handleSelect (item) {
       sle.forEach(i => {

+ 18 - 6
mobile/src/components/citySelect/style.scss

@@ -21,7 +21,7 @@
   color: rgba(0, 0, 0, 0.65);
   .address-input-item {
     display: flex;
-    margin-bottom: 8px;
+    margin-bottom: 17px;
     .address-sub {
       width: 100%;
       .prov,
@@ -56,7 +56,7 @@
         overflow: hidden;
         text-overflow: ellipsis;
         white-space: nowrap;
-        color: rgba(0, 0, 0, 0.85);
+        color: #202020;
         padding: 0 0 8px;
         margin: 0;
         display: block;
@@ -71,17 +71,16 @@
           font-size: 12px;
           color: #f04134;
         }
+        &.notrequired {
+          visibility: hidden;
+        }
       }
     }
-    .address-name,
     .prov-name {
       width: 33.33%;
       padding-right: 4px;
       flex-shrink: 0;
     }
-    .prov-name {
-      width: 50%;
-    }
     .address-phone,
     .city-name {
       flex: auto;
@@ -91,4 +90,17 @@
     line-height: 32px;
     margin-bottom: 8px;
   }
+}
+.actions-w {
+  display: flex;
+  margin-top: 30px;
+  .ant-btn {
+    flex: 1;
+    height: 48px;
+    line-height: 48px;
+    margin: 0;
+  }
+  .cancel {
+    margin: 0 15px 0 0;
+  }
 }

+ 2 - 2
mobile/src/components/editInvoice/style.scss

@@ -71,7 +71,7 @@
             line-height: 30px;
             height: 30px;
             font-size: 12px;
-            color: rgba(0, 0, 0, 0.7);
+            color: #202020;
           }
         }
       }
@@ -82,7 +82,7 @@
         overflow: hidden;
         text-overflow: ellipsis;
         white-space: nowrap;
-        color: rgba(0, 0, 0, 0.85);
+        color: #202020;
         padding: 0 0 8px;
         margin: 0;
         display: block;

+ 37 - 32
mobile/src/components/priceTable/index.vue

@@ -39,7 +39,7 @@
         </div>
       </li>
        <li class="t-sub">
-        <div class="box thin" :style="{lineHeight:language==='en'?'30px':'60px'}"><span>{{langPurchase.pricelist[21]}}</span></div>
+        <div class="box thin" ><span>{{langPurchase.pricelist[21]}}</span></div>
       </li>
     </ul>
   </div>
@@ -68,29 +68,34 @@ export default {
 <style lang="scss" scoped>
 .price-table {
   box-sizing: border-box;
-  border-top: 1px solid #e7e7e7;
-  border-left: 1px solid #e7e7e7;
-  width: 341px;
-  background-color: #f8f9fc;
+  border-top: 1px solid #909090;
+  border-left: 1px solid #909090;
+  width: 100%;
   margin: 0 auto;
+  * {
+    box-sizing: border-box;;
+  }
   .box {
-    width: 72px;
+    width: 78px;
     height: 60px;
     line-height: 60px;
     display: inline-block;
     vertical-align: top;
-    font-size: 14px;
-    border-right: 1px solid #e7e7e7;
-    border-bottom: 1px solid #e7e7e7;
+    font-size: 10px;
+    border-right: 1px solid #909090;
+    border-bottom: 1px solid #909090;
   }
 
   .big-box {
-    height: 120px;
-    line-height: 120px;
+    height: auto;
+    line-height: 46px;
   }
   .big-list {
     div {
-      border-bottom: 1px solid #e7e7e7;
+      border-bottom: 1px solid #909090;
+      &:last-child {
+        border-bottom: none;
+      }
     }
   }
 
@@ -98,13 +103,9 @@ export default {
     height: 30px;
     line-height: 30px;
     >span{
-      top: 50%;
-      left: 50%;
       width: 100%;
       display: inline-block;
-      text-align: left;
-      transform: translateX(10%);
-      position: static;
+      text-align: center;
     }
   }
   .centerthin{
@@ -114,14 +115,15 @@ export default {
     }
   }
   .long {
-    width: 98px;
+    // width: 98px;
+    flex: 1;
   }
   .price {
-    width: 196px;
-    font-size: 14px;
+    flex: 1;
+    font-size: 10px;
     display: inline-block;
     vertical-align: top;
-    border-right: 1px solid #e7e7e7;
+    border-right: 1px solid #909090;
     span{
       transform: none;
       text-align: center;
@@ -129,36 +131,39 @@ export default {
     .shang {
       height: 30px;
       line-height: 30px;
-      border-bottom: 1px solid #e7e7e7;
+      border-bottom: 1px solid #909090;
     }
     .xia {
       height: 30px;
       line-height: 30px;
       display: flex;
-      border-bottom: 1px solid #e7e7e7;
+      border-bottom: 1px solid #909090;
       justify-content: space-around;
       div {
         width: 50%;
         &:first-of-type {
-          border-right: 1px solid #e7e7e7;
+          border-right: 1px solid #909090;
         }
       }
     }
   }
-
+  .top {
+    background: #EBEBEB;
+  }
   .top,
   .t-middle,
   .t-bottom,
   .t-sub {
     width: 100%;
     font-size: 0;
+    display: flex;
   }
   .t-sub{
     .box{
       width: 100%;
     }
     .thin{
-      height: 60px;
+      height: 30px;
       span{
         text-align: center;
         transform: translateX(0)
@@ -167,7 +172,7 @@ export default {
   }
   .t-middle {
     > div {
-      background-color: #f4f4f4;
+      background-color:#EBEBEB;
     }
   }
 }
@@ -178,22 +183,22 @@ export default {
     .box {
       width: 62px;
       height: 52px;
-      font-size: 12px;
+      font-size: 10px;
       line-height: 52px;
     }
     .big-box {
-      height: 104px;
+      height: auto;
       line-height: 104px;
     }
     .thin {
-      height: 26px;
-      line-height: 26px;
+      height: 24px;
+      line-height: 24px;
     }
     .long {
       width: 84px;
     }
     .price {
-      font-size: 12px;
+      font-size: 10px;
       width: 168px;
       .shang {
         height: 26px;

+ 3 - 1
mobile/src/components/shared/Icon.vue

@@ -23,5 +23,7 @@ export default {
 </script>
 
 <style lang="less">
-
+.iconfont {
+  font-size: inherit;
+}
 </style>

+ 1 - 1
mobile/src/components/shared/MessageBox/MessageBox.vue

@@ -26,7 +26,7 @@
           <h-icon :type="icon" style="font-size: 40px;line-height: 52px" />
         </div>
         <p class="message">{{ message }}</p>
-        <div class="submit-btn" @click="handleAction('close')">确定</div>
+        <div class="submit-btn" @click="handleAction('confirm')">确定</div>
       </div>
     </template>
   </HModal>

+ 5 - 2
mobile/src/lang/_zh/index.js

@@ -2,10 +2,13 @@ import agent from './modules/agent'
 import coreProduct from './modules/coreProduct'
 import conduct from './modules/conduct'
 import common from './modules/common'
-
+import account from './modules/account'
+import mall from './modules/mall'
 export default {
   common,
   agent,
   coreProduct,
-  conduct
+  conduct,
+  account,
+  mall
 }

+ 13 - 0
mobile/src/lang/_zh/modules/account.js

@@ -0,0 +1,13 @@
+export default {
+  loginTitle: '用户登录',
+  accountPlaceholder: '请输入手机号码/邮箱',
+  passwordPlaceholder: '请输入密码',
+  forgetPassword: '忘记密码',
+  registerAccount: '立即注册',
+  passwordLogin: '密码登录',
+  registerTitle: '四维账号注册',
+  register: '注册',
+  accountMailPlaceholder: '请输入邮箱地址',
+  mailCodePlaceholder: '验证码(6位数)',
+  forgetTitle: '找回密码'
+}

+ 7 - 0
mobile/src/lang/_zh/modules/mall.js

@@ -0,0 +1,7 @@
+export default {
+  receiver: '收货人',
+  receiverPlaceholder: '请填写收货人名称',
+  phoneNum: '手机号码',
+  phoneNumPlaceholder: '请输入手机号码',
+  receiveAddress: '收货地址'
+}

+ 6 - 10
mobile/src/pages/account/codeLogin/index.vue

@@ -1,16 +1,13 @@
 <template>
   <div class="register-layout">
-    <div class="banner">
-      <img :src="`${$cdn}images/icon/codeLogin.png`" alt="">
-    </div>
-    <div class="r-line"></div>
     <div class="login-con">
+      <h1 class="common-title">{{ $t('account.loginTitle') }}</h1>
       <div class="input-con" :class="{inputActive:inputActive==='phone'}">
-        <img :src="`${$cdn}images/icon/icon-phone@2x.png`" alt="">
         <div class="phone-select" ref="quhaoMenu">
           <div @click="showSelect=!showSelect">
             <span>{{codeActive[1]}}</span>
-            <img :src="`${$cdn}images/quhao-jiantou.png`" >
+            (<span>{{codeActive[0]}}</span>)
+            <div class="sanjiao"></div>
           </div>
           <ul v-show="showSelect" >
             <li @click="selectItem(item)" v-for="(item,i) in selectCall" :key="i">
@@ -22,11 +19,10 @@
       </div>
       <div class="code-con">
         <div class="input-con" :class="{inputActive:inputActive==='code'}">
-          <img :src="`${$cdn}images/icon/icon-code@2x.png`" style="width:23px;" alt="">
           <input v-model="authCode" @focus="inputActive='code'" @blur="inputActive=''" style="padding-left:6px;" type="text" oninput="value=value.replace(/[^\d]/g,'')" maxlength='6' :placeholder="langLogin.code.placeholder">
+          <div class="send-btn" v-if="!jishi"  @click="getAuthCode">{{langLogin.code.txt}}</div>
+          <span class="send-btn"  v-else>{{language==='en'?`Resend after ${interTime}s`:`${interTime}s后重新发送`}}</span>
         </div>
-        <div v-if="!jishi" class="btns" @click="getAuthCode">{{langLogin.code.txt}}</div>
-        <span class="btns" v-else>{{language==='en'?`Resend after ${interTime}s`:`${interTime}s后重新发送`}}</span>
       </div>
       <div class="forget">
         <router-link :to="{path:'/login'}">{{langLogin.defaultLogin}}</router-link>
@@ -34,7 +30,7 @@
       <div class="btns" @click="submit">{{langLogin.login}}</div>
       <div class="to-login">
         <div class="lo-con">
-          {{langLogin.loginsub1}}<router-link :to="{path:'/register'}">{{langLogin.loginsub2}}</router-link>
+          <router-link :to="{path:'/forget'}">{{ $t('account.forgetPassword') }}</router-link><router-link :to="{path:'/register'}">{{langLogin.loginsub2}}</router-link>
         </div>
       </div>
     </div>

+ 40 - 15
mobile/src/pages/account/codeLogin/style.scss

@@ -16,7 +16,7 @@ input[type='password']{
   outline: 0;
   cursor: pointer;
   margin: 16px 0;
-  background-image: linear-gradient(-135deg, #1fe4dc 0%, #1fc3dc 100%);
+  background-color: #1FE4DC;
   height: 48px;
   line-height: 48px;
   text-align: center;
@@ -26,16 +26,28 @@ input[type='password']{
   color: rgba(0, 0, 0, 0.7);
 }
 .phone-select{
+  width: 104px;
+  padding-left: 10px;
+  font-size: 14px;
   &>div{
     height: 18px;
-    border-right: 1px solid #f1f1f1;
+    border-right: 1px solid #909090;
     display: flex;
     flex-wrap: nowrap;
     align-items: center;
+    position: relative;
     &>span{
       display: inline-block;
       vertical-align: middle;
     }
+    .sanjiao {
+      border: 4px solid #909090;
+      border-left-color: transparent;
+      border-right-color: transparent;
+      border-bottom: none;
+      position: absolute;
+      right: 10px;
+    }
   }
   
   img{
@@ -73,13 +85,8 @@ input[type='password']{
 }
 .register-layout{
   width: 100%;
-  .banner{
-    position: relative;
-    padding-top: 30px;
-    img{
-      width: 100%;
-    }
-  }
+  padding-top: 27px;
+  padding-bottom: 40px;
   $padd:16px;
   .r-line{
     width: calc(100% - 32px);
@@ -96,14 +103,13 @@ input[type='password']{
       align-items: center;
       justify-content: space-between;
       .input-con{
-        width: 55%;
+        width: 100%;
         input{
-          width: 100%;
         }
       }
-      .btns{
-        margin: 16px 0 0 10px;
-        flex: 1;
+      .send-btn {
+        font-size: 14px;
+        padding: 0 10px;
       }
     }
     .input-con{
@@ -148,7 +154,26 @@ input[type='password']{
         color: #707070;
         margin: 16px 0;
         a{
-          color: #1fe4dc;
+          font-size: 14px;
+          color:#202020;
+          font-weight: normal;
+          line-height: 20px;
+          &:first-of-type {
+            padding-right: 20px;
+            margin-right: 20px;
+            position: relative;
+            &::after {
+              content: '';
+              display: block;
+              width: 1px;
+              height: 12px;
+              background-color: #202020;
+              position: absolute;
+              right: 0;
+              top: 50%;
+              margin-top: -6px;
+            }
+          }
         }
       }
     }

+ 194 - 0
mobile/src/pages/account/forget/components/emailForget.vue

@@ -0,0 +1,194 @@
+<template>
+  <div>
+    <div class="login-con">
+      <div class="input-con" :class="{inputActive:inputActive==='phone'}">
+        <input
+          class="guding"
+          v-model="phone"
+          @focus="inputActive='phone'"
+          @blur="inputActive=''"
+          type="text"
+          :placeholder="$t('account.accountMailPlaceholder')"
+        />
+      </div>
+      <div class="code-con">
+        <div class="input-con" :class="{inputActive:inputActive==='code'}">
+          <input
+            v-model="authCode"
+            @focus="inputActive='code'"
+            @blur="inputActive=''"
+            style="padding-left:6px;"
+            type="text"
+            oninput="value=value.replace(/[^\d]/g,'')"
+            maxlength="6"
+            :placeholder="langLogin.code.placeholder"
+          />
+          <div  class="send-btn" v-if="!jishi" @click="getAuthCode">{{langLogin.code.txt}}</div>
+          <span
+          class="send-btn"
+            v-else
+          >{{language==='en'?`Resend after ${interTime}s`:`${interTime}s后重新发送`}}</span>
+        </div>
+      </div>
+      <div class="input-con" :class="{inputActive:inputActive==='password'}">
+        <input
+          v-model="password"
+          @focus="inputActive='password'"
+          @blur="inputActive=''"
+          maxlength="16"
+          type="password"
+          :placeholder="langLogin.newpass.placeholder"
+        />
+      </div>
+      <div class="input-con" :class="{inputActive:inputActive==='confirm'}">
+        <input
+          v-model="confirmpass"
+          @focus="inputActive='confirm'"
+          @blur="inputActive=''"
+          maxlength="16"
+          type="password"
+          :placeholder="langLogin.comfirmpass.placeholder"
+        />
+      </div>
+      <div class="btns" @click="submit">{{langLogin.submit}}</div>
+      <div class="to-login">
+        <div class="lo-con">
+          {{langLogin.resigter1}}
+          <router-link :to="{path:'/login'}">{{langLogin.resigter2}}</router-link>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import {mapState} from 'vuex'
+import selectCall from '../../country.js'
+import { encodeStr } from '@/util'
+import { Base64 } from 'js-base64'
+export default {
+  computed: {
+    ...mapState({
+      language: state => state.language.current,
+      langToast: state => state.language.home.toast,
+      langLogin: state => state.language.home.home.loginAside,
+      token: state => state.user.token
+    })
+  },
+  data () {
+    return {
+      showSelect: false,
+      selectCall,
+      codeActive: ['中国', '+86', 'China'],
+      phone: '',
+      authCode: '',
+      interTime: 60,
+      jishi: false,
+      password: '',
+      confirmpass: '',
+      inputActive: ''
+    }
+  },
+  mounted () {
+    document.addEventListener('click', (e) => {
+      if (this.$refs.quhaoMenu) {
+        if (!this.$refs.quhaoMenu.contains(e.target)) {
+          this.showSelect = false
+        }
+      }
+    })
+  },
+  methods: {
+    selectItem (item) {
+      this.showSelect = false
+      this.codeActive = item
+    },
+
+    async getAuthCode () {
+      let res = await this.$store.dispatch('getAuthCode', {
+        phone: this.phone,
+        code: Number(this.codeActive[1].substr(1))
+      })
+      if (res) {
+        this.interl && clearInterval(this.interl)
+        this.interl = null
+        this.jishi = true
+        this.interl = setInterval(() => {
+          this.interTime--
+          if (this.interTime <= 0) {
+            this.jishi = false
+            this.interTime = 60
+            clearInterval(this.interl)
+            this.interl = null
+          }
+        }, 1000)
+      }
+    },
+    async submit () {
+      let check = value => {
+        for (let i = 0, len = value.length; i < len; i++) {
+          if (!value[i].val) {
+            return this.$toast.show('warn', (this.language === 'en' ? value[i].En : value[i].name) + this.langToast['7'])
+          }
+        }
+        return true
+      }
+      let checkStr = [
+        {
+          name: '手机',
+          En: 'Phone number',
+          val: this.phone
+        },
+        {
+          name: '验证码',
+          En: 'Verification code',
+          val: this.authCode
+        },
+        {
+          name: '密码',
+          En: 'Password',
+          val: this.password
+        },
+        {
+          name: '确认密码',
+          En: 'Password',
+          val: this.confirmpass
+        }
+      ]
+      if (!check(checkStr)) {
+        return
+      }
+      if (this.password.length < 8 || this.confirmpass.length < 8) {
+        return this.$toast.show('warn', this.langToast['31'])
+      }
+      let temp = encodeStr(Base64.encode(this.password), Base64.encode(this.confirmpass))
+
+      let params = {
+        password: temp[0],
+        phoneNum: this.phone,
+        confirmPwd: temp[1],
+        msgAuthCode: this.authCode
+      }
+      let res = await this.$http({
+        method: 'post',
+        headers: {
+          token: this.token
+        },
+        data: params,
+        url: 'sso/user/changePassword'
+      })
+      let response = res.data
+      if (response.code !== 0) {
+        return this.$toast.show('warn', this.langToast[response.code])
+      }
+      this.$toast.show('warn', this.langToast['32'], () => {
+        this.$router.push({path: '/login'})
+      })
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+@import './style.scss';
+</style>

+ 213 - 0
mobile/src/pages/account/forget/components/phoneForget.vue

@@ -0,0 +1,213 @@
+<template>
+  <div>
+    <div class="login-con">
+      <div class="input-con" :class="{inputActive:inputActive==='phone'}">
+        <div class="phone-select" ref="quhaoMenu">
+          <div @click="showSelect=!showSelect">
+            <span>{{codeActive[1]}}</span>
+            (<span>{{codeActive[0]}}</span>)
+            <div class="sanjiao"></div>
+          </div>
+          <ul v-show="showSelect">
+            <li
+              @click="selectItem(item)"
+              v-for="(item,i) in selectCall"
+              :key="i"
+            >{{language==='en'?item[2]:item[0]}}{{item[1]}}</li>
+          </ul>
+        </div>
+        <input
+          class="guding"
+          v-model="phone"
+          oninput="value=value.replace(/[^\d]/g,'')"
+          maxlength="11"
+          @focus="inputActive='phone'"
+          @blur="inputActive=''"
+          type="text"
+          :placeholder="langLogin.phone.placeholder"
+        />
+      </div>
+      <div class="code-con">
+        <div class="input-con" :class="{inputActive:inputActive==='code'}">
+          <input
+            v-model="authCode"
+            @focus="inputActive='code'"
+            @blur="inputActive=''"
+            style="padding-left:6px;"
+            type="text"
+            oninput="value=value.replace(/[^\d]/g,'')"
+            maxlength="6"
+            :placeholder="langLogin.code.placeholder"
+          />
+          <div  class="send-btn" v-if="!jishi" @click="getAuthCode">{{langLogin.code.txt}}</div>
+          <span
+          class="send-btn"
+            v-else
+          >{{language==='en'?`Resend after ${interTime}s`:`${interTime}s后重新发送`}}</span>
+        </div>
+      </div>
+      <div class="input-con" :class="{inputActive:inputActive==='password'}">
+        <input
+          v-model="password"
+          @focus="inputActive='password'"
+          @blur="inputActive=''"
+          maxlength="16"
+          type="password"
+          :placeholder="langLogin.newpass.placeholder"
+        />
+      </div>
+      <div class="input-con" :class="{inputActive:inputActive==='confirm'}">
+        <input
+          v-model="confirmpass"
+          @focus="inputActive='confirm'"
+          @blur="inputActive=''"
+          maxlength="16"
+          type="password"
+          :placeholder="langLogin.comfirmpass.placeholder"
+        />
+      </div>
+      <div class="btns" @click="submit">{{langLogin.submit}}</div>
+      <div class="to-login">
+        <div class="lo-con">
+          {{langLogin.resigter1}}
+          <router-link :to="{path:'/login'}">{{langLogin.resigter2}}</router-link>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import {mapState} from 'vuex'
+import selectCall from '../../country.js'
+import { encodeStr } from '@/util'
+import { Base64 } from 'js-base64'
+export default {
+  computed: {
+    ...mapState({
+      language: state => state.language.current,
+      langToast: state => state.language.home.toast,
+      langLogin: state => state.language.home.home.loginAside,
+      token: state => state.user.token
+    })
+  },
+  data () {
+    return {
+      showSelect: false,
+      selectCall,
+      codeActive: ['中国', '+86', 'China'],
+      phone: '',
+      authCode: '',
+      interTime: 60,
+      jishi: false,
+      password: '',
+      confirmpass: '',
+      inputActive: ''
+    }
+  },
+  mounted () {
+    document.addEventListener('click', (e) => {
+      if (this.$refs.quhaoMenu) {
+        if (!this.$refs.quhaoMenu.contains(e.target)) {
+          this.showSelect = false
+        }
+      }
+    })
+  },
+  methods: {
+    selectItem (item) {
+      this.showSelect = false
+      this.codeActive = item
+    },
+
+    async getAuthCode () {
+      // if (!reg.phone.test(this.phone)) {
+      //   return
+      // }
+      let res = await this.$store.dispatch('getAuthCode', {
+        phone: this.phone,
+        code: Number(this.codeActive[1].substr(1))
+      })
+      if (res) {
+        this.interl && clearInterval(this.interl)
+        this.interl = null
+        this.jishi = true
+        this.interl = setInterval(() => {
+          this.interTime--
+          if (this.interTime <= 0) {
+            this.jishi = false
+            this.interTime = 60
+            clearInterval(this.interl)
+            this.interl = null
+          }
+        }, 1000)
+      }
+    },
+    async submit () {
+      let check = value => {
+        for (let i = 0, len = value.length; i < len; i++) {
+          if (!value[i].val) {
+            return this.$toast.show('warn', (this.language === 'en' ? value[i].En : value[i].name) + this.langToast['7'])
+          }
+        }
+        return true
+      }
+      let checkStr = [
+        {
+          name: '手机',
+          En: 'Phone number',
+          val: this.phone
+        },
+        {
+          name: '验证码',
+          En: 'Verification code',
+          val: this.authCode
+        },
+        {
+          name: '密码',
+          En: 'Password',
+          val: this.password
+        },
+        {
+          name: '确认密码',
+          En: 'Password',
+          val: this.confirmpass
+        }
+      ]
+      if (!check(checkStr)) {
+        return
+      }
+      if (this.password.length < 8 || this.confirmpass.length < 8) {
+        return this.$toast.show('warn', this.langToast['31'])
+      }
+      let temp = encodeStr(Base64.encode(this.password), Base64.encode(this.confirmpass))
+
+      let params = {
+        password: temp[0],
+        phoneNum: this.phone,
+        confirmPwd: temp[1],
+        msgAuthCode: this.authCode
+      }
+      let res = await this.$http({
+        method: 'post',
+        headers: {
+          token: this.token
+        },
+        data: params,
+        url: 'sso/user/changePassword'
+      })
+      let response = res.data
+      if (response.code !== 0) {
+        return this.$toast.show('warn', this.langToast[response.code])
+      }
+      this.$toast.show('warn', this.langToast['32'], () => {
+        this.$router.push({path: '/login'})
+      })
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+@import './style.scss';
+</style>

+ 157 - 0
mobile/src/pages/account/forget/components/style.scss

@@ -0,0 +1,157 @@
+input[type='text'],
+input[type='password']{
+  border: 0;
+  outline: 0;
+  height: 48px;
+  padding-right: 16px;
+  padding-left: 12px;
+  font-size: 14px;
+  color: #000;
+  flex: auto;
+}
+.btns{
+  display: block;
+  width: 100%;
+  border: 0;
+  outline: 0;
+  cursor: pointer;
+  margin: 16px 0;
+  background-color: #1FE4DC;
+  height: 48px;
+  line-height: 48px;
+  text-align: center;
+  border-radius: 2px;
+  font-weight: bold;
+  font-size: 16px;
+  color: rgba(0, 0, 0, 0.7);
+}
+.disAgree{
+  background-image: none;
+  background-color: #e2e2e2;
+}
+.phone-select{
+  &>div{
+    height: 18px;
+    border-right: 1px solid #909090;
+    display: flex;
+    flex-wrap: nowrap;
+    align-items: center;
+    position: relative;
+    padding: 0 20px 0 10px;
+    &>span{
+      display: inline-block;
+      vertical-align: middle;
+    }
+    .sanjiao {
+      border: 4px solid #909090;
+      border-left-color: transparent;
+      border-right-color: transparent;
+      border-bottom: none;
+      position: absolute;
+      right: 10px;
+    }
+  }
+  img{
+    width: 10px!important;
+    margin: 0 10px 0 6px!important;
+    vertical-align: middle!important;
+  }
+  ul{
+    position: absolute;
+    top: 0;
+    left: 0;
+    background: #fff;
+    min-width: 200px;
+    height: 230px;
+    padding: 0 10px;
+    overflow: auto;
+    transition: ease 0.3s all;
+    z-index: 888;
+    box-shadow: 0px 1px 8px #ddd;
+    li{
+      height: 40px;
+      line-height: 50px;
+      color: #999;
+      word-break: break-all;
+      font-size: 14px;
+      cursor: pointer;
+      &:hover{
+        color: #000;
+      }
+    }
+  }
+}
+.guding{
+  padding-right: 0!important;
+}
+.login-con{
+  width: 100%;
+  background-color: #fff;
+  .code-con{
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    .input-con{
+      width: 100%;
+      
+    }
+  }
+  .input-con{
+    position: relative;
+    border: 1px solid #D9D9D9;
+    border-radius: 2px;
+    margin-top: 16px;
+    display: flex;
+    align-items: center;
+    img{
+      flex: none;
+      width: 18px;
+      margin: 0 16px;
+    }
+  }
+  .inputActive{
+    border: 1px solid #1fe4dc;
+  }
+  .agree{
+    display: flex;
+    align-items: center;
+    font-size: 12px;
+    margin-top: 16px;
+    color: rgba(0, 0, 0, 0.7);
+  }
+  .to-login{
+    font-size: 14px;
+    font-weight: 400;
+    color: rgba(0, 0, 0, 0.45);
+    .lo-con{
+      display: block;
+      text-align: center;
+      color: #707070;
+      margin: 16px 0;
+      a{
+        color: #1fe4dc;
+      }
+    }
+  }
+}
+.toMail {
+  text-align: right;
+  margin: 12px 0;
+  a {
+    color: #909090;
+  }
+}
+.send-btn {
+  font-size: 14px;
+  padding: 0 10px;
+}
+
+@media screen and (max-width: 340px) {
+  .phone-select{
+    img{
+      width: 10px !important;
+      margin: 0 4px !important;
+      vertical-align: middle !important;  
+    }
+  }
+}

+ 50 - 165
mobile/src/pages/account/forget/index.vue

@@ -1,183 +1,68 @@
 <template>
   <div class="forget-layout">
-    <div class="banner">
-      <img :src="`${$cdn}images/icon/forget.png`" alt="">
-      <p>{{langLogin.pforget}}</p>
-    </div>
-    <div class="r-line"></div>
-    <div class="login-con">
-      <div class="input-con" :class="{inputActive:inputActive==='phone'}">
-        <img :src="`${$cdn}images/icon/icon-phone@2x.png`" alt="">
-        <div class="phone-select" ref="quhaoMenu">
-          <div @click="showSelect=!showSelect">
-            <span>{{codeActive[1]}}</span>
-            <img :src="`${$cdn}images/quhao-jiantou.png`" >
-          </div>
-          <ul v-show="showSelect" >
-            <li @click="selectItem(item)" v-for="(item,i) in selectCall" :key="i">
-              {{language==='en'?item[2]:item[0]}}{{item[1]}}
-            </li>
-          </ul>
-        </div>
-        <input class="guding" v-model="phone" oninput="value=value.replace(/[^\d]/g,'')" maxlength='11' @focus="inputActive='phone'" @blur="inputActive=''" type="text" :placeholder="langLogin.phone.placeholder">
-      </div>
-      <div class="code-con">
-        <div class="input-con" :class="{inputActive:inputActive==='code'}">
-          <img :src="`${$cdn}images/icon/icon-code@2x.png`" style="width:23px;" alt="">
-          <input v-model="authCode" @focus="inputActive='code'" @blur="inputActive=''" style="padding-left:6px;" type="text" oninput="value=value.replace(/[^\d]/g,'')" maxlength='6' :placeholder="langLogin.code.placeholder">
-        </div>
-        <div v-if="!jishi" class="btns" @click="getAuthCode">{{langLogin.code.txt}}</div>
-        <span class="btns" v-else>{{language==='en'?`Resend after ${interTime}s`:`${interTime}s后重新发送`}}</span>
-      </div>
-      <div class="input-con"  :class="{inputActive:inputActive==='password'}">
-        <img :src="`${$cdn}images/icon/icon-password@2x.png`" alt="">
-        <input v-model="password" @focus="inputActive='password'" @blur="inputActive=''" maxlength="16" type="password" :placeholder="langLogin.newpass.placeholder">
+    <h1 class="common-title">{{ $t('account.forgetTitle') }}</h1>
+    <div v-if="!forgetComponent">
+      <div class="forget-home-header">
+        <div class="bg"></div>
+        <p>为确认您是本人操作,</p>
+        <p>请选择验证方式完成密码重置</p>
       </div>
-      <div class="input-con"  :class="{inputActive:inputActive==='confirm'}">
-        <img :src="`${$cdn}images/icon/icon-confirm@2x.png`" alt="">
-        <input v-model="confirmpass" @focus="inputActive='confirm'" @blur="inputActive=''" maxlength="16" type="password" :placeholder="langLogin.comfirmpass.placeholder">
-      </div>
-      <div class="btns" @click="submit">{{langLogin.submit}}</div>
-      <div class="to-login">
-        <div class="lo-con">
-          {{langLogin.resigter1}}<router-link :to="{path:'/login'}">{{langLogin.resigter2}}</router-link>
-        </div>
+      <div class="forget-entry-list">
+        <router-link to="/forget?type=phoneForget">使用手机短信验证码</router-link>
+        <router-link to="/forget?type=emailForget">使用E-mail验证码</router-link>
       </div>
     </div>
+    <phoneForget v-if="forgetComponent === 'phoneForget'" />
+    <emailForget v-else-if="forgetComponent === 'emailForget'" />
   </div>
 </template>
 
 <script>
-import {mapState} from 'vuex'
-import selectCall from '../country.js'
-import { encodeStr } from '@/util'
-import { Base64 } from 'js-base64'
+import phoneForget from './components/phoneForget'
+import emailForget from './components/emailForget'
 export default {
-  computed: {
-    ...mapState({
-      language: state => state.language.current,
-      langToast: state => state.language.home.toast,
-      langLogin: state => state.language.home.home.loginAside,
-      token: state => state.user.token
-    })
+  components: {
+    phoneForget,
+    emailForget
   },
-  data () {
-    return {
-      showSelect: false,
-      selectCall,
-      codeActive: ['中国', '+86', 'China'],
-      phone: '',
-      authCode: '',
-      interTime: 60,
-      jishi: false,
-      password: '',
-      confirmpass: '',
-      inputActive: ''
-    }
-  },
-  mounted () {
-    document.addEventListener('click', (e) => {
-      if (this.$refs.quhaoMenu) {
-        if (!this.$refs.quhaoMenu.contains(e.target)) {
-          this.showSelect = false
-        }
-      }
-    })
-  },
-  methods: {
-    selectItem (item) {
-      this.showSelect = false
-      this.codeActive = item
-    },
-
-    async getAuthCode () {
-      // if (!reg.phone.test(this.phone)) {
-      //   return
-      // }
-      let res = await this.$store.dispatch('getAuthCode', {
-        phone: this.phone,
-        code: Number(this.codeActive[1].substr(1))
-      })
-      if (res) {
-        this.interl && clearInterval(this.interl)
-        this.interl = null
-        this.jishi = true
-        this.interl = setInterval(() => {
-          this.interTime--
-          if (this.interTime <= 0) {
-            this.jishi = false
-            this.interTime = 60
-            clearInterval(this.interl)
-            this.interl = null
-          }
-        }, 1000)
-      }
-    },
-    async submit () {
-      let check = value => {
-        for (let i = 0, len = value.length; i < len; i++) {
-          if (!value[i].val) {
-            return this.$toast.show('warn', (this.language === 'en' ? value[i].En : value[i].name) + this.langToast['7'])
-          }
-        }
-        return true
-      }
-      let checkStr = [
-        {
-          name: '手机',
-          En: 'Phone number',
-          val: this.phone
-        },
-        {
-          name: '验证码',
-          En: 'Verification code',
-          val: this.authCode
-        },
-        {
-          name: '密码',
-          En: 'Password',
-          val: this.password
-        },
-        {
-          name: '确认密码',
-          En: 'Password',
-          val: this.confirmpass
-        }
-      ]
-      if (!check(checkStr)) {
-        return
-      }
-      if (this.password.length < 8 || this.confirmpass.length < 8) {
-        return this.$toast.show('warn', this.langToast['31'])
-      }
-      let temp = encodeStr(Base64.encode(this.password), Base64.encode(this.confirmpass))
-
-      let params = {
-        password: temp[0],
-        phoneNum: this.phone,
-        confirmPwd: temp[1],
-        msgAuthCode: this.authCode
-      }
-      let res = await this.$http({
-        method: 'post',
-        headers: {
-          token: this.token
-        },
-        data: params,
-        url: 'sso/user/changePassword'
-      })
-      let response = res.data
-      if (response.code !== 0) {
-        return this.$toast.show('warn', this.langToast[response.code])
-      }
-      this.$toast.show('warn', this.langToast['32'], () => {
-        this.$router.push({path: '/login'})
-      })
+  computed: {
+    forgetComponent () {
+      return this.$route.query.type
     }
   }
 }
 </script>
 
 <style lang="scss" scoped>
-@import './style.scss';
+.forget-layout {
+  padding: 27px 20px 50px;
+}
+.forget-home-header {
+  text-align: center;
+  color: #909090;
+  font-size: 12px;
+  line-height: 18px;
+  margin-top: 30px;
+  .bg {
+    background: url(~@/assets/images/refactor/account/forget-img.png) no-repeat center center;
+    height: 63px;
+    width: 100%;
+    background-size: auto 62px;
+    margin-bottom: 7px;
+  }
+}
+.forget-entry-list {
+  margin-top: 28px;
+  a {
+    display: block;
+    background: #ebebeb;
+    color: #202020;
+    font-size: 14px;
+    line-height: 48px;
+    text-align: center;
+    &:first-child {
+      margin-bottom: 15px;
+    }
+  }
+}
 </style>

+ 8 - 11
mobile/src/pages/account/login/index.vue

@@ -1,27 +1,24 @@
 <template>
   <div class="account-layout">
-    <div class="banner">
-      <img :src="`${$cdn}images/icon/login.png`" alt="">
-      <p>Hi~ {{langLogin.plogin}}</p>
-    </div>
-    <div class="r-line"></div>
+    <h1 class="common-title">{{ $t('account.loginTitle') }}</h1>
     <div class="login-con">
       <div class="input-con" :class="{inputActive:inputActive==='text'}">
-        <img :src="`${$cdn}images/icon/icon-phone@2x.png`" alt="">
-        <input v-model="phone" oninput="value=value.replace(/[^\d]/g,'')" maxlength='11' @blur="inputActive=''" @focus="inputActive='text'" type="text" :placeholder="langLogin.phone.placeholder">
+        <!-- <img :src="`${$cdn}images/icon/icon-phone@2x.png`" alt=""> -->
+        <input v-model="phone" oninput="value=value" @blur="inputActive=''" @focus="inputActive='text'" type="text" :placeholder="$t('account.accountPlaceholder')">
       </div>
       <div class="input-con"  :class="{inputActive:inputActive==='password'}">
-        <img :src="`${$cdn}images/icon/icon-password@2x.png`" alt="">
-        <input v-model="password" @focus="inputActive='password'" @blur="inputActive=''" maxlength='16' type="password" :placeholder="langLogin.password.placeholder">
+        <!-- <img :src="`${$cdn}images/icon/icon-password@2x.png`" alt=""> -->
+        <input v-model="password" @focus="inputActive='password'" @blur="inputActive=''" maxlength='16' type="password" :placeholder="$t('account.passwordPlaceholder')">
       </div>
       <div class="forget">
-        <router-link :to="{path:'/forget'}">{{langLogin.forget}}</router-link>
+        <!-- <router-link :to="{path:'/forget'}">{{langLogin.forget}}</router-link> -->
+        <span></span>
         <router-link :to="{path:'/codeLogin'}">{{langLogin.codeLogin}}</router-link>
       </div>
       <div class="btns" @click="login">{{langLogin.login}}</div>
       <div class="to-register">
         <div class="re-con">
-          {{langLogin.loginsub1}}<router-link :to="{path:'/register'}">{{langLogin.loginsub2}}</router-link>
+          <router-link :to="{path:'/forget'}">{{$t('account.forgetPassword')}}</router-link><router-link :to="{path:'/register'}">{{$t('account.registerAccount')}}</router-link>
         </div>
       </div>
     </div>

+ 28 - 31
mobile/src/pages/account/login/style.scss

@@ -1,7 +1,7 @@
 input{
-  border: 0;
+  border: none;
   outline: none;
-  height: 48px;
+  height: 46px;
   padding-right: 16px;
   padding-left: 12px;
   font-size: 14px;
@@ -16,7 +16,7 @@ input{
   outline: 0;
   cursor: pointer;
   margin: 16px 0;
-  background-image: linear-gradient(-135deg, #1fe4dc 0%, #1fc3dc 100%);
+  background: #1FE4DC;
   height: 48px;
   line-height: 48px;
   text-align: center;
@@ -27,36 +27,16 @@ input{
 }
 .account-layout{
   width: 100%;
-  .banner{
-    position: relative;
-    padding-top: 30px;
-    img{
-      width: 100%;
-    }
-    p{
-      top: 20%;
-      left: 9%;
-      font-size: 18px;
-      color: #2d2d2d;
-      font-weight: bold;
-      position: absolute;
-    }
-  }
-  .r-line{
-    width: calc(100% - 32px);
-    margin: 0 auto;
-    background: #D9D9D9;
-    height: 1px;
-  }
+  padding: 27px 20px 50px;
   .login-con{
     width: 100%;
-    padding: 0 16px 0;
+    margin-top: 30px;
     background-color: #fff;
     .input-con{
       position: relative;
-      border: 1px solid #D9D9D9;
+      border: 1px solid #EBEBEB;
       border-radius: 2px;
-      margin-top: 16px;
+      margin-top: 15px;
       display: flex;
       align-items: center;
       img{
@@ -64,7 +44,6 @@ input{
         width: 18px;
         margin: 0 16px;
       }
-      
     }
     .inputActive{
       border: 1px solid #1fe4dc;
@@ -72,7 +51,7 @@ input{
     .forget{
       display: flex;
       justify-content: space-between;
-      margin: 16px 0;
+      margin: 12px 0;
       a{
         font-size: 14px;
         color: rgba(0, 0, 0, 0.45);
@@ -87,10 +66,28 @@ input{
         display: block;
         text-align: center;
         color: #707070;
-        margin: 16px 0;
+        margin: 12px 0 0;
         a{
           font-size: 14px;
-          color: #1fe4dc;
+          color:#202020;
+          font-weight: normal;
+          line-height: 20px;
+          &:first-of-type {
+            padding-right: 20px;
+            margin-right: 20px;
+            position: relative;
+            &::after {
+              content: '';
+              display: block;
+              width: 1px;
+              height: 12px;
+              background-color: #202020;
+              position: absolute;
+              right: 0;
+              top: 50%;
+              margin-top: -6px;
+            }
+          }
         }
       }
     }

+ 190 - 0
mobile/src/pages/account/mailRegister/index.vue

@@ -0,0 +1,190 @@
+<template>
+  <div class="register-layout">
+    <h1 class="common-title">{{ $t('account.registerTitle') }}</h1>
+    <div class="login-con">
+      <div class="input-con" :class="{inputActive:inputActive==='phone'}">
+        <input class="guding" oninput="value=value" v-model="phone" @focus="inputActive='phone'" @blur="inputActive=''" type="text" :placeholder="$t('account.accountMailPlaceholder')">
+      </div>
+      <div class="code-con">
+        <div class="input-con" :class="{inputActive:inputActive==='code'}">
+          <input v-model="authCode" @focus="inputActive='code'" @blur="inputActive=''" oninput="value=value.replace(/[^\d]/g,'')" maxlength='6' style="padding-left:6px;" type="text" :placeholder="$t('account.mailCodePlaceholder')">
+          <div v-if="!jishi" class="send-btn" @click="getAuthCode">{{langLogin.code.txt}}</div>
+          <span class="send-btn" v-else>{{language==='en'?`Resend after ${interTime}s`:`${interTime}s后重新发送`}}</span>
+        </div>
+      </div>
+      <div class="input-con"  :class="{inputActive:inputActive==='password'}">
+        <input v-model="password" @focus="inputActive='password'" @blur="inputActive=''" maxlength="16" type="password" :placeholder="langLogin.newpass.placeholder">
+      </div>
+      <div class="input-con"  :class="{inputActive:inputActive==='confirm'}">
+        <input v-model="confirmPass" @focus="inputActive='confirm'" @blur="inputActive=''" maxlength="16" type="password" :placeholder="langLogin.comfirmpass.placeholder">
+      </div>
+      <div class="toMail">
+        <router-link to="/register">手机号注册</router-link>
+      </div>
+      <div class="agree">
+        <label class="check-con" @click="isAgree=!isAgree">
+          <span class="check-box">
+            <span class="checkbox-inner" :class="{'checkbox-inner-checked':isAgree}"></span>
+          </span>
+          <span v-html='langLogin.agree'></span><span style="color:#1fe4dc;text-decoration: underline;" @click="$router.push({name:'useimg',params:{id:2,type:0,name: 'agreement'}})" v-html='langLogin.cluse'></span>
+        </label>
+      </div>
+      <div class="btns" :class="{disAgree:!isAgree}" @click="submit">{{ $t('account.register') }}</div>
+      <div class="to-login">
+        <div class="lo-con">
+          {{langLogin.resigter1}}<router-link :to="{path:'/login'}">{{langLogin.resigter2}}</router-link>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import selectCall from '../country.js'
+import {mapState} from 'vuex'
+import { encodeStr } from '@/util'
+import { Base64 } from 'js-base64'
+export default {
+  computed: {
+    ...mapState({
+      language: state => state.language.current,
+      langToast: state => state.language.home.toast,
+      langLogin: state => state.language.home.home.loginAside
+    })
+  },
+  data () {
+    return {
+      showSelect: false,
+      codeActive: ['中国', '+86', 'China'],
+      nickname: '',
+      phone: '',
+      authCode: '',
+      inputActive: '',
+      password: '',
+      confirmPass: '',
+      interTime: 60,
+      jishi: false,
+      interl: null,
+      selectCall,
+      isAgree: true
+    }
+  },
+  mounted () {
+    document.addEventListener('click', (e) => {
+      if (this.$refs.quhaoMenu) {
+        if (!this.$refs.quhaoMenu.contains(e.target)) {
+          this.showSelect = false
+        }
+      }
+    })
+  },
+  methods: {
+
+    selectItem (item) {
+      this.showSelect = false
+      this.codeActive = item
+    },
+    async getAuthCode () {
+      // if (!reg.phone.test(this.phone)) {
+      //   return
+      // }
+
+      let res = await this.$store.dispatch('getAuthCode', {
+        phone: this.phone,
+        code: Number(this.codeActive[1].substr(1)),
+        type: 'resigter'
+      })
+      if (res) {
+        this.interl && clearInterval(this.interl)
+        this.interl = null
+        this.jishi = true
+        this.interl = setInterval(() => {
+          this.interTime--
+          if (this.interTime <= 0) {
+            this.jishi = false
+            this.interTime = 60
+            clearInterval(this.interl)
+            this.interl = null
+          }
+        }, 1000)
+      }
+    },
+    async submit () {
+      if (!this.isAgree) {
+        return
+      }
+
+      let check = value => {
+        for (let i = 0, len = value.length; i < len; i++) {
+          if (!value[i].val) {
+            return this.$toast.show('warn', (this.language === 'en' ? value[i].En : value[i].name) + this.langToast['7'])
+          }
+        }
+        return true
+      }
+      let checkStr = [
+        {
+          name: '昵称',
+          En: 'User name',
+          val: this.nickname
+        },
+        {
+          name: '手机',
+          En: 'Phone number',
+          val: this.phone
+        },
+        {
+          name: '验证码',
+          En: 'Verification code',
+          val: this.authCode
+        },
+        {
+          name: '密码',
+          En: 'Password',
+          val: this.password
+        },
+        {
+          name: '确认密码',
+          En: 'Password',
+          val: this.confirmPass
+        }
+      ]
+      if (!check(checkStr)) {
+        return
+      }
+
+      if (this.password.length < 8 || this.confirmPass.length < 8) {
+        return this.$toast.show('warn', this.langToast['31'])
+      }
+
+      let country = Number(this.codeActive[1].substr(1))
+      let temp = encodeStr(Base64.encode(this.password), Base64.encode(this.confirmPass))
+
+      let params = {
+        password: temp[0],
+        phoneNum: this.phone,
+        msgAuthCode: this.authCode,
+        nickName: this.nickname,
+        country,
+        confirmPwd: temp[1]
+      }
+      let res = await this.$http({
+        method: 'post',
+        data: params,
+        url: '/sso/user/register'
+      })
+      let response = res.data
+      if (response.code !== 0) {
+        return this.$toast.show('warn', this.langToast[response.code])
+      }
+      this.$toast.show('warn', this.langToast['23'], () => {
+        this.$router.push({path: '/login'})
+      })
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+@import './style.scss';
+</style>

+ 62 - 48
mobile/src/pages/account/forget/style.scss

@@ -16,7 +16,7 @@ input[type='password']{
   outline: 0;
   cursor: pointer;
   margin: 16px 0;
-  background-image: linear-gradient(-135deg, #1fe4dc 0%, #1fc3dc 100%);
+  background-color: #1FE4DC;
   height: 48px;
   line-height: 48px;
   text-align: center;
@@ -25,17 +25,31 @@ input[type='password']{
   font-size: 16px;
   color: rgba(0, 0, 0, 0.7);
 }
+.disAgree{
+  background-image: none;
+  background-color: #e2e2e2;
+}
 .phone-select{
   &>div{
     height: 18px;
-    border-right: 1px solid #f1f1f1;
+    border-right: 1px solid #909090;
     display: flex;
     flex-wrap: nowrap;
     align-items: center;
+    position: relative;
+    padding: 0 20px 0 10px;
     &>span{
       display: inline-block;
       vertical-align: middle;
     }
+    .sanjiao {
+      border: 4px solid #909090;
+      border-left-color: transparent;
+      border-right-color: transparent;
+      border-bottom: none;
+      position: absolute;
+      right: 10px;
+    }
   }
   img{
     width: 10px!important;
@@ -47,8 +61,8 @@ input[type='password']{
     top: 0;
     left: 0;
     background: #fff;
-    min-width: 230px;
-    height: 220px;
+    min-width: 200px;
+    height: 230px;
     padding: 0 10px;
     overflow: auto;
     transition: ease 0.3s all;
@@ -70,47 +84,19 @@ input[type='password']{
 .guding{
   padding-right: 0!important;
 }
-.forget-layout{
+.register-layout{
   width: 100%;
-  .banner{
-    position: relative;
-    padding-top: 30px;
-    img{
-      width: 100%;
-    }
-    p{
-      top: 14%;
-      right: 13%;
-      font-size: 18px;
-      color: #2d2d2d;
-      font-weight: bold;
-      position: absolute;
-    }
-  }
-  $padd:16px;
-  .r-line{
-    width: calc(100% - 32px);
-    margin: 0 auto;
-    background: #D9D9D9;
-    height: 1px;
-  }
+  padding: 27px 20px 50px;
   .login-con{
     width: 100%;
-    padding: 0 $padd 0;
     background-color: #fff;
     .code-con{
       display: flex;
       align-items: center;
       justify-content: space-between;
       .input-con{
-        width: 55%;
-        input{
-          width: 100%;
-        }
-      }
-      .btns{
-        margin: 16px 0 0 10px;
-        flex: 1;
+        width: 100%;
+        
       }
     }
     .input-con{
@@ -129,19 +115,47 @@ input[type='password']{
     .inputActive{
       border: 1px solid #1fe4dc;
     }
-  }
-  .to-login{
-    font-size: 14px;
-    font-weight: bold;
-    color: rgba(0, 0, 0, 0.45);
-    .lo-con{
-      display: block;
-      text-align: center;
-      color: #707070;
-      margin: 16px 0;
-      a{
-        color: #1fe4dc;
+    .agree{
+      display: flex;
+      align-items: center;
+      font-size: 12px;
+      margin-top: 16px;
+      color: rgba(0, 0, 0, 0.7);
+    }
+    .to-login{
+      font-size: 14px;
+      font-weight: 400;
+      color: rgba(0, 0, 0, 0.45);
+      .lo-con{
+        display: block;
+        text-align: center;
+        color: #707070;
+        margin: 16px 0;
+        a{
+          color: #1fe4dc;
+        }
       }
     }
   }
+  .toMail {
+    text-align: right;
+    margin: 12px 0;
+    a {
+      color: #909090;
+    }
+  }
+}
+.send-btn {
+  font-size: 14px;
+  padding: 0 10px;
+}
+
+@media screen and (max-width: 340px) {
+  .phone-select{
+    img{
+      width: 10px !important;
+      margin: 0 4px !important;
+      vertical-align: middle !important;  
+    }
+  }
 }

+ 0 - 183
mobile/src/pages/account/manage/confirm/index.vue

@@ -1,183 +0,0 @@
-<template>
-  <div class="confirm-layout">
-    <div class="time-line">
-      <div class="line"></div>
-      <div class="auth">
-        <img :src="`${$cdn}images/hasLogin.png`" alt="" class="timeline-icon">
-        <div class="timeline-text">登录信息</div>
-      </div>
-      <div class="shipping">
-        <img :src="`${$cdn}images/spot.png`" alt="" class="timeline-icon">
-        <div class="timeline-text">配送信息</div>
-      </div>
-      <div class="payment">
-        <img :src="`${$cdn}images/ic_schedule_default_mb@2x.png`" alt="" class="timeline-icon">
-        <div class="timeline-text">支付信息</div>
-        </div>
-      <div class="review">
-        <img :src="`${$cdn}images/ic_schedule_default_mb@2x.png`" alt="" class="timeline-icon">
-        <div class="timeline-text">订单提交</div>
-      </div>
-    </div>
-    <div class="box-con">
-      <div class="bc-title">收货地址</div>
-      <div class="bc-item " :class="{'address-item':address.shipName}"  v-if="isShowAddress">
-        <div class="bc-ct" v-if="address.shipName">
-          <div class="bc-contact">
-            {{address.shipName}}
-            <div>{{address.shipMobile}}</div>
-          </div>
-          <div class="bc-locotion">
-            {{`${address.shipAreaPath}${address.shipAddress}`}}
-          </div>
-        </div>
-        <div class="noaddress" v-else>
-          <p>暂无收货地址</p>
-        </div>
-        <div class="bc-edit" @click="isShowAddress=false">编辑</div>
-      </div>
-      <div class="address-con" v-else>
-        <citySelect :address='address' :token="token" @closeSelect="data=>{isShowAddress=data}" />
-      </div>
-    </div>
-    <div class="box-con">
-      <div class="bc-title">物流方式</div>
-      <div class="bc-item  express-item">
-        <div class="item-method">顺丰速运</div>
-        <div class="item-time">标准配送</div>
-      </div>
-    </div>
-    <div class="box-con">
-      <div class="bc-title">发票</div>
-      <div class="invoice-con" :class="{'invoice-focus':selected}">
-        <div class="invoice-select" @click="selected=!selected">
-          <div class="select-txt">{{selectedTxt}}</div>
-          <i class="iconfont icon-xia"></i>
-        </div>
-        <ul class="invoice-item" :class="{'invoice-active':selected}">
-          <li v-for="(item,i) in invoiceType" :key="i" @click="handleItem(item)">{{item.name}}</li>
-        </ul>
-        <cinvoices v-if="selectedId!==1" :invoice='invoice2' :selectedId='selectedId' :invoicet="invoice3" @showInvoice="data=>{showinvoice=data}" :token="token" @closeInvoice="data=>{isShowInvoice=data}"/>
-      </div>
-    </div>
-    <div class="btn-confirm" @click="next()">下一步</div>
-  </div>
-</template>
-
-<script>
-import { mapState } from 'vuex'
-import citySelect from '@/components/citySelect'
-import cinvoices from '@/components/cinvoices'
-var cloneObj = function (obj) {
-  var newObj = {}
-  if (obj instanceof Array) {
-    newObj = []
-  }
-  for (var key in obj) {
-    var val = obj[key] || ''
-    newObj[key] = typeof val === 'object' ? cloneObj(val) : val
-  }
-  return newObj
-}
-
-export default {
-  components: {
-    citySelect,
-    cinvoices,
-    showinvoice: true
-  },
-  computed: {
-    ...mapState({
-      token: state => state.user.token,
-      invoice2: state => {
-        let type = Object.prototype.toString.call(state.user.invoice2)
-        if (type === '[object Object]') {
-          return state.user.invoice2
-        }
-        let condition = state.user.invoice2 && state.user.invoice2 !== 'null' && type !== '[object Array]'
-        return (condition ? JSON.parse(state.user.invoice2) : {})
-      },
-      invoice3: state => {
-        let type = Object.prototype.toString.call(state.user.invoice3)
-        if (type === '[object Object]') {
-          return state.user.invoice3
-        }
-        let condition = state.user.invoice3 && state.user.invoice3 !== 'null' && type !== '[object Array]'
-
-        return (condition ? JSON.parse(state.user.invoice3) : {})
-      },
-      payinfo: state => {
-        let type = Object.prototype.toString.call(state.user.payinfo)
-        if (type === '[object Object]') {
-          return state.user.payinfo
-        }
-        let condition = state.user.payinfo && state.user.payinfo !== 'null' && type !== '[object Array]'
-        return condition ? JSON.parse(state.user.payinfo) : {}
-      },
-      address: state => cloneObj(state.user.address) || {}
-    })
-  },
-  data () {
-    let invoiceType = [{
-      id: 1,
-      name: '不需要发票'
-    }, {
-      id: 2,
-      name: '增值税普票(电子发票)'
-    }, {
-      id: 3,
-      name: '增值税专用发票'
-    }]
-    return {
-      invoiceType,
-      selected: false,
-      selectedTxt: '不需要发票',
-      selectedId: 1,
-      isShowAddress: true,
-      showinvoice: true
-    }
-  },
-  methods: {
-    handleItem (item) {
-      this.selectedTxt = item.name
-      this.selectedId = item.id
-      this.selected = false
-    },
-    next () {
-      if (!this.address.shipName) {
-        return this.$toast.show('warn', '请先填写收货地址')
-      }
-      if (!this.isShowAddress) {
-        return this.$toast.show('warn', '请先保存收货信息')
-      }
-      if (!this.showinvoice && this.selectedId !== 1) {
-        return this.$toast.show('warn', '请先保存发票信息')
-      }
-
-      let temp = cloneObj(this.payinfo)
-      let invoice = this.selectedId === 2 ? this.invoice2 : this.selectedId === 3 ? this.invoice3 : null
-      temp['invoice'] = invoice
-      temp['receiver'] = this.address
-      temp['selectedId'] = this.selectedId
-      temp['selectedTxt'] = this.selectedTxt
-
-      this.$store.commit('PAYINFO', temp)
-      this.$router.push({path: '/paytype'})
-    }
-  },
-  mounted () {
-    this.selectedId = this.payinfo.selectedId ? this.payinfo.selectedId : 1
-    this.selectedTxt = this.payinfo.selectedTxt ? this.payinfo.selectedTxt : '不需要发票'
-
-    if (this.address && Object.keys(this.address).length > 0) return
-    this.$store.dispatch('getInfo', {
-      url: '/user/getReceiverInfo',
-      name: 'address'
-    })
-  }
-}
-</script>
-
-<style lang="scss" scoped>
-@import './style.scss';
-</style>

+ 2 - 2
mobile/src/pages/account/manage/openInvoice/index.vue

@@ -89,7 +89,7 @@ export default {
       overflow-wrap: break-word;
       .bc-contact{
         font-size: 12px;
-        color: rgba(0,0,0,.7);
+        color: #202020;
         line-height: 18px;
 
       }
@@ -103,7 +103,7 @@ export default {
         top: 16px;
         right: 16px;
         font-size: 12px;
-        color: rgba(0,0,0,.7);
+        color: #202020;
         line-height: 18px;
       }
     }

+ 2 - 2
mobile/src/pages/account/manage/orderInvoice/index.vue

@@ -94,7 +94,7 @@ export default {
       overflow-wrap: break-word;
       .bc-contact{
         font-size: 12px;
-        color: rgba(0,0,0,.7);
+        color: #202020;
         line-height: 18px;
 
       }
@@ -108,7 +108,7 @@ export default {
         top: 16px;
         right: 16px;
         font-size: 12px;
-        color: rgba(0,0,0,.7);
+        color: #202020;
         line-height: 18px;
       }
     }

+ 1 - 1
mobile/src/pages/account/manage/payselect/style.scss

@@ -32,7 +32,7 @@
     }
     span{
       font-size: 12px;
-      color: rgba(0,0,0,.7);
+      color: #202020;
       float: left;
       font-weight: 600;
     }

+ 0 - 86
mobile/src/pages/account/manage/paytype/index.vue

@@ -1,86 +0,0 @@
-<template>
-  <div class="paytype-layout">
-    <div class="time-line">
-      <div class="line"></div>
-      <div class="auth">
-        <img :src="`${$cdn}images/hasLogin.png`" alt="" class="timeline-icon">
-        <div class="timeline-text">登录信息</div>
-      </div>
-      <div class="shipping">
-        <img :src="`${$cdn}images/hasLogin.png`" alt="" class="timeline-icon">
-        <div class="timeline-text">配送信息</div>
-      </div>
-      <div class="payment">
-        <img :src="`${$cdn}images/spot.png`" alt="" class="timeline-icon">
-        <div class="timeline-text">支付信息</div>
-        </div>
-      <div class="review">
-        <img :src="`${$cdn}images/ic_schedule_default_mb@2x.png`" alt="" class="timeline-icon">
-        <div class="timeline-text">订单提交</div>
-      </div>
-    </div>
-    <div class="paytype">
-      <div class="pay-header">
-        支付方式
-      </div>
-      <div class="pay-item" v-for="(item,i) in data" :key="i" @click="goPay(item)">
-        <span>{{item.name}}</span>
-        <img :src="item.img" alt="">
-      </div>
-    </div>
-    <div class="btn-back" @click="$router.push({path:'/confirm'})">返回</div>
-  </div>
-</template>
-
-<script>
-import { mapState } from 'vuex'
-import browser from '@/util/browser'
-
-export default {
-  computed: {
-    ...mapState({
-      payinfo: state => {
-        let type = Object.prototype.toString.call(state.user.payinfo)
-        if (type === '[object Object]') {
-          return state.user.payinfo
-        }
-        let condition = state.user.payinfo && state.user.payinfo !== 'null' && type !== '[object Array]'
-        return condition ? JSON.parse(state.user.payinfo) : {}
-      }
-    })
-  },
-  data () {
-    let data = [{
-      name: '支付宝',
-      img: this.$cdn + `images/ic_alipay_mb@2x.png`,
-      id: 1
-    }, {
-      id: 0,
-      name: '微信支付',
-      img: this.$cdn + `images/ic_weixin@2x.png`
-    }]
-    let weichatdata = [{
-      id: 0,
-      name: '微信支付',
-      img: this.$cdn + `images/ic_weixin@2x.png`
-    }]
-    return {
-      data: browser.weixin ? weichatdata : data
-    }
-  },
-  methods: {
-    goPay (item) {
-      let temp = this.payinfo
-      temp['payType'] = item.id
-      temp['payTypeName'] = item.name
-
-      this.$store.commit('PAYINFO', temp)
-      this.$router.push({path: '/submit'})
-    }
-  }
-}
-</script>
-
-<style lang="scss" scoped>
-@import './style.scss';
-</style>

+ 0 - 91
mobile/src/pages/account/manage/paytype/style.scss

@@ -1,91 +0,0 @@
-.paytype-layout{
-  .time-line{
-    height: 46px;
-    padding-top: 12px;
-    background: #f8f8f8;
-    margin: 16px 60px;
-    position: relative;
-    box-sizing: content-box;
-    .line{
-      border-top: 2px solid #e6e6e6;
-    }
-    .auth, .payment, .review, .shipping{
-      width: 66px;
-      text-align: center;
-      position: absolute;
-      top: 0;
-      margin-left: -33px;
-      .timeline-text{
-        margin-top: 4px;
-        font-size: 12px;
-        color: rgba(0,0,0,.7);
-        line-height: 18px;
-        font-weight: 600;
-      }
-      img{
-        width: 24px;
-        vertical-align: middle;
-        border-style: none;
-      }
-    }
-    .auth{
-      left: 0;
-    }
-    .payment{
-      left: 66.67%;
-    }
-    .review{
-      left: 100%;
-    }
-    .shipping{
-      left: 33.33%;
-    }
-  }
-  .paytype{
-    background: #fff;
-    padding: 16px 16px 24px;
-    margin: 8px 0;
-    .pay-header{
-      color: rgba(0,0,0,.7);
-      line-height: 12px;
-      font-weight: 600;
-      margin-bottom: 8px;
-    }
-  }
-  .pay-item{
-    height: 56px;
-    padding: 17px 1px;
-    border-bottom: 1px solid #e6e6e6;
-    background-position: 100%;
-    background-repeat: no-repeat;
-    background-image: url(https://4dscene.4dage.com/new4dkk/mobile/images/ic_right@2x.png);
-    background-size: 16px;
-    display: flex;
-    justify-content: space-between;
-    align-items: center;
-    span{
-      font-size: 12px;
-      color: rgba(0,0,0,.7);
-      float: left;
-      font-weight: 600;
-    }
-    img{
-      width: 120px;
-      float: right;
-      margin-right: 32px;
-     
-    }
-  }
-  .btn-back{
-    height: 48px;
-    display: inline-block;
-    line-height: 48px;
-    text-align: center;
-    font-size: 14px;
-    color: #1fe4dc;
-    border-radius: 2px;
-    width: 100%;
-    background-color: #fff;
-    margin: 16px 0 30px;
-  }
-}

+ 1 - 1
mobile/src/pages/account/manage/vieworder/style.scss

@@ -2,7 +2,7 @@
   height: 48px;
   display: inline-block;
   line-height: 48px;
-  color: rgba(0,0,0,.7);
+  color: #202020;
   border-radius: 2px;
   width: 100%;
   background-color: #1fe4dc;

+ 9 - 14
mobile/src/pages/account/register/index.vue

@@ -1,21 +1,16 @@
 <template>
   <div class="register-layout">
-    <div class="banner">
-      <img :src="`${$cdn}images/icon/register.png`" alt="">
-      <p>{{langLogin.pregister}}</p>
-    </div>
-    <div class="r-line"></div>
+    <h1 class="common-title">{{ $t('account.registerTitle') }}</h1>
     <div class="login-con">
       <div class="input-con" :class="{inputActive:inputActive==='nickname'}">
-        <img :src="`${$cdn}images/icon/icon-user@2x.png`" alt="">
         <input v-model="nickname" @focus="inputActive='nickname'" @blur="inputActive=''" type="text" :placeholder="langLogin.userName.placeholder">
       </div>
       <div class="input-con" :class="{inputActive:inputActive==='phone'}">
-        <img :src="`${$cdn}images/icon/icon-phone@2x.png`" alt="">
         <div class="phone-select" ref="quhaoMenu">
           <div @click="showSelect=!showSelect">
             <span>{{codeActive[1]}}</span>
-            <img :src="`${$cdn}images/quhao-jiantou.png`" >
+            (<span>{{codeActive[0]}}</span>)
+            <div class="sanjiao"></div>
           </div>
           <ul v-show="showSelect" >
             <li @click="selectItem(item)" v-for="(item,i) in selectCall" :key="i">
@@ -27,20 +22,20 @@
       </div>
       <div class="code-con">
         <div class="input-con" :class="{inputActive:inputActive==='code'}">
-          <img :src="`${$cdn}images/icon/icon-code@2x.png`" style="width:23px;" alt="">
           <input v-model="authCode" @focus="inputActive='code'" @blur="inputActive=''" oninput="value=value.replace(/[^\d]/g,'')" maxlength='6' style="padding-left:6px;" type="text" :placeholder="langLogin.code.placeholder">
+          <div v-if="!jishi" class="send-btn" @click="getAuthCode">{{langLogin.code.txt}}</div>
+          <span class="send-btn" v-else>{{language==='en'?`Resend after ${interTime}s`:`${interTime}s后重新发送`}}</span>
         </div>
-        <div v-if="!jishi" class="btns" @click="getAuthCode">{{langLogin.code.txt}}</div>
-        <span class="btns" v-else>{{language==='en'?`Resend after ${interTime}s`:`${interTime}s后重新发送`}}</span>
       </div>
       <div class="input-con"  :class="{inputActive:inputActive==='password'}">
-        <img :src="`${$cdn}images/icon/icon-password@2x.png`" alt="">
         <input v-model="password" @focus="inputActive='password'" @blur="inputActive=''" maxlength="16" type="password" :placeholder="langLogin.newpass.placeholder">
       </div>
       <div class="input-con"  :class="{inputActive:inputActive==='confirm'}">
-        <img :src="`${$cdn}images/icon/icon-confirm@2x.png`" alt="">
         <input v-model="confirmPass" @focus="inputActive='confirm'" @blur="inputActive=''" maxlength="16" type="password" :placeholder="langLogin.comfirmpass.placeholder">
       </div>
+      <div class="toMail">
+        <router-link to="/mailRegister">邮箱注册</router-link>
+      </div>
       <div class="agree">
         <label class="check-con" @click="isAgree=!isAgree">
           <span class="check-box">
@@ -49,7 +44,7 @@
           <span v-html='langLogin.agree'></span><span style="color:#1fe4dc;text-decoration: underline;" @click="$router.push({name:'useimg',params:{id:2,type:0,name: 'agreement'}})" v-html='langLogin.cluse'></span>
         </label>
       </div>
-      <div class="btns" :class="{disAgree:!isAgree}" @click="submit">{{langLogin.submit}}</div>
+      <div class="btns" :class="{disAgree:!isAgree}" @click="submit">{{ $t('account.register') }}</div>
       <div class="to-login">
         <div class="lo-con">
           {{langLogin.resigter1}}<router-link :to="{path:'/login'}">{{langLogin.resigter2}}</router-link>

+ 27 - 34
mobile/src/pages/account/register/style.scss

@@ -16,7 +16,7 @@ input[type='password']{
   outline: 0;
   cursor: pointer;
   margin: 16px 0;
-  background-image: linear-gradient(-135deg, #1fe4dc 0%, #1fc3dc 100%);
+  background-color: #1FE4DC;
   height: 48px;
   line-height: 48px;
   text-align: center;
@@ -32,14 +32,24 @@ input[type='password']{
 .phone-select{
   &>div{
     height: 18px;
-    border-right: 1px solid #f1f1f1;
+    border-right: 1px solid #909090;
     display: flex;
     flex-wrap: nowrap;
     align-items: center;
+    position: relative;
+    padding: 0 20px 0 10px;
     &>span{
       display: inline-block;
       vertical-align: middle;
     }
+    .sanjiao {
+      border: 4px solid #909090;
+      border-left-color: transparent;
+      border-right-color: transparent;
+      border-bottom: none;
+      position: absolute;
+      right: 10px;
+    }
   }
   img{
     width: 10px!important;
@@ -76,45 +86,17 @@ input[type='password']{
 }
 .register-layout{
   width: 100%;
-  .banner{
-    position: relative;
-    padding-top: 30px;
-    img{
-      width: 100%;
-    }
-    p{
-      top: 18%;
-      right: 9%;
-      font-size: 18px;
-      color: #2d2d2d;
-      font-weight: bold;
-      position: absolute;
-    }
-  }
-  $padd:16px;
-  .r-line{
-    width: calc(100% - 32px);
-    margin: 0 auto;
-    background: #D9D9D9;
-    height: 1px;
-  }
+  padding: 27px 20px 50px;
   .login-con{
     width: 100%;
-    padding: 0 $padd 0;
     background-color: #fff;
     .code-con{
       display: flex;
       align-items: center;
       justify-content: space-between;
       .input-con{
-        width: 55%;
-        input{
-          width: 100%;
-        }
-      }
-      .btns{
-        margin: 16px 0 0 10px;
-        flex: 1;
+        width: 100%;
+        
       }
     }
     .input-con{
@@ -142,7 +124,7 @@ input[type='password']{
     }
     .to-login{
       font-size: 14px;
-      font-weight: bold;
+      font-weight: 400;
       color: rgba(0, 0, 0, 0.45);
       .lo-con{
         display: block;
@@ -155,6 +137,17 @@ input[type='password']{
       }
     }
   }
+  .toMail {
+    text-align: right;
+    margin: 12px 0;
+    a {
+      color: #909090;
+    }
+  }
+}
+.send-btn {
+  font-size: 14px;
+  padding: 0 10px;
 }
 
 @media screen and (max-width: 340px) {

+ 3 - 1
mobile/src/pages/coreProduct/index.vue

@@ -1,7 +1,7 @@
 <template>
   <div class="coreProduct">
     <div class="banner">
-      {{ $t('coreProduct.bannerTitle') }}
+      <!-- {{ $t('coreProduct.bannerTitle') }} -->
     </div>
     <ul class="desc-video">
       <li v-for="item in videoArr" :key="item.name">
@@ -83,6 +83,8 @@ export default {
     color: #202020;
     font-weight: bold;
     background: #D4D4D4;
+    background: url(~@/assets/images/refactor/coreProduct/banner.png);
+    background-size: cover;
   }
   .desc-video {
     padding: 27px 20px;

+ 25 - 6
mobile/src/pages/home/components/plate3.vue

@@ -7,8 +7,10 @@
         v-for="(item,i) in list"
         :key="i"
       >
-        <img :src="item.img" alt="">
-        <h2>{{ item.title }}</h2>
+      <div @click="toLink(item)">
+        <img  :src="item.bgImg" alt="">
+        <h2>{{ item.text }}</h2>
+      </div>
       </swiper-slide>
     </swiper>
   </div>
@@ -20,12 +22,24 @@ export default {
     return {
       list: [
         {
-          img: require('@/assets/images/refactor/home/plate03-1.png'),
-          title: '雍正故宫'
+          text: '雍正故宫',
+          bgImg: require('@/assets/images/refactor/home/4case_01@2x.png'),
+          link: 'https://www.4dkankan.com/showPC.html?m=JPoqsQXL'
         },
         {
-          img: require('@/assets/images/refactor/home/plate03-2.png'),
-          title: '雍正故宫'
+          text: '小米有品',
+          bgImg: require('@/assets/images/refactor/home/4case_02@2x.png'),
+          link: 'https://www.4dkankan.com/showProPC.html?m=5p1fFyLxv'
+        },
+        {
+          text: '华发依山郡',
+          bgImg: require('@/assets/images/refactor/home/4case_03@2x.png'),
+          link: 'https://www.4dkankan.com/spc.html?m=JBx2hetpp'
+        },
+        {
+          text: '万豪酒店',
+          bgImg: require('@/assets/images/refactor/home/4case_04@2x.png'),
+          link: 'https://www.4dkankan.com/showPC.html?m=PoCGXVFP'
         }
       ],
       swiperOption: {
@@ -34,6 +48,11 @@ export default {
         spaceBetween: 20
       }
     }
+  },
+  methods: {
+    toLink ({link}) {
+      window.open(link)
+    }
   }
 }
 </script>

+ 6 - 1
mobile/src/pages/home/components/plate4.vue

@@ -2,7 +2,7 @@
   <div class="plate04">
     <h1 class="common-title">核心技术</h1>
     <ul class="plate04-list">
-      <li v-for="(item, index) in list" :key="index">
+      <li v-for="(item, index) in list" :key="index" @click="toLink(item)">
         <div class="item-left">
           <img :src="item.img" />
         </div>
@@ -48,6 +48,11 @@ export default {
         }
       ]
     }
+  },
+  methods: {
+    toLink ({id}) {
+      window.open(`/location?id=${id}`)
+    }
   }
 }
 </script>

+ 27 - 10
mobile/src/pages/home/components/plate5.vue

@@ -1,21 +1,25 @@
 <template>
   <div class="plate05">
-    <h1 class="common-title">新闻动态</h1>
+    <h1 class="common-title">新闻动态
+      <span class="more">更多</span>
+    </h1>
     <swiper class="swiper-wrapper" :options="swiperOption">
       <swiper-slide
         class="swiper-slide"
         v-for="(item,i) in newsData"
         :key="i"
       >
-        <img :src="item.img" alt="">
-        <div class="news-info">
-          <div class="plate02-desc">
-            <p class="publish-time">{{ item.time }}</p>
-            <h3 >{{ item.title }}</h3>
-            <div class="news-content">{{ item.text }}
-              <div class="fade-bg "></div>
+        <div @click="toLink(item)">
+          <div class="img" :style="{'background-image': `url(${item.img})`}"></div>
+          <div class="news-info">
+            <div class="plate02-desc">
+              <p class="publish-time">{{ item.time }}</p>
+              <h3 >{{ item.title }}</h3>
+              <div class="news-content">{{ item.text }}
+                <div class="fade-bg "></div>
+              </div>
+              <p class="publisher">{{ item.sub }}</p>
             </div>
-            <p class="publisher">{{ item.sub }}</p>
           </div>
         </div>
       </swiper-slide>
@@ -35,6 +39,11 @@ export default {
         spaceBetween: 20
       }
     }
+  },
+  methods: {
+    toLink ({link}) {
+      window.open(link)
+    }
   }
 }
 </script>
@@ -49,8 +58,11 @@ export default {
 }
 .swiper-slide {
   width: 286px;
-  img {
+  .img {
     width: 286px;
+    height: 188px;
+    background-position: center center;
+    background-size: cover;
   }
   &:last-child {
     margin-right: 20px;
@@ -62,6 +74,11 @@ export default {
     h3 {
       padding-right: 70px;
       margin-bottom: 12px;
+      display: -webkit-box;
+      -webkit-line-clamp: 2;
+      overflow: hidden;
+      text-overflow: ellipsis;
+      -webkit-box-orient: vertical;
     }
   }
   .news-content {

+ 34 - 15
mobile/src/pages/layout/footer.vue

@@ -1,8 +1,8 @@
 <template>
   <div>
-    <div class="footer-find">
+    <div class="footer-find" v-if="!$route.meta.hideFooterBanner">
       <p>四维看看,让空间讲故事</p>
-      <div class="find-btn">发现精彩</div>
+      <div class="find-btn" @click="$router.push('/cases/全部')">发现精彩</div>
     </div>
     <div class="footer">
       <div class="footer-header">
@@ -16,7 +16,7 @@
           {{item.name}}
           <h-icon type="shang" class="arrow" />
           <ul class="types-child-list">
-            <li class="types-child" v-for="(item, index) in item.childs" :key="index">{{ item.name }}</li>
+            <li class="types-child" v-for="(child, index) in item.childs" :key="index" @click="toLink(child)">{{ child.name }}</li>
           </ul>
         </li>
       </ul>
@@ -81,19 +81,24 @@ export default {
           name: '行业应用',
           childs: [
             {
-              name: '房产营销'
+              name: '房产营销',
+              url: '/conduct/house'
             },
             {
-              name: '线上展会'
+              name: '线上展会',
+              url: '/conduct/exhibition'
             },
             {
-              name: '数字文博'
+              name: '数字文博',
+              url: '/conduct/subject'
             },
             {
-              name: 'VR购物'
+              name: 'VR购物',
+              url: '/conduct/shop'
             },
             {
-              name: '安防勘察'
+              name: '安防勘察',
+              url: '/conduct/secury'
             }
           ]
         },
@@ -101,13 +106,16 @@ export default {
           name: '关于我们',
           childs: [
             {
-              name: '公司简介'
+              name: '公司简介',
+              url: '/about'
             },
             {
-              name: '新闻资讯'
+              name: '新闻资讯',
+              url: '/news'
             },
             {
-              name: '成为经销商'
+              name: '成为经销商',
+              url: '/agent'
             }
           ]
         },
@@ -115,13 +123,16 @@ export default {
           name: '探索四维',
           childs: [
             {
-              name: '公司简介'
+              name: '四维时代',
+              url: 'http://www.4dage.com/cn/#/'
             },
             {
-              name: '新闻资讯'
+              name: '中德人工智能研究院',
+              url: 'https://www.cgaii.com/#/'
             },
             {
-              name: '成为经销商'
+              name: '四维模库',
+              url: 'http://www.4dmodel.com/'
             }
           ]
         }
@@ -149,6 +160,13 @@ export default {
       } else {
         this.openType = index
       }
+    },
+    toLink (item) {
+      if (item.url.indexOf('http') > -1) {
+        window.open(item.url)
+      } else {
+        this.$router.push(item.url)
+      }
     }
   }
 }
@@ -213,8 +231,9 @@ export default {
       .arrow {
         float: right;
         color: #909090;
-        margin-right: 20px;
+        margin: 22px 20px;
         transform: rotate(90deg);
+        line-height: 1;
       }
       .types-child-list {
         max-height: 0;

+ 17 - 17
mobile/src/pages/layout/header.vue

@@ -12,7 +12,7 @@
     </div>
     <div class="h-center">
       <vcenter>
-        <h-icon type="logo" class="logo-icon"></h-icon>
+        <h-icon type="logo" class="logo-icon" @click="$router.push('/')"></h-icon>
         <!-- <img v-if="!isBack||$route.name==='useimg'" :src="language==='en'?`${$cdn}images/logo-en.png`:`${$cdn}images/logo.png`"  @click="()=>{goto({name:'home'})} " alt> -->
         <!-- <div v-else>{{$route.name==='consumpdetail'?titleName[$route.name][$route.params.id]:titleName[$route.name]}}</div> -->
       </vcenter>
@@ -37,7 +37,7 @@
             <h-icon type="shang" class="icon" :class="{active: activeIdx===index}"></h-icon>
           </div>
           <div class="n-child" :class="{'open':activeIdx === index}">
-            <div  v-for="(sub,i) in item.childs" :key="i" @click="goto(sub.to)">
+            <div  v-for="(sub,i) in item.childs" :key="i" @click="goto(sub.url)">
               <i class="iconfont" :class="sub.icon"></i>
               <span :style="{minWidth:index==='cpgm'?'120px':'60px'}"  v-html="sub.name"></span>
               <img v-if="sub.isNew" class="new-icon" :src="`${$cdn}images/new.png`" alt="">
@@ -192,36 +192,36 @@ export default {
       navs: [
         {
           name: '核心产品',
-          url: '/location'
+          url: '/coreProduct'
         },
         {
           name: '行业解决方案',
           childs: [
             {
               name: '房产营销',
-              url: {}
+              url: '/conduct/house'
             },
             {
               name: '线上展会',
-              url: {}
+              url: '/conduct/exhibition'
             },
             {
               name: '数字文博',
-              url: {}
+              url: '/conduct/subject'
             },
             {
               name: 'VR购物',
-              url: {}
+              url: '/conduct/shop'
             },
             {
               name: '保险勘察',
-              url: {}
+              url: '/conduct/secury'
             }
           ]
         },
         {
           name: '看看空间',
-          url: '/location'
+          url: '/cases/全部'
         },
         {
           name: '核心技术',
@@ -232,19 +232,19 @@ export default {
           childs: [
             {
               name: 'APP下载',
-              url: {}
+              url: '/service/app'
             },
             {
               name: '使用教程',
-              url: {}
+              url: '/service/use'
             },
             {
               name: '保修条款',
-              url: {}
+              url: '/service/clause'
             },
             {
               name: '视频教程',
-              url: {}
+              url: '/video-course'
             }
           ]
         },
@@ -253,21 +253,21 @@ export default {
           childs: [
             {
               name: '新闻资讯',
-              url: {}
+              url: '/news'
             },
             {
               name: '成为经销商',
-              url: {}
+              url: '/agent'
             },
             {
               name: '关于我们',
-              url: {}
+              url: '/about'
             }
           ]
         },
         {
           name: '我的账号',
-          url: '/location'
+          url: '/information'
         }
       ]
     }

+ 3 - 2
mobile/src/pages/layout/style.scss

@@ -329,10 +329,11 @@ $bannerHeight:50px;
       width: 264px;
       padding: 20px 0 0 20px;
       background-color: #fff;
-      height: calc(100vh - 50px);
-      max-height: calc(100vh - 50px);
+      // height: calc(100vh - 50px);
+      min-height: calc(100vh - 50px);
       position: relative;
       z-index: 10000;
+      // overflow: hidden;
     }
     ul {
       

+ 147 - 85
mobile/src/pages/location/index.vue

@@ -1,39 +1,34 @@
 <template>
   <div class="home-layout">
-    <div class="plate01">
-      <div class="fdkk-pro">
-        <img :src="`${$cdn}images/hxjs-model.png`" alt="">
-        <div class="pulse" v-for="(item,i) in langCoreTech.kjdw.points" :style="item.posi" :key="i"></div>
-      </div>
-      <div class="title">
-        <h2 class="b-text2">{{langCoreTech.kjdw.title}}</h2>
-        <p class="b-text3" v-html="langCoreTech.kjdw.ability.sub"></p>
-      </div>
-      <div class="figure">
-        <figure v-for="(item,index) in langCoreTech.kjdw.ability.app" :key="index">
-          <img :src="item.icon" alt="">
-          <figcaption class="b-text1" v-html="item.sub"></figcaption>
-        </figure>
-      </div>
+    <div class="banner">
+      核心技术
     </div>
-    <div class="plate02" >
-      <h2 class="b-text2">{{langCoreTech.kjjm.title}}</h2>
-      <p class="b-text3" v-html="langCoreTech.kjjm.logon"></p>
-      <div class="p2-imgcon">
-        <wave height='50'/>
-        <img :src="`${$cdn}images/kjcj1.png`"  alt="">
-        <img :src="`${$cdn}images/kjcj2.png`" :class="{p2_img2_active:loop}" alt="">
+    <div class="plate1">
+      <h1 class="common-title">空间数字化</h1>
+      <p class="desc">记录与计算相机在拍摄时的空间位置,并提取对应的3D点云,从而获取三维空间的真实情况。</p>
+      <div class="video">
+        <video autoplay controls src="@/assets/images/refactor/location/AI AR SLAM 01(剪辑版2).mp4"></video>
       </div>
     </div>
-
-    <div class="plate03">
-      <h2 class="b-text2">{{langCoreTech.kjzs.title}}</h2>
-      <p class="b-text3" v-html="langCoreTech.jianrong.sub"></p>
-      <div class="kjdw">
-        <div class="k-con">
-          <img :src="this.language==='en'?`${$cdn}images/shebei-en.png`:`${$cdn}images/shebei.png`" alt="">
-        </div>
-      </div>
+    <div class="plate2">
+      <h1 class="common-title">空间互动</h1>
+      <p class="desc">自动导览 预先设定路线,球幕视频 BOX视频 增强体验的互动效果,多形式动态热点 赋以空间说话的艺术。</p>
+      <ul>
+        <li v-for="(item, index) in plate2List" :key="item.name" :class="{'is-active': plate2ActiveIndex === index}" @click="plate2ActiveIndex=index">
+          {{ item.name }}
+        </li>
+      </ul>
+      <video autoplay controls :src="plate2List[plate2ActiveIndex].video"></video>
+    </div>
+    <div class="plate3">
+      <h1 class="common-title">空间展示</h1>
+      <p class="desc">无需插件,可在手机、 平板、PC端、VR眼镜,实现720°沉浸式漫游体验。</p>
+      <ul>
+        <li v-for="item in plate3List" :key="item.name">
+          <div class="item-img" :style="{'background-image': `url(${item.img})`}"></div>
+          <h4>{{ item.name }}</h4>
+        </li>
+      </ul>
     </div>
   </div>
 </template>
@@ -42,49 +37,6 @@
 import {mapState} from 'vuex'
 import wave from '@/components/wave'
 
-let points = [
-  {
-    posi: {
-      top: '52%',
-      left: '27%'
-    }
-  },
-  {
-    posi: {
-      top: '58%',
-      left: '47%'
-    }
-  },
-  {
-    posi: {
-      top: '51%',
-      left: '57%'
-    }
-  },
-  {
-    posi: {
-      top: '47%',
-      left: '51%'
-    }
-  },
-  {
-    posi: {
-      top: '67%',
-      left: '49%'
-    }
-  },
-  {
-    posi: {
-      top: '70%',
-      left: '64%'
-    }
-  },
-  {
-    posi: {
-      top: '75%',
-      left: '82%'
-    }
-  }]
 export default {
   computed: {
     ...mapState({
@@ -96,10 +48,32 @@ export default {
   components: {wave},
   data () {
     return {
-      hoverIfr: '',
-      interval: null,
-      loop: false,
-      points
+      plate2ActiveIndex: 0,
+      plate2List: [
+        {
+          name: '动态热点'
+        },
+        {
+          name: '互动视频'
+        },
+        {
+          name: '自动导览'
+        }
+      ],
+      plate3List: [
+        {
+          name: 'VR端',
+          img: require('@/assets/images/refactor/location/show-1.png')
+        },
+        {
+          name: '网页端',
+          img: require('@/assets/images/refactor/location/show-2.png')
+        },
+        {
+          name: '移动端',
+          img: require('@/assets/images/refactor/location/show-3.png')
+        }
+      ]
     }
   },
   methods: {
@@ -108,18 +82,106 @@ export default {
     }
   },
   mounted () {
-    this.interval && clearInterval(this.interval)
-    this.interval = setInterval(() => {
-      this.loop = !this.loop
-    }, 2000)
   },
   beforeDestroy () {
-    clearInterval(this.interval)
-    this.interval = null
   }
 }
 </script>
 
 <style lang="scss" scoped>
-@import './style.scss';
+.banner {
+  width: 100%;
+  height: 140px;
+  background: url(~@/assets/images/refactor/location/banner.png) no-repeat center center;
+  background-size: cover;
+  font-size: 22px;
+  color: #202020;
+  line-height: 33px;
+  padding: 55px 0 0 42px;
+  font-weight: bold;
+}
+.desc {
+  color: #909090;
+  font-size: 12px;
+  line-height: 18px;
+}
+.plate1 {
+  padding: 26px 20px 60px;
+  .desc {
+    margin: 27px 0 18px;
+  }
+}
+.plate2 {
+  padding: 56px 20px 60px;
+  background: #F7F7F7;
+  .desc {
+    margin: 27px 0 18px;
+  }
+  ul {
+    display: flex;
+    margin-bottom: 18px;
+    li {
+      padding-right: 19px;
+      margin-right: 20px;
+      font-size: 14px;
+      line-height: 21px;
+      color: #909090;
+      font-weight: bold;
+      position: relative;
+      &.is-active {
+        color: #202020;
+      }
+      &::after {
+        content: '';
+        display: block;
+        width: 1px;
+        height: 14px;
+        background: #909090;
+        position: absolute;
+        top: 3px;
+        right: 0;
+      }
+      &:last-child {
+        &::after {
+          display: none;
+        }
+      }
+    }
+  }
+  video {
+    width: 100%;
+  }
+}
+.plate3 {
+  padding: 56px 20px 60px;
+  .desc {
+    margin: 27px 0 28px;
+  }
+  ul {
+    display: flex;
+    flex-wrap: wrap;
+    text-align: center;
+    padding: 0 0 0 30px;
+    li {
+      margin-bottom: 27px;
+    }
+    li:first-child {
+      margin-right: 98px;
+    }
+  }
+  .item-img {
+    width: 90px;
+    height: 90px;
+    background-size: contain;
+    background-repeat: no-repeat;
+    background-position: center center;
+    margin-bottom: 17px;
+  }
+}
+.video {
+
+  video {
+    width: 100%;
+  }
+}
 </style>

+ 0 - 194
mobile/src/pages/location/style.scss

@@ -1,194 +0,0 @@
-.b-text3,.b-text1{
-  color: #95979B;
-}
-.btns{
-  background: #1fe4dc;
-  text-align: center;
-  line-height: 30px;
-  height: 30px;
-  border-radius: 14px;
-  margin: 20px auto;
-  font-size: 14px;
-  width: 100px;
-  cursor: pointer;
-  border: #1fe4dc 1px solid;
-}
-
-.home-layout {
-  overflow: hidden;
-  .ifr-con{
-    position: fixed;
-    top: 0;
-    width: 100%;
-    height: 100vh;
-    z-index: 9999;
-    background: rgba(0, 0, 0, 0.7);
-    .ifr-hover{
-      position: absolute;
-      width: 100%;
-      height: 50%;
-      top: 50%;
-      transform: translateY(-50%);
-    }
-    .ifr-btns{
-      top: 75%;
-      left: 50%;
-      transform: translateX(-50%);
-      position: absolute;
-      z-index: 1888;
-    }
-  }
-  .plate01 {
-    position: relative;
-    background: url(https://4dscene.4dage.com/new4dkk/mobile/images/hxjs-bg2_temp.png) top center no-repeat;
-    background-size: cover;
-    background-color: #0e0e0e;
-    width: 100%;
-    text-align: center;
-    padding: 0;
-    .fdkk-pro {
-      margin: 0;
-      position: relative;
-      padding-top: 60px;
-      img {
-        margin-top: 44px;
-        width: 100%;
-      }
-      .pulse {
-        background: #fff;
-        border: 2px solid #1fe4dc;
-        border-radius: 50%;
-        height: 10px;
-        width: 10px;
-        position: absolute;
-        left: 10%;
-        top: 10%;
-        margin: 12px 0px 0px -7px;
-        z-index: 10;
-        &::after {
-          content: "";
-          border-radius: 50%;
-          height: 25px;
-          width: 25px;
-          position: absolute;
-          margin: -10px 0 0 -12px;
-          animation: pulsate 2s ease-out;
-          animation-iteration-count: infinite;
-          opacity: 0;
-          filter: alpha(opacity=0);
-          box-shadow: 0 0 1px 2px rgba(31, 228, 220, 1);
-          animation-delay: 1.1s;
-        }
-      }
-    }
-    .title {
-      position: absolute;
-      top: 26px;
-      left: 50%;
-      transform: translateX(-50%);
-      width: 100%;
-      h2 {
-        width: 100%;
-      }
-     
-      .b-text3 {
-        margin-top: 16px;
-        width: 87%;
-        position: relative;
-      }
-    }
-    .figure{
-      justify-content: space-around;
-      display: flex;
-      padding: 0 0 44px;
-      figure{
-        width: 27%;
-        img{
-          width: 65%;
-          margin-bottom: 10px;
-        }
-        figcaption{
-          line-height: 1.5;
-        }
-      }
-    }
-  }
-
-  .plate02 {
-    position: relative;
-    margin-top: 30px;
-    overflow: hidden;
-    text-align: center;
-    
-    .b-text2{
-      margin-bottom: 16px;
-    }
-    .p2-imgcon{
-      width: 100%;
-      position: relative;
-      img{
-        position: absolute;
-        top: 10%;
-        left: 0;
-        width: 90%;
-        margin: 0 5%;
-        &:last-of-type{
-          opacity: 0;
-          z-index: 99;
-          transition: 1s opacity ease;
-        }
-      }
-      .p2_img2_active{
-        opacity: 1!important;
-      }
-    }
-  }
-
-  .plate03 {
-    background: #f4f4f4;
-    background-size: 100% auto;
-    text-align: center;
-    .b-text2{
-      padding-top: 30px;
-      margin-bottom: 16px;
-    }
-    .b-text3 {
-      text-align: center;
-      width: 94%;
-    }
-    .b3-txt{
-      color: #2d2d2d;
-    }
-    .swkz {
-      img {
-        width: 100%;
-        margin: 0 0 0;
-        &:first-of-type {
-          width: 25%;
-          margin-bottom: -25px;
-          margin-top: 20px;
-        }
-      }
-    }
-    .zfb{
-      background-size: 100% auto;
-      margin-top: 20px;
-      img {
-        margin-top: 10px;
-        margin-bottom: 20px;
-        width: 70%;
-      }
-    }
-    .kjdw {
-      padding-bottom: 20px;
-      .k-con{
-        margin: 20px auto 0;
-        width: 100%;
-        img {
-          width: 90%;
-          margin: 0 auto;
-        }
-      }
-    }
-  }
-}

+ 32 - 0
mobile/src/pages/mall/index.vue

@@ -0,0 +1,32 @@
+<template>
+  <div class="mall">
+    <div class="banner">
+      <p>四维看看Pro</p>
+      <div class="btn">立即购买</div>
+    </div>
+
+  </div>
+</template>
+
+<script>
+export default {
+  data () {
+    return {
+      goods: [
+        {
+          img: '',
+          name: '全景相机'
+        },
+        {
+          img: '',
+          name: '精选配件'
+        },
+        {
+          img: '',
+          name: '增值服务'
+        }
+      ]
+    }
+  }
+}
+</script>

+ 157 - 0
mobile/src/pages/news/index.vue

@@ -0,0 +1,157 @@
+<template>
+  <div class="news">
+    <div class="banners">
+      <swiper class="swiper-wrapper" :options="swiperOption" ref="mySwiper" >
+        <swiper-slide
+          class="swiper-slide"
+          v-for="(item,i) in banners"
+          :key="i"
+        >
+        <template>
+          <div class="swiper-item" :class="`swiper-item${i+1}`" :style="{'background-image': `url(${item.img}`}" @click="handleClickSlide(item)">
+            <p v-html="item.text"></p>
+          </div>
+        </template>
+        </swiper-slide>
+      </swiper>
+      <ul class="banner-dots">
+        <li class="banner-dot" :class="{'is-active': activeIndex === i}" v-for="(_, i) in banners" :key="i"></li>
+      </ul>
+    </div>
+    <ul class="news-list">
+      <li class="news-item" v-for="(item,index) in newsList" :key="index" @click="toNewsDetail(item)">
+        <img :src="item.img" alt="">
+        <h4>{{ item.title }}</h4>
+        <p><span>{{item.sub}}</span><span>{{item.time}}</span></p>
+      </li>
+    </ul>
+  </div>
+</template>
+
+<script>
+import { News } from '@/../../common/data/newsData'
+export default {
+  data () {
+    return {
+      newsList: News,
+      activeIndex: 0,
+      swiperOption: {
+        autoplay: {
+          delay: 5000,
+          autoplayStopOnLast: false
+        },
+        on: {
+          slideChangeTransitionEnd: () => {
+            this.activeIndex = this.mySwiper.activeIndex
+          }
+        }
+      },
+      banners: [
+        {
+          text: '36Kr独家报道<br/>四维时代发布<br/>3D相机四维看看Pro',
+          img: require('@/assets/images/refactor/news/banner1.jpg'),
+          link: 'https://36kr.com/p/782262201344647?from=groupmessage&isappinstalled=0'
+        },
+        {
+          text: '火爆美国CES<br/>四维看看Pro获谷歌AI、LG集团<br/>等国际性企业青睐',
+          img: require('@/assets/images/refactor/news/banner2.jpg'),
+          link: 'https://mp.weixin.qq.com/s/EHxLGCGvznqijxOLPLTXkQ'
+        },
+        {
+          text: '四维看展与德国<br/>黑提恩斯-陶瓷博物馆合作<br/>可3D鉴赏珍宝',
+          img: require('@/assets/images/refactor/news/banner3.jpg'),
+          link: 'https://mp.weixin.qq.com/s/eQ2IuHdlIVg7n0IsXJs5iA'
+        }
+      ]
+    }
+  },
+  computed: {
+    mySwiper () {
+      return this.$refs.mySwiper.swiper
+    }
+  },
+  methods: {
+    toNewsDetail (item) {
+      location.href = item.link
+    },
+    handleClickSlide (item) {
+      window.open(item.link)
+    }
+  }
+}
+</script>
+
+<style lang="less" scoped>
+.banners {
+  position: relative;
+}
+.swiper-item {
+  width: 100%;
+  height: 140px;
+  background-size: cover;
+  background-position: center center;
+  position: relative;
+  font-size: 18px;
+  color: #202020;
+  line-height: 27px;
+  font-weight: bold;
+  padding-right: 20px;
+  display: flex;
+  align-items: center;
+  justify-content: flex-end;
+  text-align: right;
+  &.swiper-item2 {
+    color: #fff;
+    text-align: center;
+    justify-content: center;
+  }
+  &.swiper-item3 {
+    color: #fff;
+  }
+}
+
+.banner-dots {
+  position: absolute;
+  bottom: 10px;
+  display: flex;
+  left: 50%;
+  transform: translateX(-50%);
+  z-index: 1;
+}
+.banner-dot {
+  width: 7px;
+  height: 7px;
+  background: #ebebeb;
+  border-radius: 50%;
+  margin-right: 7px;
+  &:last-child {
+    margin-right: 0;
+  }
+  &.is-active {
+    background: #1FE4DC;
+  }
+}
+.news-list  {
+  padding: 20px;
+  .news-item {
+    padding: 0 0 18px;
+    border-bottom: 1px solid #EBEBEB;
+    margin-bottom: 20px;
+  }
+  img {
+    width: 100%;
+    margin-bottom: 7px;
+    vertical-align: middle;
+  }
+  h4 {
+    font-size: 14px;
+    line-height: 21px;
+    margin-bottom: 4px;
+  }
+  span {
+    color: #909090;
+    font-size: 12px;
+    margin-right: 5px;
+  }
+}
+</style>

+ 1 - 1
mobile/src/pages/payresult/index.vue

@@ -80,7 +80,7 @@ $theme-color: #1fe4dc;
     line-height: 48px;
     text-align: center;
     font-size: 14px;
-    color: rgba(0,0,0,.7);
+    color: #202020;
     border-radius: 2px;
     width: 100%;
     background-color: #1fe4dc;

+ 35 - 28
mobile/src/pages/pricedetail/index.vue

@@ -1,21 +1,26 @@
 <template>
   <div class="pricedetail-layout">
     <div class="plate">
-      <template v-if="language!=='en'">
-        <p class="b-title">{{langPurchase.pricename}}</p>
-        <priceTable  style="margin-bottom:20px;"  />
-      </template>
-      <div class="b-title">{{langPurchase.pricename1}}</div>
-      <priceTable :type="'hw'" />
-      <ul class="qa-con">
-        <li>
-          <p>{{langPurchase.directions}}</p>
-        </li>
-        <li v-for="(item,i) in langPurchase.qa" :key="i">
-          <p>{{item.q}}</p>
-          <p v-html="item.a"></p>
-        </li>
-      </ul>
+      <div class="table-w">
+        <template v-if="language!=='en'">
+          <p class="common-title">{{langPurchase.pricename}}</p>
+          <priceTable  style="margin-bottom:20px;"  />
+        </template>
+        <div class="common-title">{{langPurchase.pricename1}}</div>
+        <priceTable :type="'hw'" />
+      </div>
+      <div class="qa-w">
+        <h1 class="common-title">关于云容量</h1>
+        <ul class="qa-con">
+          <li>
+            <p>{{langPurchase.directions}}</p>
+          </li>
+          <li v-for="(item,i) in langPurchase.qa" :key="i">
+            <p>{{item.q}}</p>
+            <p v-html="item.a"></p>
+          </li>
+        </ul>
+      </div>
     </div>
   </div>
 </template>
@@ -47,15 +52,13 @@ export default {
   .plate {
     width: 100%;
     margin: 0 auto;
-    padding: 20px 0 40px;
+    padding: 20px 0 0 0;
     text-align: center;
-    .b-title {
-      font-weight: 700;
-      font-size: 22px;
-      color: rgba(0, 0, 0, 0.7);
-      line-height: 44px;
-      margin: 0 auto 20px;
-      width: 98%;
+    .common-title {
+      margin-bottom: 30px;
+    }
+    .table-w {
+      padding: 0 20px;
     }
     .price-txt {
       text-align: left;
@@ -69,9 +72,8 @@ export default {
         list-style: disc;
       }
     }
-
     .qa-con {
-      max-width: 90%;
+      max-width: 100%;
       margin: 50px auto 0;
       li {
         margin-bottom: 18px;
@@ -80,11 +82,11 @@ export default {
           STHeiti;
         p {
           font-size: 12px;
-          color: #666;
+          color: #202020;
           line-height: 18px;
           &:first-of-type {
-            font-size: 14px;
-            color: #333;
+            font-size: 16px;
+            color: #202020;
             font-weight: bold;
             margin-bottom: 4px;
           }
@@ -92,5 +94,10 @@ export default {
       }
     }
   }
+  .qa-w {
+      margin-top: 60px;
+      background: #f7f7f7;
+      padding: 56px 20px;
+    }
 }
 </style>

+ 137 - 24
mobile/src/pages/purchase/index.vue

@@ -38,25 +38,46 @@
               <p>¥{{ mallConfig.zhijiaPrice }}</p>
             </div>
           </div>
-          <spinner v-if="language!=='en'" class="count" @count='handleNum' />
+          <div class="zhijia-desc">
+            <p><h-icon type="gouwuche" class="icon" size="16"></h-icon>预计3日内发货</p>
+            <spinner v-if="language!=='en'" class="count" @count='handleZhijiaCount' />
+          </div>
         </div>
       </div>
     </div>
     <div class="plate02" ref="jsgg">
-      <div class="p2-name">{{langPurchase.parmas.name}}</div>
-      <div class="p2-imgc">
-        <img :src="`${$cdn}images/m-paramspro.png`" alt="">
+      <ul class="plate02-type-list">
+        <li :class="{'is-active': plate02ShowType === 'product'}" @click="plate02ShowType='product'">产品说明</li>
+        <li :class="{'is-active': plate02ShowType === 'tech'}" @click="plate02ShowType='tech'">技术参数</li>
+      </ul>
+      <div v-show="plate02ShowType === 'product'">
+        <ul class="desc-video">
+          <li v-for="item in videoArr" :key="item.name">
+            <h1 class="common-title" v-html="item.name"></h1>
+            <div class="player">
+              <video class="video" controls="controls" playsinline="playsinline" muted="muted" :poster="`${$cdn}images/postv${item.post}.png`">
+                <source :src="`${$cdn}video/homevideo/v${item.img}.mp4`" type="video/mp4">
+              </video>
+            </div>
+          </li>
+        </ul>
       </div>
-      <div class="p2-pramas">
-        <div v-for="(item,i) in langPurchase.parmas.detail" :key="i">
-          <p class="title">{{item.label}}</p>
-          <div class="name">{{item.name}}</div>
-          <div class="detail" >
-            <span v-for="(sub,idx) in item.dec" :key="idx">
-              <span v-html="sub">* 付款成功后5个工作日内发货,默认顺丰快递包邮</span>
-            </span>
+      <div v-show="plate02ShowType === 'tech'">
+        <div class="common-title">{{langPurchase.parmas.name}}</div>
+        <div class="p2-pramas">
+          <div v-for="(item,i) in techData" :key="i">
+            <p class="title">{{item.label}}</p>
+            <div class="detail" >
+              <span v-for="(sub,idx) in item.desc" :key="idx">
+                {{sub}}
+                <!-- <span v-html="sub">* 付款成功后5个工作日内发货,默认顺丰快递包邮</span> -->
+              </span>
+            </div>
           </div>
         </div>
+        <div class="p2-imgc">
+          <img :src="`${$cdn}images/m-paramspro.png`" alt="">
+        </div>
       </div>
     </div>
     <!-- <div class="plate03" ref="rlgz">
@@ -77,7 +98,7 @@
     </div> -->
     <div class="hover-btns">
       <div class="h-price">
-       {{language!=='en'? `RMB ${selectParts?count*(12800 + 899):count*12800}`:'USD 1799'}}
+       {{language!=='en'? `RMB ${totalPrice}`:'USD 1799'}}
       </div>
       <div class="h-btns">
         <span v-if="language!=='en'" @click="addcart">加入购物车</span>
@@ -95,6 +116,7 @@ import priceTable from '@/components/priceTable'
 import browse from '@/components/browse'
 import { getPosition } from '@/util'
 import mallConfig from '@/../../common/mall/mall'
+import { i18n } from '@/lang'
 
 export default {
   components: {
@@ -107,7 +129,10 @@ export default {
       token: state => state.user.token,
       language: state => state.language.current,
       langPurchase: state => state.language.home.purchase
-    })
+    }),
+    totalPrice () {
+      return mallConfig.price * this.count + (this.selectParts ? mallConfig.zhijiaPrice * this.zhijiaCount : 0)
+    }
   },
   data () {
     let browdata = [
@@ -128,18 +153,101 @@ export default {
         big: 'big-3'
       }]
     return {
+      plate02ShowType: 'product',
       mallConfig,
       count: 1,
       browdata,
       selectParts: true,
       pathname: window.location.pathname,
-      buyPackage: 'normal'
+      buyPackage: 'normal',
+      zhijiaCount: 1,
+      techData: [
+        {
+          label: '机身尺寸',
+          desc: [`高度:220.7mm / 宽度:78.2mm / 厚度:78.2mm`]
+        },
+        {
+          label: '分辨率',
+          desc: [`4608*3456像素(每个);8192*4096像素(合计)`]
+        },
+        {
+          label: '存储内存',
+          desc: ['16GB']
+        },
+        {
+          label: 'WiFi',
+          desc: ['802.11a/b/g/n网络协议 / ', '支持2.4/5GHz通信']
+        },
+        {
+          label: '镜头',
+          desc: [`类型:200°鱼眼镜头     孔径:f/2.0     数量:8个`]
+        },
+        {
+          label: '传感器',
+          desc: [`范围:1/2.3英寸     数量:8个`]
+        },
+        {
+          label: '电池',
+          desc: ['7.4V 4200mAh /  可通过USB快速充电']
+        },
+        {
+          label: '设备接口',
+          desc: ['TYPE-C']
+        }
+      ],
+      videoArr: [
+        {
+          name: i18n.t('coreProduct.title1'),
+          img: 1,
+          post: 1,
+          runAnimation: true
+        },
+        {
+          name: i18n.t('coreProduct.title2'),
+          img: 2,
+          post: 2,
+          runAnimation: true
+        },
+        {
+          name: i18n.t('coreProduct.title3'),
+          img: 2,
+          post: 2,
+          runAnimation: true
+        },
+        {
+          name: i18n.t('coreProduct.title4'),
+          img: 2,
+          post: 2,
+          runAnimation: true
+        },
+        {
+          name: i18n.t('coreProduct.title5'),
+          img: 3,
+          post: 3,
+          runAnimation: true
+        },
+        {
+          name: i18n.t('coreProduct.title6'),
+          img: 4,
+          post: 4,
+          runAnimation: true
+        },
+        {
+          name: i18n.t('coreProduct.title7'),
+          img: 5,
+          post: 5,
+          runAnimation: true
+        }
+      ]
     }
   },
   methods: {
     handleNum (data) {
       this.count = data
     },
+    handleZhijiaCount (data) {
+      this.zhijiaCount = data
+    },
     async addcart () {
       if (!this.token) {
         return this.$router.push({path: '/login'})
@@ -147,12 +255,12 @@ export default {
       let params = {
         goodsId: 4,
         goodsCount: this.count,
-        skuSn: 'U15609161635760015'
+        skuSn: mallConfig.goodsMap[4].skuSn
       }
       let zhijia = {
         goodsId: 7,
-        goodsCount: this.count,
-        skuSn: 'U15604134406280073'
+        goodsCount: this.zhijiaCount,
+        skuSn: mallConfig.goodsMap[7].skuSn
       }
       await this.$store.dispatch('addCart', params)
       this.selectParts && await this.$store.dispatch('addCart', zhijia)
@@ -171,15 +279,15 @@ export default {
 
       let params = {
         goodsId: 4,
-        price: 12800,
+        price: mallConfig.price,
         goodsCount: this.count,
-        skuSn: 'U15609161635760015'
+        skuSn: mallConfig.goodsMap[4].skuSn
       }
       let zhijia = {
         goodsId: 7,
-        goodsCount: this.count,
-        price: 899,
-        skuSn: 'U15604134406280073'
+        goodsCount: this.zhijiaCount,
+        price: mallConfig.zhijiaPrice,
+        skuSn: mallConfig.goodsMap[7].skuSn
       }
       let tmpcart = []
       let temp = {}
@@ -204,7 +312,12 @@ export default {
         }
       })
     },
-    changeSelectParts () {}
+    changeSelectParts () {
+      if (this.buyPackage === 'lot') {
+        return
+      }
+      this.selectParts = !this.selectParts
+    }
   }
 }
 </script>

+ 67 - 28
mobile/src/pages/purchase/style.scss

@@ -28,7 +28,7 @@
         text-align: left;
         .p-title{
           font-size: 20px;
-          color: rgba(0,0,0,.7);
+          color: #202020;
           line-height: 24px;
           font-weight: 700;
         }
@@ -38,20 +38,26 @@
         }
         .p-label{
           font-size: 12px;
-          color: rgba(0,0,0,.7);
+          color: #202020;
           line-height: 16px;
         }
         .p-price{
           margin-top: 10px;
           font-size: 20px;
           line-height: 1;
-          color: rgba(0,0,0,.7);
+          color: #202020;
           font-weight: 700;
           .zdj{
             font-size: 16px;
             color: #1fe4dc;
           }
         }
+        p {
+          color: #909090;
+          margin-top: 3px;
+          line-height: 18px;
+          font-size: 12px;
+        }
       }
       .postage {
         color: #909090;
@@ -87,16 +93,19 @@
         }
       }
       .zhijia{
-        padding: 5px 22px;
+        padding: 0 22px;
         width: 100%;
         cursor: pointer;
         text-align: center;
         border: 1px solid #70eee9;
         display: flex;
         align-items: center;
-        margin: 20px 0 6px;
+        margin: 18px 0 10px;
         display: flex;
         width: 100%;
+        &.no-active {
+          border-color: #ebebeb;
+        }
         img{
           vertical-align: middle;
           margin-right: 20px;
@@ -110,6 +119,8 @@
           text-align: left;
           font-size: 12px;
           color: #202020;
+          line-height: 18px;
+          padding: 12px 0;
           p {
             margin: 1px 0 19px;
             font-size: 12px;
@@ -145,12 +156,38 @@
         margin-top: 20px;
       }
     }
+    .zhijia-desc {
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+      p {
+        color: #909090;
+      }
+      .icon {
+        margin-right: 5px;
+      }
+    }
   }
   .plate02{
-    padding: 40px 0 0;
-    .p2-name{
-      font-size: 20px;
-      text-align: center;
+    margin-top: 50px;
+    padding: 27px 20px 0;
+    background: #F7F7F7;
+    .plate02-type-list {
+      display: flex;
+      font-size: 14px;
+      color: #909090;
+      font-weight: bold;
+      margin-bottom: 54px;
+      li {
+        padding: 0 18px;
+        &.is-active {
+          color: #202020;
+        }
+        &:first-child {
+          padding-left: 0;
+          border-right: 1px solid #909090;
+        }
+      }
     }
     .p2-imgc{
       width: 90%;
@@ -161,9 +198,8 @@
       }
     }
     .p2-pramas{
-      background: #f8f9fc;
       text-align: left;
-      padding: 40px 24px;
+      margin-top: 10px;
       >div{
         &:last-of-type{
           .detail{
@@ -173,25 +209,18 @@
       }
       .title {
         font-size: 14px;
-        color: rgba(0, 0, 0, 0.7);
-        line-height: 14px;
-        margin-bottom: 16px;
-        font-weight: 900;
-      }
-      .name {
-        color: rgba(0, 0, 0, 0.7);
-        line-height: 24px;
-        font-size: 12px;
-        color: rgba(0, 0, 0, 0.7);
+        color: #202020;
+        line-height: 21px;
+        margin-bottom: 4px;
+        font-weight: bold;
+        padding-top: 17px;
       }
       .detail {
         font-size: 12px;
-        color: rgb(115,115,115);
-        line-height: 24px;
-        margin-bottom: 16px;
-        padding-bottom: 16px;
-        border-bottom: 1px solid rgba(0, 0, 0, 0.15);
-        white-space: pre-wrap;
+        line-height: 17px;
+        color: #909090;
+        padding-bottom: 17px;
+        border-bottom: 1px solid #EBEBEB;
       }
     }
   }
@@ -278,7 +307,17 @@
     }
   }
 }
-
+.desc-video {
+  padding: 0px 0 27px;
+  video {
+    margin-top: 30px;
+    width: 100%;
+    vertical-align: middle;
+  }
+  li {
+    margin-bottom: 56px;
+  }
+}
 .select-w {
   padding: 0 20px;
 }

+ 7 - 7
mobile/src/pages/purchasetwo/style.scss

@@ -31,7 +31,7 @@
         border-bottom: 1px solid rgba(0, 0, 0, 0.1);
         .p-title{
           font-size: 20px;
-          color: rgba(0,0,0,.7);
+          color: #202020;
           line-height: 24px;
           font-weight: 700;
         }
@@ -41,14 +41,14 @@
         }
         .p-label{
           font-size: 12px;
-          color: rgba(0,0,0,.7);
+          color: #202020;
           line-height: 16px;
         }
         .p-price{
           margin-top: 10px;
           font-size: 20px;
           line-height: 1;
-          color: rgba(0,0,0,.7);
+          color: #202020;
           font-weight: 700;
         }
       }
@@ -62,7 +62,7 @@
         }
         .attr{
           font-size: 14px;
-          color: rgba(0,0,0,.7);
+          color: #202020;
           line-height: 18px;
           font-weight: 600;
           margin: 12px 0 10px;
@@ -88,7 +88,7 @@
           width: 190px;
           padding: 0;
           font-size: 14px;
-          color: rgba(0,0,0,.7);
+          color: #202020;
           font-weight: 600;
         }
         .service{
@@ -109,7 +109,7 @@
               font-size: 12px;
               line-height: 1.5;
               position: relative;
-              color: rgba(0,0,0,.7);
+              color: #202020;
               &::before{
                 content: '';
                 width: 3px;
@@ -148,7 +148,7 @@
             font-size: 12px;
             line-height: 1.2;
             text-align: left;
-            color: rgba(0,0,0,.7);
+            color: #202020;
           }
         }
         .peijian{

+ 16 - 16
mobile/src/pages/purchasezhijia/index.vue

@@ -7,24 +7,24 @@
           :floder="'zhijiabrowse'"
          />
         <div class="txt-con">
-          <img class="p-logo" :src="this.language==='en'?`${$cdn}images/zhijia-logo-en.png`:`${$cdn}images/zhijia-logo-black.png`" alt="">
-          <div class="p-label" v-html="langzhijia.dec"></div>
-          <div class="p-price">{{langzhijia.price}}</div>
+          <!-- <img class="p-logo" :src="this.language==='en'?`${$cdn}images/zhijia-logo-en.png`:`${$cdn}images/zhijia-logo-black.png`" alt=""> -->
+          <h2>四维看看Pro三脚架套装</h2>
+          <div class="p-price">¥899</div>
+          <p>运费:顺丰包邮</p>
         </div>
         <div class="attr-con">
-          <div class="attr">{{langzhijia.color.key}}</div>
-          <div class="box color">
-            <i class="iconfont icon-yuandian">{{langzhijia.color.val}}</i>
+          <div class="detail-box">
+            <div class="attr">套餐内容</div>
+            <div class="box service">
+              <ul>
+                <li v-for="(item,i) in langzhijia.peijian.val" :key="i" v-html="item"></li>
+              </ul>
+            </div>
           </div>
-          <div class="attr">{{langzhijia.peijian.key}}</div>
-          <div class="box service">
-            <ul>
-              <li v-for="(item,i) in langzhijia.peijian.val" :key="i" v-html="item"></li>
-            </ul>
+          <div class="zhijia-desc">
+            <p><h-icon type="gouwuche" class="icon" size="16"></h-icon>预计3日内发货</p>
+            <spinner v-if="language!=='en'" class="count" @count='handleNum' />
           </div>
-          <div v-if="language!=='en'" class="attr">{{langzhijia.count.key}}</div>
-          <spinner v-if="language!=='en'" class="count" @count='handleNum' />
-          <div class="dec">{{langzhijia.tiaokuan}}</div>
         </div>
       </div>
     </div>
@@ -32,7 +32,7 @@
    <div class="zhijia-params">
     <div class="mobile2">
       <div class="top">
-        <h2 class="b-text2" v-html="langzhijia.zhijia.name"></h2>
+        <h2 class="common-title" v-html="langzhijia.zhijia.name"></h2>
         <!-- <p class="b-text3" v-html="langzhijia.zhijia.sub"></p> -->
         <!-- <phone class="front-img"/> -->
         <img class="front-img" :src="`${$cdn}images/m-zhijia.png`" alt>
@@ -82,7 +82,7 @@
 
     <div class="hover-btns">
       <div class="h-price">
-       {{language!=='en'? `RMB ${count*12800}`:'USD 209'}}
+       {{language!=='en'? `RMB ${count*899}`:'USD 209'}}
       </div>
       <div class="h-btns">
         <span v-if="language!=='en'" @click="addcart">加入购物车</span>

+ 73 - 103
mobile/src/pages/purchasezhijia/style.scss

@@ -1,8 +1,6 @@
 .purchase-layout{
   overflow: hidden;
   .plate01{
-    background: url(https://4dscene.4dage.com/new4dkk/mobile/images/purchase-bg.png) #f8f9fc top center no-repeat;
-    background-size: 100% auto;
     .top{
       height: 60px;
       padding-top: 20px;
@@ -10,92 +8,52 @@
       span{
         padding-right: 5%;
         font-size: 14px;
-        color: rgba(0, 0, 0, 0.7);
+        color: #202020;
         line-height: 18px;
         font-weight: 600;
       }
     }
     .main-layout{
       width: 100%;
-      text-align: center;
       .pro{
-        width: 90%;
+        padding: 0 20px;
         border-radius: 4px;
         margin: 40px auto;
       }
       .txt-con{
-        width: 90%;
+        padding: 30px 20px 0;
         margin: 0 auto;
-        text-align: left;
-        padding: 16px 0;
-        border-top: 1px solid rgba(0, 0, 0, 0.1);
-        border-bottom: 1px solid rgba(0, 0, 0, 0.1);
-        .p-title{
-          font-size: 20px;
-          color: rgba(0,0,0,.7);
-          line-height: 24px;
-          font-weight: 700;
-        }
-        .p-logo{
-          width: 100%;
-          margin-bottom: 8px;
-        }
-        .p-label{
-          font-size: 12px;
-          color: rgba(0,0,0,.7);
-          line-height: 16px;
+        color:  #202020;
+        h2 {
+          font-size: 22px;
+          line-height: 33px;
+          letter-spacing: 2px;
         }
         .p-price{
-          margin-top: 10px;
-          font-size: 20px;
+          margin-top: 12px;
+          margin-bottom: 3px;
           line-height: 1;
-          color: rgba(0,0,0,.7);
+          color:  #202020;
           font-weight: 700;
+          font-size: 16px;
+          line-height: 24px;
+        }
+        p {
+          color: #909090;
+          font-size: 12px;
         }
       }
       .attr-con{
-        text-align: left;
-        width: 90%;
-        margin: 0 auto;
-        padding: 0 0 40px;
-        .icon-yuandian{
-          font-size: 14px;
-        }
-        .attr{
-          font-size: 14px;
-          color: rgba(0,0,0,.7);
-          line-height: 18px;
-          font-weight: 600;
-          margin: 12px 0 10px;
-        }
-        .box{
-          display: inline-block;
-          color: rgba(0,0,0,.45);
-          padding: 0 63px;
-          box-sizing: border-box;
-          position: relative;
-          text-align: left;
-          .t-click{
-            position: absolute;
-            right: 0;
-            bottom: 0;
-            margin: 0;
-            width: 16px;
-            height: 16px;
-            padding: 0;
-          }
-        }
-        .color{
-          width: 100%;
-          padding: 0;
-          font-size: 14px;
-          color: rgba(0,0,0,.7);
-          font-weight: 600;
-          span{
-            color: #1fe4dc;
-            font-weight: bold;
-            cursor: pointer;
-            margin-left: 5%;
+        padding: 0 20px;
+        .detail-box {
+          display: flex;
+          border: 1px solid #1FE4DC;
+          margin-top: 19px;
+          padding: 12px 10px;
+          .attr {
+            margin-right: 27px;
+            white-space: nowrap;
+            line-height: 18px;
           }
         }
         .service{
@@ -104,19 +62,16 @@
           padding: 0;
           .icon-yuandian{
             font-size: 14px;
-            color: rgba(0, 0, 0, 0.7);
+            color: #909090;
             font-weight: 600;
           }
+          
           ul{
-            padding: 0 10px 0 15px;
-            display: inline-block;
-            width: 100%;
-            vertical-align: top;
             li{
               font-size: 12px;
-              line-height: 1.5;
+              line-height: 18px;
               position: relative;
-              color: rgba(0,0,0,.7);
+              color:  #909090;
               &::before{
                 content: '';
                 width: 3px;
@@ -127,7 +82,7 @@
                 left: -10px;
                 top: 50%;
                 transform: translateY(-50%);
-                background-color: rgba(0,0,0,.45);
+                background-color: #909090;
               }
               // &:last-of-type{
               //   &::before{
@@ -142,7 +97,6 @@
           text-align: left;
           width: 100%;
           border: 1px solid #70eee9;
-          background: #f8fefe;
           padding-left: 5%;
           img{
             vertical-align: middle;
@@ -158,7 +112,7 @@
             font-size: 12px;
             line-height: 1.2;
             text-align: left;
-            color: rgba(0,0,0,.7);
+            color:  #202020;
           }
         }
         .peijian{
@@ -201,7 +155,7 @@
           text-align: center;
         }
         .dec{
-          color: rgba(0, 0, 0, 0.7);
+          color: #202020;
           font-size: 12px;
           text-align: left;
           margin-top: 12px;
@@ -213,17 +167,23 @@
   .zhijia-params{
     text-align: center;
     overflow: hidden;
+    
+    &>div {
+      background: #F7F7F7;
+    }
+    margin-top: 60px;
     .p2-pramas{
       text-align: left;
-      background: #f8f8f8;
-      padding: 40px 24px;
+      background: #fff;
+      padding: 57px 20px ;
       .p2-name{
         font-size: 20px;
-        text-align: center;
-        color: #2d2d2d;
+        color: #202020;
         margin-bottom: 20px;
       }
       >div{
+        padding: 17px 0;
+        border-bottom: 1px solid rgba(0, 0, 0, 0.15);
         &:last-of-type{
           .detail{
             margin-bottom: 0;
@@ -231,25 +191,23 @@
         }
       }
       .title {
-        font-size: 14px;
-        color: rgba(0, 0, 0, 0.7);
-        line-height: 14px;
-        margin-bottom: 16px;
-        font-weight: 900;
+        font-size: 12px;
+        color: #202020;
+        margin-bottom: 4px;
+        font-weight: bold;
+        line-height: 21px;
       }
       .name {
-        color: rgba(0, 0, 0, 0.7);
-        line-height: 24px;
+        color: #202020;
+        line-height: 21px;
         font-size: 12px;
-        color: rgba(0, 0, 0, 0.7);
+        color: #202020;
       }
       .detail {
         font-size: 12px;
         color: rgb(115,115,115);
-        line-height: 24px;
-        margin-bottom: 16px;
-        padding-bottom: 16px;
-        border-bottom: 1px solid rgba(0, 0, 0, 0.15);
+        line-height: 18px;
+        
         white-space: pre-wrap;
       }
       .sub{
@@ -261,10 +219,12 @@
     }
     .mobile2 {
       color: #fff;
-      padding: 40px 0 0;
+      padding:  40px 0 0;
       font-weight: 300;
       font-size: 0;
       .top {
+        background: #f7f7f7;
+        padding:0 20px;
         .front-img {
           margin: 30px auto 0;
           width: 100%;
@@ -297,15 +257,12 @@
         }
       }
       .jiaojia{
-        background: #f8f8f8;
         padding: 0 0;
         .text{
-          display: inline-block;
-          width: 85%;
-          color: #2d2d2d;
-          font-size: 12px;
+          color: #202020;
+          font-size: 14px;
           padding-bottom: 10px;
-          border-bottom: 1px solid rgba($color: #2d2d2d, $alpha: 0.1);
+          border-bottom: 1px solid rgba($color: #909090, $alpha: 0.1);
         }
         .jiaojia-img{
           display: flex;
@@ -412,4 +369,17 @@
       }
     }
   }
+}
+
+.zhijia-desc {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-top: 10px;
+  p {
+    color: #909090;
+  }
+  .icon {
+    margin-right: 5px;
+  }
 }

+ 88 - 0
mobile/src/pages/userCenter/addressForm/index.vue

@@ -0,0 +1,88 @@
+<template>
+  <div class="address">
+    <div class="address-header">
+      <h-icon type="jiantou" class="back" @click="$router.back()"  />
+      添加收货地址
+    </div>
+    <citySelect class="citySelect-w" :address='address' :token="token" @cancle="$router.back()" @submit="createAddress"  />
+  </div>
+</template>
+
+<script>
+import citySelect from '@/components/citySelect'
+import { mapState } from 'vuex'
+import API from '@/apis'
+
+var cloneObj = function (obj) {
+  var newObj = {}
+  if (obj instanceof Array) {
+    newObj = []
+  }
+  for (var key in obj) {
+    var val = obj[key] || ''
+    newObj[key] = typeof val === 'object' ? cloneObj(val) : val
+  }
+  console.log(newObj)
+  return newObj
+}
+
+export default {
+  data () {
+    return {
+      address: cloneObj({})
+    }
+  },
+  computed: {
+    ...mapState({
+      token: state => state.user.token
+      // address: state => cloneObj(state.user.address) || {}
+    })
+  },
+  components: {
+    citySelect
+  },
+  methods: {
+    createAddress (form) {
+      API.insertAddress(form).then(async res => {
+        if (res.data.code === 0) {
+          await this.getAddressList()
+          this.$alert('添加成功', {
+            icon: 'success'
+          }).then(() => {
+            this.$router.back()
+          })
+        }
+      })
+    },
+    getAddressList () {
+      return API.getReceiverList().then(res => {
+        console.log(res, 'getReceiverList')
+        this.addressList = res.data.data
+      })
+    }
+  }
+}
+</script>
+
+<style lang="less" scoped>
+.address {
+  color: #202020;
+}
+.address-header {
+  padding: 27px 20px 17px;
+  text-align: center;
+  font-size: 14px;
+  font-weight: bold;
+  line-height: 21px;
+  border-bottom: 1px solid #EBEBEB;
+  position: relative;
+  .back {
+    position: absolute;
+    left: 20px;
+    top: 27px;
+  }
+}
+.citySelect-w {
+  padding:  17px 20px 60px;
+}
+</style>

+ 23 - 10
mobile/src/pages/account/manage/cart/index.vue

@@ -1,10 +1,13 @@
 <template>
   <div class="cart-layout">
+    <div class="cart-title">购物车</div>
     <div class="cart-con" v-if="cart.length>0">
       <div class="c-header">
         <label class="check-con">
           <span class="check-box" @click="selectAll">
-            <span class="checkbox-inner" :class="{'checkbox-inner-checked':checked}"></span>
+            <span class="checkbox-inner" :class="{'checked':checked}">
+              <h-icon type="duihao" />
+            </span>
           </span>
           <span>全选</span>
         </label>
@@ -13,7 +16,9 @@
         <div class="i-left">
           <label class="check-con" @click="selectItem(item,index)">
             <span class="check-box">
-              <span class="checkbox-inner" :class="{'checkbox-inner-checked':String(checkedArr[index])}"></span>
+              <span class="checkbox-inner" :class="{'checked':String(checkedArr[index])}">
+                <h-icon type="duihao" />
+              </span>
             </span>
           </label>
         </div>
@@ -49,19 +54,15 @@
       <div class="sum-con">
         <div class="sum-price">
           <div>
-            <span>合计:</span>
+            <span>共计{{ totalGoodsCount }}件商品</span>
             <span class="price-txt">¥{{getSum()[1]}}</span>
           </div>
-          <div>
-            <span>本订单包邮</span>
-          </div>
         </div>
+        <div class="btn-submit btn-continue" @click="$router.push({path:'/purchase'})">继续选购</div>
         <div class="btn-submit" @click="toPay">结算</div>
-        <div class="dec">温馨提示:您的订单将由顺丰速运专业配送</div>
       </div>
       <div class="paytype">
-        <div>支付方式</div>
-        <img :src="`${$cdn}images/paytypelist.png`" alt="">
+        <img src="@/assets/images/refactor/usercenter/pay-type.png" alt="">
       </div>
     </div>
     <div class="no-cart-con" v-else>
@@ -74,6 +75,8 @@
 
 <script>
 import { mapState } from 'vuex'
+import mallConfig from '@/../../common/mall/mall'
+
 var cloneObj = function (obj) {
   var newObj = {}
   if (obj instanceof Array) {
@@ -98,7 +101,10 @@ export default {
         let tmp = (state.user.cart && state.user.cart !== 'null' ? JSON.parse(state.user.cart) : [])
         return cloneObj(tmp)
       }
-    })
+    }),
+    totalGoodsCount () {
+      return this.cart.reduce((pre, item) => pre + item.goodsCount, 0)
+    }
   },
   data () {
     let pictures = {
@@ -126,6 +132,7 @@ export default {
       detail,
       cameraName,
       checked: true,
+      goodsDetail: mallConfig.goodsMap,
       checkedArr: {
         0: '',
         1: '',
@@ -217,4 +224,10 @@ export default {
 
 <style lang="scss" scoped>
 @import './style.scss';
+.cart-title {
+  font-size: 14px;
+  font-weight: bold;
+  padding: 27px 0 17px 20px;
+  line-height: 21px;
+}
 </style>

+ 28 - 45
mobile/src/pages/account/manage/cart/style.scss

@@ -2,21 +2,24 @@
   height: 48px;
   display: inline-block;
   line-height: 48px;
-  color: rgba(0,0,0,.7);
+  color: #202020;
   border-radius: 2px;
   width: 100%;
   background-color: #1fe4dc;
-  margin: 16px 0 0;
+  margin: 0 0 15px;
   font-size: 16px;
-  font-weight: 700;
+  font-weight: bold;
   text-align: center;
-  padding: 0 16px;
+  &.btn-continue {
+    margin-top: 27px;
+    background: #EBEBEB;
+  }
 }
 .check-con {
   box-sizing: border-box;
   margin: 0;
   padding: 0;
-  color: rgba(0, 0, 0, 0.65);
+  color: #909090;
   font-size: 14px;
   font-variant: tabular-nums;
   line-height: 1.5;
@@ -25,7 +28,6 @@
   display: inline-block;
   line-height: unset;
   cursor: pointer;
-  color: rgba(0,0,0,.65);
   font-size: 14px;
   .check-box {
     box-sizing: border-box;
@@ -59,8 +61,8 @@
     }
     .checkbox-inner {
       border-radius: 90px;
-      width: 18px;
-      height: 18px;
+      width: 16px;
+      height: 16px;
       margin-right: 8px;
       position: relative;
       top: 0;
@@ -70,36 +72,12 @@
       border: 1px solid #d9d9d9;
       border-collapse: separate;
       transition: all 0.3s;
-      &::after {
-        position: absolute;
-        top: 50%;
-        left: 16%;
-        display: table;
-        width: 5.71428571px;
-        height: 9.14285714px;
-        border: 2px solid #fff;
-        width: 6px;
-        height: 10px;
-        border-top: 0;
-        border-left: 0;
-        transform: rotate(45deg) scale(0) translate(-50%, -50%);
-        opacity: 0;
-        transition: all 0.1s cubic-bezier(0.71, -0.46, 0.88, 0.6),
-      }
-    }
-    .checkbox-inner-checked {
-      background-color: #1fe4dc;
-      border-color: #1fe4dc;
-      &::after {
-        position: absolute;
-        display: table;
-        border: 2px solid #fff;
-        border-top: 0;
-        border-left: 0;
-        transform: rotate(45deg) scale(1) translate(-50%, -50%);
-        opacity: 1;
-        transition: all 0.2s cubic-bezier(0.12, 0.4, 0.29, 1.46) 0.1s;
-        content: " ";
+      color: #fff;
+      &.checked {
+        background: #1FE4DC;
+        border-color: #1FE4DC;
+        font-size: 14px;
+        line-height: 16px;
       }
     }
   }
@@ -180,8 +158,8 @@
               align-items: center;
               .btm-price{
                 flex: 1 1;
-                color: #1fe4dc;
-                font-weight: 700;
+                color: #202020;
+                font-weight: 400;
               }
               .ipt-number{
                 display: flex;
@@ -220,13 +198,17 @@
       
     }
     .sum-con{
-      padding: 12px;
+      padding: 15px 20px 0;
+      
       .sum-price{
         text-align: right;
-        padding: 12px 0;
         line-height: 2;
+        color: #909090;
         .price-txt{
-          font-weight: 700;
+          color: #202020;
+          font-weight: bold;
+          margin-left: 15px;
+          font-size: 14px;
         }
       }
       .dec{
@@ -240,13 +222,14 @@
       text-align: center;
       width: 80%;
       margin: 0 auto;
-      padding-bottom: 24px;
+      padding-bottom: 60px;
+      margin-top: 15px;
       >div{
         font-size: 12px;
         margin-bottom: 8px;
       }
       img{
-        width:80%;
+        height: 28px;
       }
     }
   }

+ 287 - 0
mobile/src/pages/userCenter/confirm/index.vue

@@ -0,0 +1,287 @@
+<template>
+  <div class="confirm-layout">
+    <div class="confirm-title">确认订单</div>
+    <div class="box-con">
+      <div class="bc-title">收货地址</div>
+      <div class="bc-item address-item" :class="{'is-active': item.id === address.id}"  v-for="item in addressList" :key="item.id" @click="address = item">
+        <div class="bc-ct">
+          <div class="bc-contact">
+            {{item.shipName}}
+            <div>{{item.shipMobile}}</div>
+          </div>
+          <div class="bc-locotion">
+            {{`${item.shipAreaPath}${item.shipAddress}`}}
+          </div>
+        </div>
+      </div>
+      <div class="noaddress"  v-if="addressList.length < 3">
+          <p @click="$router.push({name: 'addressCreate'})"><h-icon type="jiahao" />新增收货地址</p>
+        </div>
+    </div>
+    <div class="box-con">
+      <div class="bc-title">发票信息</div>
+      <div class="invoice-con" :class="{'invoice-focus':selected}">
+        <div class="invoice-select" @click="selected=!selected">
+          <div class="select-txt">{{selectedTxt}}</div>
+          <i class="iconfont icon-xia"></i>
+        </div>
+        <ul class="invoice-item" :class="{'invoice-active':selected}">
+          <li v-for="(item,i) in invoiceType" :key="i" @click="handleItem(item)">{{item.name}}</li>
+        </ul>
+        <cinvoices v-if="selectedId!==1" :invoice='invoice2' :selectedId='selectedId' :invoicet="invoice3" @showInvoice="data=>{showinvoice=data}" :token="token" @closeInvoice="data=>{isShowInvoice=data}"/>
+      </div>
+    </div>
+    <div class="box-con">
+      <div class="bc-title">商品信息</div>
+      <div class="confirm-products">
+        <div class="confirm-products-item" v-for="(item,i) in payinfo.goods" :key="i">
+          <div class="product-thumb" :style="{'background-image': `url(${pictures[item.goodsId]})`}">
+            <!-- <img :src="" alt=""> -->
+          </div>
+          <div class="product-info">
+            <div class="product-name">
+              <p class="img-p">{{cameraName[item.goodsId]}}</p>
+            </div>
+            <ul>
+              <li class="product-name" v-for="(item,i) in detail[item.goodsId]" :key="i">{{item}}</li>
+            </ul>
+            <div class="product-count">
+              <span class="product-price">¥{{item.price}} x {{item.goodsCount}}</span>
+              <span class="product-sum fr">¥{{item.price*item.goodsCount}}</span>
+            </div>
+          </div>
+        </div>
+        <div class="cart-table-count">
+          <div class="cart-table-count-item">
+            <span class="title">商品总价:</span>
+            <span class="price">¥{{getSum()[1]}}</span>
+          </div>
+          <div class="cart-table-count-item">
+            <span class="title">税费及其他费用:</span>
+            <span class="price">
+              ¥0
+            </span>
+          </div>
+          <div class="cart-table-count-item">
+            <span class="title">运费:</span>
+            <span class="price">
+              <span class="free-shipping">
+                ¥0
+              </span>
+            </span>
+          </div>
+         <div class="cart-table-total cart-table-count-item">
+           <span class="total-title">合计:</span>
+           <span class="total-price">¥{{getSum()[1]}}</span>
+          </div>
+        </div>
+        <!-- <div class="xieyi"><input type="checkbox" />我已阅读并同意四维看看用户协议</div> -->
+      </div>
+      <div class="btn-confirm" @click="next()">付款</div>
+    </div>
+  </div>
+</template>
+
+<script>
+import { mapState } from 'vuex'
+import cinvoices from '@/components/cinvoices'
+var cloneObj = function (obj) {
+  var newObj = {}
+  if (obj instanceof Array) {
+    newObj = []
+  }
+  for (var key in obj) {
+    var val = obj[key] || ''
+    newObj[key] = typeof val === 'object' ? cloneObj(val) : val
+  }
+  return newObj
+}
+
+export default {
+  components: {
+    cinvoices,
+    showinvoice: true
+  },
+  computed: {
+    ...mapState({
+      token: state => state.user.token,
+      invoice2: state => {
+        let type = Object.prototype.toString.call(state.user.invoice2)
+        if (type === '[object Object]') {
+          return state.user.invoice2
+        }
+        let condition = state.user.invoice2 && state.user.invoice2 !== 'null' && type !== '[object Array]'
+        return (condition ? JSON.parse(state.user.invoice2) : {})
+      },
+      invoice3: state => {
+        let type = Object.prototype.toString.call(state.user.invoice3)
+        if (type === '[object Object]') {
+          return state.user.invoice3
+        }
+        let condition = state.user.invoice3 && state.user.invoice3 !== 'null' && type !== '[object Array]'
+
+        return (condition ? JSON.parse(state.user.invoice3) : {})
+      },
+      payinfo: state => {
+        let type = Object.prototype.toString.call(state.user.payinfo)
+        if (type === '[object Object]') {
+          return state.user.payinfo
+        }
+        let condition = state.user.payinfo && state.user.payinfo !== 'null' && type !== '[object Array]'
+        return condition ? JSON.parse(state.user.payinfo) : {}
+      },
+      // address: state => cloneObj(state.user.address) || {},
+      addressList: state => state.user.addressList
+    })
+  },
+  data () {
+    let invoiceType = [{
+      id: 1,
+      name: '不需要发票'
+    }, {
+      id: 2,
+      name: '增值税普票(电子发票)'
+    }, {
+      id: 3,
+      name: '增值税专用发票'
+    }]
+    let pictures = {
+      7: `${this.$cdn}images/zhijia.png`,
+      1: `${this.$cdn}images/t_product.png`,
+      4: `${this.$cdn}images/banner_pro.png`
+    }
+    let cameraName = {
+      7: `四维看看 三脚架套装`,
+      1: `四维看看 Lite二目相机`,
+      4: `四维看看 Pro八目相机`
+    }
+    let detail = {
+      7: ['四维看看 三脚架套装(标准色)'],
+      1: [
+        '四维看看 Lite二目相机(静谧黑)',
+        '容量套餐(5G/5年)',
+        '四维看看 Lite专用三脚架(标准色)'
+      ],
+      4: ['四维看看 Pro八目相机(静谧黑)', '容量套餐(10G)']
+    }
+    return {
+      pictures,
+      cameraName,
+      detail,
+      invoiceType,
+      selected: false,
+      selectedTxt: '不需要发票',
+      selectedId: 1,
+      isShowAddress: true,
+      showinvoice: true,
+      address: cloneObj({})
+    }
+  },
+  methods: {
+    handleItem (item) {
+      this.selectedTxt = item.name
+      this.selectedId = item.id
+      this.selected = false
+    },
+    next () {
+      if (!this.address.shipName) {
+        return this.$toast.show('warn', '请先填写收货地址')
+      }
+      if (!this.isShowAddress) {
+        return this.$toast.show('warn', '请先保存收货信息')
+      }
+      if (!this.showinvoice && this.selectedId !== 1) {
+        return this.$toast.show('warn', '请先保存发票信息')
+      }
+
+      let temp = cloneObj(this.payinfo)
+      let invoice = this.selectedId === 2 ? this.invoice2 : this.selectedId === 3 ? this.invoice3 : null
+      temp['invoice'] = invoice
+      temp['receiver'] = this.address
+      temp['selectedId'] = this.selectedId
+      temp['selectedTxt'] = this.selectedTxt
+
+      this.$store.commit('PAYINFO', temp)
+      this.$router.push({path: '/paytype'})
+    },
+    getSum () {
+      let sum = 0
+      let count = 0
+      this.payinfo.goods && this.payinfo.goods.forEach(item => {
+        sum += item.goodsCount * item.price
+        count += item.goodsCount
+      })
+      return [count, sum]
+    }
+  },
+  async mounted () {
+    this.selectedId = this.payinfo.selectedId ? this.payinfo.selectedId : 1
+    this.selectedTxt = this.payinfo.selectedTxt ? this.payinfo.selectedTxt : '不需要发票'
+    this.$store.dispatch('getInfo', {
+      url: '/user/getReceiverInfo',
+      name: 'address'
+    })
+    await this.$store.dispatch('updateAddressList')
+    this.address = this.addressList[0]
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+@import './style.scss';
+.confirm-products-item {
+  display: flex;
+  padding: 10px 0 17px;
+  border-bottom: 1px solid #EBEBEB;
+}
+.confirm-title {
+  font-size: 14px;
+  font-weight: bold;
+  padding: 27px 0 17px 20px;
+  line-height: 21px;
+  border-bottom: 1px solid #EBEBEB;
+}
+.product-thumb {
+  width: 60px;
+  height: 60px;
+  background-repeat: no-repeat;
+  background-size: auto 100%;
+  background-position: center center;
+  border: 1px solid #EBEBEB;
+  margin-right: 10px;
+}
+.product-info {
+  font-size: 12px;
+  color: #202020;
+  flex: 1;
+  ul {
+    height: 46px;
+  }
+  .product-name {
+    color: #909090;
+    line-height: 18px;
+    .img-p {
+      font-size: 14px;
+      font-weight: bold;
+      line-height: 21px;
+      margin-bottom: 3px;
+      color: #202020;
+    }
+  }
+}
+.cart-table-count {
+  text-align: right;
+  padding-top: 17px;
+  .cart-table-count-item {
+    margin-bottom: 4px;
+    line-height: 18px;
+  }
+  .cart-table-total {
+    font-size: 14px;
+    font-weight: bold;
+    margin-top: 13px;
+    line-height: 20px;
+  }
+}
+
+</style>

+ 34 - 29
mobile/src/pages/account/manage/confirm/style.scss

@@ -18,7 +18,7 @@
       .timeline-text{
         margin-top: 4px;
         font-size: 12px;
-        color: rgba(0,0,0,.7);
+        color: #202020;
         line-height: 18px;
         font-weight: 600;
       }
@@ -43,40 +43,34 @@
   }
   .box-con{
     background: #fff;
-    padding: 16px 16px 24px;
-    margin: 8px 0;
+    padding: 16px 20px 20px;
+    border-bottom: 1px solid #EBEBEB;
     .bc-title{
       font-size: 12px;
-      color: rgba(0,0,0,.7);
-      line-height: 16px;
+      color: #202020;
+      line-height: 18px;
       font-weight: 600;
-    }
-    .address-item{
-      background-image: url("https://static.insta360.com/assets/storage/20190615/894e2ec7c04482c8e899c319c5991608/ic_gps@2x.png");
+      margin-bottom: 18px;
     }
     .address-con{
       padding: 16px 0;
     }
     .bc-item{
-      padding: 16px;
-      margin: 8px 0;
-      background-size: 18px 32px;
-      background-repeat: no-repeat;
-      background-position: left 16px top 16px;
-      border: 1px solid #1fe4dc;
+      padding: 12px 10px;
+      border: 1px solid #ebebeb;
       position: relative;
-      background-color: #f6f9ff;
-      .noaddress{
-        color: rgba(0,0,0,.45);
+      &.is-active {
+        border-color: #1fe4dc;
       }
       .bc-ct{
-        margin-left: 32px;
-        margin-right: 50px;
         min-height: 55px;
         .bc-contact{
           font-size: 12px;
-          color: rgba(0,0,0,.7);
+          color: #202020;
           line-height: 18px;
+          font-weight: bold;
+          display: flex;
+          justify-content: space-between;
         }
         .bc-locotion{
           font-size: 10px;
@@ -89,15 +83,22 @@
         top: 16px;
         right: 16px;
         font-size: 12px;
-        color: rgba(0,0,0,.7);
+        color: #202020;
         line-height: 18px;
       }
     }
+    .noaddress{
+      color: #202020;
+      background: #EBEBEB;
+      line-height: 40px;
+      margin-top: 10px;
+      text-align: center;
+    }
     .express-item{
       background-image: url("https://4dscene.4dage.com/new4dkk/mobile/images/ic_sf_zh@2x.png");
       margin-top: 8px;
       border-radius: 2px;
-      color: rgba(0,0,0,.7);
+      color: #202020;
       padding: 15px 16px;
       background-position: right 16px center;
       background-repeat: no-repeat;
@@ -124,8 +125,7 @@
         margin-top: 8px;
         box-sizing: border-box;
         background-color: #fff;
-        border: 1px solid #d9d9d9;
-        border-top: 1.02px solid #d9d9d9;
+        border: 1px solid #EBEBEB;
         border-radius: 4px;
         outline: none;
         transition: all .3s cubic-bezier(.645,.045,.355,1);
@@ -137,7 +137,7 @@
           height: 48px;
           line-height: 48px;
           font-size: 12px;
-          color: rgba(0,0,0,.7);
+          color: #202020;
         }
       }
       .invoice-item{
@@ -156,7 +156,7 @@
           line-height: 30px;
           height: 30px;
           font-size: 12px;
-          color: rgba(0,0,0,.7);
+          color: #202020;
         }
       }
       .invoice-active{
@@ -181,11 +181,16 @@
     display: inline-block;
     line-height: 48px;
     text-align: center;
-    font-size: 14px;
-    color: rgba(0,0,0,.7);
+    font-size: 16px;
+    color: #202020;
     border-radius: 2px;
     width: 100%;
     background-color: #1fe4dc;
-    margin: 16px 0 30px;
+    margin-top: 30px;
+    font-weight: bold;
+  }
+  .address-item {
+    margin-bottom: 10px;
+
   }
 }

+ 141 - 0
mobile/src/pages/userCenter/paytype/index.vue

@@ -0,0 +1,141 @@
+<template>
+  <div class="paytype-layout">
+    <div class="paytype-header">
+      <h-icon type="jiantou" class="back" @click="$router.push({path:'/confirm'})" />
+      支付中心
+    </div>
+    <div class="paytype-session">
+      <div class="common-sub-header ">
+        当前账号:{{info.userName}}
+      </div>
+      <div class="paytype">
+        <div class="common-sub-header no-border">
+          支付方式
+        </div>
+        <div class="pay-item" v-for="(item,i) in data" :key="i" @click="goPay(item)">
+          <img :src="item.img" alt="">
+          <span>{{item.name}}</span>
+        </div>
+      </div>
+      <div class="order-money">
+        <span>应付金额:</span><span class="total_num">¥ {{getSum()[1]}}</span>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import { mapState } from 'vuex'
+import browser from '@/util/browser'
+
+export default {
+  computed: {
+    ...mapState({
+      info: state => state.user.info,
+      payinfo: state => {
+        let type = Object.prototype.toString.call(state.user.payinfo)
+        if (type === '[object Object]') {
+          return state.user.payinfo
+        }
+        let condition = state.user.payinfo && state.user.payinfo !== 'null' && type !== '[object Array]'
+        return condition ? JSON.parse(state.user.payinfo) : {}
+      }
+    })
+  },
+  data () {
+    let data = [{
+      name: '支付宝',
+      img: require('@/assets/images/refactor/userCenter/ali_pay.png'),
+      id: 1
+    }, {
+      id: 0,
+      name: '微信支付',
+      img: require('@/assets/images/refactor/userCenter/wx_pay.png')
+    }]
+    let weichatdata = [{
+      id: 0,
+      name: '微信支付',
+      img: require('@/assets/images/refactor/userCenter/wx_pay.png')
+    }]
+    return {
+      data: browser.weixin ? weichatdata : data
+    }
+  },
+  methods: {
+    goPay (item) {
+      let temp = this.payinfo
+      temp['payType'] = item.id
+      temp['payTypeName'] = item.name
+
+      this.$store.commit('PAYINFO', temp)
+      this.$router.push({path: '/submit'})
+    },
+    getSum () {
+      let sum = 0
+      let count = 0
+      this.payinfo.goods.forEach(item => {
+        sum += item.goodsCount * item.price
+        count += item.goodsCount
+      })
+      return [count, sum]
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+@import './style.scss';
+.paytype-header {
+  padding: 27px 20px 17px;
+  text-align: center;
+  font-size: 14px;
+  font-weight: bold;
+  line-height: 21px;
+  border-bottom: 1px solid #EBEBEB;
+  position: relative;
+  .back {
+    position: absolute;
+    left: 20px;
+    top: 27px;
+  }
+}
+.paytype-session {
+  padding: 0 20px 66px;
+}
+.common-sub-header {
+  color: #202020;
+  font-size: 12px;
+  font-weight: bold;
+  line-height: 18px;
+  padding: 17px 0 11px;
+  border-bottom: 1px solid #EBEBEB;
+  &.no-border {
+    border-bottom: none;
+  }
+}
+.pay-item {
+  height: 40px;
+  display: flex;
+  width: 100%;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 10px;
+  padding: 0 10px;
+  border: 1px solid #EBEBEB;
+  color: #202020;
+  img {
+    height: 28px;
+  }
+}
+.order-money {
+  margin-top: 17px;
+  font-size: 12px;
+  line-height: 18px;
+}
+.total_num {
+  color: #1FE4DC;
+  font-size: 16px;
+  line-height: 18px;
+  font-weight: bold;
+}
+</style>

+ 0 - 0
mobile/src/pages/userCenter/paytype/style.scss


+ 19 - 40
mobile/src/pages/account/manage/submit/index.vue

@@ -5,27 +5,9 @@
         <input v-model="orderType" type="text" name='orderType'>
         <input type="submit" value="提交">
     </form>
-    <div class="time-line">
-      <div class="line"></div>
-      <div class="auth">
-        <img :src="`${$cdn}images/hasLogin.png`"  alt="" class="timeline-icon">
-        <div class="timeline-text">登录信息</div>
-      </div>
-      <div class="shipping">
-        <img :src="`${$cdn}images/hasLogin.png`" alt="" class="timeline-icon">
-        <div class="timeline-text">配送信息</div>
-      </div>
-      <div class="payment">
-        <img :src="`${$cdn}images/hasLogin.png`" alt="" class="timeline-icon">
-        <div class="timeline-text">支付信息</div>
-        </div>
-      <div class="review">
-        <img :src="`${$cdn}images/spot.png`" alt="" class="timeline-icon">
-        <div class="timeline-text">订单提交</div>
-      </div>
-    </div>
+    <div class="common-header">确认订单</div>
     <div class="box-con">
-      <div class="bc-title">收货信息</div>
+      <div class="bc-title">收货地址</div>
       <div class="bc-item">
         <div class="bc-ct">
           <div class="bc-contact">
@@ -33,10 +15,9 @@
             <div>{{payinfo.receiver.shipMobile}}</div>
           </div>
           <div class="bc-locotion">
-            {{payinfo.receiver.shipAreaPath}}{{payinfo.receiver.shipAddress}}
+            {{payinfo.receiver.shipAreaPath}}<br/>{{payinfo.receiver.shipAddress}}
           </div>
         </div>
-        <div class="bc-express">顺丰速运</div>
       </div>
     </div>
     <div class="box-con">
@@ -49,8 +30,8 @@
         <div class="item-time">提交订单后,请您在新打开的页面完成支付</div>
       </div>
     </div>
-    <div class="box-con">
-      <div class="bc-title">订单概览</div>
+    <div class="box-con noborder">
+      <div class="bc-title">商品信息</div>
       <div class="confirm-products">
         <div class="confirm-products-item" v-for="(item,i) in payinfo.goods" :key="i">
           <div class="product-thumb">
@@ -75,20 +56,18 @@
             <span class="price">¥{{getSum()[1]}}</span>
           </div>
           <div class="cart-table-count-item">
-            <span class="title">税费及其他费用:</span>
+            <span class="title">税费及其它费用:</span>
             <span class="price">
               <span class="free-shipping">
-                <img :src="`${$cdn}images/free@2x.png`" alt="" class="free-shipping-img">
-                <span class="free-shipping-text">包含</span>
+                <span class="free-shipping-text">¥ 0</span>
               </span>
             </span>
           </div>
           <div class="cart-table-count-item">
-            <span class="title">运费:</span>
+            <span class="title">运费</span>
             <span class="price">
               <span class="free-shipping">
-                <img :src="`${$cdn}images/free@2x.png`" alt="" class="free-shipping-img">
-                <span class="free-shipping-text">免费</span>
+                <span class="free-shipping-text">¥ 0</span>
               </span>
             </span>
           </div>
@@ -98,16 +77,16 @@
           </div>
         </div>
       </div>
-    </div>
-    <div class="btn-submit" :style="{backgroundColor:isAgree?'#1fe4dc':'#e2e2e2'}" @click="pay">提交订单</div>
-    <div class="agree">
-      <label class="check-con" @click="isAgree=!isAgree">
-        <span class="check-box">
-          <span class="checkbox-inner" :class="{'checkbox-inner-checked':isAgree}"></span>
-        </span>
-        同意<span style="color:#1fe4dc;text-decoration: underline;" @click.stop="$router.push({name:'useimg',params:{id:1,type:0,name: 'agreement'}})">四维看看销售协议</span>
-      </label>
-      <!-- <input type="checkbox" v-model="isAgree"> -->
+      <div class="agree">
+        <label class="check-con" @click="isAgree=!isAgree">
+          <span class="check-box">
+            <span class="checkbox-inner" :class="{'checkbox-inner-checked':isAgree}"></span>
+          </span>
+          同意<span style="" @click.stop="$router.push({name:'useimg',params:{id:1,type:0,name: 'agreement'}})">四维看看销售协议</span>
+        </label>
+        <!-- <input type="checkbox" v-model="isAgree"> -->
+      </div>
+      <div class="btn-submit" :style="{backgroundColor:isAgree?'#1fe4dc':'#e2e2e2'}" @click="pay">付款</div>
     </div>
   </div>
 </template>

+ 36 - 48
mobile/src/pages/account/manage/submit/style.scss

@@ -1,12 +1,12 @@
 .submit-layout{
   .agree{
-    padding: 20px 10px;
     background: #fff;
     margin-top: 10px;
     display: flex;
     align-items: center;
     font-size: 12px;
     color: rgba(0, 0, 0, 0.7);
+    margin-bottom: 14px;
   }
   .form-con{
     opacity: 0;
@@ -33,7 +33,7 @@
       .timeline-text{
         margin-top: 4px;
         font-size: 12px;
-        color: rgba(0,0,0,.7);
+        color: #202020;
         line-height: 18px;
         font-weight: 600;
       }
@@ -58,38 +58,46 @@
   }
   .box-con{
     background: #fff;
-    padding: 16px 16px;
+    padding: 16px 20px;
     margin: 8px 0;
+    padding-bottom: 18px;
+    border-bottom: 1px solid #EBEBEB;
+    &.noborder {
+      border-bottom: none;
+    }
     .bc-title{
       font-size: 12px;
-      color: rgba(0,0,0,.7);
+      color: #202020;
       line-height: 16px;
       font-weight: 600;
       display: flex;
       justify-content: space-between;
     }
     .bc-item{
-      margin: 8px 0;
+      margin: 15px 0 0;
+      
       position: relative;
+      
       .bc-ct{
         padding-right: 50px;
-        border-bottom: 1px solid #f2f2f2;
+        
         padding-bottom: 8px;
         .bc-contact{
           font-size: 12px;
-          color: rgba(0,0,0,.7);
+          color: #202020;
           line-height: 18px;
+          font-weight: bold;
         }
         .bc-locotion{
-          font-size: 10px;
-          color: rgba(0,0,0,.45);
-          line-height: 1.2;
+          font-size: 12px;
+          color:#909090;
+          line-height: 18px;
           margin-top: 4px;
         }
       }
       .bc-express{
         font-size: 12px;
-        color: rgba(0,0,0,.7);
+        color: #202020;
         line-height: 18px;
         margin-top: 8px;
       }
@@ -150,50 +158,29 @@
               flex: 1 1;
             }
             .product-sum{
-              color: rgba(0,0,0,.7);
+              color: #202020;
               font-weight: 700;
             }
           }
+          ul {
+            .product-name {
+              color: #909090;
+            }
+          }
         }
       }
-      .cart-table-count{
-        margin-top: 16px;
+      .cart-table-count {
+        text-align: right;
+        padding-top: 5px;
         .cart-table-count-item {
-          height: 32px;
-          line-height: 32px;
           margin-bottom: 4px;
-          .title{
-            font-size: 12px;
-            color: rgba(0,0,0,.45);
-            line-height: 16px;
-            float: left;
-          }
-          .price{
-            font-size: 12px;
-            color: rgba(0,0,0,.7);
-            line-height: 18px;
-            float: right;
-            .free-shipping-img{
-              height: 24px;
-              vertical-align: middle;
-            }
-          }
+          line-height: 18px;
         }
-        .cart-table-total{
-          margin-top: 16px;
-          .total-title{
-            font-size: 14px;
-            color: rgba(0,0,0,.7);
-            line-height: 24px;
-            float: left;
-          }
-          .total-price{
-            font-size: 14px;
-            color: rgba(0,0,0,.7);
-            line-height: 24px;
-            float: right;
-            font-weight: 600;
-          }
+        .cart-table-total {
+          font-size: 14px;
+          font-weight: bold;
+          margin-top: 13px;
+          line-height: 20px;
         }
       }
       
@@ -205,7 +192,8 @@
     line-height: 48px;
     text-align: center;
     font-size: 14px;
-    color: rgba(0,0,0,.7);
+    color: #202020;
+    font-weight: bold;
     border-radius: 2px;
     width: 100%;
     background-color: #1fe4dc;

+ 6 - 4
mobile/src/pages/video/index.vue

@@ -10,10 +10,12 @@
       <p class="common-title">{{langVideoCourse.name}}</p>
       <!-- <p class="b-text3">{{langVideoCourse.sub}}</p> -->
       <h-row tag="ul" :gutter="20" class="i-ul">
-        <h-col tag="li" :span="12" @click="itemHandle(sub)" v-for="(sub,idx) in langVideoCourse.items" :key="idx">
-          <img class="li-img" :src="`${$cdn}course/img/${sub.code}.jpg`" alt="">
-          <img class="bofang" src="@/assets/images/refactor/service/play-btn.png" alt="">
-          <h3 class="btom-text">{{sub.name}}</h3>
+        <h-col tag="li" :span="12" v-for="(sub,idx) in langVideoCourse.items" :key="idx">
+          <div  @click="itemHandle(sub)">
+            <img class="li-img" :src="`${$cdn}course/img/${sub.code}.jpg`" alt="">
+            <img class="bofang" src="@/assets/images/refactor/service/play-btn.png" alt="">
+            <h3 class="btom-text">{{sub.name}}</h3>
+          </div>
         </h-col>
       </h-row>
     </div>

+ 67 - 40
mobile/src/router/index.js

@@ -55,6 +55,73 @@ let router = new Router({
       name: 'about',
       component: resolve => require(['@/pages/about'], resolve)
     },
+    {
+      path: '/news',
+      name: 'news',
+      component: resolve => require(['@/pages/news'], resolve)
+    },
+    {
+      path: '/login',
+      name: 'login',
+      component: resolve => require(['@/pages/account/login'], resolve),
+      meta: {
+        hideFooterBanner: true
+      }
+    },
+    {
+      path: '/codeLogin',
+      name: 'codeLogin',
+      component: resolve => require(['@/pages/account/codeLogin'], resolve),
+      meta: {
+        hideFooterBanner: true
+      }
+    },
+    {
+      path: '/register',
+      name: 'register',
+      component: resolve => require(['@/pages/account/register'], resolve),
+      meta: {
+        hideFooterBanner: true
+      }
+    },
+    {
+      path: '/mailRegister',
+      name: 'mailRegister',
+      component: resolve => require(['@/pages/account/mailRegister'], resolve),
+      meta: {
+        hideFooterBanner: true
+      }
+    },
+    {
+      name: 'cart',
+      path: '/cart',
+      component: resolve => require(['@/pages/userCenter/cart'], resolve),
+      meta: {requireAuth: true, noEnglish: true, hideFooterBanner: true}
+    },
+    {
+      name: 'confirm',
+      path: '/confirm',
+      component: resolve => require(['@/pages/userCenter/confirm'], resolve),
+      meta: {requireAuth: true, noEnglish: true, hideFooterBanner: true}
+    },
+    {
+      name: 'addressCreate',
+      path: '/addressCreate',
+      component: resolve => require(['@/pages/userCenter/addressForm'], resolve),
+      meta: {requireAuth: true, noEnglish: true, hideFooterBanner: true}
+    },
+    {
+      name: 'paytype',
+      path: '/paytype',
+      component: resolve => require(['@/pages/userCenter/paytype'], resolve),
+      meta: {requireAuth: true, noEnglish: true}
+    },
+    {
+      name: 'submit',
+      path: '/submit',
+      component: resolve => require(['@/pages/userCenter/submit'], resolve),
+      meta: {requireAuth: true}
+    },
     // 重构版未做的
     {
       path: '/introduce/:id',
@@ -92,22 +159,6 @@ let router = new Router({
       component: resolve => require(['@/pages/check'], resolve)
     },
     {
-      path: '/login',
-      name: 'login',
-      component: resolve => require(['@/pages/account/login'], resolve)
-    },
-    {
-      path: '/codeLogin',
-      name: 'codeLogin',
-      component: resolve => require(['@/pages/account/codeLogin'], resolve)
-    },
-    {
-      path: '/register',
-      name: 'register',
-      component: resolve => require(['@/pages/account/register'], resolve)
-    },
-
-    {
       path: '/forget',
       name: 'forget',
       component: resolve => require(['@/pages/account/forget'], resolve)
@@ -185,30 +236,6 @@ let router = new Router({
           meta: {requireAuth: true}
         },
         {
-          name: 'confirm',
-          path: '/confirm',
-          component: resolve => require(['@/pages/account/manage/confirm'], resolve),
-          meta: {requireAuth: true, noEnglish: true}
-        },
-        {
-          name: 'submit',
-          path: '/submit',
-          component: resolve => require(['@/pages/account/manage/submit'], resolve),
-          meta: {requireAuth: true}
-        },
-        {
-          name: 'paytype',
-          path: '/paytype',
-          component: resolve => require(['@/pages/account/manage/paytype'], resolve),
-          meta: {requireAuth: true, noEnglish: true}
-        },
-        {
-          name: 'cart',
-          path: '/cart',
-          component: resolve => require(['@/pages/account/manage/cart'], resolve),
-          meta: {requireAuth: true, noEnglish: true}
-        },
-        {
           name: 'vieworder',
           path: '/vieworder',
           component: resolve => require(['@/pages/account/manage/vieworder'], resolve),

+ 1 - 1
mobile/src/store/language/cn/home.js

@@ -197,7 +197,7 @@ export default{
     scansub: '打开四维看看app扫一扫登录',
     forget: '忘记密码',
     codeLogin: '验证码登录',
-    defaultLogin: '账号密码登录',
+    defaultLogin: '密码登录',
     loginsub1: '还没有账号?',
     loginsub2: '立即注册',
     resigter1: '已有账号,',

+ 18 - 19
mobile/src/store/language/cn/purchase.js

@@ -10,24 +10,15 @@ export default{
   tiaokuan: '* 付款成功后5个工作日内发货,默认顺丰快递包邮',
   guige: {
     name: '技术规格',
-    dec: '注:本页面所列配置及参数均以实际上市产品为准,如有变更,恕不另行通知',
+    dec: '注:本页面所列配置及参数均以实际上市产品为准,如有变更,恕不另行通知',
     arr: [
       {
         name: '机身尺寸',
-        val: ['高度:220.7毫米', '宽度:78.2毫米', '厚度:78.2毫米']
+        val: [`高度:220.7mm 宽度:78.2mm 厚度:78.2mm`]
       },
       {
-        name: '镜头',
-        val: [
-          '类型:200°鱼眼镜头',
-          '孔径:f/2.0',
-          '数量:8个',
-          '分辨率:4608*3456像素(每个);8192*4096像素(合计)'
-        ]
-      },
-      {
-        name: '传感器',
-        val: ['范围:1/2.3英寸', '数量:8个']
+        name: '分辨率',
+        val: `分辨率:4608*3456像素(每个);8192*4096像素(合计)`
       },
       {
         name: '存储内存',
@@ -36,17 +27,25 @@ export default{
         ]
       },
       {
-        name: '电池',
+        name: 'WiFi',
         val: [
-          '7.4V 4200mAh',
-          '可通过USB快速充电'
+          `802.11a/b/g/n网络协议 支持2.4/5GHz通信`
         ]
       },
       {
-        name: 'WiFi',
+        name: '镜头',
+        val: [
+          `类型:200°鱼眼镜头 孔径:f/2.0 数量:8个 `
+        ]
+      },
+      {
+        name: '传感器',
+        val: [`范围:1/2.3英寸 数量:8个`]
+      },
+      {
+        name: '电池',
         val: [
-          '802.11a/b/g/n网络协议',
-          '支持2.4/5GHz通信'
+          `7.4V 4200mAh 可通过USB快速充电`
         ]
       },
       {

+ 14 - 2
mobile/src/store/user.js

@@ -4,6 +4,7 @@ import Toast from '@/components/toast/toast'
 import Cookies from 'js-cookie'
 import toastZH from '@/store/language/cn/toast'
 import toastEN from '@/store/language/en/toast'
+import API from '@/apis'
 
 Vue.use(Toast)
 
@@ -55,7 +56,8 @@ export default {
     recordinfo,
     invoice2: invoice2,
     invoice3: invoice3,
-    ...dataObj
+    ...dataObj,
+    addressList: []
   },
 
   mutations: {
@@ -149,6 +151,10 @@ export default {
 
     user_not_login (state) {
       state.name = null
+    },
+
+    UPDATEADDRESSLIST (state, list) {
+      state.addressList = list
     }
   },
 
@@ -357,6 +363,7 @@ export default {
       let toastCode = localStorage.getItem('language') === 'en' ? toastEN : toastZH
 
       let {phone, code, type = ''} = item
+      console.log(item)
       let areaNum = Number(code) || 86
       if (phone) {
         let resp = await http
@@ -376,7 +383,7 @@ export default {
             break
         }
         let params = {
-          phoneNum: Number(phone),
+          phoneNum: phone,
           areaNum
         }
         http({
@@ -449,6 +456,11 @@ export default {
       let data = res.data
       if (data.code !== 0) return
       context.commit('INVOICEDEVICE', data.data)
+    },
+    updateAddressList ({ commit }) {
+      return API.getReceiverList().then(res => {
+        commit('UPDATEADDRESSLIST', res.data.data)
+      })
     }
   }
 }

+ 7 - 1
mobile/src/util/http.js

@@ -8,7 +8,7 @@ let vue = new Vue()
 const exceptUrls = ['/sso/user/logout', '/sso/user/sendUserInfo', '/user/checkToken']
 
 // axios.defaults.baseURL = process.env.NODE_ENV === 'development' ? 'http://120.79.15.136:8086/api' : '/api'
-axios.defaults.baseURL = process.env.NODE_ENV === 'development' ? 'https://test.4dkankan.com/api' : '/api'
+axios.defaults.baseURL = process.env.NODE_ENV === 'development' ? '/api' : '/api'
 
 // 请求超时时限
 axios.defaults.timeout = 15000
@@ -40,6 +40,12 @@ axios.interceptors.request.use(function (config) {
       return config
     }
   }
+
+  if (store.state.user.token) {
+    config.headers = {
+      token: store.state.user.token
+    }
+  }
   vue.$toast.showLoading()
   return config
 }, function (error) {

+ 1 - 1
pc/src/config/newsData.js

@@ -16,7 +16,7 @@ export const News = [
     link: 'https://pub-zhtb.hizh.cn/s/202007/14/AP5f0dcd64e4b02ae7a2c80d08.html'
   },
   {
-    img: require('@/assets/images/refactor/news/new-3@2x.png'),
+    img: require('@/assets/images/home/solutions-house.png'),
     time: '2020年7月10日',
     title: '「四维时代」发布新品3D相机四维看看Pro,售价不到...',
     text: '“高性价比VR采集计算设备,消费级简易操作”2020年上半年的疫情防疫措施,使国内房地产企业纷纷通过VR看房形式进行带看。四维时代近期发布了3D空间相机四维看看Pro,为相关领域提供稳定、精确且低成本的数字化解决方案,并在行业内首次实现低成本、快速复制和规模化。该产品售价9800元,可以帮助使用者通过简单操作录入大量VR信息。',

+ 7 - 4
pc/src/page/home2/index.vue

@@ -2,7 +2,7 @@
   <div class="home-layout">
     <div class="plate01">
       <div class="my-video">
-        <video :src="language==='en'?`${$cdn}video/banner1.mp4`:require('@/assets/images/refactor/home-video.mp4')" autoplay muted loop></video>
+        <video :src="language==='en'?`${$cdn}video/banner1.mp4`: 'https://4dscene.oss-cn-shenzhen.aliyuncs.com/new4dkk/v2/video/2020%E5%AE%98%E7%BD%91Version2%20%E4%B8%8D%E5%B8%A6%E5%AD%97_3%281%29.mp4'" autoplay muted loop></video>
         <div class="container">
           <div class="video-info">
           <h1>四维看看Pro</h1>
@@ -152,7 +152,8 @@ export default {
       space: [
         {
           text: '雍正故宫',
-          bgImg: require('@/assets/images/home/4case_01@2x.png')
+          bgImg: require('@/assets/images/home/4case_01@2x.png'),
+          link: 'https://www.4dkankan.com/showPC.html?m=JPoqsQXL'
         },
         {
           text: '小米有品',
@@ -161,11 +162,13 @@ export default {
         },
         {
           text: '华发依山郡',
-          bgImg: require('@/assets/images/home/4case_03@2x.png')
+          bgImg: require('@/assets/images/home/4case_03@2x.png'),
+          link: 'https://www.4dkankan.com/spc.html?m=JBx2hetpp'
         },
         {
           text: '万豪酒店',
-          bgImg: require('@/assets/images/home/4case_04@2x.png')
+          bgImg: require('@/assets/images/home/4case_04@2x.png'),
+          link: 'https://www.4dkankan.com/showPC.html?m=PoCGXVFP'
         }
       ],
       plate04List: [