tremble 5 年之前
父节点
当前提交
40c57f8437
共有 100 个文件被更改,包括 8256 次插入430 次删除
  1. 17 6
      mobile/src/assets/font/iconfont.css
  2. 二进制
      mobile/src/assets/images/agreement/binocular/zh/1.jpg
  3. 二进制
      mobile/src/assets/images/agreement/binocular/zh/2.jpg
  4. 二进制
      mobile/src/assets/images/agreement/eight/zh/1.jpg
  5. 二进制
      mobile/src/assets/images/agreement/eight/zh/2.jpg
  6. 151 0
      mobile/src/assets/style/public.scss
  7. 100 0
      mobile/src/components/browse/index.vue
  8. 13 13
      mobile/src/components/cinvoices/index.vue
  9. 185 54
      mobile/src/components/createInvoice/index.vue
  10. 20 1
      mobile/src/components/createInvoice/style.scss
  11. 4793 0
      mobile/src/components/editInvoice/city.js
  12. 305 0
      mobile/src/components/editInvoice/edit.vue
  13. 53 0
      mobile/src/components/editInvoice/index.vue
  14. 86 0
      mobile/src/components/editInvoice/invoice.js
  15. 236 0
      mobile/src/components/editInvoice/style.scss
  16. 1 1
      mobile/src/components/invoices/index.vue
  17. 1 1
      mobile/src/components/toast/binding.vue
  18. 3 2
      mobile/src/components/toast/index.vue
  19. 3 2
      mobile/src/components/toast/style.scss
  20. 4 1
      mobile/src/components/toast/toast.js
  21. 10 3
      mobile/src/pages/404/index.vue
  22. 2 2
      mobile/src/pages/account/codeLogin/index.vue
  23. 7 2
      mobile/src/pages/account/codeLogin/style.scss
  24. 2 2
      mobile/src/pages/account/forget/index.vue
  25. 8 1
      mobile/src/pages/account/forget/style.scss
  26. 23 0
      mobile/src/pages/account/login/index.vue
  27. 1 1
      mobile/src/pages/account/manage/cart/index.vue
  28. 11 4
      mobile/src/pages/account/manage/device/index.vue
  29. 1 1
      mobile/src/pages/account/manage/index.vue
  30. 111 22
      mobile/src/pages/account/manage/information/index.vue
  31. 207 47
      mobile/src/pages/account/manage/information/style.scss
  32. 35 7
      mobile/src/pages/account/manage/myscene/index.vue
  33. 17 0
      mobile/src/pages/account/manage/myscene/style.scss
  34. 99 23
      mobile/src/pages/account/manage/order/index.vue
  35. 95 2
      mobile/src/pages/account/manage/order/style.scss
  36. 133 0
      mobile/src/pages/account/manage/orderInvoice/index.vue
  37. 15 2
      mobile/src/pages/account/manage/submit/index.vue
  38. 10 1
      mobile/src/pages/account/manage/submit/style.scss
  39. 1 1
      mobile/src/pages/account/manage/vieworder/index.vue
  40. 16 12
      mobile/src/pages/account/register/index.vue
  41. 13 2
      mobile/src/pages/account/register/style.scss
  42. 1 1
      mobile/src/pages/agent/index.vue
  43. 2 1
      mobile/src/pages/agent/style.scss
  44. 1 0
      mobile/src/pages/cases/index.vue
  45. 1 1
      mobile/src/pages/home/index.vue
  46. 2 2
      mobile/src/pages/introduce/index.vue
  47. 13 5
      mobile/src/pages/layout/header.vue
  48. 1 0
      mobile/src/pages/layout/style.scss
  49. 26 2
      mobile/src/pages/purchase/index.vue
  50. 29 2
      mobile/src/pages/purchasezhijia/index.vue
  51. 32 1
      mobile/src/pages/service/temp/config.js
  52. 6 0
      mobile/src/router/index.js
  53. 2 0
      mobile/src/store/language/cn/home.js
  54. 36 2
      mobile/src/store/language/cn/manage.js
  55. 3 1
      mobile/src/store/language/cn/toast.js
  56. 2 0
      mobile/src/store/language/en/home.js
  57. 38 3
      mobile/src/store/language/en/manage.js
  58. 2 2
      mobile/src/store/language/en/purchase.js
  59. 3 1
      mobile/src/store/language/en/toast.js
  60. 15 1
      mobile/src/store/language/home_cn.js
  61. 16 1
      mobile/src/store/language/home_en.js
  62. 1 1
      mobile/src/store/language/index.js
  63. 8 0
      mobile/src/store/user.js
  64. 3 1
      mobile/src/util/index.js
  65. 18 6
      pc/src/assets/font/iconfont.css
  66. 92 0
      pc/src/assets/style/public.scss
  67. 29 0
      pc/src/components/browse/index.vue
  68. 51 0
      pc/src/components/browse/style.scss
  69. 357 0
      pc/src/components/editInvoice/edit.vue
  70. 57 0
      pc/src/components/editInvoice/index.vue
  71. 86 0
      pc/src/components/editInvoice/invoice.js
  72. 12 10
      pc/src/components/toast/editInvoice.vue
  73. 4 3
      pc/src/components/toast/index.vue
  74. 3 2
      pc/src/components/toast/toast.js
  75. 10 3
      pc/src/page/404/index.vue
  76. 1 1
      pc/src/page/agent/index.vue
  77. 2 1
      pc/src/page/agent/style.scss
  78. 7 12
      pc/src/page/cases/index.vue
  79. 2 2
      pc/src/page/cases/style.scss
  80. 1 1
      pc/src/page/chat/index.vue
  81. 8 1
      pc/src/page/home2/index.vue
  82. 2 0
      pc/src/page/layout/aside/index.vue
  83. 1 1
      pc/src/page/layout/aside/temp/ctemp/detail.scss
  84. 14 12
      pc/src/page/layout/aside/temp/ctemp/detail.vue
  85. 2 1
      pc/src/page/layout/aside/temp/ltemp/deviceLogin.vue
  86. 1 1
      pc/src/page/layout/aside/temp/ltemp/forget.vue
  87. 24 1
      pc/src/page/layout/aside/temp/ltemp/login.vue
  88. 1 1
      pc/src/page/layout/aside/temp/ltemp/register.vue
  89. 1 1
      pc/src/page/layout/aside/temp/ltemp/style.scss
  90. 2 6
      pc/src/page/layout/footer.vue
  91. 19 2
      pc/src/page/manage/index.vue
  92. 10 3
      pc/src/page/manage/temp/consumption.vue
  93. 150 52
      pc/src/page/manage/temp/information.vue
  94. 161 41
      pc/src/page/manage/temp/order.vue
  95. 17 15
      pc/src/page/manage/temp/scene.vue
  96. 1 1
      pc/src/page/navs/search/item/index.vue
  97. 31 2
      pc/src/page/purchase/index.vue
  98. 14 3
      pc/src/page/purchase/style.scss
  99. 34 1
      pc/src/page/purchasezhijia/index.vue
  100. 0 0
      pc/src/page/purchasezhijia/style.scss

+ 17 - 6
mobile/src/assets/font/iconfont.css

@@ -1,11 +1,11 @@
 @font-face {
   font-family: 'iconfont';  /* project id 941679 */
-  src: url('//at.alicdn.com/t/font_941679_cx64etzgw84.eot');
-  src: url('//at.alicdn.com/t/font_941679_cx64etzgw84.eot?#iefix') format('embedded-opentype'),
-  url('//at.alicdn.com/t/font_941679_cx64etzgw84.woff2') format('woff2'),
-  url('//at.alicdn.com/t/font_941679_cx64etzgw84.woff') format('woff'),
-  url('//at.alicdn.com/t/font_941679_cx64etzgw84.ttf') format('truetype'),
-  url('//at.alicdn.com/t/font_941679_cx64etzgw84.svg#iconfont') format('svg');
+  src: url('//at.alicdn.com/t/font_941679_itececxzw5a.eot');
+  src: url('//at.alicdn.com/t/font_941679_itececxzw5a.eot?#iefix') format('embedded-opentype'),
+  url('//at.alicdn.com/t/font_941679_itececxzw5a.woff2') format('woff2'),
+  url('//at.alicdn.com/t/font_941679_itececxzw5a.woff') format('woff'),
+  url('//at.alicdn.com/t/font_941679_itececxzw5a.ttf') format('truetype'),
+  url('//at.alicdn.com/t/font_941679_itececxzw5a.svg#iconfont') format('svg');
 }
 
 .iconfont {
@@ -108,6 +108,10 @@
   content: "\e637";
 }
 
+.icon-industry_home:before {
+  content: "\e6a7";
+}
+
 .icon-industry_gover:before {
   content: "\e638";
 }
@@ -320,3 +324,10 @@
   content: "\e676";
 }
 
+.icon-edit:before {
+  content: "\e6a6";
+}
+
+.icon-choice:before {
+  content: "\e6a5";
+}

二进制
mobile/src/assets/images/agreement/binocular/zh/1.jpg


二进制
mobile/src/assets/images/agreement/binocular/zh/2.jpg


二进制
mobile/src/assets/images/agreement/eight/zh/1.jpg


二进制
mobile/src/assets/images/agreement/eight/zh/2.jpg


+ 151 - 0
mobile/src/assets/style/public.scss

@@ -128,6 +128,148 @@ body{
   padding: 0 16px;
 }
 
+.loading-hover{
+  position: absolute;
+  width: 100%;
+  height: 100%;
+  transform: translate(-50%,-50%);
+  top: 50%;
+  left: 50%;
+  background-color: rgba(0, 0, 0, 0.7);
+  text-align: center;
+}
+
+.loading-hover p{
+ color: #fff;
+ margin-top: 10px;
+}
+
+.loading-hover  .loading-icon{
+  transform: translate(-50%,-50%);
+  top: 50%;
+  left: 50%;
+  position: absolute;
+}
+
+.refreshing-loader{
+  animation: refreshing-loader 1000ms infinite linear;
+  border-radius: 25px;
+  border: 5px solid #fff;
+  border-left-color: transparent;
+  color: transparent;
+  display: inline-block;
+  font-size: 10px;
+  line-height: 1.2;
+  width: 50px;
+  height: 50px;
+  text-indent: 100%;
+}
+
+.refreshing-loader::after{
+  display: block;
+  border: 8px solid transparent;
+  border-top-color: #fff;
+  border-left-color: #fff;
+  content: '';
+  width: 0;
+  height: 0;
+  overflow: hidden;
+  margin-left: -2px;
+  margin-top: 30px;
+}
+
+.check-con {
+  box-sizing: border-box;
+  margin: 0;
+  padding: 0;
+  color: rgba(0, 0, 0, 0.65);
+  font-size: 14px;
+  font-variant: tabular-nums;
+  line-height: 1.5;
+  list-style: none;
+  font-feature-settings: "tnum", "tnum";
+  display: inline-block;
+  line-height: unset;
+  cursor: pointer;
+  color: rgba(0,0,0,.65);
+  font-size: 12px;
+  .check-box {
+    box-sizing: border-box;
+    margin: 0;
+    padding: 0;
+    color: rgba(0, 0, 0, 0.65);
+    font-size: 12px;
+    font-variant: tabular-nums;
+    line-height: 1.5;
+    list-style: none;
+    font-feature-settings: "tnum", "tnum";
+    position: relative;
+    top: -0.09em;
+    display: inline-block;
+    line-height: 1;
+    white-space: nowrap;
+    vertical-align: middle;
+    outline: none;
+    cursor: pointer;
+    .checkbox-input {
+      position: absolute;
+      top: 0;
+      right: 0;
+      bottom: 0;
+      left: 0;
+      z-index: 1;
+      width: 100%;
+      height: 100%;
+      cursor: pointer;
+      opacity: 0;
+    }
+    .checkbox-inner {
+      width: 14px;
+      height: 14px;
+      margin-right: 2px;
+      position: relative;
+      top: 0;
+      left: 0;
+      display: block;
+      background-color: #fff;
+      border: 1px solid #d9d9d9;
+      border-collapse: separate;
+      transition: all 0.3s;
+      &::after {
+        position: absolute;
+        top: 42%;
+        left: 12%;
+        display: table;
+        width: 5px;
+        height: 9px;
+        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(0.8) translate(-50%, -50%);
+        opacity: 1;
+        transition: all 0.2s cubic-bezier(0.12, 0.4, 0.29, 1.46) 0.1s;
+        content: " ";
+      }
+    }
+  }
+}
+
 @keyframes rotateLoader {
   0% {
       transform: rotate(0deg)
@@ -148,4 +290,13 @@ body{
   .b-text3 {
     font-size: 12px;
   }
+}
+
+@keyframes refreshing-loader {
+  0% {
+    transform: rotate(0deg);
+  }
+  100% {
+    transform: rotate(360deg);
+  }
 }

+ 100 - 0
mobile/src/components/browse/index.vue

@@ -0,0 +1,100 @@
+<template>
+  <div class="swiper-container">
+    <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" :src="`${$cdn}images/${floder}/${item.big}.mp4`" autoplay muted loop></video>
+          <img v-else class="main-img" :src="`${$cdn}images/${floder}/${item.big}.png`">
+        </div>
+      </swiper-slide>
+      <div class="swiper-pagination" slot="pagination"></div>
+    </swiper>
+  </div>
+</template>
+<script>
+import 'swiper/dist/css/swiper.css'
+import { swiper, swiperSlide } from 'vue-awesome-swiper'
+
+let wh = {
+  width: window.innerWidth,
+  height: window.innerHeight
+}
+
+export default {
+  props: ['idata', 'floder', 'mTop'],
+  data () {
+    return {
+      wh,
+      swiperOption: {
+        slidesPerView: 'auto',
+        autoplay: false,
+        centeredSlides: true,
+        watchSlidesProgress: true,
+        pagination: {
+          el: '.swiper-pagination'
+          // bulletClass: 'my-bullet'
+        },
+        loop: true,
+        paginationClickable: true
+      }
+    }
+  },
+  methods: {
+    goto (url) {
+      window.open(url, '_blank')
+    }
+  },
+  components: {
+    swiper,
+    swiperSlide
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.swiper-wrapper{
+  position: relative!important;
+}
+
+.swiper-slide {
+  width: 100%;
+  transform-style: preserve-3d;
+}
+
+.swiper-slide {
+  .main-img {
+    width: 100%;
+    margin: 0 auto;
+    display: block;
+  }
+}
+
+.swiper-slide {
+  .s-item{
+    width: 100%;
+  }
+}
+
+.swiper-slide{
+    width: 100%;
+   .s-item{
+      width: 100%;
+      display: flex;
+      align-items: center;
+      video,img{
+        // position: absolute;
+        // transform: translate(-50%,-50%);
+        // left: 50%;
+        // top: 50%;
+        width: 100%;
+      }
+   }
+}
+
+</style>
+
+<style>
+.swiper-pagination-bullet-active{
+  background: #1fe4dc!important;
+}
+</style>

+ 13 - 13
mobile/src/components/cinvoices/index.vue

@@ -18,7 +18,7 @@
         <template v-else>
           <div class="bc-item">
             <div class="bc-contact">
-              <span>暂无发票信息</span>
+              <span>暂无信息</span>
             </div>
             <div class="bc-edit" @click="isShowInvoice3=false">编辑</div>
           </div>
@@ -27,7 +27,7 @@
       <template v-else>
         <div class="address-input-item">
           <div class="address-sub">
-            <div class="top-title">抬头名称</div>
+            <div class="top-title">发票抬头</div>
             <div class="ant-input">
               <input @blur="blurHandle"
                 v-model="tempInvoice3.title"
@@ -43,23 +43,23 @@
           <div class="address-sub">
             <div class="top-title">税务登记号</div>
             <div class="ant-input">
-              <input @blur="blurHandle" oninput="value=value.replace(/[^\d]/g,'')" maxlength='18' v-model="tempInvoice3.code" type="text" placeholder="请输入税务登记号" />
+              <input @blur="blurHandle" oninput="value=value.replace(/[^\d]/g,'')" maxlength='18' v-model="tempInvoice3.code" type="text" placeholder="请输入18位税务登记号" />
             </div>
           </div>
         </div>
         <div class="address-input-item">
           <div class="address-sub">
-            <div class="top-title">地址</div>
+            <div class="top-title">注册地址</div>
             <div class="ant-input">
-              <input @blur="blurHandle" v-model="tempInvoice3.organizedAddress" type="text" placeholder="公司地址" />
+              <input @blur="blurHandle" v-model="tempInvoice3.organizedAddress" type="text" placeholder="注册地址" />
             </div>
           </div>
         </div>
         <div class="address-input-item">
           <div class="address-sub">
-            <div class="top-title">电话号码</div>
+            <div class="top-title">注册电话</div>
             <div class="ant-input">
-              <input @blur="blurHandle" v-model="tempInvoice3.registerPhone" type="text" placeholder="公司电话号码" />
+              <input @blur="blurHandle" oninput="value=value.replace(/[^\d\-]/g,'')" v-model="tempInvoice3.registerPhone" type="text" placeholder="注册电话" />
             </div>
           </div>
         </div>
@@ -102,7 +102,7 @@
         <template v-else>
           <div class="bc-item">
             <div class="bc-contact">
-              <span>暂无发票信息</span>
+              <span>暂无信息</span>
             </div>
             <div class="bc-edit" @click="isShowInvoice2=false">编辑</div>
           </div>
@@ -111,9 +111,9 @@
       <template v-else>
         <div class="address-input-item">
           <div class="address-sub">
-            <div class="top-title">抬头名称</div>
+            <div class="top-title">发票抬头</div>
             <div class="ant-input">
-              <input @blur="blurHandle" maxlength='15' v-model="tempInvoice2.title" type="text" placeholder="发票抬头" />
+              <input @blur="blurHandle" maxlength='15' v-model="tempInvoice2.title" type="text" placeholder="请输入发票抬头" />
             </div>
           </div>
         </div>
@@ -121,7 +121,7 @@
           <div class="address-sub">
             <div class="top-title no-require">税务登记号</div>
             <div class="ant-input">
-              <input @blur="blurHandle" oninput="value=value.replace(/[^\d]/g,'')" maxlength='18' v-model="tempInvoice2.code" type="text" placeholder="18位税务登记号" />
+              <input @blur="blurHandle" oninput="value=value.replace(/[^\d]/g,'')" maxlength='18' v-model="tempInvoice2.code" type="text" placeholder="请输入18位税务登记号" />
             </div>
           </div>
         </div>
@@ -129,7 +129,7 @@
           <div class="address-sub">
             <div class="top-title">电子邮箱</div>
             <div class="ant-input">
-              <input @blur="blurHandle" v-model="tempInvoice2.emailAddress" type="text" placeholder="电子邮箱" />
+              <input @blur="blurHandle" v-model="tempInvoice2.emailAddress" type="text" placeholder="请输入电子邮箱" />
             </div>
           </div>
         </div>
@@ -298,7 +298,7 @@ export default {
           return this.$toast.show('warn', this.langToast['21'])
         }
 
-        if (!reg.phone.test(registerPhone)) {
+        if (!reg.guhua.test(registerPhone)) {
           return this.$toast.show('warn', this.langToast['22'])
         }
       }

+ 185 - 54
mobile/src/components/createInvoice/index.vue

@@ -8,8 +8,11 @@
         <div class="address-input-item">
           <div class="address-sub">
             <div class="top-title">设备选择</div>
-            <div class="ant-input prov" @click="handleSelect('device')">
+            <div class="ant-input prov sajiao" @click="handleSelect('device')">
               {{activeDevice.childName||'设备选择'}}
+              <div class="xia">
+                <i class="iconfont icon-xia" ></i>
+              </div>
               <ul v-if="device">
                 <li
                   v-for="(item,i) in invoicedevice"
@@ -29,9 +32,9 @@
       <div class="address-input-con">
         <div class="address-input-item">
           <div class="address-sub">
-            <div class="top-title">开票金额</div>
+            <div class="top-title">开票金额 (可开票额度:{{max}}元)</div>
             <div class="ant-input">
-              <input v-model="amount" oninput="value=Math.max(Number(value.replace(/[^\d]/g,'')),1)"  type="text" placeholder="请输入开票金额" />
+              <input v-model="amount" @input="limitMoney" type="text" placeholder="请输入开票金额" />
             </div>
           </div>
         </div>
@@ -46,45 +49,45 @@
           <span class="check-box">
             <span class="checkbox-inner" :class="{'checkbox-inner-checked':type==='geren'}"></span>
           </span>
-          <span>个人</span>
+          <span>增值税普票(电子发票)</span>
         </label>
         <label class="check-con" @click="type='qiye'">
           <span class="check-box">
             <span class="checkbox-inner" :class="{'checkbox-inner-checked':type==='qiye'}"></span>
           </span>
-          <span>企业</span>
+          <span>增值税专用发票</span>
         </label>
       </div>
       <div class="address-input-con" v-if="type==='qiye'">
         <div class="address-input-item">
           <div class="address-sub">
-            <div class="top-title">抬头名称</div>
+            <div class="top-title">发票抬头</div>
             <div class="ant-input">
-              <input v-model="tempInvoice3.title" type="text" placeholder="请输入发票抬头" />
+              <input v-model="tempInvoice3.title" maxlength='20' type="text" placeholder="请输入发票抬头" />
             </div>
           </div>
         </div>
         <div class="address-input-item">
           <div class="address-sub">
-            <div class="top-title">税号</div>
+            <div class="top-title">税务登记号</div>
             <div class="ant-input">
-              <input v-model="tempInvoice3.code" type="text" placeholder="请输入税务登记号" />
+              <input v-model="tempInvoice3.code" oninput="value=value.replace(/[^\w\.\/]/ig,'')" maxlength='18' type="text" placeholder="请输入18位税务登记号" />
             </div>
           </div>
         </div>
         <div class="address-input-item">
           <div class="address-sub">
-            <div class="top-title">地址</div>
+            <div class="top-title">注册地址</div>
             <div class="ant-input">
-              <input v-model="tempInvoice3.organizedAddress" type="text" placeholder="公司地址" />
+              <input v-model="tempInvoice3.organizedAddress" maxlength='30' type="text" placeholder="注册地址" />
             </div>
           </div>
         </div>
         <div class="address-input-item">
           <div class="address-sub">
-            <div class="top-title">电话号码</div>
+            <div class="top-title">注册电话</div>
             <div class="ant-input">
-              <input v-model="tempInvoice3.registerPhone" type="text" placeholder="公司电话号码" />
+              <input v-model="tempInvoice3.registerPhone" oninput="value=value.replace(/[^\d\-]/g,'')" maxlength='30' type="text" placeholder="注册电话" />
             </div>
           </div>
         </div>
@@ -92,7 +95,7 @@
           <div class="address-sub">
             <div class="top-title">开户银行</div>
             <div class="ant-input">
-              <input v-model="tempInvoice3.bankName" type="text" placeholder="开户银行" />
+              <input v-model="tempInvoice3.bankName" maxlength='30' type="text" placeholder="开户银行" />
             </div>
           </div>
         </div>
@@ -100,7 +103,7 @@
           <div class="address-sub">
             <div class="top-title">银行账户</div>
             <div class="ant-input">
-              <input v-model="tempInvoice3.bankAccount" type="text" placeholder="银行账户" />
+              <input v-model="tempInvoice3.bankAccount" maxlength='30' type="text" placeholder="银行账户" />
             </div>
           </div>
         </div>
@@ -108,24 +111,32 @@
       <div class="address-input-con" v-else>
         <div class="address-input-item">
           <div class="address-sub">
-            <div class="top-title">抬头名称</div>
+            <div class="top-title">发票抬头</div>
             <div class="ant-input">
-              <input v-model="tempInvoice2.title" type="text" placeholder="发票抬头" />
+              <input v-model="tempInvoice2.title" maxlength='30' type="text" placeholder="请输入发票抬头" />
             </div>
           </div>
         </div>
         <div class="address-input-item">
           <div class="address-sub">
-            <div class="top-title">税号</div>
+            <div class="top-title no-require" >税务登记号</div>
             <div class="ant-input">
-              <input v-model="tempInvoice2.code" type="text" placeholder="税务登记号" />
+              <input v-model="tempInvoice2.code" type="text" oninput="value=value.replace(/[^\w\.\/]/ig,'')" maxlength='18' placeholder="请输入18位税务登记号" />
+            </div>
+          </div>
+        </div>
+        <div class="address-input-item">
+          <div class="address-sub">
+            <div class="top-title">电子邮箱</div>
+            <div class="ant-input">
+              <input v-model="tempInvoice2.emailAddress" maxlength='30' type="text" placeholder="请输入电子邮箱" />
             </div>
           </div>
         </div>
       </div>
     </div>
 
-    <div class="select-layout">
+    <div class="select-layout" v-if="type==='qiye'">
       <p class="sub-title">
         <span>收货地址</span>
       </p>
@@ -134,13 +145,13 @@
           <div class="address-sub address-name">
             <div class="top-title">姓名</div>
             <div class="ant-input">
-              <input v-model="tempAddress.shipName" type="text" placeholder="姓名" />
+              <input v-model="tempAddress.shipName" maxlength='20' type="text" placeholder="姓名" />
             </div>
           </div>
           <div class="address-sub address-phone">
             <div class="top-title">联系电话</div>
             <div class="ant-input">
-              <input v-model="tempAddress.shipMobile" type="text" placeholder="联系电话" />
+              <input v-model="tempAddress.shipMobile" maxlength='30' type="text" placeholder="联系电话" />
             </div>
           </div>
         </div>
@@ -186,7 +197,7 @@
               </ul>
             </div>
             <div class="ant-input">
-              <input v-model="tempAddress.shipAddress" type="text" placeholder="详细地址" />
+              <input v-model="tempAddress.shipAddress" maxlength='50' type="text" placeholder="详细地址" />
             </div>
           </div>
         </div>
@@ -207,6 +218,8 @@
 <script>
 import { mapState } from 'vuex'
 import { citylist } from './city'
+import { reg } from '@/util'
+
 let sle = ['prov', 'city', 'dist', 'device']
 
 export default {
@@ -215,6 +228,7 @@ export default {
 
     return {
       type: 'geren',
+      max: 0,
       amount: '',
       tempInvoice2: {},
       tempInvoice3: {},
@@ -233,6 +247,8 @@ export default {
   },
   computed: {
     ...mapState({
+      langToast: state => state.language.home.toast,
+      language: state => state.language.current,
       token: state => state.user.token,
       invoicedevice: state => {
         let type = Object.prototype.toString.call(state.user.invoicedevice)
@@ -257,14 +273,43 @@ export default {
     currentProv () {
       this.currentCID = 0
       this.currentSID = 0
+    },
+    activeDevice () {
+      this.getMax()
     }
   },
   methods: {
+    limitMoney (e) {
+      let value = e.target.value
+      // this.edu = Math.max(Math.min(Number(value.replace(/[^\d]/g, '')), this.edititem.max), 1)
+      this.amount = Math.max(Math.min(Number(value.replace(/[^\d]/g, '')), this.max), 0) || ''
+    },
+    async getMax () {
+      let res = await this.$http({
+        method: 'post',
+        data: {
+          cameraId: this.activeDevice.id
+        },
+        headers: {
+          token: this.token
+        },
+        url: '/user/invoice/max'
+      })
+
+      let data = res.data
+      if (data.code !== 0) return
+      this.max = data.data.maxInvoice
+    },
     async getAllDevice (searchKey = '') {
       let params = {
         cameraType: ''
       }
       await this.$store.dispatch('getInvoiceDevice', params)
+      if (this.invoicedevice.length <= 0) {
+        this.$toast.show('warn', '暂无可开票设备', () => {
+          this.$router.back()
+        })
+      }
       this.activeDevice = this.invoicedevice[0]
     },
     handledeviceClick (item) {
@@ -291,26 +336,66 @@ export default {
       console.log(this.areaPath)
     },
     async saveInvoice () {
+      if (!this.amount) {
+        return this.$toast.show('warn', '请输入开票金额')
+      }
+      let isObject = function (obj) {
+        return JSON.stringify(obj) === '{}' ? '' : obj
+      }
       let params = {}
       let invoiceType = ''
+      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
+      }
+
       if (this.type === 'geren') {
         invoiceType = 2
-        let { title = '', code = '' } = this.tempInvoice2
+        let title = isObject(this.tempInvoice2.title)
+        let code = isObject(this.tempInvoice2.code)
+        let emailAddress = isObject(this.tempInvoice2.emailAddress)
+
         params = {
           invoiceType,
           title,
-          code
+          code,
+          emailAddress
+        }
+        let checkStr = [
+          {
+            name: '发票抬头',
+            En: 'Title',
+            val: title
+          },
+          {
+            name: '电子邮箱',
+            En: 'Email',
+            val: emailAddress
+          }
+        ]
+        if (!check(checkStr)) {
+          return
+        }
+        if (code && code.length !== 18) {
+          return this.$toast.show('warn', this.langToast['21'])
+        }
+        if (!reg.email.test(emailAddress)) {
+          return this.$toast.show('warn', this.langToast['8'])
         }
       } else {
-        let {
-          title = '',
-          code = '',
-          organizedAddress = '',
-          registerPhone = '',
-          bankName = '',
-          bankAccount = ''
-        } = this.tempInvoice3
+        let {title: title1, code: code1, organizedAddress: organizedAddress1, registerPhone: registerPhone1, bankName: bankName1, bankAccount: bankAccount1} = this.tempInvoice3
         invoiceType = 3
+        let title = isObject(title1)
+        let code = isObject(code1)
+        let organizedAddress = isObject(organizedAddress1)
+        let registerPhone = isObject(registerPhone1)
+        let bankName = isObject(bankName1)
+        let bankAccount = isObject(bankAccount1)
+
         params = {
           invoiceType,
           title,
@@ -320,32 +405,78 @@ export default {
           bankName,
           bankAccount
         }
-      }
-      let {
-        shipName = '',
-        shipMobile = '',
-        shipAddress = ''
-      } = this.tempAddress
+        let checkStr = [
+          {
+            name: '发票抬头',
+            En: 'Title',
+            val: title
+          },
+          {
+            name: '税务登记号',
+            En: 'Code',
+            val: code
+          },
+          {
+            name: '注册地址',
+            En: 'Organized Address',
+            val: organizedAddress
+          },
+          {
+            name: '注册电话',
+            En: 'Register Phone',
+            val: registerPhone
+          },
+          {
+            name: '开户银行',
+            En: 'Bank Name',
+            val: bankName
+          },
+          {
+            name: '银行账号',
+            En: 'Bank Account',
+            val: bankAccount
+          }
+        ]
+        if (!check(checkStr)) {
+          return
+        }
 
-      this.tempAddress.shipAreaPath = this.areaPath.join(',')
-      this.tempAddress.amount = Number(this.amount)
-      this.tempAddress.shipName = shipName || ''
-      this.tempAddress.shipMobile = shipMobile || ''
-      this.tempAddress.shipAddress = shipAddress || ''
+        if (!code || code.length !== 18) {
+          return this.$toast.show('warn', this.langToast['21'])
+        }
 
-      let temp = Object.keys(this.tempAddress)
-      temp.forEach(item => {
-        params[item] = this.tempAddress[item] || ''
-      })
-      console.log(params)
-      let arr = Object.keys(params)
-      for (let i = 0; i < arr.length; i++) {
-        if (!params[arr[i]]) {
-          return this.$toast.show('warn', '信息填写不能为空')
+        if (!reg.guhua.test(registerPhone)) {
+          return this.$toast.show('warn', this.langToast['22'])
         }
       }
 
+      let {shipName = '', shipMobile = '', shipAddress = ''} = this.tempAddress
+
+      if (this.type !== 'geren') {
+        this.tempAddress.shipAreaPath = this.areaPath.join(',')
+        this.tempAddress.shipName = shipName || ''
+        this.tempAddress.shipMobile = shipMobile || ''
+        this.tempAddress.shipAddress = shipAddress || ''
+
+        //  this.tempAddress.shipAreaPath = this.areaPath.join(',')
+        //       this.tempAddress.amount = Number(this.amount)
+        //       this.tempAddress.shipName = shipName || ''
+        //       this.tempAddress.shipMobile = shipMobile || ''
+        //       this.tempAddress.shipAddress = shipAddress || ''
+
+        let temp = Object.keys(this.tempAddress)
+        temp.forEach(item => {
+          params[item] = this.tempAddress[item] || ''
+        })
+        let arr = Object.keys(params)
+        for (let i = 0; i < arr.length; i++) {
+          if (!params[arr[i]]) {
+            return this.$toast.show('warn', '请完善收货信息')
+          }
+        }
+      }
       params['cameraId'] = this.activeDevice.id
+      params['amount'] = Number(this.amount)
 
       let res = await this.$http.post('/user/invoice/add', params, {
         headers: {
@@ -364,8 +495,8 @@ export default {
     }
   },
   mounted () {
-    this.handleChange()
     this.getAllDevice()
+    this.handleChange()
   }
 }
 </script>

+ 20 - 1
mobile/src/components/createInvoice/style.scss

@@ -15,6 +15,15 @@
   }
 }
 
+.sanjiao{
+  position: relative;
+}
+.xia{
+  position: absolute;
+  right: 12px;
+  top: 0;
+  display: inline-block;
+}
 .select-layout{
   margin-top: 10px;
   background-color: #fff;
@@ -90,6 +99,17 @@
           color: #f04134;
         }
       }
+      .no-require{
+        &::before{
+          display: none;
+          margin-right: 4px;
+          content: "";
+          font-family: SimSun;
+          line-height: 1;
+          font-size: 12px;
+          color: #f04134;
+        }
+      }
     }
     .address-name,
     .prov-name {
@@ -130,7 +150,6 @@
   cursor: pointer;
   color: rgba(0,0,0,.65);
   font-size: 14px;
-  margin-right: 30px;
   .check-box {
     box-sizing: border-box;
     margin: 0;

文件差异内容过多而无法显示
+ 4793 - 0
mobile/src/components/editInvoice/city.js


+ 305 - 0
mobile/src/components/editInvoice/edit.vue

@@ -0,0 +1,305 @@
+<template>
+  <div>
+    <div class="select-layout">
+      <p class="sub-title">
+        <span>{{langOrders.invoice}}</span>
+      </p>
+      <div class="invoice-header">
+        <label class="check-con" @click="invoice=null">
+          <span class="check-box">
+            <span class="checkbox-inner" :class="{'checkbox-inner-checked':invoice===null}"></span>
+          </span>
+          <span>{{langOrders.type1}}</span>
+        </label>
+        <label class="check-con" @click="invoice=2">
+          <span class="check-box">
+            <span class="checkbox-inner" :class="{'checkbox-inner-checked':invoice===2}"></span>
+          </span>
+          <span>{{langOrders.type2}}</span>
+        </label>
+        <label class="check-con" @click="invoice=3">
+          <span class="check-box">
+            <span class="checkbox-inner" :class="{'checkbox-inner-checked':invoice===3}"></span>
+          </span>
+          <span>{{langOrders.type3}}</span>
+        </label>
+      </div>
+      <div class="address-input-con" v-if="invoice===3">
+        <div class="address-input-item">
+          <div class="address-sub">
+            <div class="top-title">{{langOrders.title}}</div>
+            <div class="ant-input">
+              <input v-model="editInvoice3.title" maxlength='20' type="text" :placeholder="langOrders.title" />
+            </div>
+          </div>
+        </div>
+        <div class="address-input-item">
+          <div class="address-sub">
+            <div class="top-title">{{langOrders.code}}</div>
+            <div class="ant-input">
+              <input v-model="editInvoice3.code" oninput="value=value.replace(/[^\w\.\/]/ig,'')" maxlength='18' type="text" :placeholder="langOrders.code" />
+            </div>
+          </div>
+        </div>
+        <div class="address-input-item">
+          <div class="address-sub">
+            <div class="top-title">{{langOrders.organizedAddress}}</div>
+            <div class="ant-input">
+              <input v-model="editInvoice3.organizedAddress" maxlength='30' type="text" :placeholder="langOrders.organizedAddress" />
+            </div>
+          </div>
+        </div>
+        <div class="address-input-item">
+          <div class="address-sub">
+            <div class="top-title">{{langOrders.registerPhone}}</div>
+            <div class="ant-input">
+              <input v-model="editInvoice3.registerPhone" oninput="value=value.replace(/[^\d\-]/g,'')" maxlength='30' type="text" :placeholder="langOrders.registerPhone" />
+            </div>
+          </div>
+        </div>
+        <div class="address-input-item">
+          <div class="address-sub">
+            <div class="top-title">{{langOrders.bankName}}</div>
+            <div class="ant-input">
+              <input v-model="editInvoice3.bankName" maxlength='30' type="text" :placeholder="langOrders.bankName" />
+            </div>
+          </div>
+        </div>
+        <div class="address-input-item">
+          <div class="address-sub">
+            <div class="top-title">{{langOrders.bankAccount}}</div>
+            <div class="ant-input">
+              <input v-model="editInvoice3.bankAccount" maxlength='30' type="text" :placeholder="langOrders.bankAccount" />
+            </div>
+          </div>
+        </div>
+      </div>
+      <div class="address-input-con" v-else-if="invoice===2">
+        <div class="address-input-item">
+          <div class="address-sub">
+            <div class="top-title">{{langOrders.title}}</div>
+            <div class="ant-input">
+              <input v-model="editInvoice2.title" maxlength='30' type="text" :placeholder="langOrders.title" />
+            </div>
+          </div>
+        </div>
+        <div class="address-input-item">
+          <div class="address-sub">
+            <div class="top-title no-require" >{{langOrders.code}}</div>
+            <div class="ant-input">
+              <input v-model="editInvoice2.code" type="text" oninput="value=value.replace(/[^\w\.\/]/ig,'')" maxlength='18' :placeholder="langOrders.code" />
+            </div>
+          </div>
+        </div>
+        <div class="address-input-item">
+          <div class="address-sub">
+            <div class="top-title">{{langOrders.email}}</div>
+            <div class="ant-input">
+              <input v-model="editInvoice2.emailAddress" maxlength='30' type="text" :placeholder="langOrders.email" />
+            </div>
+          </div>
+        </div>
+      </div>
+      <div v-else>
+      </div>
+    </div>
+    <div class="invoice-save">
+      <button @click="saveInvoice(invoice)" type="submit" class="ant-btn ant-btn-primary">
+        <span>{{langOrders.save}}</span>
+      </button>
+      <button type="submit" class="ant-btn ant-btn-primary cancel" @click="$router.back()">
+        <span>{{langOrders.cancal1}}</span>
+      </button>
+    </div>
+  </div>
+</template>
+
+<script>
+import { mapState } from 'vuex'
+import { reg } from '@/util'
+
+export default {
+  props: ['data', 'orderId', 'invoiceId'],
+  data: function () {
+    return {
+      editInvoice2: this.data.type === 2 ? this.data : {},
+      editInvoice3: this.data.type === 3 ? this.data : {},
+      invoice: this.data.type === 'no' ? null : this.data.type
+    }
+  },
+  computed: {
+    ...mapState({
+      langToast: state => state.language.home.toast,
+      langOrders: state => state.language.home.manage.myOrders,
+      language: state => state.language.current,
+      token: state => state.user.token
+    })
+  },
+  watch: {
+
+  },
+  methods: {
+    saveInvoice (cInvoice) {
+      if (!cInvoice) {
+        if (this.invoiceId && this.invoiceId !== 'no') {
+          this.$http
+            .post('user/invoice/delete', {
+              invoiceId: this.invoiceId
+            }, {
+              headers: {
+                token: this.token
+              }
+            })
+            .then(data => {
+              let response = data.data
+              if (response.code === 0) {
+                this.$toast.show('warn', this.langToast['47'], () => {
+                  this.$router.back()
+                })
+              }
+            })
+        }
+        return this.$router.back()
+      }
+      let isObject = function (obj) {
+        return JSON.stringify(obj) === '{}' ? '' : obj
+      }
+      let params = {}
+      let invoiceType = ''
+      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
+      }
+
+      if (cInvoice === 2) {
+        invoiceType = 2
+
+        let title = isObject(this.editInvoice2.title)
+        let code = isObject(this.editInvoice2.code)
+        let emailAddress = isObject(this.editInvoice2.emailAddress)
+
+        if (code && code.length !== 18) {
+          return this.$toast.show('warn', this.langToast['21'])
+        }
+        if (!reg.email.test(emailAddress)) {
+          return this.$toast.show('warn', this.langToast['8'])
+        }
+        params = {
+          invoiceType,
+          title,
+          code: code || '',
+          emailAddress
+        }
+
+        let checkStr = [
+          {
+            name: '发票抬头',
+            En: 'Title',
+            val: title
+          },
+          {
+            name: '电子邮箱',
+            En: 'Email',
+            val: emailAddress
+          }
+        ]
+        if (!check(checkStr)) {
+          return
+        }
+      } else {
+        let {title: title1, code: code1, organizedAddress: organizedAddress1, registerPhone: registerPhone1, bankName: bankName1, bankAccount: bankAccount1} = this.editInvoice3
+        invoiceType = 3
+        let title = isObject(title1)
+        let code = isObject(code1)
+        let organizedAddress = isObject(organizedAddress1)
+        let registerPhone = isObject(registerPhone1)
+        let bankName = isObject(bankName1)
+        let bankAccount = isObject(bankAccount1)
+
+        params = {
+          invoiceType,
+          title,
+          code: code || '',
+          organizedAddress,
+          registerPhone,
+          bankName,
+          bankAccount
+        }
+        let checkStr = [
+          {
+            name: '发票抬头',
+            En: 'Title',
+            val: title
+          },
+          {
+            name: '税务登记号',
+            En: 'Code',
+            val: code
+          },
+          {
+            name: '注册地址',
+            En: 'Organized Address',
+            val: organizedAddress
+          },
+          {
+            name: '注册电话',
+            En: 'Register Phone',
+            val: registerPhone
+          },
+          {
+            name: '开户银行',
+            En: 'Bank Name',
+            val: bankName
+          },
+          {
+            name: '银行账号',
+            En: 'Bank Account',
+            val: bankAccount
+          }
+        ]
+        if (!check(checkStr)) {
+          return
+        }
+        if (!code || code.length !== 18) {
+          return this.$toast.show('warn', this.langToast['21'])
+        }
+
+        if (!reg.guhua.test(registerPhone)) {
+          return this.$toast.show('warn', this.langToast['22'])
+        }
+      }
+
+      if (this.invoiceId && this.invoiceId !== 'no') {
+        params['invoiceId'] = params['id'] = this.invoiceId || null
+      }
+      params['orderId'] = this.orderId
+      params['invoiceType'] = invoiceType
+
+      this.$http
+        .post('user/invoice/update', params, {
+          headers: {
+            token: this.token
+          }
+        })
+        .then(data => {
+          let response = data.data
+          if (response.code === 0) {
+            this.$toast.show('warn', this.langToast['47'], () => {
+              this.$router.back()
+            })
+          }
+        })
+    }
+  },
+  mounted () {
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+@import "./style.scss";
+</style>

+ 53 - 0
mobile/src/components/editInvoice/index.vue

@@ -0,0 +1,53 @@
+<template>
+  <div class="i-lay">
+    <template >
+      <p v-if="!data.type">{{langOrders.dontneed}}</p>
+      <template v-else>
+        <p v-for="(item,i) in invoiceData" :key="i">{{(language==='en'?item['en']:item['name'])+':'+(data[item['key']]||'--')}}</p>
+      </template>
+      <div>{{langOrders.editInfo}}</div>
+    </template>
+  </div>
+</template>
+
+<script>
+import { mapState } from 'vuex'
+import { normal, zengzhi } from './invoice'
+export default {
+  props: ['data', 'orderId', 'invoiceId'],
+  mounted () {
+  },
+  computed: {
+    ...mapState({
+      token: state => state.user.token,
+      langToast: state => state.language.home.toast,
+      language: state => state.language.current,
+      langOrders: state => state.language.home.manage.myOrders
+    }),
+    invoiceData () {
+      if (!this.data) {
+        return ''
+      }
+      return this.data.type === 2 ? normal : zengzhi
+    }
+  },
+  data () {
+    return {
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.i-lay{
+  p,div{
+    color: #a0a0a0;
+    margin: 10px 25px;
+  }
+  div{
+    color: #1fe4dc;
+    font-size: 12px;
+    margin-top: 15px;
+  }
+}
+</style>

+ 86 - 0
mobile/src/components/editInvoice/invoice.js

@@ -0,0 +1,86 @@
+let normal = [
+  {
+    key: 'typeName',
+    name: '发票类型',
+    en: 'Invoice type'
+  }, {
+    key: 'title',
+    name: '发票抬头',
+    en: 'Invoice Title'
+  }, {
+    key: 'code',
+    name: '发票税号',
+    en: 'Invoice tax No.'
+  }, {
+    key: 'emailAddress',
+    name: '电子邮箱',
+    en: 'E-mail'
+  }
+]
+
+let zengzhi = [
+  {
+    key: 'typeName',
+    name: '发票类型',
+    en: 'Invoice type'
+  }, {
+    key: 'title',
+    name: '发票抬头',
+    en: 'Invoice Title'
+  }, {
+    key: 'code',
+    name: '发票税号',
+    en: 'Invoice tax No.'
+  }, {
+    key: 'organizedAddress',
+    name: '注册地址',
+    en: 'Address'
+  }, {
+    key: 'registerPhone',
+    name: '注册电话',
+    en: 'Phone number'
+  }, {
+    key: 'bankName',
+    name: '开户银行',
+    en: 'Banker'
+  }, {
+    key: 'bankAccount',
+    name: '开户账号',
+    en: 'Bank account'
+  }
+
+]
+
+let invoice = [
+  {
+    key: 'createTime',
+    en: '申请时间',
+    name: '申请时间'
+  }, {
+    key: 'type',
+    en: '发票类型',
+    name: '发票类型'
+  }, {
+    key: 'title',
+    en: '发票抬头',
+    name: '发票抬头'
+  }, {
+    key: 'money',
+    en: '开票金额',
+    name: '开票金额'
+  }, {
+    key: 'finish',
+    en: '状态',
+    name: '状态'
+  }, {
+    key: 'detail',
+    name: '操作',
+    en: '操作',
+    canclick: true
+  }
+]
+export {
+  normal,
+  zengzhi,
+  invoice
+}

+ 236 - 0
mobile/src/components/editInvoice/style.scss

@@ -0,0 +1,236 @@
+.cancel{
+  background: #e7e7e7!important;
+  margin-left: 5px;
+}
+.ant-input{
+  height: auto;
+  input{
+    border: 0;
+    width: 100%;
+    height: 40px;
+    line-height: 40px;
+    padding: 0;
+    font-size: 12px;
+    color: rgba(0, 0, 0, 0.65);
+  }
+}
+
+.sanjiao{
+  position: relative;
+}
+.xia{
+  position: absolute;
+  right: 12px;
+  top: 0;
+  display: inline-block;
+}
+.select-layout{
+  background-color: #fff;
+  .sub-title{
+    font-size: 14px;
+    line-height: 21px;
+    font-weight: 700;
+    padding: 13px 16px;
+    border-bottom: 1px solid #e9e9e9;
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+  }
+}
+
+
+.address-input-con {
+  font-size: 12px;
+  line-height: 1.5;
+  margin-bottom: 10px;
+  color: rgba(0, 0, 0, 0.65);
+  padding: 16px;
+  .address-input-item {
+    display: flex;
+    margin-bottom: 8px;
+    .address-sub {
+      width: 100%;
+      .prov,
+      .city,
+      .dist {
+        position: relative;
+        ul{
+          position: absolute;
+          top: 48px;
+          left: 0;
+          background: #fff;
+          width: 100%;
+          box-shadow: 0 0 8px rgba(0, 0, 0, 0.2);
+          border-radius: 4px;
+          z-index: 999;
+          transition: all 0.15s cubic-bezier(0.645, 0.045, 0.355, 1);
+          overflow: auto;
+          max-height: 300px;
+          li{
+            padding: 0 11px;
+            line-height: 30px;
+            height: 30px;
+            font-size: 12px;
+            color: rgba(0, 0, 0, 0.7);
+          }
+        }
+      }
+      .dist{
+        margin-bottom:8px;
+      }
+      .top-title {
+        overflow: hidden;
+        text-overflow: ellipsis;
+        white-space: nowrap;
+        color: rgba(0, 0, 0, 0.85);
+        padding: 0 0 8px;
+        margin: 0;
+        display: block;
+        text-align: left;
+        line-height: 1.5;
+        &::before {
+          display: inline-block;
+          margin-right: 4px;
+          content: "*";
+          font-family: SimSun;
+          line-height: 1;
+          font-size: 12px;
+          color: #f04134;
+        }
+      }
+      .no-require{
+        &::before{
+          display: none;
+          margin-right: 4px;
+          content: "";
+          font-family: SimSun;
+          line-height: 1;
+          font-size: 12px;
+          color: #f04134;
+        }
+      }
+    }
+    .address-name,
+    .prov-name {
+      width: 33.33%;
+      padding-right: 4px;
+      flex-shrink: 0;
+    }
+    .prov-name {
+      width: 50%;
+    }
+    .address-phone,
+    .city-name {
+      flex: auto;
+    }
+  }
+  .p-dec {
+    line-height: 32px;
+    margin-bottom: 8px;
+  }
+}
+.cancel{
+  background: #e7e7e7!important;
+  margin-left: 5px;
+}
+
+.check-con {
+  box-sizing: border-box;
+  padding-bottom: 10px;
+  color: rgba(0, 0, 0, 0.65);
+  font-size: 14px;
+  font-variant: tabular-nums;
+  line-height: 1.5;
+  list-style: none;
+  font-feature-settings: "tnum", "tnum";
+  display: block;
+  line-height: unset;
+  cursor: pointer;
+  color: rgba(0,0,0,.65);
+  font-size: 14px;
+  .check-box {
+    box-sizing: border-box;
+    margin: 0;
+    padding: 0;
+    color: rgba(0, 0, 0, 0.65);
+    font-size: 14px;
+    font-variant: tabular-nums;
+    line-height: 1.5;
+    list-style: none;
+    font-feature-settings: "tnum", "tnum";
+    position: relative;
+    top: -0.09em;
+    display: inline-block;
+    line-height: 1;
+    white-space: nowrap;
+    vertical-align: middle;
+    outline: none;
+    cursor: pointer;
+    .checkbox-input {
+      position: absolute;
+      top: 0;
+      right: 0;
+      bottom: 0;
+      left: 0;
+      z-index: 1;
+      width: 100%;
+      height: 100%;
+      cursor: pointer;
+      opacity: 0;
+    }
+    .checkbox-inner {
+      border-radius: 90px;
+      width: 18px;
+      height: 18px;
+      position: relative;
+      top: 0;
+      left: 0;
+      display: block;
+      background-color: #fff;
+      border: 1px solid #d9d9d9;
+      border-collapse: separate;
+      transition: all 0.3s;
+      &::after {
+        position: absolute;
+        top: 50%;
+        left: 21%;
+        display: table;
+        width: 5.71428571px;
+        height: 9.14285714px;
+        border: 2px solid #fff;
+        width: 8px;
+        height: 12px;
+        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: " ";
+      }
+    }
+  }
+}
+
+.invoice-header{
+  padding: 18px 16px 0;
+  margin-bottom: 10px;
+}
+
+.invoice-save{
+  padding: 16px;
+  background-color: #fff;
+}

+ 1 - 1
mobile/src/components/invoices/index.vue

@@ -43,7 +43,7 @@
         <div class="address-sub">
           <div class="top-title">电话号码</div>
           <div class="ant-input" >
-            <input @blur="blurHandle" v-model="tempInvoice3.registerPhone" type="text" placeholder="公司电话号码" />
+            <input @blur="blurHandle" oninput="value=value.replace(/[^\d\-]/g,'')" v-model="tempInvoice3.registerPhone" type="text" placeholder="公司电话号码" />
           </div>
         </div>
       </div>

+ 1 - 1
mobile/src/components/toast/binding.vue

@@ -12,7 +12,7 @@
       <div class="binding-con">
         <div class="binding-body" v-if="!bindingSuccess">
           <div class="b-input" :class="{notbing:hasBind}">
-            <input v-model="SN" :placeholder="lang==='en'?'Please input the SN at the bottom of the camera.':'请输入产品底部的SN码'" type="text">
+            <input v-model="SN" :placeholder="lang==='en'?'Input the S/N at camera bottom':'请输入产品底部的SN码'" type="text">
           </div>
           <div class="bind-error">{{hasBind?errorMsg:''}}</div>
           <div class="bind-info">

+ 3 - 2
mobile/src/components/toast/index.vue

@@ -31,10 +31,10 @@
         <div class="bottom" v-if="toastType==='comfirm'">
           <span @click="visible=false" class="btn primary">{{lang==='en'?'Cancel':'取消'}}</span>
           <span class="b-line"></span>
-          <span class="btn primary" @click="emitCallback">{{comfirmtxt}}</span>
+          <span class="btn primary" @click="emitCallback">{{diycomfirm||comfirmtxt}}</span>
         </div>
         <div class="bottom mid-bottom" v-else>
-          <span class="btn primary" @click="emitCallback">{{comfirmtxt}}</span>
+          <span class="btn primary" @click="emitCallback">{{diycomfirm||comfirmtxt}}</span>
         </div>
       </div>
     </div>
@@ -73,6 +73,7 @@ export default {
       toastType: 'show',
       callback: '',
       comfirmtxt: '确定',
+      diycomfirm: '',
       isLoaing: false,
       lang: localStorage.getItem('language'),
       img: this.$cdn + 'images/icon/warn.png'

+ 3 - 2
mobile/src/components/toast/style.scss

@@ -53,7 +53,7 @@ $anima-delay:0.15s;
     left: 50%;
     transform: translate(-50%, -50%);
     background: #fff;
-    width: 75%;
+    min-width: 75%;
     border-radius: 6px;
     box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);
     .t-line {
@@ -85,7 +85,7 @@ $anima-delay:0.15s;
         top: 50%;
         width: 100%;
         left: 50%;
-        padding: 0 10%;
+        padding: 0 4%;
         transform: translate(-50%,-50%);
         .main-msg{
           font-size: 18px;
@@ -99,6 +99,7 @@ $anima-delay:0.15s;
           color: #2d2d2d;
           margin-top: 6px;
           line-height: 15px;
+          padding: 0 5%;
         }
       }
     }

+ 4 - 1
mobile/src/components/toast/toast.js

@@ -21,12 +21,13 @@ Toast.install = function (Vue) {
     error: cdn + 'images/icon/error.png'
   }
   Vue.prototype.$toast = {
-    showConfirm: (type, msg, callback, submsg = '') => {
+    showConfirm: (type, msg, callback, submsg = '', comfirmtxt = '') => {
       instance.img = imgs[type] || (cdn + 'images/icon/success.png')
       instance.message = msg
       instance.submsg = submsg
       instance.type = type
       instance.visible = true
+      instance.diycomfirm = comfirmtxt
       instance.toastType = 'comfirm'
       instance.callback = callback || function () {
       }
@@ -44,7 +45,9 @@ Toast.install = function (Vue) {
     },
     showBinding: (val, callback) => {
       instance.bindingVisible = true
+      instance.diycomfirm = ''
       instance.bindingType = val
+      instance.submsg = ''
       instance.callback = callback || function () {
       }
     },

+ 10 - 3
mobile/src/pages/404/index.vue

@@ -2,15 +2,22 @@
   <div class="layout-404">
     <div class="_404">
       <img :src="`${$cdn}images/404.png`" alt="">
-      <p>抱歉,您访问的页面出现了错误,请重新加载</p>
-      <div @click="$router.push({name:'home'})">返回首页</div>
+      <p>{{lang404.txt}}</p>
+      <div @click="$router.push({name:'home'})">{{lang404.btn}}</div>
     </div>
   </div>
 </template>
 
 <script>
-export default {
+import { mapState } from 'vuex'
 
+export default {
+  computed: {
+    ...mapState({
+      language: state => state.language.current,
+      lang404: state => state.language.home._404
+    })
+  }
 }
 </script>
 

+ 2 - 2
mobile/src/pages/account/codeLogin/index.vue

@@ -14,11 +14,11 @@
           </div>
           <ul v-show="showSelect" >
             <li @click="selectItem(item)" v-for="(item,i) in selectCall" :key="i">
-              {{item[0]}}{{item[1]}}
+              {{language==='en'?item[2]:item[0]}}{{item[1]}}
             </li>
           </ul>
         </div>
-        <input oninput="value=value.replace(/[^\d]/g,'')" v-model="phone" @focus="inputActive='phone'" @blur="inputActive=''" type="text" :placeholder="langLogin.phone.placeholder">
+        <input class="guding" oninput="value=value.replace(/[^\d]/g,'')" v-model="phone" @focus="inputActive='phone'" @blur="inputActive=''" type="text" :placeholder="langLogin.phone.placeholder">
       </div>
       <div class="code-con">
         <div class="input-con" :class="{inputActive:inputActive==='code'}">

+ 7 - 2
mobile/src/pages/account/codeLogin/style.scss

@@ -37,6 +37,7 @@ input[type='password']{
       vertical-align: middle;
     }
   }
+  
   img{
     width: 10px!important;
     margin: 0 10px 0 6px!important;
@@ -47,8 +48,8 @@ input[type='password']{
     top: 0;
     left: 0;
     background: #fff;
-    width: 200px;
-    height: 220px;
+    min-width: 200px;
+    height: 230px;
     padding: 0 10px;
     overflow: auto;
     transition: ease 0.3s all;
@@ -60,12 +61,16 @@ input[type='password']{
       color: #999;
       font-size: 14px;
       cursor: pointer;
+      word-break: break-all;
       &:hover{
         color: #000;
       }
     }
   }
 }
+.guding{
+  padding-right: 0!important;
+}
 .register-layout{
   width: 100%;
   .banner{

+ 2 - 2
mobile/src/pages/account/forget/index.vue

@@ -15,11 +15,11 @@
           </div>
           <ul v-show="showSelect" >
             <li @click="selectItem(item)" v-for="(item,i) in selectCall" :key="i">
-              {{item[0]}}{{item[1]}}
+              {{language==='en'?item[2]:item[0]}}{{item[1]}}
             </li>
           </ul>
         </div>
-        <input v-model="phone" oninput="value=value.replace(/[^\d]/g,'')" maxlength='11' @focus="inputActive='phone'" @blur="inputActive=''" type="text" :placeholder="langLogin.phone.placeholder">
+        <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'}">

+ 8 - 1
mobile/src/pages/account/forget/style.scss

@@ -29,6 +29,9 @@ input[type='password']{
   &>div{
     height: 18px;
     border-right: 1px solid #f1f1f1;
+    display: flex;
+    flex-wrap: nowrap;
+    align-items: center;
     &>span{
       display: inline-block;
       vertical-align: middle;
@@ -44,7 +47,7 @@ input[type='password']{
     top: 0;
     left: 0;
     background: #fff;
-    width: 200px;
+    min-width: 230px;
     height: 220px;
     padding: 0 10px;
     overflow: auto;
@@ -55,6 +58,7 @@ input[type='password']{
       height: 40px;
       line-height: 50px;
       color: #999;
+      word-break: break-all;
       font-size: 14px;
       cursor: pointer;
       &:hover{
@@ -63,6 +67,9 @@ input[type='password']{
     }
   }
 }
+.guding{
+  padding-right: 0!important;
+}
 .forget-layout{
   width: 100%;
   .banner{

+ 23 - 0
mobile/src/pages/account/login/index.vue

@@ -49,6 +49,29 @@ export default {
   },
   methods: {
     async login () {
+      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: 'Password',
+          val: this.password
+        }
+      ]
+      if (!check(checkStr)) {
+        return
+      }
       let params = {
         phoneNum: this.phone,
         password: this.password

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

@@ -57,7 +57,7 @@
           </div>
         </div>
         <div class="btn-submit" @click="toPay">结算</div>
-        <div class="dec">温馨提示:您的订单将顺丰速运专业配送</div>
+        <div class="dec">温馨提示:您的订单将顺丰速运专业配送</div>
       </div>
       <div class="paytype">
         <div>支付方式</div>

+ 11 - 4
mobile/src/pages/account/manage/device/index.vue

@@ -23,8 +23,8 @@
             <div class="btn-con">
               <span></span>
               <div>
-                <span class="btn" @click="unbind(item)">{{langDevices.unbind}}</span>
-                <span class="btn primary" @click="$router.push({name:'introduce',params:{id:item.childName}})">{{langDevices.capacity}}</span>
+                <div class="btn" @click="unbind(item)"><span>{{langDevices.unbind}}</span></div>
+                <div class="btn primary" @click="$router.push({name:'introduce',params:{id:item.childName}})"><span>{{langDevices.capacity}}</span></div>
               </div>
             </div>
           </div>
@@ -39,8 +39,8 @@
             <p class="i-dec">剩余点数:<span>{{item.balance}}</span></p>
             <div class="btn-con">
               <div>
-                <span class="btn" @click="unbind(item)">{{langDevices.unbind}}</span>
-                <span class="btn primary" @click="$router.push({name:'introtow',params:{id:item.childName}})">{{langDevices.recharge}}</span>
+                <div class="btn" @click="unbind(item)"><span>{{langDevices.unbind}}</span></div>
+                <div class="btn primary" @click="$router.push({name:'introtow',params:{id:item.childName}})"><span>{{langDevices.recharge}}</span></div>
               </div>
             </div>
           </div>
@@ -206,6 +206,13 @@ $theme-color: #1fe4dc;
   font-size: 12px;
   margin-right: 4px;
   line-height: 26px;
+  position: relative;
+  span{
+    position: absolute;
+    top: 50%;
+    left: 50%;
+    transform: translate(-50%,-50%);
+  }
 }
 .primary{
   background-color: $theme-color;

+ 1 - 1
mobile/src/pages/account/manage/index.vue

@@ -65,7 +65,7 @@ let titleNameEn = {
   'vieworder': 'Confirm'
 }
 
-let noNav = ['consumpdetail', 'information', 'openInvoice', 'openInvoice']
+let noNav = ['consumpdetail', 'information', 'openInvoice', 'openInvoice', 'orderInvoice']
 
 let recid = {
   0: '扩容记录',

+ 111 - 22
mobile/src/pages/account/manage/information/index.vue

@@ -72,34 +72,85 @@
         <div class="btn" :style="{backgroundColor:isSelect?'#1fe4dc':'#e2e2e2'}" @click="isSelect&&$router.push({name:'introduce',params:{id:activeCamera.childName}})">{{ langAccount.btntype }}</div>
       </div>
     </div>
-    <div class="user-con">
-      <div class="user-top">
-        <div
-          class="user-img"
-          :style="{
-            backgroundImage: `url(${info.head ||
-              `${$cdn}images/head-default.png`})`
-          }"
-        ></div>
-        <div class="user-upload">
-          <p>{{ langAccount.avatar }}</p>
-          <div type="button" class="ant-btn">
+    <div class="address-con">
+      <p class="sub-title">
+        <span>{{ langAccount.info}}</span>
+      </p>
+      <div class="address-show" v-if="isShowInfo">
+        <template>
+          <div class="info" :class="{'info-en':language==='en'}" slot="show">
+            <div class="s-tx">
+              <p>{{langAccount.avatar}}</p>
+              <div class="card-img avatar" :style="{backgroundImage: `url(${info.head})`}"></div>
+            </div>
+            <p><span>{{langAccount.account}}</span><span>{{info.userName||'--'}}</span></p>
+            <p><span>{{langAccount.nickname}}</span><span>{{info.nickName||'--'}}</span></p>
+            <p><span>{{langAccount.email}}</span><span>{{info.email||'--'}}</span></p>
+          </div>
+          <div class="add-edit" @click="isShowInfo = false">
+            <img :src="`${$cdn}images/icon/edit.png`" alt="" />
+          </div>
+        </template>
+      </div>
+      <div class="info edit-info address-show" :class="{'edit-en':language==='en','info-en':language==='en'}" v-else>
+        <div class="info-left">
+          <div class="i-tx">
+            <p>{{langAccount.avatar}}</p>
+            <div class="itx-con">
+              <div class="card-img avatar" :style="{backgroundImage: `url(${info.head})`}"></div>
+              <div class="it-right">
+                <div class="user-upload">
+                  <div type="button" class="ant-btn" :style="{width:language==='en'?'auto':'65px'}">
+                    <input
+                      class="el-upload"
+                      ref="uploadInput"
+                      name="file"
+                      type="file"
+                      @change="update"
+                    />
+                    <span>{{ langAccount.select}}</span>
+                  </div>
+                </div>
+                <p class="p-desc" v-for="(item,i) in langAccount.sinfo" :key="i">{{item}}</p>
+              </div>
+            </div>
+          </div>
+          <p><span>{{langAccount.account}}</span><span>{{info.userName}}</span></p>
+          <p>
+            <span>{{langAccount.nickname}}</span>
+            <input
+              v-model="editinfo.nickName"
+              :placeholder="langAccount.placeholder.nickname"
+              class="ant-input"
+              maxlength="10"
+              type="text"
+            >
+          </p>
+          <p>
+            <span>{{langAccount.email}}</span>
             <input
-              class="el-upload"
-              ref="uploadInput"
-              name="file"
-              type="file"
-              @change="update"
-            />
-            <span>{{ langAccount.select }}</span>
+              v-model="editinfo.email"
+              :placeholder="langAccount.placeholder.email"
+              class="ant-input"
+              maxlength="40"
+              type="text"
+            >
+          </p>
+          <label class="check-con" @click="isReceive=!isReceive">
+            <span class="check-box">
+              <span class="checkbox-inner" :class="{'checkbox-inner-checked':isReceive}"></span>
+            </span>
+            <span style="font-size:12px;color:#000;" v-html="langAccount.isReceive"></span>
+          </label>
+          <div @click="saveNickName" class="ant-btn ant-btn-primary">
+            <span>{{langAccount.save}}</span>
           </div>
-          <p>{{ langAccount.sinfo }}</p>
         </div>
       </div>
     </div>
     <div class="address-con">
       <p class="sub-title">
-        <span>{{ langAccount.address }}</span>
+        <span>{{ langAccount.address}}</span>
       </p>
       <div class="address-show" v-if="isShowAddress">
         <template v-if="address.shipName">
@@ -142,6 +193,7 @@
 
 <script>
 import { mapState } from 'vuex'
+import { reg } from '@/util'
 import citySelect from '@/components/citySelect'
 import invoices from '@/components/invoices'
 var cloneObj = function (obj) {
@@ -167,6 +219,7 @@ export default {
       langAccount: state => state.language.home.manage.account,
       langToast: state => state.language.home.toast,
       language: state => state.language.current,
+      editinfo: state => cloneObj(state.user.info),
       invoice2: state => {
         let type = Object.prototype.toString.call(state.user.invoice2)
         if (type === '[object Object]') {
@@ -220,16 +273,52 @@ export default {
     return {
       isShowAddress: true,
       tempSelect: '',
-      isShowInvoice: true,
+      isShowInfo: true,
       content: {
         cameraList: []
       },
+      isReceive: true,
       selectActive: false,
       activeCamera: {},
       isSelect: false
     }
   },
   methods: {
+    async saveNickName () {
+      if (!this.editinfo.nickName.trim()) {
+        return this.$toast.show('warn', this.langToast['35'])
+      }
+
+      if (this.editinfo.email.trim() && !reg.email.test(this.editinfo.email)) {
+        return this.$toast.show('warn', this.langToast['8'])
+      }
+      let res = await this.$http
+        .post(
+          '/user/updateUserDetail',
+          {
+            nickName: this.editinfo.nickName,
+            email: this.editinfo.email || null,
+            isNotice: Number(this.isReceive)
+          },
+          {
+            headers: {
+              token: this.token
+            }
+          }
+        )
+      let data = res.data
+      if (data.code === 0) {
+        this.isShowInfo = true
+        this.$store.dispatch('getInfo', {url: '/user/getUserInfo', name: 'info'})
+      } else {
+        this.$toast.show('warn', this.langToast[data.code], async () => {
+          if (data.code === 3004) {
+            await this.$store.dispatch('logout')
+            this.$router.push({name: 'home'})
+          }
+        })
+      }
+    },
     addstar (item) {
       let back = item.substring(7, 12)
       let font = item.substring(0, 3)

+ 207 - 47
mobile/src/pages/account/manage/information/style.scss

@@ -1,3 +1,35 @@
+$theme-color: #1fe4dc;
+$border-color: #e7e7e7;
+$info-width: 100px;
+$info-w: 60px;
+
+input {
+  appearance: none;
+  line-height: 36px;
+  height: 36px;
+  border: solid 1px $border-color;
+  padding-left: 10px;
+}
+.btn {
+  text-align: center;
+  cursor: pointer;
+}
+.parmary {
+  background-color: $theme-color;
+  width: 126px;
+  height: 36px;
+  line-height: 36px;
+  margin-top: 20px;
+}
+.choose {
+  background-color: #ddd;
+  color: #fff;
+  width: 100px;
+  line-height: 26px;
+  height: 26px;
+  font-size: 12px;
+  margin: 12px 0 20px;
+}
 .el-upload {
   position: absolute;
   top: 0;
@@ -122,62 +154,164 @@
       }
     }
   }
-  .user-con{
-    width: 100%;
-    display: flex;
-    flex-direction: column;
-    align-items: center;
-    text-align: center;
-    margin-bottom: 10px;
-    background: #fff;
-    .user-top{
-      width: 100%;
-      display: flex;
-      flex-direction: column;
-      align-items: center;
-      text-align: center;
-      padding: 15px 0 10px;
-      .user-img{
-        width: 100px;
-        background-position: center;
-        height: 100px;
-        border-radius: 50px;
-        overflow: hidden;
-        background-size: cover;
-        background-repeat: no-repeat;
-        margin-bottom: 8px;
-        img{
-          width: 100%;
-          height: 100%;
+
+  .info {
+    p {
+      line-height: 1;
+      margin: 15px 0;
+      span {
+        padding-right: 10px;
+      }
+    }
+    .p-desc {
+      color: #a0a0a0;
+      line-height: 24px;
+    }
+    .card-img{
+      font-size: 0;
+      display: inline-block;
+      cursor: pointer;
+      background-position: center;
+      background-size: auto 100%;
+    }
+    .avatar {
+      width: 90px;
+      height: 90px;
+      box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.4);
+      margin: 0;
+      background-size: cover;
+      background-repeat: no-repeat;
+
+    }
+    .nickname {
+      width: 250px;
+    }
+  }
+
+
+  .info{
+    .s-tx{
+      position: relative;
+      &>p{
+        position: absolute;
+        left: 0;
+        top: 0;
+        margin: 0;
+      }
+      .avatar{
+        margin-left: $info-w;
+      }
+    }
+    p{
+      span{
+        display: inline-block;
+        &:first-of-type{
+          width: $info-w;
         }
       }
     }
-    .user-upload{
-      display: flex;
-      flex-direction: column;
-      align-items: center;
-      text-align: center;
-      p{
-        line-height: 17px;
-        width: 180px;
-        font-size: 12px;
-        color: #898A8E;
-        padding: 8px 0;
+  }
+
+  .info-en{
+    .s-tx{
+      .avatar{
+        margin-left: $info-width;
+      }
+    }
+    p{
+      span{
+        &:first-of-type{
+          width: $info-width;
+        }
       }
-      .ant-btn{
-        height: 24px;
-        line-height: 24px;
+    }
+  }
+
+  .edit-info {
+    display: flex;
+    .info-left {
+      &>p{
+        margin: 10px 0;
+        display: flex;
+        align-items: center;
+        >span{
+          &:first-of-type{
+            flex-shrink: 0;
+          }
+        }
+        .ant-input{
+          width: 70%;
+        }
+      }
+      min-width: 210px;
+      .i-tx{
         position: relative;
-        background: #EDEFF2;
-        color: #000000;
-        letter-spacing: 0.8px;
-        border: none;
-        span{
-          pointer-events: none;
+        &>p{
+          position: absolute;
+          left: 0;
+          top: 0;
+          margin: 0;
+        }
+        .itx-con{
+          display: flex;
+          margin-left: $info-w;
+          font-size: 14px;
+          .avatar{
+            flex-shrink: 0;
+          }
+          .it-right{
+            margin-left: 20px;
+            .user-upload{
+              margin-bottom: 10px;
+              p{
+                line-height: 17px;
+                width: 180px;
+                font-size: 12px;
+                color: #898A8E;
+                padding: 8px 0;
+              }
+              .ant-btn{
+                height: 24px;
+                line-height: 24px;
+                position: relative;
+                background: #EDEFF2;
+                color: #000000;
+                letter-spacing: 0.8px;
+                border: none;
+                span{
+                  pointer-events: none;
+                }
+              }
+            }
+            p{
+              line-height: 1.6;
+              margin: 0;
+              font-size: 12px;
+            }
+           
+          }
         }
       }
     }
+    .choose {
+      cursor: pointer;
+      position: relative;
+      span {
+        cursor: pointer;
+      }
+    }
   }
+
+  .edit-en{
+     .info-left {
+      .i-tx{
+        .itx-con{
+          margin-left: $info-width;
+        }
+      }
+    }
+  }
+
   .address-con{
     background: #fff;
     .sub-title{
@@ -249,6 +383,7 @@
       justify-content: space-between;
       padding: 18px 16px;
       margin-bottom: 10px;
+      position: relative;
       .add-info{
         max-width: calc(100% - 40px);
         .show-name{
@@ -273,10 +408,35 @@
         }
       }
       .add-edit{
+        position: absolute;
+        top: 20px;
+        right: 20px;
         img{
           width: 20px;
         }
       }
     }
   }
+}
+
+.check-con .check-box .checkbox-inner-checked::after{
+  border-color: #000;
+  top: 37%;
+  left: 13%;
+  width: 4px;
+  height: 8px;
+}
+
+.ant-btn{
+  display: block;
+  width: 65px;
+  position: relative;
+  span{
+    display: inline-block;
+    position: absolute;
+    left: 50%;
+    height: auto;
+    top: 50%;
+    transform: translate(-50%,-50%);
+  }
 }

+ 35 - 7
mobile/src/pages/account/manage/myscene/index.vue

@@ -3,15 +3,27 @@
     <template v-if="total">
       <div
         class="items"
-        @click="(item.status === 1||item.status===-2) && goto(item.webSite)"
+        @click="((item.status === 1||item.status===-2)&&item.payStatus !== -2) && goto(item.webSite)"
         v-for="(item,i) in myscene.list"
         :key="i"
       >
         <div
           class="card-img"
-          :style="{backgroundImage: `url(${item.thumb+'?v='+ item.version||`${$cdn}images/default.png`})`}"
+          :style="{backgroundImage: `url(${getSceneImg(item)})`}"
         >
-          <img  @click.stop="(item.status === 1||item.status===-2)&&handleShare(item)" :src="`${$cdn}images/share-btn.png`" alt />
+          <img v-if="((item.status === 1||item.status===-2)&&item.payStatus !== -2)" @click.stop="handleShare(item)" :src="`${$cdn}images/share-btn.png`" alt />
+          <div class="loading-hover" v-if="item.status === 0">
+            <div class="loading-icon">
+              <span class="refreshing-loader"></span>
+              <p>{{langScenes.share.calcule}}</p>
+            </div>
+          </div>
+          <div @click.stop class="loading-hover" v-if="item.payStatus === -2">
+            <div class="loading-icon" style="width:90%">
+              <p style="font-weight:bold;margin-top: 0;" v-html="langScenes.limit.insufficient"></p>
+            </div>
+            <p class="huifu" @click.stop="rechargeTip(item)">{{langScenes.limit.recharge}}</p>
+          </div>
         </div>
         <div class="item-txt">
           <!-- <p>{{typeArr[item.sceneType]}}</p> -->
@@ -25,13 +37,15 @@
             </div>-->
             <div class="btmr-con">
               <div
+              v-if="item.status !== 0"
                 class="btm-right"
-                @click.stop="(item.status === 1||item.status===-2) && del(item)"
-              >{{langScenes.delete}}</div>
+                @click.stop="del(item)"
+              ><span>{{langScenes.delete}}</span></div>
               <div
+              v-if="item.status === 1||item.status===-2"
                 class="btm-right primary"
-                @click.stop="(item.status === 1||item.status===-2) && gotoEdit(item)"
-              >{{langScenes.edit}}</div>
+                @click.stop="gotoEdit(item)"
+              ><span>{{langScenes.edit}}</span></div>
             </div>
           </div>
         </div>
@@ -125,6 +139,20 @@ export default {
     this.getList()
   },
   methods: {
+    rechargeTip (item) {
+      this.$toast.showConfirm('warn', this.langToast['28'], () => {
+        this.$router.push({name: 'introduce', params: {id: item.childName}})
+      }, this.langToast['28_1'], this.langScenes.limit.expand)
+    },
+    getSceneImg (item) {
+      switch (item.status) {
+        case -1:
+          let to = this.language === 'en' ? this.$cdn + 'images/scene_error-en.png' : this.$cdn + 'images/scene_error.png'
+          return to
+        default:
+          return item.thumb + '?v=' + item.version
+      }
+    },
     toShare (item) {
       var i, r, f, sceneName
       i = encodeURIComponent

+ 17 - 0
mobile/src/pages/account/manage/myscene/style.scss

@@ -4,6 +4,16 @@
   padding: 10px 24px;
   border-top: 1px solid #e9e9e9;
 }
+.huifu{
+  position: absolute;
+  bottom: 10px;
+  right: 10px;
+  color: #1fe4dc;
+  display: inline-block;
+  border-bottom: 1px solid #1fe4dc;
+  padding-bottom: 2px;
+  cursor: pointer;
+}
 .scene-nothing{
   text-align: center;
   padding-bottom:30px;
@@ -76,6 +86,13 @@
             line-height: 26px;
             text-align: center;
             margin-right: 4px;
+            position: relative;
+            span{
+              position: absolute;
+              top: 50%;
+              left: 50%;
+              transform: translate(-50%,-50%);
+            }
           }
           .primary{
             background: #1fe4dc;

+ 99 - 23
mobile/src/pages/account/manage/order/index.vue

@@ -25,34 +25,50 @@
           <div class="o-price">
             <span>{{langOrders.total}}{{item.goodsAmount}}</span>
           </div>
-          <div class="to-pay">
-            <template v-if="getStatus(item) === 'unpaid'">
-              <div class="o-button">
-                <span class="cancel"  @click="cancal(item)">{{langOrders.cancal}}</span>
-                <span class="pay" @click="goPay(item)">{{langOrders.pay}}</span>
-              </div>
-            </template>
-            <template v-else-if="getStatus(item) === 'shipped'">
-              <span class="expreeNum">物流单号:{{item.orderItems[0].expressNum}}</span>
-            </template>
-            <template v-else-if="getStatus(item) === 'unshipped'">
-              <span class="expreeNum">等待商家发货</span>
-            </template>
-            <template v-else-if="getStatus(item) === 'finish'">
-              <span class="expreeNum">已完成</span>
-            </template>
-            <template v-else-if="getStatus(item) === 'partShipped'">
-              <span class="expreeNum">部分发货</span>
-            </template>
-            <template v-else>
-              <span class="expreeNum">已取消</span>
+          <div class="inovice-con" :class="{'ic-active':item.showInvoice}">
+            <div class="o-invoiceTitle">
+              <span>{{langOrders.invoice}}</span>
+              <span v-if="getStatus(item) !== 'shipped'" @click="edit(item)"><i class="iconfont icon-edit"></i>{{langOrders.edit}}</span>
+              <!-- <span v-else><i class="iconfont icon-choice"></i>发票已寄出</span> -->
+            </div>
+            <div class="o-invoice">
+              <editInvoice :data="getItemInvoice(item)" :orderId='item.id' :invoiceId="item.invoice&&(item.invoice.id)"/>
+            </div>
+          </div>
+          <div class="bottom-area">
+            <div class="bottom-left">
+              <template v-if="getStatus(item) === 'unpaid'">
+                <span></span>
+              </template>
+              <template v-else-if="getStatus(item) === 'shipped'">
+                <span class="expreeNum">{{langOrders.wlNum}}{{item.orderItems[0].expressNum}}</span>
+              </template>
+              <template v-else-if="getStatus(item) === 'unshipped'">
+                <span class="expreeNum">{{langOrders.unshipped}}</span>
+              </template>
+              <template v-else-if="getStatus(item) === 'finish'">
+                <span class="expreeNum">{{langOrders.finish}}</span>
+              </template>
+              <template v-else-if="getStatus(item) === 'partShipped'">
+                <span class="expreeNum">{{langOrders.partShipped}}</span>
+              </template>
+              <template v-else>
+                <span class="expreeNum">{{langOrders.hasCancal}}</span>
+              </template>
+            </div>
+            <div class="to-pay">
+              <span class="cancel btns" @click="changeIvoiceStatus(i,item)">{{langOrders.invoice}}</span>
+              <template v-if="getStatus(item) === 'unpaid'">
+              <span class="cancel btns" @click="cancal(item)">{{langOrders.cancal}}</span>
+              <span class="pay btns" @click="goPay(item)">{{langOrders.pay}}</span>
             </template>
+            </div>
           </div>
         </div>
       </template>
       <div class="scene-nothing" v-else>
         <img :src="`${$cdn}images/nothing.png`" alt="">
-        <div>暂无任何订单,赶紧去购买吧。</div>
+        <div>{{langOrders.norecord}}</div>
       </div>
       <div class="paging" v-if="total">
         <Paging @clickHandle="pageChange" :current="currentPage" :total="total" :equable="pageSize"/>
@@ -62,8 +78,21 @@
 </template>
 
 <script>
+import Vue from 'vue'
 import { mapState } from 'vuex'
+import editInvoice from '@/components/editInvoice'
 import Paging from '@/components/Paging'
+let typeName = {
+  'no': '不需要发票',
+  2: '增值税普票(电子发票)',
+  3: '增值税专用发票'
+}
+
+let typeNameEn = {
+  'no': 'No invoice required',
+  2: 'VAT invoice (electronic invoice)',
+  3: 'VAT special invoice'
+}
 let cameraName = {
   7: `四维看看 三脚架套装`,
   1: `四维看看 Lite二目相机`,
@@ -94,7 +123,7 @@ let detailEn = {
   4: ['4DKanKan Pro Camera (Night Sky Black)', 'Storage Plan (10G)']
 }
 export default {
-  components: { Paging },
+  components: { Paging, editInvoice },
   data () {
     return {
       pageSize: 5,
@@ -124,6 +153,9 @@ export default {
       cameraName: state => {
         return state.language.current === 'en' ? cameraNameEn : cameraName
       },
+      typeName: state => {
+        return state.language.current === 'en' ? typeNameEn : typeName
+      },
       detail: state => {
         return state.language.current === 'en' ? detailEn : detail
       }
@@ -133,6 +165,50 @@ export default {
     this.getList()
   },
   methods: {
+    edit (item) {
+      let invoice = item.invoice
+      let type = 'no'
+      let invoiceId = 'no'
+      let orderId = 'no'
+      if (invoice) {
+        type = invoice.type
+        invoiceId = invoice.id
+        invoice['typeName'] = this.typeName[type]
+      } else {
+        invoice = {
+          type
+        }
+      }
+      orderId = item.id
+
+      this.$router.push({
+        name: 'orderInvoice',
+        params: {
+          type,
+          invoiceId,
+          orderId
+        }
+      })
+
+      this.$store.commit('OINVOICEINFO', invoice)
+      // this.$bus.$emit('isOrderInvoice', false)
+    },
+    changeIvoiceStatus (i, item) {
+      item.showInvoice = !item.showInvoice
+      this.$bus.$emit('isOrderInvoice', true)
+      this.currentI = i
+      this.currentItem = item
+      Vue.set(this.myorder.list, i, item)
+    },
+    getItemInvoice (item) {
+      let invoice = item.invoice
+      if (!invoice) {
+        return ''
+      }
+      invoice['typeName'] = this.typeName[invoice.type]
+
+      return invoice
+    },
     pageChange (data) {
       this.currentPage = data
     },

+ 95 - 2
mobile/src/pages/account/manage/order/style.scss

@@ -1,9 +1,26 @@
+$theme-color: #1fe4dc;
+$border-color: #e7e7e7;
+
 .expreeNum{
   text-align: right;
   display: block;
-  padding: 10px 24px;
-  border-top: 1px solid #e9e9e9;
+  padding: 10px 0;
+}
+
+.btns {
+  width: 80px;
+  height: 34px;
+  line-height: 34px;
+  display: inline-block;
+  vertical-align: middle;
+  border-radius: 2px;
+  text-align: center;
+  margin-left: 10px;
+  background: $theme-color;
+  color: #2d2d2d;
+  font-size: 12px;
 }
+
 .scene-nothing{
   text-align: center;
   padding-bottom:30px;
@@ -25,6 +42,7 @@
     overflow: hidden;
     margin: 18px auto 0;
     font-size: 12px;
+    
     .o-header{
       font-weight: 500;
       padding: 14px;
@@ -33,6 +51,43 @@
         color: rgba(16,142,233,.63);
       }
     }
+    .inovice-con{
+      max-height: 0;
+      overflow: hidden;
+    }
+    .ic-active{
+      max-height: 500px;
+      transition: 0.3s ease max-height;
+    }
+    .o-invoiceTitle {
+      user-select: none;
+      display: flex;
+      padding: 14px 25px;
+      align-items: center;
+      border-top: 1px solid $border-color;
+      border-bottom: 1px solid $border-color;
+      .iconfont{
+        vertical-align: middle;
+        font-size: 20px;
+        margin-right: 5px;
+      }
+      .icon-edit{
+        color: #21e4dc;
+      }
+      .icon-choice{
+        color: #02e430;
+      }
+      span {
+        font-size: 12px;
+        flex: 1;
+        &:first-child {
+          text-align: left;
+        }
+        &:last-child{
+          text-align: right;
+        }
+      }
+    }
     .o-con{
       padding: 12px;
       display: flex;
@@ -105,6 +160,36 @@
       }
     }
   }
+  .bottom-area{
+    position: relative;
+    border-top: 1px solid #e9e9e9;
+    .bottom-left{
+      position: absolute;
+      top: 50%;
+      left: 25px;
+      color: #a0a0a0;
+      transform: translateY(-50%);
+      font-size: 12px;
+    }
+    .to-pay {
+      text-align: right;
+      height: 73px;
+      line-height: 73px;
+      padding: 0 25px;
+      font-size: 0;
+      .cancel {
+        border: 1px solid #ccc;
+        display: inline-block;
+        text-align: center;
+        cursor: pointer;
+        background: none;
+      }
+      .expreeNum {
+        margin-right: 60px;
+        color: #2d2d2d;
+      }
+    }
+  }
   .paging {
     // border-left: #e5e5e5 1px solid;
     height: 100%;
@@ -147,4 +232,12 @@
       transition: transform 0.3s;
     }
   }
+}
+
+@media screen and (max-width: 320px) {
+  .btns{
+    width: 65px;
+    height: 32px;
+    line-height: 32px;
+  }
 }

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

@@ -0,0 +1,133 @@
+<template>
+  <div class="i-layout">
+    <div class="address-con">
+      <editInvoice :data='oinvoiceinfo' :orderId='orderId' :invoiceId="invoiceId" class="address-scon" />
+    </div>
+  </div>
+</template>
+
+<script>
+import { mapState } from 'vuex'
+import editInvoice from '@/components/editInvoice/edit'
+
+export default {
+  components: {
+    editInvoice
+  },
+  data () {
+    return {
+      orderId: this.$route.params.orderId,
+      invoiceId: this.$route.params.invoiceId
+    }
+  },
+  computed: {
+    ...mapState({
+      oinvoiceinfo: state => {
+        let type = Object.prototype.toString.call(state.user.oinvoiceinfo)
+        if (type === '[object Object]') {
+          return state.user.oinvoiceinfo
+        }
+        let condition = state.user.oinvoiceinfo && state.user.oinvoiceinfo !== 'null' && type !== '[object Array]'
+        return condition ? JSON.parse(state.user.oinvoiceinfo) : {}
+      }
+    })
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.i-layout{
+  .address-input-con{
+    padding: 16px 0 0;
+    font-size: 12px;
+    line-height: 1.5;
+    color: rgba(0, 0, 0, 0.65);
+    .address-input-item{
+      display: flex;
+      margin-bottom:8px;
+
+      .address-sub{
+        width: 100%;
+        .top-title{
+          overflow: hidden;
+          text-overflow: ellipsis;
+          white-space: nowrap;
+          color: rgba(0, 0, 0, 0.85);
+          padding: 0 0 8px;
+          margin: 0;
+          display: block;
+          text-align: left;
+          line-height: 1.5;
+          &::before{
+            display: inline-block;
+            margin-right: 4px;
+            content: "*";
+            font-family: SimSun;
+            line-height: 1;
+            font-size: 12px;
+            color: #f04134;
+          }
+        }
+      }
+      .address-name,.prov-name{
+        width: 33.33%;
+        padding-right:4px;
+        flex-shrink: 0;
+      }
+      .prov-name{
+        width: 50%;
+      }
+      .address-phone,.city-name{
+        flex: auto;
+      }
+
+    }
+    .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;
+      position: relative;
+      background-color: #f6f9ff;
+      overflow-wrap: break-word;
+      .bc-contact{
+        font-size: 12px;
+        color: rgba(0,0,0,.7);
+        line-height: 18px;
+
+      }
+      .bc-locotion{
+        font-size: 10px;
+        color: rgba(0,0,0,.45);
+        line-height: 12px;
+      }
+      .bc-edit{
+        position: absolute;
+        top: 16px;
+        right: 16px;
+        font-size: 12px;
+        color: rgba(0,0,0,.7);
+        line-height: 18px;
+      }
+    }
+    .p-dec{
+      line-height:32px;
+      margin-bottom: 8px;
+    }
+  }
+  .address-con{
+    .sub-title{
+      font-size: 14px;
+      line-height: 21px;
+      font-weight: 700;
+      padding: 13px 16px;
+      border-bottom: 1px solid #e9e9e9;
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+    }
+  }
+}
+</style>

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

@@ -99,7 +99,16 @@
         </div>
       </div>
     </div>
-    <div class="btn-submit" @click="pay">提交订单</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>
   </div>
 </template>
 
@@ -167,11 +176,15 @@ export default {
       isWeixin: browser.weixin,
       orderId: '',
       orderType: 0,
-      detail
+      detail,
+      isAgree: true
     }
   },
   methods: {
     async pay () {
+      if (!this.isAgree) {
+        return
+      }
       let {invoice, goods, payType, receiver} = this.payinfo
       let params = {
         goods,

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

@@ -1,4 +1,13 @@
 .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);
+  }
   .form-con{
     opacity: 0;
     height: 1px;
@@ -200,6 +209,6 @@
     border-radius: 2px;
     width: 100%;
     background-color: #1fe4dc;
-    margin: 16px 0 30px;
+    margin: 0;
   }
 }

+ 1 - 1
mobile/src/pages/account/manage/vieworder/index.vue

@@ -42,7 +42,7 @@
           </div>
         </div>
         <div class="btn-submit" @click="toPay">结算</div>
-        <div class="dec">温馨提示:您的订单将顺丰速运专业配送</div>
+        <div class="dec">温馨提示:您的订单将顺丰速运专业配送</div>
       </div>
       <div class="paytype">
         <div>支付方式</div>

+ 16 - 12
mobile/src/pages/account/register/index.vue

@@ -19,11 +19,11 @@
           </div>
           <ul v-show="showSelect" >
             <li @click="selectItem(item)" v-for="(item,i) in selectCall" :key="i">
-              {{item[0]}}{{item[1]}}
+              {{language==='en'?item[2]:item[0]}}{{item[1]}}
             </li>
           </ul>
         </div>
-        <input oninput="value=value.replace(/[^\d]/g,'')" v-model="phone" @focus="inputActive='phone'" @blur="inputActive=''" type="text" :placeholder="langLogin.phone.placeholder">
+        <input class="guding" oninput="value=value.replace(/[^\d]/g,'')" v-model="phone" @focus="inputActive='phone'" @blur="inputActive=''" type="text" :placeholder="langLogin.phone.placeholder">
       </div>
       <div class="code-con">
         <div class="input-con" :class="{inputActive:inputActive==='code'}">
@@ -41,11 +41,15 @@
         <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="agree">
-        <input type="checkbox" v-model="isAgree">
-        同意四维看看条款
-      </div> -->
-      <div class="btns" @click="submit">{{langLogin.submit}}</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">{{langLogin.submit}}</div>
       <div class="to-login">
         <div class="lo-con">
           {{langLogin.resigter1}}<router-link :to="{path:'/login'}">{{langLogin.resigter2}}</router-link>
@@ -80,8 +84,8 @@ export default {
       interTime: 60,
       jishi: false,
       interl: null,
-      selectCall
-      // isAgree: true
+      selectCall,
+      isAgree: true
     }
   },
   mounted () {
@@ -120,9 +124,9 @@ export default {
       }
     },
     async submit () {
-      // if (!this.isAgree) {
-      //   return this.$toast.show('warn', '请查阅并同意四维看看条款')
-      // }
+      if (!this.isAgree) {
+        return
+      }
 
       let check = value => {
         for (let i = 0, len = value.length; i < len; i++) {

+ 13 - 2
mobile/src/pages/account/register/style.scss

@@ -25,10 +25,17 @@ 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;
+    display: flex;
+    flex-wrap: nowrap;
+    align-items: center;
     &>span{
       display: inline-block;
       vertical-align: middle;
@@ -44,8 +51,8 @@ input[type='password']{
     top: 0;
     left: 0;
     background: #fff;
-    width: 200px;
-    height: 220px;
+    min-width: 200px;
+    height: 230px;
     padding: 0 10px;
     overflow: auto;
     transition: ease 0.3s all;
@@ -55,6 +62,7 @@ input[type='password']{
       height: 40px;
       line-height: 50px;
       color: #999;
+      word-break: break-all;
       font-size: 14px;
       cursor: pointer;
       &:hover{
@@ -63,6 +71,9 @@ input[type='password']{
     }
   }
 }
+.guding{
+  padding-right: 0!important;
+}
 .register-layout{
   width: 100%;
   .banner{

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

@@ -101,7 +101,7 @@
                   @click="selectItem(item)"
                   v-for="(item,i) in selectCall"
                   :key="i"
-                >{{item[0]}}{{item[1]}}</li>
+                >{{language==='en'?item[2]:item[0]}}{{item[1]}}</li>
               </ul>
             </div>
             <div class="ant-input">

+ 2 - 1
mobile/src/pages/agent/style.scss

@@ -226,12 +226,13 @@
         box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
         left: 0;
         background: #fff;
-        width: 120px;
+        min-width: 230px;
         height: 150px;
         padding: 0 10px;
         overflow: auto;
         transition: all .3s ease;
         border-radius: 4px;
+        word-break: normal;
         li{
           height: 40px;
           line-height: 1.5;

+ 1 - 0
mobile/src/pages/cases/index.vue

@@ -59,6 +59,7 @@ import {mapState} from 'vuex'
 let typeArr = {
   '房地产': 2,
   '博物馆': 1,
+  '电商': 3,
   '家居': 5,
   '餐饮': 4,
   '其他': 0,

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

@@ -1,6 +1,6 @@
 <template>
   <div class="home-layout">
-    <div class="popup-player" v-show="showVideo">
+    <div class="popup-player" v-if="showVideo">
       <div class="mask" @click="()=>{currenVideo='';showVideo=false}"></div>
       <video autoplay controls :src="currenVideo" class="video-fr"></video>
     </div>

+ 2 - 2
mobile/src/pages/introduce/index.vue

@@ -26,7 +26,7 @@
      <div class="card-scroll">
        <div @click="toPay(item)" class="card-item" v-for="(item,i) in type" :key="i">
          <div class="top-card">
-           <img :src="`${$cdn}images/card-bg1.png`" alt="">
+           <img :src="language==='en'?`${$cdn}images/card-bg1-en.png`:`${$cdn}images/card-bg1.png`" alt="">
            <div>
             <p>{{item.unit}}</p>
             <p>{{langPurchase.introduce.buy}}</p>
@@ -56,7 +56,7 @@
         </div>
         <div class="p-right">
           <div class="top-card">
-           <img :src="`${$cdn}images/card-bg1.png`" alt="">
+           <img :src="language==='en'?`${$cdn}images/card-bg1-en.png`:`${$cdn}images/card-bg1.png`" alt="">
            <div>
             <p>{{item.unit}}</p>
             <p>{{langPurchase.introduce.buy}}</p>

+ 13 - 5
mobile/src/pages/layout/header.vue

@@ -7,7 +7,7 @@
         <span class="l3"></span>
       </div>
     </div>
-    <div @click="$router.back()" class="h-left back" v-else>
+    <div @click="backHome?$router.push({name:'home'}):$router.back()" class="h-left back" v-else>
       <i class="iconfont icon-jiantou"></i>
     </div>
     <div class="h-center">
@@ -23,7 +23,7 @@
       <div class="h-user"  v-else-if="isAccout||isLogin">
           <i class="iconfont icon-cart" :style="{opacity:language==='en'?0:1}" @click="gocart"><span>{{count>99?'99+':count}}</span></i>
           <img ref="userList" :src="`${$cdn}images/icon/nav_icon.png`" @click="userList=!userList,active = false" alt="">
-          <ul :style="{width:language==='en'?'150px':'110px'}" :class="{'ul-active':userList}" >
+          <ul :style="{width:language==='en'?'160px':'110px'}" :class="{'ul-active':userList}" >
             <li v-for="(item,i) in langHeader.manage" :key="i" @click="handleClick(item)">{{item.name}}</li>
           </ul>
       </div>
@@ -89,6 +89,7 @@ let hasBack = [
   'introduce',
   'introtow',
   'openInvoice',
+  'orderInvoice',
   'consumpdetail',
   'useimg'
 ]
@@ -163,7 +164,6 @@ export default {
       return this.language === 'en' ? titleNameEn : titleName
     },
     noEnglish () {
-      console.log(noEngList[this.$route.name])
       return noEngList[this.$route.name]
     },
     isBack: function () {
@@ -205,7 +205,7 @@ export default {
       searchTxt: '',
       activeIdx: '',
       count: 0,
-
+      backHome: false,
       total: 0,
       pageSize: 10,
       currentPage: 1,
@@ -214,6 +214,14 @@ export default {
     }
   },
   watch: {
+    '$route.query': function (newVal) {
+      if (newVal.lang && newVal.lang === 'en') {
+        this.$store.commit('change_language', 'en')
+      }
+      this.backHome = newVal.token
+      // let lang = this.$route.query.lang
+      // this.$store.commit('change_language', lang)
+    },
     currentPage () {
       this.getData()
     },
@@ -299,7 +307,7 @@ export default {
       this.active = false
     },
     linkto (url) {
-      location.href = url.replace('http://', 'https://')
+      location.href = url.replace('http://', 'https://') + (this.language === 'en' ? '&lang=en' : '')
     },
     maskTitle (name) {
       if (!name) { return '' }

+ 1 - 0
mobile/src/pages/layout/style.scss

@@ -122,6 +122,7 @@ $bannerHeight:60px;
       }
       .ul-active{
         max-height: 250px;
+        word-break: break-all;
       }
       img{
         width: 50%;

+ 26 - 2
mobile/src/pages/purchase/index.vue

@@ -2,7 +2,11 @@
   <div class="purchase-layout">
     <div class="plate01">
       <div class="main-layout">
-        <img class="pro" :src="`${$cdn}images/banner_pro.png`" alt="">
+        <!-- <img class="pro" :src="`${$cdn}images/banner_pro.png`" alt=""> -->
+        <browse
+          :idata='browdata'
+          :floder="'probrowse'"
+         />
         <div class="txt-con">
           <img class="p-logo" :src="language==='en'?`${$cdn}images/pro-logo-m-en.png`:`${$cdn}images/pro-logo-m.png`" alt="">
           <div class="p-label" v-html="langPurchase.dec"></div>
@@ -74,7 +78,7 @@
     </div>
     <div class="hover-btns">
       <div class="h-price">
-       {{language!=='en'? `RMB ${selectParts?count*(9800 + 899):count*9800}`:'USD 1500'}}
+       {{language!=='en'? `RMB ${selectParts?count*(9800 + 899):count*9800}`:'USD 1499'}}
       </div>
       <div class="h-btns">
         <span v-if="language!=='en'" @click="addcart">加入购物车</span>
@@ -89,11 +93,13 @@ import { mapState } from 'vuex'
 
 import spinner from '@/components/spinner'
 import priceTable from '@/components/priceTable'
+import browse from '@/components/browse'
 import { getPosition } from '@/util'
 
 export default {
   components: {
     spinner,
+    browse,
     priceTable
   },
   computed: {
@@ -104,8 +110,26 @@ export default {
     })
   },
   data () {
+    let browdata = [
+      {
+        small: 'small-0',
+        big: 'big-0',
+        video: true
+      }, {
+        small: 'small-1',
+        big: 'big-1'
+      },
+      {
+        small: 'small-2',
+        big: 'big-2'
+      },
+      {
+        small: 'small-3',
+        big: 'big-3'
+      }]
     return {
       count: 1,
+      browdata,
       selectParts: true
     }
   },

+ 29 - 2
mobile/src/pages/purchasezhijia/index.vue

@@ -2,7 +2,10 @@
   <div class="purchase-layout">
     <div class="plate01">
       <div class="main-layout">
-        <img class="pro" :src="`${$cdn}images/zhijia-gif.gif`" alt>
+         <browse
+          :idata='browdata'
+          :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>
@@ -94,11 +97,13 @@ import { mapState } from 'vuex'
 
 import spinner from '@/components/spinner'
 import priceTable from '@/components/priceTable'
+import browse from '@/components/browse'
 
 export default {
   components: {
     spinner,
-    priceTable
+    priceTable,
+    browse
   },
   computed: {
     ...mapState({
@@ -109,8 +114,30 @@ export default {
     })
   },
   data () {
+    let browdata = [
+      {
+        small: 'small-0',
+        big: 'big-0',
+        video: true
+      }, {
+        small: 'small-1',
+        big: 'big-1'
+      },
+      {
+        small: 'small-2',
+        big: 'big-2'
+      },
+      {
+        small: 'small-3',
+        big: 'big-3'
+      },
+      {
+        small: 'small-4',
+        big: 'big-4'
+      }]
     return {
       count: 1,
+      browdata,
       selectParts: true
     }
   },

+ 32 - 1
mobile/src/pages/service/temp/config.js

@@ -250,6 +250,36 @@ const app = {
   titleEn: 'Download',
   title: '四维看看 软件下载'
 }
+
+const agreement = {
+  cp: 'iapp',
+  titleEn: 'Download',
+  title: '四维看看 软件下载',
+  data: {
+    lite: [
+      {
+        title: '与全景相机的区别',
+        img: 1
+      },
+      {
+        title: '与全景相机的区别',
+        img: 2
+      }
+
+    ],
+    pro: [
+      {
+        title: '与全景相机的区别',
+        img: 1
+      },
+      {
+        title: '与全景相机的区别',
+        img: 2
+      }
+    ]
+  }
+}
+
 const qa = {
   cp: 'iqa',
   titleEn: '四维看看 常见问题',
@@ -389,5 +419,6 @@ export default {
   use,
   app,
   qa,
-  clause
+  clause,
+  agreement
 }

+ 6 - 0
mobile/src/router/index.js

@@ -111,6 +111,12 @@ let router = new Router({
           meta: {requireAuth: true, noEnglish: true}
         },
         {
+          path: '/orderInvoice/:type/:invoiceId/:orderId',
+          name: 'orderInvoice',
+          component: resolve => require(['@/pages/account/manage/orderInvoice'], resolve),
+          meta: {requireAuth: true}
+        },
+        {
           name: 'device',
           path: '/device/:id',
           component: resolve => require(['@/pages/account/manage/device'], resolve),

+ 2 - 0
mobile/src/store/language/cn/home.js

@@ -187,6 +187,8 @@ export default{
     ]
   },
   loginAside: {
+    agree: '同意',
+    cluse: '四维看看平台用户条款',
     plogin: '请登录',
     pregister: '立即注册吧',
     pforget: '帮您找回密码',

+ 36 - 2
mobile/src/store/language/cn/manage.js

@@ -92,6 +92,8 @@ export default{
     show: '收起',
     avatar: '头像',
     nickname: '昵称',
+    account: '账号',
+    email: '邮箱',
     placeholder: {
       nickname: '输入昵称',
       phone: '电话',
@@ -109,7 +111,12 @@ export default{
     save: '保 存',
     cancel: '取 消',
     select: '选择图片',
-    sinfo: '允许的文件类型为JPG 或 PNG。',
+    sinfo: [
+      '请选择一张新照片进行上传',
+      '支持图片格式为:JPG/PNG',
+      '512*512px,大小不大于1MB'
+    ],
+    isReceive: '获取四维看看优惠信息和最新动态',
     recaddress: '请务必详细填写相符无误的地址以免耽误收货',
     fill: '请把信息填写完整'
   },
@@ -140,6 +147,11 @@ export default{
       copyfail: '复制失败',
       delsuccess: '删除成功',
       delfail: '删除失败,'
+    },
+    limit: {
+      insufficient: '云端容量不足<br/>场景已关闭',
+      recharge: '恢复>>',
+      expand: '扩容'
     }
   },
   myOrders: {
@@ -149,7 +161,29 @@ export default{
     subtotal: '价格',
     total: '总价:¥',
     cancal: '取消订单',
-    pay: '立即付款'
+    pay: '立即付款',
+    norecord: '暂无任何订单,赶紧去购买吧。',
+    invoice: '发票信息',
+    wlNum: '物流单号:',
+    unshipped: '等待商家发货',
+    finish: '已完成',
+    partShipped: '部分发货',
+    hasCancal: '已取消',
+    edit: '修改',
+    editInfo: '发货后7天内能修改',
+    dontneed: '发票类型:不需要发票',
+    type1: '不需要发票',
+    type2: '增值税普票(电子发票)',
+    type3: '增值税专用发票',
+    title: '发票抬头',
+    code: '18位税务登记号',
+    email: '电子邮箱',
+    organizedAddress: '注册地址',
+    registerPhone: '注册电话',
+    bankName: '开户银行',
+    bankAccount: '银行账户',
+    save: '保 存',
+    cancal1: '取 消'
   },
   myDevices: {
     add: '+添加新设备',

+ 3 - 1
mobile/src/store/language/cn/toast.js

@@ -26,7 +26,8 @@ export default{
   '25': '没有找到相应的记录',
   '26': '确定要解绑当前相机吗?',
   '27': '上传的图片类型不正确,请重新上传',
-  '28': '您的云端容量已用完,请删除其他场景或扩容, 以保证足够的容量。',
+  '28': '您的云端容量已用完',
+  '28_1': '请删除其他场景或扩容,以保证足够的容量。',
   '29': '手机号码不合法',
   '30': '请重新登录',
   '31': '密码位数不能少于8位',
@@ -45,6 +46,7 @@ export default{
   '44': '微信支付',
   '45': '请在使用第三方浏览器内打开',
   '46': '请在微信内打开',
+  '47': '修改成功',
 
   '4007': '用户名不存在',
   '4010': '绑定的相机不存在',

+ 2 - 0
mobile/src/store/language/en/home.js

@@ -185,6 +185,8 @@ export default{
     ]
   },
   loginAside: {
+    agree: 'Agree to&nbsp;',
+    cluse: '4DKankan User Agreement',
     plogin: 'Please log in.',
     pregister: 'Sign up now.',
     pforget: 'I\'ll get your password back.',

+ 38 - 3
mobile/src/store/language/en/manage.js

@@ -91,7 +91,9 @@ export default{
     edit: 'Edit',
     show: 'Hide',
     avatar: 'Profile Picture',
-    nickname: 'Name',
+    nickname: 'Nick name',
+    account: 'User name',
+    email: 'E-mail',
     placeholder: {
       nickname: 'Please input name',
       phone: 'Phone',
@@ -109,7 +111,12 @@ export default{
     save: 'Save',
     cancel: 'Cancel',
     select: 'Select Picture',
-    sinfo: 'Please upload .jpg or .png file.',
+    sinfo: [
+      'Select a new picture to upload.',
+      'Supported picture formats: JPG/PNG',
+      '512*512 px; less than 1 MB'
+    ],
+    isReceive: 'Get the latest 4DKANKAN news and deals',
     recaddress: 'Please be sure to fill in the correct address so as not to delay the receipt',
     fill: 'Please fill in the information completely'
 
@@ -142,6 +149,11 @@ export default{
       copyfail: 'Fail',
       delsuccess: 'Success',
       delfail: 'Fail'
+    },
+    limit: {
+      insufficient: 'Insufficient cloud storage<br/>The scene is archived.',
+      recharge: 'Recover>>',
+      expand: 'To expand'
     }
   },
   myOrders: {
@@ -151,7 +163,30 @@ export default{
     subtotal: 'Price',
     total: 'Total price: ¥',
     cancal: 'Cancel order',
-    pay: 'Pay now'
+    pay: 'Pay now',
+    norecord: 'No order',
+    invoice: 'Invoice',
+    wlNum: 'Shipment No.: ',
+    unshipped: 'Waiting for shipment',
+    finish: 'Finished',
+    partShipped: 'Partly dispatched',
+    hasCancal: 'Cancelled',
+    edit: 'Edit',
+    editInfo: 'Only within 7 days after delivery',
+    dontneed: 'Invoice type: No invoice required',
+    type1: 'No invoice required',
+    type2: 'VAT invoice (electronic invoice)',
+    type3: 'VAT special invoice',
+    title: 'Invoice Title',
+    code: 'Invoice tax No.',
+    email: 'E-mail',
+    organizedAddress: 'Address',
+    registerPhone: 'Phone number',
+    bankName: 'Banker',
+    bankAccount: 'Bank account',
+    save: 'Save',
+    cancal1: 'Cancel'
+
   },
   myDevices: {
     add: '+Add a new device',

+ 2 - 2
mobile/src/store/language/en/purchase.js

@@ -2,7 +2,7 @@ export default{
   top1: '概览',
   top2: '技术规格',
   dec: 'Capture the World in 3D with Eight-Lens HD Camera',
-  yushou: '【New Product Presale Price】',
+  yushou: '【Early Bird Price】',
   price: 'USD 1499',
   why: 'Why do I need to purchase storage capacity?',
   addzhijia: 'RMB 10,395',
@@ -215,7 +215,7 @@ export default{
     used: 'Already used:',
     belong: 'Storage Capacity: ',
     scence: 'My scenes',
-    buyType: 'Please select the service type:',
+    buyType: 'Please select the service type',
     mounthly: 'Monthly',
     year: 'Annually',
     buy: 'Buy Now',

+ 3 - 1
mobile/src/store/language/en/toast.js

@@ -26,7 +26,8 @@ export default{
   '25': 'No record found.',
   '26': 'Are you sure to unbind the current camera?',
   '27': 'Incorrect image format. Please upload again.',
-  '28': 'Your cloud storage is used up, please delete scenes or expand the storage. ',
+  '28': 'Your cloud storage is used up ',
+  '28_1': ' please delete scenes or expand the storage. ',
   '29': 'Illegal mobile number',
   '30': 'Please re-log in.',
   '31': 'Password digits must not be less than 8 digits',
@@ -45,6 +46,7 @@ export default{
   '44': 'Wechat',
   '45': 'Please open it in a third party browser',
   '46': 'Please open it in WeChat',
+  '47': 'Modify successfully',
 
   '4007': 'User name doesn\'t exist.',
   '4010': 'The bound camera doesn\'t exist.',

+ 15 - 1
mobile/src/store/language/home_cn.js

@@ -54,8 +54,12 @@ export default {
             icon: 'icon-industry_museum',
             to: {name: 'cases', params: {id: '博物馆'}}
           }, {
-            name: '家居',
+            name: '电商',
             icon: 'icon-industry_ecom',
+            to: {name: 'cases', params: {id: '电商'}}
+          }, {
+            name: '家居',
+            icon: 'icon-industry_home',
             to: {name: 'cases', params: {id: '家居'}}
           }, {
             name: '餐饮',
@@ -149,6 +153,10 @@ export default {
       }
     ]
   },
+  _404: {
+    txt: '抱歉,您访问的页面出现了错误,请重新加载',
+    btn: '返回首页'
+  },
   purchase,
   purchasetow,
   purchasezhijia,
@@ -189,6 +197,7 @@ export default {
       '博物馆': '博物馆',
       '家居': '家居',
       '餐饮': '餐饮',
+      '电商': '电商',
       '其他': '其他',
       '全部': '全部'
     },
@@ -220,6 +229,11 @@ export default {
           name: '博物馆'
         },
         {
+          id: 3,
+          to: {name: 'cases', params: {id: '电商'}},
+          name: '电商'
+        },
+        {
           id: 5,
           to: {name: 'cases', params: {id: '家居'}},
           name: '家居'

+ 16 - 1
mobile/src/store/language/home_en.js

@@ -55,8 +55,12 @@ export default {
             icon: 'icon-industry_museum',
             to: {name: 'cases', params: {id: '博物馆'}}
           }, {
-            name: 'Home',
+            name: 'E-commerce',
             icon: 'icon-industry_ecom',
+            to: {name: 'cases', params: {id: '电商'}}
+          }, {
+            name: 'Home',
+            icon: 'icon-industry_home',
             to: {name: 'cases', params: {id: '家居'}}
           }, {
             name: 'Catering',
@@ -148,6 +152,10 @@ export default {
       }
     ]
   },
+  _404: {
+    txt: 'Error,Please reload.',
+    btn: 'Go Back'
+  },
   home,
   eight,
   purchase,
@@ -186,6 +194,7 @@ export default {
     typeName: {
       '房地产': 'Real estate',
       '博物馆': 'Museum',
+      '电商': 'E-commerce',
       '家居': 'Home',
       '餐饮': 'Catering',
       '其他': 'Others',
@@ -219,10 +228,16 @@ export default {
           name: 'Museum'
         },
         {
+          id: 3,
+          to: {name: 'cases', params: {id: '电商'}},
+          name: 'E-commerce'
+        },
+        {
           id: 5,
           to: {name: 'cases', params: {id: '家居'}},
           name: 'Home'
         },
+
         {
           id: 4,
           to: {name: 'cases', params: {id: '餐饮'}},

+ 1 - 1
mobile/src/store/language/index.js

@@ -10,7 +10,7 @@ const en = {
 }
 
 let current = (localStorage && localStorage.getItem('language')) || '中'
-// let current = '中'
+document.title = current === 'en' ? '4DKanKan' : '四维看看'
 
 let languageObj = current === '中' ? cn : en
 

+ 8 - 0
mobile/src/store/user.js

@@ -16,6 +16,8 @@ let fdkankantoken = Cookies.get('4dkankantoken') || ''
 let cart = (localStorage && localStorage.getItem('cart')) || []
 let payinfo = (localStorage && localStorage.getItem('payinfo')) || {}
 let orderinfo = (localStorage && localStorage.getItem('orderinfo')) || {}
+let oinvoiceinfo = (localStorage && localStorage.getItem('oinvoiceinfo')) || {}
+
 let recordinfo = (localStorage && localStorage.getItem('recordinfo')) || {}
 
 let invoice2 = (localStorage && localStorage.getItem('invoice2')) || []
@@ -49,6 +51,7 @@ export default {
     invoicedevice: '',
     payinfo,
     orderinfo,
+    oinvoiceinfo,
     recordinfo,
     invoice2: invoice2,
     invoice3: invoice3,
@@ -95,6 +98,11 @@ export default {
       localStorage.setItem('orderinfo', JSON.stringify(data))
     },
 
+    OINVOICEINFO (state, data) {
+      state.oinvoiceinfo = data
+      localStorage.setItem('oinvoiceinfo', JSON.stringify(data))
+    },
+
     RECORDINFO (state, data) {
       state.recordinfo = data
       localStorage.setItem('recordinfo', JSON.stringify(data))

+ 3 - 1
mobile/src/util/index.js

@@ -14,7 +14,9 @@ module.exports = {
   reg: {
     idCard: /^\d{6}(18|19|20)?\d{2}(0[1-9]|1[012])(0[1-9]|[12]\d|3[01])\d{3}(\d|[xX])$/,
     phone: /^1(?:3\d|4[4-9]|5[0-35-9]|6[67]|7[013-8]|8\d|9\d)\d{8}$/,
-    email: /^([a-zA-Z0-9]+[_|_|.]?)*[a-zA-Z0-9]+@([a-zA-Z0-9]+[_|_|.]?)*[a-zA-Z0-9]+\.[a-zA-Z]{2,3}$/
+    email: /^([a-zA-Z0-9]+[_|_|.]?)*[a-zA-Z0-9]+@([a-zA-Z0-9]+[_|_|.]?)*[a-zA-Z0-9]+\.[a-zA-Z]{2,3}$/,
+    guhua: /^(\(\d{3,4}\)|\d{3,4}-|\s)?\d{7,14}$/
+
   },
   isEmptyObject: function (obj) {
     for (var key in obj) {

+ 18 - 6
pc/src/assets/font/iconfont.css

@@ -1,11 +1,11 @@
 @font-face {
   font-family: 'iconfont';  /* project id 941679 */
-  src: url('//at.alicdn.com/t/font_941679_cx64etzgw84.eot');
-  src: url('//at.alicdn.com/t/font_941679_cx64etzgw84.eot?#iefix') format('embedded-opentype'),
-  url('//at.alicdn.com/t/font_941679_cx64etzgw84.woff2') format('woff2'),
-  url('//at.alicdn.com/t/font_941679_cx64etzgw84.woff') format('woff'),
-  url('//at.alicdn.com/t/font_941679_cx64etzgw84.ttf') format('truetype'),
-  url('//at.alicdn.com/t/font_941679_cx64etzgw84.svg#iconfont') format('svg');
+  src: url('//at.alicdn.com/t/font_941679_itececxzw5a.eot');
+  src: url('//at.alicdn.com/t/font_941679_itececxzw5a.eot?#iefix') format('embedded-opentype'),
+  url('//at.alicdn.com/t/font_941679_itececxzw5a.woff2') format('woff2'),
+  url('//at.alicdn.com/t/font_941679_itececxzw5a.woff') format('woff'),
+  url('//at.alicdn.com/t/font_941679_itececxzw5a.ttf') format('truetype'),
+  url('//at.alicdn.com/t/font_941679_itececxzw5a.svg#iconfont') format('svg');
 }
 
 .iconfont {
@@ -108,6 +108,10 @@
   content: "\e637";
 }
 
+.icon-industry_home:before {
+  content: "\e6a7";
+}
+
 .icon-industry_gover:before {
   content: "\e638";
 }
@@ -307,3 +311,11 @@
 .icon-lirunfencheng:before {
   content: "\e671";
 }
+
+.icon-edit:before {
+  content: "\e6a6";
+}
+
+.icon-choice:before {
+  content: "\e6a5";
+}

+ 92 - 0
pc/src/assets/style/public.scss

@@ -71,6 +71,98 @@ body{
   }
 }
 
+.check-con {
+  box-sizing: border-box;
+  margin: 0;
+  padding: 0;
+  color: rgba(0, 0, 0, 0.65);
+  font-size: 14px;
+  font-variant: tabular-nums;
+  line-height: 1.5;
+  list-style: none;
+  font-feature-settings: "tnum", "tnum";
+  display: inline-block;
+  line-height: unset;
+  cursor: pointer;
+  color: rgba(0,0,0,.65);
+  font-size: 12px;
+  .check-box {
+    box-sizing: border-box;
+    margin: 0;
+    padding: 0;
+    color: rgba(0, 0, 0, 0.65);
+    font-size: 12px;
+    font-variant: tabular-nums;
+    line-height: 1.5;
+    list-style: none;
+    font-feature-settings: "tnum", "tnum";
+    position: relative;
+    top: -0.09em;
+    display: inline-block;
+    line-height: 1;
+    white-space: nowrap;
+    vertical-align: middle;
+    outline: none;
+    cursor: pointer;
+    .checkbox-input {
+      position: absolute;
+      top: 0;
+      right: 0;
+      bottom: 0;
+      left: 0;
+      z-index: 1;
+      width: 100%;
+      height: 100%;
+      cursor: pointer;
+      opacity: 0;
+    }
+    .checkbox-inner {
+      width: 14px;
+      height: 14px;
+      margin-right: 2px;
+      position: relative;
+      top: 0;
+      left: 0;
+      display: block;
+      background-color: #fff;
+      border: 1px solid #d9d9d9;
+      border-collapse: separate;
+      transition: all 0.3s;
+      &::after {
+        position: absolute;
+        top: 30%;
+        left: 12%;
+        display: table;
+        width: 5px;
+        height: 9px;
+        border: 2px solid #000;
+        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 #000;
+        border-top: 0;
+        border-left: 0;
+        transform: rotate(45deg) scale(0.8) translate(-50%, -50%);
+        opacity: 1;
+        transition: all 0.2s cubic-bezier(0.12, 0.4, 0.29, 1.46) 0.1s;
+        content: " ";
+      }
+    }
+  }
+}
+
 .b-title {
   line-height: 66px;
   font-size: 44px;

+ 29 - 0
pc/src/components/browse/index.vue

@@ -0,0 +1,29 @@
+<template>
+  <div class="brow-layout">
+    <div  class="product-img" >
+      <video v-if="active.video" :src="`${$cdn}images/${floder}/${active.big}.mp4`" autoplay muted loop></video>
+      <img v-else :src="`${$cdn}images/${floder}/${active.big}.png`">
+    </div>
+    <ul>
+      <li v-for="(item,i) in data" :key="i" :class="{active:active === item}" @click="active = item">
+        <img :src="`${$cdn}images/${floder}/${item.small}.png`" >
+      </li>
+    </ul>
+  </div>
+</template>
+
+<script>
+export default {
+  props: ['iactive', 'idata', 'floder'],
+  data () {
+    return {
+      data: this.idata,
+      active: this.iactive
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+@import './style.scss';
+</style>

+ 51 - 0
pc/src/components/browse/style.scss

@@ -0,0 +1,51 @@
+
+
+.brow-layout{
+  .product-img{
+    width: 500px;
+    height: 500px;
+    margin: 40px auto 25px;
+    position: relative;
+    img,video{
+      transform: translate(-50%,-50%);
+      position: absolute;
+      top: 50%;
+      left: 50%;
+      width: 100%;
+    }
+    video{
+      width: 130%;
+    }
+  }
+  ul{
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    margin: 0 auto;
+    li{
+      width: 80px;
+      height: 80px;
+      text-align: center;
+      background: #e7e7e7;
+      flex-shrink: 0;
+      cursor: pointer;
+      img{
+        width: 100%;
+      }
+    }
+    .active{
+      border: 1px solid #cccccc;
+    }
+  }
+}
+
+
+@media screen and (max-width: 1450px) {
+  .brow-layout{
+    .product-img{
+      video{
+        width: 100%;
+      }
+    }
+  }
+}

+ 357 - 0
pc/src/components/editInvoice/edit.vue

@@ -0,0 +1,357 @@
+<template>
+  <div class="invoice edit-invoice" slot="edit">
+    <div class="select-con">
+      <div :class="{'tag-active':invoice===null}" @click="invoice=null">
+        <span>{{langOrders.type1}}</span>
+        <img :src="`${$cdn}images/tag-icon.png`" alt />
+      </div>
+      <div :class="{'tag-active':invoice===2}" @click="invoice=2">
+        <span>{{langOrders.type2}}</span>
+        <img :src="`${$cdn}images/tag-icon.png`" alt />
+      </div>
+      <div :class="{'tag-active':invoice===3}" @click="invoice=3">
+        <span>{{langOrders.type3}}</span>
+        <i></i>
+        <img :src="`${$cdn}images/tag-icon.png`" alt />
+      </div>
+    </div>
+    <div class="invoice-input" v-if="invoice===2">
+      <div class="input-con">
+        <input type="text" :placeholder="langOrders.title" maxlength="20" v-model="editInvoice2.title" />
+        <input
+          type="text"
+          :placeholder="langOrders.code"
+          oninput="value=value.replace(/[^\w\.\/]/ig,'')"
+          maxlength="18"
+          v-model="editInvoice2.code"
+        />
+      </div>
+      <div class="input-con">
+        <input type="text" :placeholder="langOrders.email" maxlength="30" v-model="editInvoice2.emailAddress" />
+      </div>
+    </div>
+    <div class="invoice-input" v-if="invoice===3">
+      <div class="input-con">
+        <input type="text" v-model="editInvoice3.title" maxlength="20" :placeholder="langOrders.title"/>
+        <input
+          type="text"
+          maxlength="18"
+          v-model="editInvoice3.code"
+          oninput="value=value.replace(/[^\w\.\/]/ig,'')"
+          :placeholder="langOrders.code"
+        />
+      </div>
+      <div class="input-con">
+        <input
+          type="text"
+          maxlength="100"
+          v-model="editInvoice3.organizedAddress"
+          :placeholder="langOrders.organizedAddress"
+        />
+        <input type="text" maxlength="20" oninput="value=value.replace(/[^\d\-]/g,'')" v-model="editInvoice3.registerPhone" :placeholder="langOrders.registerPhone"/>
+      </div>
+      <div class="input-con">
+        <input type="text" maxlength="40" v-model="editInvoice3.bankName" :placeholder="langOrders.bankName" />
+        <input type="text" maxlength="40" v-model="editInvoice3.bankAccount" :placeholder="langOrders.bankAccount"  />
+      </div>
+    </div>
+    <div @click="saveInvoice(invoice)" class="btn parmary">{{langOrders.save}}</div>
+
+    <div @click="$bus.$emit('isOrderInvoice', true)" class="btn">{{langOrders.cancal1}}</div>
+
+  </div>
+</template>
+<script>
+import { reg } from '@/util'
+import { mapState } from 'vuex'
+
+export default {
+  props: ['data', 'orderId', 'invoiceId'],
+  data: function () {
+    return {
+      editInvoice2: this.data.type === 2 ? this.data : {},
+      editInvoice3: this.data.type === 3 ? this.data : {},
+      invoice: this.data.type || null
+    }
+  },
+  watch: {
+    data (newVal) {
+      this.invoice = newVal.type || null
+      this.editInvoice2 = newVal.type === 2 ? newVal : {}
+      this.editInvoice3 = newVal.type === 3 ? newVal : {}
+    }
+  },
+  computed: {
+    ...mapState({
+      token: state => state.user.token,
+      langToast: state => state.language.home.toast,
+      language: state => state.language.current,
+      langOrders: state => state.language.home.manage.myOrders
+    })
+  },
+  methods: {
+    changeType (type) {
+      this.$emit('changtype', type)
+    },
+    saveInvoice (cInvoice) {
+      if (!cInvoice) {
+        if (this.invoiceId) {
+          this.$http
+            .post('user/invoice/delete', {
+              invoiceId: this.invoiceId
+            }, {
+              headers: {
+                token: this.token
+              }
+            })
+            .then(data => {
+              let response = data.data
+              if (response.code === 0) {
+                this.$bus.$emit('editItem', {
+                  id: '',
+                  type: null
+                })
+                this.$bus.$emit('isOrderInvoice', true)
+              }
+            })
+        }
+        return
+      }
+      let isObject = function (obj) {
+        return JSON.stringify(obj) === '{}' ? '' : obj
+      }
+      let params = {}
+      let invoiceType = ''
+      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
+      }
+
+      if (cInvoice === 2) {
+        invoiceType = 2
+
+        let title = isObject(this.editInvoice2.title)
+        let code = isObject(this.editInvoice2.code)
+        let emailAddress = isObject(this.editInvoice2.emailAddress)
+
+        if (code && code.length !== 18) {
+          return this.$toast.show('warn', this.langToast['21'])
+        }
+        if (!reg.email.test(emailAddress)) {
+          return this.$toast.show('warn', this.langToast['8'])
+        }
+        params = {
+          invoiceType,
+          title,
+          code: code || '',
+          emailAddress
+        }
+
+        let checkStr = [
+          {
+            name: '发票抬头',
+            En: 'Title',
+            val: title
+          },
+          {
+            name: '电子邮箱',
+            En: 'Email',
+            val: emailAddress
+          }
+        ]
+        if (!check(checkStr)) {
+          return
+        }
+      } else {
+        let {title: title1, code: code1, organizedAddress: organizedAddress1, registerPhone: registerPhone1, bankName: bankName1, bankAccount: bankAccount1} = this.editInvoice3
+        invoiceType = 3
+        let title = isObject(title1)
+        let code = isObject(code1)
+        let organizedAddress = isObject(organizedAddress1)
+        let registerPhone = isObject(registerPhone1)
+        let bankName = isObject(bankName1)
+        let bankAccount = isObject(bankAccount1)
+
+        params = {
+          invoiceType,
+          title,
+          code: code || '',
+          organizedAddress,
+          registerPhone,
+          bankName,
+          bankAccount
+        }
+        let checkStr = [
+          {
+            name: '发票抬头',
+            En: 'Title',
+            val: title
+          },
+          {
+            name: '税务登记号',
+            En: 'Code',
+            val: code
+          },
+          {
+            name: '注册地址',
+            En: 'Organized Address',
+            val: organizedAddress
+          },
+          {
+            name: '注册电话',
+            En: 'Register Phone',
+            val: registerPhone
+          },
+          {
+            name: '开户银行',
+            En: 'Bank Name',
+            val: bankName
+          },
+          {
+            name: '银行账号',
+            En: 'Bank Account',
+            val: bankAccount
+          }
+        ]
+        if (!check(checkStr)) {
+          return
+        }
+        if (!code || code.length !== 18) {
+          return this.$toast.show('warn', this.langToast['21'])
+        }
+
+        if (!reg.guhua.test(registerPhone)) {
+          return this.$toast.show('warn', this.langToast['22'])
+        }
+      }
+
+      if (this.invoiceId) {
+        params['invoiceId'] = params['id'] = this.invoiceId || null
+      }
+      params['orderId'] = this.orderId
+      params['invoiceType'] = invoiceType
+
+      this.$http
+        .post('user/invoice/update', params, {
+          headers: {
+            token: this.token
+          }
+        })
+        .then(data => {
+          let response = data.data
+          if (response.code === 0) {
+            this.$bus.$emit('editItem', response.data)
+            this.$bus.$emit('isOrderInvoice', true)
+          }
+        })
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+$theme-color: #1fe4dc;
+$border-color: #e7e7e7;
+input {
+  appearance: none;
+  line-height: 36px;
+  height: 36px;
+  border: solid 1px $border-color;
+  padding-left: 10px;
+  &:focus {
+    border: solid 1px $theme-color;
+  }
+}
+.btn {
+  text-align: center;
+  cursor: pointer;
+  width: 126px;
+  height: 36px;
+  line-height: 36px;
+  margin: 10px 25px 0 0;
+  display: inline-block;
+  border: solid 1px #ccc;
+}
+.parmary {
+  background-color: $theme-color;
+  border: solid 1px $theme-color;
+}
+.invoice {
+  margin-top: 20px;
+  p {
+    line-height: 18px;
+    margin-bottom: 8px;
+    overflow-wrap: break-word;
+    &:last-of-type {
+      margin-bottom: 0;
+    }
+    span {
+      padding-right: 10px;
+    }
+  }
+  .p-desc {
+    color: #a0a0a0;
+    overflow-wrap: break-word;
+    line-height: 24px;
+  }
+  .no-info {
+    margin-top: 4px;
+  }
+  .avatar {
+    width: 68px;
+    height: 68px;
+    box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.4);
+    margin: 5px 0;
+  }
+  .nickname {
+    width: 126px;
+  }
+}
+.edit-invoice {
+  .select-con {
+    div {
+      position: relative;
+      cursor: pointer;
+      width: 200px;
+      line-height: 36px;
+      height: 36px;
+      margin: 10px 26px 10px 0;
+      border: solid 1px $border-color;
+      color: #a0a0a0;
+      padding: 0 10px;
+      display: inline-block;
+      img {
+        display: none;
+        position: absolute;
+        bottom: 0;
+        right: 0;
+      }
+      &:last-of-type {
+        margin-right: 0;
+      }
+    }
+    .tag-active {
+      border: solid 1px $theme-color;
+      color: #000;
+      img {
+        display: inline-block;
+      }
+    }
+  }
+  .input-con {
+    input {
+      width: 316px;
+      line-height: 36px;
+      height: 36px;
+      margin: 10px 25px 10px 0;
+      &:last-of-type {
+        margin-right: 0;
+      }
+    }
+  }
+}
+</style>

+ 57 - 0
pc/src/components/editInvoice/index.vue

@@ -0,0 +1,57 @@
+<template>
+  <div class="i-lay">
+    <template v-if="isShow">
+      <p v-if="!data.type">{{langOrders.dontneed}}</p>
+      <template v-else>
+        <p v-for="(item,i) in invoiceData" :key="i">{{(language==='en'?item['en']:item['name'])+':'+(data[item['key']]||'--')}}</p>
+      </template>
+    </template>
+    <edit v-else :data='data' :orderId='orderId' :invoiceId="invoiceId"/>
+  </div>
+</template>
+
+<script>
+import { mapState } from 'vuex'
+import { normal, zengzhi } from './invoice'
+import edit from './edit'
+export default {
+  props: ['data', 'orderId', 'invoiceId'],
+  components: {
+    edit
+  },
+  mounted () {
+    this.$bus.$on('isOrderInvoice', data => {
+      this.isShow = data
+    })
+  },
+  computed: {
+    ...mapState({
+      token: state => state.user.token,
+      langToast: state => state.language.home.toast,
+      language: state => state.language.current,
+      langOrders: state => state.language.home.manage.myOrders
+    }),
+    invoiceData () {
+      if (!this.data) {
+        return ''
+      }
+      return this.data.type === 2 ? normal : zengzhi
+    }
+  },
+  data () {
+    return {
+      isShow: true
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.i-lay{
+  p{
+    color: #a0a0a0;
+    margin: 10px 0;
+
+  }
+}
+</style>

+ 86 - 0
pc/src/components/editInvoice/invoice.js

@@ -0,0 +1,86 @@
+let normal = [
+  {
+    key: 'typeName',
+    name: '发票类型',
+    en: 'Invoice type'
+  }, {
+    key: 'title',
+    name: '发票抬头',
+    en: 'Invoice Title'
+  }, {
+    key: 'code',
+    name: '发票税号',
+    en: 'Invoice tax No.'
+  }, {
+    key: 'emailAddress',
+    name: '电子邮箱',
+    en: 'E-mail'
+  }
+]
+
+let zengzhi = [
+  {
+    key: 'typeName',
+    name: '发票类型',
+    en: 'Invoice type'
+  }, {
+    key: 'title',
+    name: '发票抬头',
+    en: 'Invoice Title'
+  }, {
+    key: 'code',
+    name: '发票税号',
+    en: 'Invoice tax No.'
+  }, {
+    key: 'organizedAddress',
+    name: '注册地址',
+    en: 'Address'
+  }, {
+    key: 'registerPhone',
+    name: '注册电话',
+    en: 'Phone number'
+  }, {
+    key: 'bankName',
+    name: '开户银行',
+    en: 'Banker'
+  }, {
+    key: 'bankAccount',
+    name: '开户账号',
+    en: 'Bank account'
+  }
+
+]
+
+let invoice = [
+  {
+    key: 'createTime',
+    en: '申请时间',
+    name: '申请时间'
+  }, {
+    key: 'type',
+    en: '发票类型',
+    name: '发票类型'
+  }, {
+    key: 'title',
+    en: '发票抬头',
+    name: '发票抬头'
+  }, {
+    key: 'money',
+    en: '开票金额',
+    name: '开票金额'
+  }, {
+    key: 'finish',
+    en: '状态',
+    name: '状态'
+  }, {
+    key: 'detail',
+    name: '操作',
+    en: '操作',
+    canclick: true
+  }
+]
+export {
+  normal,
+  zengzhi,
+  invoice
+}

+ 12 - 10
pc/src/components/toast/editInvoice.vue

@@ -28,32 +28,32 @@
           </div>
           <div v-if="cInvoice==='normal'">
             <div class="input-con">
-              <input type="text" placeholder="请输入发票抬头" v-model="normal.title" />
+              <input type="text" maxlength='20' placeholder="请输入发票抬头" v-model="normal.title" />
               <input type="text" placeholder="请输入18位税务登记号" oninput="value=value.replace(/[^\w\.\/]/ig,'')" maxlength='18' v-model="normal.code" />
             </div>
              <div class="input-con">
-              <input type="text" placeholder="请输入电子邮箱" v-model="normal.emailAddress" />
+              <input type="text" maxlength='30' placeholder="请输入电子邮箱" v-model="normal.emailAddress" />
             </div>
           </div>
           <div v-else>
             <div class="input-con">
-              <input type="text" v-model="zengzhi.title" placeholder="请输入发票抬头" />
+              <input type="text" v-model="zengzhi.title" maxlength='20' placeholder="请输入发票抬头" />
               <input type="text" v-model="zengzhi.code" placeholder="请输入18位税务登记号" oninput="value=value.replace(/[^\w\.\/]/ig,'')" maxlength='18' />
             </div>
             <div class="input-con">
-              <input type="text" v-model="zengzhi.organizedAddress" placeholder="注册地址" />
-              <input type="text" v-model="zengzhi.registerPhone" placeholder="注册电话" />
+              <input type="text" v-model="zengzhi.organizedAddress" maxlength='100' placeholder="注册地址" />
+              <input type="text" oninput="value=value.replace(/[^\d\-]/g,'')" v-model="zengzhi.registerPhone" maxlength='20' placeholder="注册电话" />
             </div>
             <div class="input-con">
-              <input type="text" v-model="zengzhi.bankName" placeholder="开户银行" />
-              <input type="text" v-model="zengzhi.bankAccount" placeholder="银行账户" />
+              <input type="text" v-model="zengzhi.bankName" maxlength='40' placeholder="开户银行" />
+              <input type="text" v-model="zengzhi.bankAccount" maxlength='40' placeholder="银行账户" />
             </div>
           </div>
         </div>
         <div class="address edit-address" v-if="cInvoice!=='normal'">
           <div class="input-con">
-            <input type="text" v-model="editAdd.shipName" :placeholder="'姓名'" />
-            <input type="text" v-model="editAdd.shipMobile" :placeholder="'电话'" />
+            <input type="text" v-model="editAdd.shipName" maxlength='20' :placeholder="'姓名'" />
+            <input type="text" v-model="editAdd.shipMobile" maxlength='20' :placeholder="'电话'" />
           </div>
           <div class="input-con">
             <citySelect :areaPath="editAdd.shipAreaPath" @currentVal="getCurrentSelect" />
@@ -62,6 +62,7 @@
             <input
               type="text"
               v-model="editAdd.shipAddress"
+              maxlength='100'
               :placeholder="'详细地址'"
             />
           </div>
@@ -225,7 +226,7 @@ export default {
           return this.$toast.show('warn', this.toastCode['21'])
         }
 
-        if (!reg.phone.test(registerPhone)) {
+        if (!reg.guhua.test(registerPhone)) {
           return this.$toast.show('warn', this.toastCode['22'])
         }
       }
@@ -260,6 +261,7 @@ export default {
       let response = res.data
 
       if (response.code === 0) {
+        this.$bus.$emit('refreshInvoice')
         this.$toast.show('success', '开票成功', () => {
           this.handleClick()
         })

+ 4 - 3
pc/src/components/toast/index.vue

@@ -38,11 +38,11 @@
         </div>
         <div class="t-line"></div>
         <div class="bottom" v-if="toastType==='comfirm'">
-          <span class="btn primary" @click="emitCallback">{{comfirmtxt}}</span>
+          <span class="btn primary" @click="emitCallback">{{diycomfirm||comfirmtxt}}</span>
           <span @click="visible=false,cancal()" class="btn cancel">{{lang==='en'?'Cancel':'取消'}}</span>
         </div>
         <div class="bottom mid-bottom" v-else>
-          <span class="btn primary" @click="emitCallback">{{comfirmtxt}}</span>
+          <span class="btn primary" @click="emitCallback">{{diycomfirm||comfirmtxt}}</span>
         </div>
       </div>
     </div>
@@ -94,8 +94,9 @@ export default {
       toastType: 'show',
       callback: '',
       cancal: '',
+      diycomfirm: '',
       isLoaing: false,
-      comfirmtxt: '确定',
+      comfirmtxt: localStorage.getItem('language') === 'en' ? 'OK' : '确定',
       img: this.$cdn + 'images/icon/warn.png',
       lang: localStorage.getItem('language')
     }

+ 3 - 2
pc/src/components/toast/toast.js

@@ -21,13 +21,13 @@ Toast.install = function (Vue) {
   }
   Vue.prototype.$toast = {
     showConfirm: (type, msg, callback, cancal, comfirmtxt) => {
-      let langauge = localStorage.getItem('language')
+      // let langauge = localStorage.getItem('language')
       instance.img = imgs[type] || (baseUrl + 'images/icon/success.png')
       instance.message = msg
       instance.type = type
       instance.visible = true
       instance.toastType = 'comfirm'
-      instance.comfirmtxt = comfirmtxt || langauge !== 'en' ? '确定' : 'OK'
+      instance.diycomfirm = comfirmtxt
       instance.callback = callback || function () {
       }
       instance.cancal = cancal || function () {
@@ -42,6 +42,7 @@ Toast.install = function (Vue) {
       instance.type = type
       instance.visible = true
       instance.toastType = 'show'
+      instance.diycomfirm = ''
       instance.callback = callback || function () {
       }
     },

+ 10 - 3
pc/src/page/404/index.vue

@@ -2,15 +2,22 @@
   <div class="layout-404">
     <div class="_404">
       <img :src="`${$cdn}images/404.png`" alt="">
-      <p>抱歉,您访问的页面出现了错误,请重新加载</p>
-      <div @click="$router.push({name:'home'})">返回首页</div>
+      <p>{{lang404.txt}}</p>
+      <div @click="$router.push({name:'home'})">{{lang404.btn}}</div>
     </div>
   </div>
 </template>
 
 <script>
-export default {
+import { mapState } from 'vuex'
 
+export default {
+  computed: {
+    ...mapState({
+      language: state => state.language.current,
+      lang404: state => state.language.home._404
+    })
+  }
 }
 </script>
 

+ 1 - 1
pc/src/page/agent/index.vue

@@ -70,7 +70,7 @@
               <span>{{codeActive[1]}}</span>
               <ul v-if="showSelect" >
                 <li @click="selectItem(item)" v-for="(item,i) in selectCall" :key="i">
-                  {{item[0]}}{{item[1]}}
+                  {{language==='en'?item[2]:item[0]}}{{item[1]}}
                 </li>
               </ul>
             </div>

+ 2 - 1
pc/src/page/agent/style.scss

@@ -234,7 +234,8 @@ $num_time: 0.6s;
         box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
         left: 0;
         background: #fff;
-        width: 200px;
+        min-width: 230px;
+        width: auto;
         height: 230px;
         padding: 0 10px;
         overflow: auto;

+ 7 - 12
pc/src/page/cases/index.vue

@@ -6,9 +6,9 @@
       <div class="case-nav">
         <div class="nav-con">
           <vcenter>
-            <div class="list-nav" :style="{width:language==='en'?'900px':'705px'}">
+            <div class="list-nav" :style="{width:language==='en'?'950px':'705px'}">
               <!-- <div class="list-txt b-title">{{caseType}}</div> -->
-              <router-link :style="{marginLeft:language==='en'?'30px':'38px'}" :class="{'active-txt':caseType===langCases.typeName[item.name]}" class="sub-list b-title" :to="item.to" v-for="(item,i) in navs" :key="i">{{langCases.typeName[item.name]}}</router-link>
+              <router-link :style="{marginLeft:language==='en'?'20px':'38px'}" :class="{'active-txt':caseType===langCases.typeName[item.name]}" class="sub-list b-title" :to="item.to" v-for="(item,i) in navs" :key="i">{{langCases.typeName[item.name]}}</router-link>
             </div>
             <div class="lists">
               <ul class="list-navs">
@@ -49,15 +49,6 @@ import vcenter from '@/components/vcenter'
 import card from '@/components/card'
 import Paging from '@/components/Paging'
 
-let typeArr = {
-  '房地产': 2,
-  '博物馆': 1,
-  '家居': 5,
-  '餐饮': 4,
-  '其他': 0,
-  '全部': null
-}
-
 let sceneSTYpe = {
   '全部': null,
   '四维看看 Lite': 1,
@@ -74,6 +65,10 @@ let nav = [
     to: {name: 'cases', params: {id: '博物馆'}}
   },
   {
+    name: '电商',
+    to: {name: 'cases', params: {id: '电商'}}
+  },
+  {
     name: '家居',
     to: {name: 'cases', params: {id: '家居'}}
   },
@@ -176,7 +171,7 @@ export default {
       window.scrollTo(0, 0)
       let params = {
         pageSize: this.pageSize,
-        sceneType: typeArr[this.caseType],
+        sceneType: this.langCases.typeArr[this.caseType],
         sceneInterest: this.sortActive,
         pageNum: this.currentPage,
         sceneScheme: sceneSTYpe[this.selected]

+ 2 - 2
pc/src/page/cases/style.scss

@@ -30,14 +30,14 @@
           }
           .sub-list{
             padding-top: 10px;
-            font-size: 28px;
+            font-size: 24px;
             color: #969696;
             margin-left: 38px;
             cursor: pointer;
             text-align: center;
           }
           .active-txt{
-            font-size: 44px;
+            font-size: 38px;
             color: #2D2D2D;
           }
         }

+ 1 - 1
pc/src/page/chat/index.vue

@@ -56,7 +56,7 @@ export default {
       if (!content || !email) {
         return
       }
-      if (!reg.email.test(email) && !reg.phone.test(email)) {
+      if (!reg.email.test(email) && !reg.guhua.test(email)) {
         return this.$toast.show('warn', this.langToast['10'])
       }
       let params = {

+ 8 - 1
pc/src/page/home2/index.vue

@@ -128,10 +128,17 @@ export default {
     ...mapState({
       langHome: state => state.language.home.home,
       language: state => state.language.current,
-      sequenceArr: state => state.language.home.home.sequenceArr
+      sequenceArr: state => state.language.home.home.sequenceArr,
+      token: state => state.user.token
     })
   },
   mounted () {
+    let open = this.$route.query.open
+    setTimeout(() => {
+      if (open && !this.token) {
+        this.$bus.$emit('showAside')
+      }
+    })
     this.sizeHandle = () => {
       let ny = getPosition(this.$refs.numcount).y + this.$refs.numcount.offsetHeight
       let sy = getPosition(this.$refs.slide).y + this.$refs.slide.offsetHeight

+ 2 - 0
pc/src/page/layout/aside/index.vue

@@ -124,6 +124,7 @@ export default {
         transform: translate(-50%,-50%);
         left: 50%;
         top: 50%;
+        background: #fff;
         padding: 0;
         .clause-img{
           height: 80%;
@@ -132,6 +133,7 @@ export default {
         }
         p{
           margin: 25px 0;
+          color: #2d2d2d;
         }
         .cls-btn{
           span{

+ 1 - 1
pc/src/page/layout/aside/temp/ctemp/detail.scss

@@ -412,7 +412,7 @@ input {
       .agree{
         cursor: pointer;
         span{
-          color: #a0a0a0;
+          color: #1fe4dc;
           vertical-align: middle;
           &:first-child{
             margin-right: 4px;

+ 14 - 12
pc/src/page/layout/aside/temp/ctemp/detail.vue

@@ -105,25 +105,25 @@
           </div>
           <div class="invoice-input" v-if="invoice==='normal'">
             <div class="input-con">
-              <input type="text" placeholder="请输入发票抬头" maxlength="15" v-model="editInvoice2.title">
+              <input type="text" placeholder="请输入发票抬头" maxlength="20" v-model="editInvoice2.title">
               <input type="text" placeholder="请输入18位税务登记号" oninput="value=value.replace(/[^\w\.\/]/ig,'')" maxlength='18' v-model="editInvoice2.code">
             </div>
             <div class="input-con">
-              <input type="text" placeholder="请输入电子邮箱" v-model="editInvoice2.emailAddress">
+              <input type="text" placeholder="请输入电子邮箱" maxlength="30" v-model="editInvoice2.emailAddress">
             </div>
           </div>
           <div class="invoice-input" v-if="invoice==='zengzhi'">
             <div class="input-con">
-              <input type="text" v-model="editInvoice3.title" maxlength="15" placeholder="请输入发票抬头">
+              <input type="text" v-model="editInvoice3.title" maxlength="20" placeholder="请输入发票抬头">
               <input type="text" maxlength='18' v-model="editInvoice3.code" oninput="value=value.replace(/[^\w\.\/]/ig,'')" placeholder="请输入18位税务登记号">
             </div>
             <div class="input-con">
-              <input type="text" v-model="editInvoice3.organizedAddress" placeholder="注册地址">
-              <input type="text" v-model="editInvoice3.registerPhone" placeholder="注册电话">
+              <input type="text" maxlength="100" v-model="editInvoice3.organizedAddress" placeholder="注册地址">
+              <input type="text" maxlength="20" oninput="value=value.replace(/[^\d\-]/g,'')" v-model="editInvoice3.registerPhone" placeholder="注册电话">
             </div>
             <div class="input-con">
-              <input type="text" v-model="editInvoice3.bankName" placeholder="开户银行">
-              <input type="text" v-model="editInvoice3.bankAccount" placeholder="银行账户">
+              <input type="text" maxlength="40" v-model="editInvoice3.bankName" placeholder="开户银行">
+              <input type="text" maxlength="40" v-model="editInvoice3.bankAccount" placeholder="银行账户">
             </div>
           </div>
             <div @click="saveInvoice(invoice)" class="btn parmary">保存</div>
@@ -437,17 +437,19 @@ export default {
       if (!this.addressStatus) {
         return this.$toast.show('warn', this.langToast['18'])
       }
-      if (!this.address.shipName) {
-        return this.$toast.show('warn', this.langToast['19'])
-      }
 
       if (this.invoice === 'normal' && !this.invoice2.title) {
         return this.$toast.show('warn', this.langToast['20'])
       }
 
       if (this.invoice === 'zengzhi' && !this.invoice3.title) {
-        return this.$toast.show('warn', this.langToast['21'])
+        return this.$toast.show('warn', this.langToast['20'])
       }
+
+      if (!this.address.shipName) {
+        return this.$toast.show('warn', this.langToast['19'])
+      }
+
       let invoice = this.invoice === 'normal' ? this.invoice2 : this.invoice === 'zengzhi' ? this.invoice3 : null
       if (invoice) {
         invoice['invoiceType'] = invoice['type']
@@ -583,7 +585,7 @@ export default {
           return this.$toast.show('warn', this.langToast['21'])
         }
 
-        if (!reg.phone.test(registerPhone)) {
+        if (!reg.guhua.test(registerPhone)) {
           return this.$toast.show('warn', this.langToast['22'])
         }
       }

+ 2 - 1
pc/src/page/layout/aside/temp/ltemp/deviceLogin.vue

@@ -5,6 +5,7 @@
     </div>
     <div class="qrcode">
       <img v-if="codeImg" :src="codeImg?`${$serverName}${codeImg}`:''" alt="">
+      <!-- <img v-if="codeImg" :src="codeImg?`${'https://www.4dkankan.com/'}${codeImg}`:''" alt=""> -->
       <div class="qrcode-con">
         <div class="qrcode-dec">{{languagelAside.scansub}}</div>
       </div>
@@ -74,7 +75,7 @@ export default {
           if (token && to !== 0) {
             this.$store.commit('DEVICELOGIN', childName)
             this.$bus.$emit('hideAside')
-            this.$router.replace({name: 'scene', query: {first: true}})
+            this.$router.replace({name: 'scene'})
           } else {
             this.$bus.$emit('hideAside')
             this.$bus.$emit('hasLogin')

+ 1 - 1
pc/src/page/layout/aside/temp/ltemp/forget.vue

@@ -7,7 +7,7 @@
       </div>
       <ul v-show="showSelect" >
         <li @click="selectItem(item)" v-for="(item,i) in selectCall" :key="i">
-          {{item[0]}}{{item[1]}}
+          {{language==='en'?item[2]:item[0]}}{{item[1]}}
         </li>
       </ul>
       <input autocomplete="off" :placeholder="languagelAside.phone.placeholder" oninput="value=value.replace(/[^\d]/g,'')" maxlength='11' v-model="phone" type="text">

+ 24 - 1
pc/src/page/layout/aside/temp/ltemp/login.vue

@@ -13,7 +13,7 @@
           </div>
           <ul v-show="showSelect" >
             <li @click="selectItem(item)" v-for="(item,i) in selectCall" :key="i">
-              {{item[0]}}{{item[1]}}
+              {{language==='en'?item[2]:item[0]}}{{item[1]}}
             </li>
           </ul>
           <input :key="'codelogin'" readonly onfocus="this.removeAttribute('readonly')"  autocomplete="off" v-model="phone" oninput="value=value.replace(/[^\d]/g,'')" maxlength='11' :placeholder="languagelAside.phone.placeholder" type="text">
@@ -168,6 +168,29 @@ export default {
       if (this.isCodeLogin) {
         await this.submit()
       } else {
+        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: 'Password',
+            val: this.password
+          }
+        ]
+        if (!check(checkStr)) {
+          return
+        }
         localStorage.setItem('remember', this.rememberMe)
         if (this.rememberMe) {
           localStorage.setItem('username', this.phone)

+ 1 - 1
pc/src/page/layout/aside/temp/ltemp/register.vue

@@ -8,7 +8,7 @@
       </div>
       <ul v-show="showSelect" >
         <li @click="selectItem(item)" v-for="(item,i) in selectCall" :key="i">
-          {{item[0]}}{{item[1]}}
+          {{language==='en'?item[2]:item[0]}}{{item[1]}}
         </li>
       </ul>
       <input readonly onfocus="this.removeAttribute('readonly')"  autocomplete="off" v-model="phone" oninput="value=value.replace(/[^\d]/g,'')" maxlength='11' :placeholder="languagelAside.phone.placeholder" type="text">

+ 1 - 1
pc/src/page/layout/aside/temp/ltemp/style.scss

@@ -213,7 +213,7 @@ $lincolor:#d0d0d1;
     top: 0;
     left: 0;
     background: #fff;
-    width: 200px;
+    min-width: 230px;
     height: 400px;
     padding: 0 10px;
     overflow: auto;

+ 2 - 6
pc/src/page/layout/footer.vue

@@ -1,10 +1,6 @@
 <template>
   <div class="footer" :style="{position: $route.name === 'service_list' ? 'absolute':'relative'}" v-show="split">
     <div class="layout">
-     <div class="forWK">
-      <a :class="{active: language === 'en'}" @click="$store.commit('change_language', 'en')">En</a>
-      <a :class="{active: language === '中'}" @click="$store.commit('change_language', '中')">中</a>
-     </div>
       <div class="infos">
         <div class="wlbm">
           <popup
@@ -37,8 +33,8 @@
       </div>
       <div class="relevant">
         <div>
-          <a href="https://www.4dage.com" target="_blank">{{langFooter.fdage}}</a>
-          <a href="https://www.cgaii.com" target="_blank">{{langFooter.cgaii}}</a>
+          <a :href="language==='en'?'https://www.4dage.com/en':'https://www.4dage.com'" target="_blank">{{langFooter.fdage}}</a>
+          <a :href="language==='en'?'https://www.cgaii.com/en':'https://www.cgaii.com'" target="_blank">{{langFooter.cgaii}}</a>
           <a href="http://www.4dmodel.com/" target="_blank">{{langFooter.model}}</a>
         </div>
         <p>Copyright © 2018 4DAGE Co., Ltd. All rights reserved. </p>

+ 19 - 2
pc/src/page/manage/index.vue

@@ -33,7 +33,7 @@
         <template v-else>
           <div class="info deviceLogin">
             <div class="member">
-              <p>{{detail.nickName||'--'}}</p>
+              <p>{{language!=='en'?(detail.nickName||'--'):(detail.nickName==='Pro设备用户'?'4DKanKan Pro User':(detail.nickName||'--'))}}</p>
               <p>
                 <span class="child-name">
                   {{detail.snCode||(detail.childName&&detail.childName.replace('4DKKPRO_',''))||'--'}}
@@ -52,6 +52,7 @@
               </div>
             </div>
           </div>
+          <div class="open-btn" :style="{backgroundColor:'#1fe4dc'}" @click="toastKR">{{langMain.btnType.buy.name}}</div>
         </template>
       </div>
     </div>
@@ -117,18 +118,34 @@ export default {
       }
       return item
     },
+    toastKR () {
+      this.$toast.showConfirm('warn', this.langToast['40'], async () => {
+        await this.$store.dispatch('logout')
+        this.$router.push({name: 'home', query: {open: true}})
+      }, '', this.langToast['41'])
+    },
     tabHandle (sub) {
       switch (sub.to) {
         case 'logout':
           this.$toast.showConfirm('warn', this.language === 'en' ? 'Are you sure to log out?' : '确定要退出登录吗?', async () => {
             await this.$store.dispatch('logout')
-            this.$router.push({name: 'home'})
+            this.$router.push({
+              name: 'home'
+            })
           })
           break
 
         default:
+
           this.active = sub
           this.$router.push(sub.to)
+          if (sub.to.name === 'scene') {
+            if (this.deviceLogin) {
+              setTimeout(() => {
+                this.$bus.$emit('mycid')
+              }, 70)
+            }
+          }
           break
       }
     },

+ 10 - 3
pc/src/page/manage/temp/consumption.vue

@@ -230,10 +230,10 @@ export default {
       })
     },
     activeId (newVal) {
-      this.getInvoiceMax()
       if (this.active === 2) {
         this.getList()
       }
+      this.getInvoiceMax()
     },
     activeTypeId (newVal) {
       if (this.active === 2) {
@@ -246,7 +246,6 @@ export default {
           this.tabHeader = recharge
           break
         case 2:
-          this.getInvoiceMax(0)
           !this.deviceLogin && this.getAllDevice()
           this.tabHeader = invoice
           break
@@ -392,8 +391,16 @@ export default {
     }
   },
   mounted () {
-    this.getInvoiceMax()
     this.getList()
+
+    this.$bus.$off('refreshInvoice')
+    this.$bus.$on('refreshInvoice', () => {
+      if (this.active === 2) {
+        this.getList()
+      }
+      this.getInvoiceMax()
+    })
+
     document.addEventListener('click', (e) => {
       if (this.$refs.invoiceMenu) {
         if (!this.$refs.invoiceMenu.contains(e.target)) {

+ 150 - 52
pc/src/page/manage/temp/information.vue

@@ -6,35 +6,58 @@
       :oper="infoStatus?langAccount.edit:langAccount.show"
       :isActive="infoStatus"
     >
-      <div class="info" slot="show">
-        <p>{{langAccount.avatar}}</p>
-        <!-- <img class="avatar" :src="info.head" alt> -->
-        <div class="card-img avatar" :style="{backgroundImage: `url(${info.head})`}"></div>
-
-        <p>{{langAccount.nickname}}</p>
-        <div>{{info.nickName}}</div>
-      </div>
-      <div class="info edit-info" slot="edit">
-        <div class="info-left">
+      <div class="info" :class="{'info-en':language==='en'}" slot="show">
+        <div class="s-tx">
           <p>{{langAccount.avatar}}</p>
-          <img class="avatar" :src="info.head" alt>
-          <p>{{langAccount.nickname}}</p>
-          <input
-            autofocus
-            v-model="editinfo.nickName"
-            :placeholder="langAccount.placeholder.nickname"
-            class="nickname"
-            maxlength="10"
-            type="text"
-          >
-          <div @click="saveNickName" class="btn parmary">{{langAccount.save}}</div>
+          <div class="card-img avatar" :style="{backgroundImage: `url(${info.head})`}"></div>
         </div>
-        <div>
-          <div class="btn choose">
-            <input class="el-upload" ref="uploadInput" name="file" type="file" @change="update">
-            <span>{{langAccount.select}}</span>
+        <p><span>{{langAccount.account}}</span><span>{{info.userName||'--'}}</span></p>
+        <p><span>{{langAccount.nickname}}</span><span>{{info.nickName||'--'}}</span></p>
+        <p><span>{{langAccount.email}}</span><span>{{info.email||'--'}}</span></p>
+      </div>
+      <div class="info edit-info" :class="{'edit-en':language==='en','info-en':language==='en'}" slot="edit">
+        <div class="info-left">
+          <div class="i-tx">
+            <p>{{langAccount.avatar}}</p>
+            <div class="itx-con">
+            <div class="card-img avatar" :style="{backgroundImage: `url(${info.head})`}"></div>
+              <div class="btn choose">
+                <input class="el-upload" ref="uploadInput" name="file" type="file" @change="update" alt="sadasdasd">
+                <span>{{langAccount.select}}</span>
+              </div>
+              <p class="p-desc" v-for="(item,i) in langAccount.sinfo" :key="i">{{item}}</p>
+            </div>
           </div>
-          <p class="p-desc" v-for="(item,i) in langAccount.sinfo" :key="i">{{item}}</p>
+          <p><span>{{langAccount.account}}</span><span>{{info.userName}}</span></p>
+          <p>
+            <span>{{langAccount.nickname}}</span>
+            <input
+              autofocus
+              v-model="editinfo.nickName"
+              :placeholder="langAccount.placeholder.nickname"
+              class="nickname"
+              maxlength="10"
+              type="text"
+            >
+          </p>
+          <p>
+            <span>{{langAccount.email}}</span>
+            <input
+              autofocus
+              v-model="editinfo.email"
+              :placeholder="langAccount.placeholder.email"
+              class="nickname"
+              maxlength="40"
+              type="text"
+            >
+          </p>
+          <label class="check-con" @click="isReceive=!isReceive">
+            <span class="check-box">
+              <span class="checkbox-inner" :class="{'checkbox-inner-checked':isReceive}"></span>
+            </span>
+            <span style="font-size:14px;color:#000;" v-html="langAccount.isReceive"></span>
+          </label>
+          <div @click="saveNickName" class="btn parmary">{{langAccount.save}}</div>
         </div>
       </div>
     </edit>
@@ -60,7 +83,7 @@
       <div class="address edit-address" slot="edit">
         <div class="input-con">
           <input type="text" maxlength="10" v-model="editAdd.shipName" :placeholder="langAccount.placeholder.name">
-          <input type="text"  oninput="value=value.replace(/[^\d]/g,'')" maxlength='11' v-model="editAdd.shipMobile" :placeholder="langAccount.placeholder.phone">
+          <input type="text"  oninput="value=value.replace(/[^\d\-]/g,'')" maxlength='11' v-model="editAdd.shipMobile" :placeholder="langAccount.placeholder.phone">
         </div>
         <div class="input-con">
           <citySelect :areaPath="editAdd.shipAreaPath" @currentVal="getCurrentSelect"/>
@@ -82,6 +105,7 @@
 <script>
 import { mapState } from 'vuex'
 import edit from '@/components/edit'
+import { reg } from '@/util'
 import citySelect from '@/components/citySelect'
 var cloneObj = function (obj) {
   var newObj = {}
@@ -147,6 +171,7 @@ export default {
       invoiceStatus: true,
       cInvoice: 'normal',
       tempSelect: '',
+      isReceive: true,
       addre: []
     }
   },
@@ -158,31 +183,38 @@ export default {
       this.tempSelect = data
     },
     async saveNickName () {
-      if (this.editinfo.nickName.trim()) {
-        let res = await this.$http
-          .post(
-            '/user/updateNickName',
-            { nickName: this.editinfo.nickName },
-            {
-              headers: {
-                token: this.token
-              }
-            }
-          )
-        let data = res.data
-        if (data.code === 0) {
-          this.infoStatus = true
-          this.$store.dispatch('getInfo', {url: '/user/getUserInfo', name: 'info'})
-        } else {
-          this.$toast.show('warn', this.langToast[data.code], async () => {
-            if (data.code === 3004) {
-              await this.$store.dispatch('logout')
-              this.$router.push({name: 'home'})
+      if (!this.editinfo.nickName.trim()) {
+        return this.$toast.show('warn', this.langToast['35'])
+      }
+
+      if (this.editinfo.email.trim() && !reg.email.test(this.editinfo.email)) {
+        return this.$toast.show('warn', this.langToast['8'])
+      }
+      let res = await this.$http
+        .post(
+          '/user/updateUserDetail',
+          {
+            nickName: this.editinfo.nickName,
+            email: this.editinfo.email || null,
+            isNotice: Number(this.isReceive)
+          },
+          {
+            headers: {
+              token: this.token
             }
-          })
-        }
+          }
+        )
+      let data = res.data
+      if (data.code === 0) {
+        this.infoStatus = true
+        this.$store.dispatch('getInfo', {url: '/user/getUserInfo', name: 'info'})
       } else {
-        return this.$toast.show('warn', this.langToast['35'])
+        this.$toast.show('warn', this.langToast[data.code], async () => {
+          if (data.code === 3004) {
+            await this.$store.dispatch('logout')
+            this.$router.push({name: 'home'})
+          }
+        })
       }
     },
 
@@ -412,6 +444,8 @@ export default {
 .info-layout {
   $theme-color: #1fe4dc;
   $border-color: #e7e7e7;
+  $info-width: 120px;
+
   width: 90%;
   padding-bottom: 100px;
   input {
@@ -472,15 +506,69 @@ export default {
       margin: 5px 0;
       background-size: cover;
       background-repeat: no-repeat;
+
     }
     .nickname {
-      width: 126px;
+      width: 250px;
+    }
+  }
+
+  .info{
+    .s-tx{
+      position: relative;
+      &>p{
+        position: absolute;
+        left: 0;
+        top: 0;
+      }
+      .avatar{
+        margin-left: 80px
+      }
+    }
+    p{
+      span{
+        display: inline-block;
+        &:first-of-type{
+          width: 80px;
+        }
+      }
     }
   }
+
+  .info-en{
+    .s-tx{
+      .avatar{
+        margin-left: $info-width;
+      }
+    }
+    p{
+      span{
+        &:first-of-type{
+          width: $info-width;
+        }
+      }
+    }
+  }
+
   .edit-info {
     display: flex;
     .info-left {
+      &>p{
+        margin: 10px 0;
+      }
       min-width: 210px;
+      .i-tx{
+        position: relative;
+        &>p{
+          position: absolute;
+          left: 0;
+          top: 0;
+        }
+        .itx-con{
+          margin-left: 80px;
+          font-size: 14px;
+        }
+      }
     }
     .choose {
       cursor: pointer;
@@ -505,6 +593,16 @@ export default {
       }
     }
   }
+
+  .edit-en{
+     .info-left {
+      .i-tx{
+        .itx-con{
+          margin-left: $info-width;
+        }
+      }
+    }
+  }
   .edit-address {
     .input-con {
       input {
@@ -525,7 +623,7 @@ export default {
       div {
         position: relative;
         cursor: pointer;
-        min-width: 200px;
+        min-width: 230px;
         line-height: 36px;
         height: 36px;
         margin: 10px 25px 10px 0;

+ 161 - 41
pc/src/page/manage/temp/order.vue

@@ -23,27 +23,46 @@
           <div></div>
           <div>{{langOrders.total}}{{item.goodsAmount}}</div>
         </div>
-        <div class="to-pay">
-          <template v-if="getStatus(item) === 'unpaid'">
-            <span class="cancel" @click="cancal(item)">{{langOrders.cancal}}</span>
-            <span class="pay btns" @click="toPay(item)">{{langOrders.pay}}</span>
-          </template>
-          <template v-else-if="getStatus(item) === 'shipped'">
-            <span class="expreeNum">物流单号:{{item.orderItems[0].expressNum}}</span>
-          </template>
-          <template v-else-if="getStatus(item) === 'unshipped'">
-            <span class="expreeNum">等待商家发货</span>
-          </template>
-          <template v-else-if="getStatus(item) === 'finish'">
-            <span class="expreeNum">已完成</span>
-          </template>
-          <template v-else-if="getStatus(item) === 'partShipped'">
-            <span class="expreeNum">部分发货</span>
-          </template>
-          <template v-else>
-            <span class="expreeNum">已取消</span>
-          </template>
+        <div class="inovice-con" :class="{'ic-active':item.showInvoice}">
+          <div class="o-invoiceTitle">
+            <span>{{langOrders.invoice}}</span>
+            <span v-if="getStatus(item) !== 'shipped'" @click="edit"><i class="iconfont icon-edit"></i>{{langOrders.edit}}</span>
+            <!-- <span v-else><i class="iconfont icon-choice"></i>发票已寄出</span> -->
+          </div>
+          <div class="o-invoice">
+            <editInvoice :data="getItemInvoice(item)" :orderId='item.id' :invoiceId="item.invoice&&(item.invoice.id)"/>
+          </div>
         </div>
+        <div class="bottom-area">
+          <div class="bottom-left">
+            <template v-if="getStatus(item) === 'unpaid'">
+              <span></span>
+            </template>
+             <template v-else-if="getStatus(item) === 'shipped'">
+              <span class="expreeNum">{{langOrders.wlNum}}{{item.orderItems[0].expressNum}}</span>
+            </template>
+            <template v-else-if="getStatus(item) === 'unshipped'">
+              <span class="expreeNum">{{langOrders.unshipped}}</span>
+            </template>
+            <template v-else-if="getStatus(item) === 'finish'">
+              <span class="expreeNum">{{langOrders.finish}}</span>
+            </template>
+            <template v-else-if="getStatus(item) === 'partShipped'">
+              <span class="expreeNum">{{langOrders.partShipped}}</span>
+            </template>
+            <template v-else>
+              <span class="expreeNum">{{langOrders.hasCancal}}</span>
+            </template>
+          </div>
+          <div class="to-pay">
+            <span class="cancel btns" @click="changeIvoiceStatus(i,item)">{{langOrders.invoice}}</span>
+            <template v-if="getStatus(item) === 'unpaid'">
+              <span class="cancel btns" @click="cancal(item)">{{langOrders.cancal}}</span>
+              <span class="pay btns" @click="toPay(item)">{{langOrders.pay}}</span>
+            </template>
+          </div>
+        </div>
+
       </div>
     </div>
     <div class="scene-nothing" v-else>
@@ -57,8 +76,20 @@
 </template>
 
 <script>
+import Vue from 'vue'
 import { mapState } from 'vuex'
 import Paging from '@/components/Paging'
+import editInvoice from '@/components/editInvoice'
+let typeName = {
+  2: '增值税普票(电子发票)',
+  3: '增值税专用发票'
+}
+
+let typeNameEn = {
+  'no': 'No invoice required',
+  2: 'VAT invoice (electronic invoice)',
+  3: 'VAT special invoice'
+}
 let cameraName = {
   7: `四维看看 三脚架套装`,
   1: `四维看看 Lite二目相机`,
@@ -89,13 +120,16 @@ let detailEn = {
   4: ['4DKanKan Pro Camera (Night Sky Black)', 'Storage Plan (10G)']
 }
 export default {
-  components: { Paging },
+  components: { Paging, editInvoice },
   data () {
     return {
       pageSize: 2,
       currentPage: 1,
       total: 0,
-      maxPage: 0
+      maxPage: 0,
+      showInvoice: false,
+      currentI: '',
+      currentItem: ''
     }
   },
   watch: {
@@ -112,6 +146,10 @@ export default {
       cameraName: state => {
         return state.language.current === 'en' ? cameraNameEn : cameraName
       },
+      typeName: state => {
+        return state.language.current === 'en' ? typeNameEn : typeName
+      },
+
       detail: state => {
         return state.language.current === 'en' ? detailEn : detail
       },
@@ -126,9 +164,33 @@ export default {
     })
   },
   mounted () {
+    this.$bus.$on('editItem', data => {
+      this.currentItem['invoice'] = data
+      Vue.set(this.myorder.list, this.currentI, this.currentItem)
+    })
+
     this.getList()
   },
   methods: {
+    edit () {
+      this.$bus.$emit('isOrderInvoice', false)
+    },
+    changeIvoiceStatus (i, item) {
+      item.showInvoice = !item.showInvoice
+      this.$bus.$emit('isOrderInvoice', true)
+      this.currentI = i
+      this.currentItem = item
+      Vue.set(this.myorder.list, i, item)
+    },
+    getItemInvoice (item) {
+      let invoice = item.invoice
+      if (!invoice) {
+        return ''
+      }
+      invoice['typeName'] = this.typeName[invoice.type]
+
+      return invoice
+    },
     pageChange (data) {
       this.currentPage = data
     },
@@ -232,14 +294,16 @@ $theme-color: #1fe4dc;
 $border-color: #e7e7e7;
 .btns {
   cursor: pointer;
-  width: 180px;
+  width: 126px;
   display: inline-block;
-  height: 50px;
-  line-height: 50px;
+  height: 36px;
+  line-height: 36px;
   color: #2d2d2d;
   text-align: center;
   font-size: 16px;
   background: $theme-color;
+  border: 1px solid $theme-color;
+  margin-left: 26px;
 }
 .order-layout {
   width: 75%;
@@ -247,15 +311,25 @@ $border-color: #e7e7e7;
   .order-item {
     margin: 40px;
     border: 1px solid $border-color;
+    .inovice-con{
+      max-height: 0;
+      overflow: hidden;
+    }
+    .ic-active{
+      max-height: 500px;
+      transition: 0.3s ease max-height;
+    }
     .o-top {
       color: #68b8f1;
       line-height: 60px;
       height: 60px;
       font-size: 16px;
       padding: 0 20px;
+      user-select: none;
       border-bottom: 1px solid $border-color;
     }
-    .o-title {
+    .o-title,.o-invoiceTitle {
+      user-select: none;
       display: flex;
       height: 50px;
       padding: 0 85px;
@@ -276,6 +350,41 @@ $border-color: #e7e7e7;
         }
       }
     }
+
+    .o-invoiceTitle{
+      align-items: center;
+      .iconfont{
+        vertical-align: middle;
+        font-size: 20px;
+        margin-right: 5px;
+      }
+      .icon-edit{
+        color: #21e4dc;
+      }
+      .icon-choice{
+        color: #02e430;
+      }
+      span {
+        display: inline-block;
+        vertical-align: middle;
+        &:first-child {
+          flex: 1;
+        }
+        &:last-child{
+          transform: translateX(11px);
+          cursor: pointer;
+        }
+      }
+    }
+    .o-invoice{
+      display: flex;
+      align-items: center;
+      padding: 10px 85px;
+      color: #4a4a4a;
+      font-size: 14px;
+      border-bottom: 1px solid $border-color;
+    }
+
     .o-detail {
       display: flex;
       align-items: center;
@@ -285,7 +394,6 @@ $border-color: #e7e7e7;
       color: #4a4a4a;
       font-size: 14px;
       border-bottom: 1px solid $border-color;
-
       .od-name {
         display: flex;
         align-items: center;
@@ -330,24 +438,36 @@ $border-color: #e7e7e7;
         }
       }
     }
-    .to-pay {
-      text-align: right;
-      height: 90px;
-      line-height: 90px;
-      padding: 0 25px;
-      .cancel {
-        font-size: 16px;
+
+    .bottom-area{
+      position: relative;
+      .bottom-left{
+        position: absolute;
+        top: 50%;
+        left: 85px;
         color: #a0a0a0;
-        display: inline-block;
-        width: 180px;
-        text-align: center;
-        cursor: pointer;
+        transform: translateY(-50%);
       }
-      .expreeNum {
-        margin-right: 60px;
-        color: #2d2d2d;
+      .to-pay {
+        text-align: right;
+        height: 90px;
+        line-height: 90px;
+        padding: 0 25px;
+        .cancel {
+          font-size: 16px;
+          border: 1px solid #ccc;
+          display: inline-block;
+          text-align: center;
+          cursor: pointer;
+          background: none;
+        }
+        .expreeNum {
+          margin-right: 60px;
+          color: #2d2d2d;
+        }
       }
     }
+
   }
   .scene-nothing{
     padding: 42px 0 150px 0;

+ 17 - 15
pc/src/page/manage/temp/scene.vue

@@ -11,8 +11,8 @@
     </div>
     <ul v-if="total">
       <li v-for="(item,index) in myscene.list" :key="index">
-        <div @click="((item.status === 1||item.status===-2)&&item.pay_status !== -2) && goto(item.webSite)" class="a-tap">
-          <div class="share-btn" @click.stop="(item.status === 1||item.status===-2)&&handleShare(item)"></div>
+        <div @click="((item.status === 1||item.status===-2)&&item.payStatus !== -2) && goto(item.webSite)" class="a-tap">
+          <div class="share-btn" v-if="((item.status === 1||item.status===-2)&&item.payStatus !== -2)" @click.stop="handleShare(item)"></div>
           <div class="card-img" :style="{backgroundImage: `url(${getSceneImg(item)})`}"></div>
           <div class="loading-hover" v-if="item.status === 0">
             <div class="loading-icon">
@@ -20,22 +20,23 @@
               <p>{{langScenes.share.calcule}}</p>
             </div>
           </div>
-          <div @click.stop class="loading-hover" v-if="item.pay_status === -2">
-            <div class="loading-icon">
-              <p style="font-weight:bold;">云端容量不足<br/>场景已关闭</p>
+          <div @click.stop class="loading-hover" v-if="item.payStatus === -2">
+            <div class="loading-icon" style="width:100%">
+              <p style="font-weight:bold;" v-html="langScenes.limit.insufficient"></p>
             </div>
-            <p class="huifu" @click.stop="rechargeTip(item)">恢复>></p>
+            <p class="huifu" @click.stop="rechargeTip(item)">{{langScenes.limit.recharge}}</p>
           </div>
         </div>
         <div class="name">
           <div class="title">{{item.sceneName}}</div>
           <div class="oper">
-            <div @click="(item.status === 1||item.status===-2) && del(item)">
+            <div v-if="item.status !== 0" @click="del(item)">
               <span >{{langScenes.delete}}</span>
             </div>
             <div
+              v-if="item.status === 1||item.status===-2"
               class="primary"
-              @click="((item.status === 1||item.status===-2)&&item.pay_status !== -2) && gotoEdit(item)"
+              @click="gotoEdit(item)"
             ><span>{{langScenes.edit}}</span></div>
           </div>
         </div>
@@ -184,12 +185,13 @@ export default {
     }
   },
   mounted () {
-    this.$bus.$off('mycid')
-    this.$bus.$on('mycid', item => {
-      this.getList()
-    })
-    let first = this.$route.query.first
-    if (first) {
+    if (this.deviceLogin) {
+      this.$bus.$off('mycid')
+      this.$bus.$on('mycid', item => {
+        setTimeout(() => {
+          this.getList()
+        })
+      })
     } else {
       this.getList()
     }
@@ -199,7 +201,7 @@ export default {
       this.$toast.showConfirm('warn', this.langToast['28'], () => {
         let routeData = this.$router.resolve({name: 'introduce', params: {id: item.childName}})
         window.open(routeData.href, '_blank')
-      }, '', '扩容')
+      }, '', this.langScenes.limit.expand)
     },
     recharge (item) {
 

+ 1 - 1
pc/src/page/navs/search/item/index.vue

@@ -82,7 +82,7 @@ export default {
       return date.format('yyyy-MM-dd')
     },
     goto (url) {
-      window.open(url.replace('http://', 'https://'), '_blank')
+      window.open(url.replace('http://', 'https://') + (this.language === 'en' ? '&lang=en' : ''), '_blank')
     },
     maskTitle (name) {
       let html = ''

+ 31 - 2
pc/src/page/purchase/index.vue

@@ -2,12 +2,19 @@
   <div class="purchase-layout" v-show="split">
     <div class="plate01">
       <div class="main-detail">
-        <img
+        <browse
+          :idata='browdata'
+          :iactive='browactive'
+          :floder="'probrowse'"
+          class="product-img"
+          :style="{marginLeft:(split - 350)+ 'px'}"
+         />
+        <!-- <img
           class="product-img"
           :style="{marginLeft:(split - 170)+ 'px'}"
           :src="`${$cdn}images/banner_pro-white.png`"
           alt
-        >
+        > -->
         <div class="layout">
           <img class="pro-logo" :src="language==='en'?`${$cdn}images/pro-logo-en.png`:`${$cdn}images/pro-logo.png`" alt="">
           <p class="sub b-label" v-html="langPurchase.dec"></p>
@@ -106,6 +113,7 @@
 import { mapState } from 'vuex'
 import spinner from '@/components/spinner'
 import vcenter from '@/components/vcenter'
+import browse from '@/components/browse'
 import priceTable from '@/components/priceTable'
 import { getPosition } from '@/util'
 
@@ -113,6 +121,7 @@ export default {
   components: {
     spinner,
     vcenter,
+    browse,
     priceTable
   },
   computed: {
@@ -167,9 +176,29 @@ export default {
         ]
       }
     ]
+    let browdata = [
+      {
+        small: 'small-0',
+        big: 'big-0',
+        video: true
+      }, {
+        small: 'small-1',
+        big: 'big-1'
+      },
+      {
+        small: 'small-2',
+        big: 'big-2'
+      },
+      {
+        small: 'small-3',
+        big: 'big-3'
+      }]
+    let browactive = browdata[0]
     return {
       detail,
       guige,
+      browactive,
+      browdata,
       count: 1,
       selectParts: true
     }

+ 14 - 3
pc/src/page/purchase/style.scss

@@ -45,13 +45,12 @@
     }
   }
   .product-img{
-    width: 170px;
-    margin-top: 75px;
+    display: inline-block;
   }
   .layout{
     width: 540px;
     margin-top: 20px;
-    margin-left: 16%;
+    margin-left: 8%;
     display: inline-block;
     vertical-align: top;
     .pro-logo{
@@ -387,4 +386,16 @@
       margin: 0 auto!important;
     }
   }
+}
+
+@media screen and (max-width: 1450px) {
+  .plate01 {
+    .product-img{
+      margin-left: 50px!important;
+
+    }
+    .layout{
+      margin-left:5%;
+    }
+  }
 }

+ 34 - 1
pc/src/page/purchasezhijia/index.vue

@@ -2,7 +2,14 @@
   <div class="purchase-layout" v-show="split">
     <div class="plate01">
       <div class="main-detail">
-        <video class="product-img" :style="{marginLeft:(split - 500)+ 'px'}" :src="`${$cdn}video/zhijia-video.mp4`" autoplay muted loop></video>
+        <browse
+          :idata='browdata'
+          :iactive='browactive'
+          :floder="'zhijiabrowse'"
+          class="product-img"
+          :style="{marginLeft:(split - 350)+ 'px'}"
+         />
+        <!-- <video class="product-img" :style="{marginLeft:(split - 500)+ 'px'}" :src="`${$cdn}video/zhijia-video.mp4`" autoplay muted loop></video> -->
         <div class="layout">
           <img class="pro-logo" :src="this.language==='en'?`${$cdn}images/zhijia-logo-en.png`:`${$cdn}images/zhijia-logo-black.png`" alt="">
           <p class="sub b-label" v-html="langPurchase.dec"></p>
@@ -108,12 +115,14 @@
 import { mapState } from 'vuex'
 import spinner from '@/components/spinner'
 import vcenter from '@/components/vcenter'
+import browse from '@/components/browse'
 import priceTable from '@/components/priceTable'
 
 export default {
   components: {
     spinner,
     vcenter,
+    browse,
     priceTable
   },
   computed: {
@@ -194,10 +203,34 @@ export default {
         ]
       }
     ]
+    let browdata = [
+      {
+        small: 'small-0',
+        big: 'big-0',
+        video: true
+      }, {
+        small: 'small-1',
+        big: 'big-1'
+      },
+      {
+        small: 'small-2',
+        big: 'big-2'
+      },
+      {
+        small: 'small-3',
+        big: 'big-3'
+      },
+      {
+        small: 'small-4',
+        big: 'big-4'
+      }]
+    let browactive = browdata[0]
     return {
       detail,
       zhijiadetail,
       guige,
+      browactive,
+      browdata,
       count: 1,
       selectParts: true
     }

+ 0 - 0
pc/src/page/purchasezhijia/style.scss


部分文件因为文件数量过多而无法显示