Browse Source

添加抗体列表,详情,询价,登陆注册,激活,密码重置,重置申请,隐私政策

wangxl@jiinfo.cn 1 month ago
parent
commit
f5aec6cc24
39 changed files with 7373 additions and 14 deletions
  1. 1 1
      config/index.js
  2. 5 9
      src/App.vue
  3. BIN
      src/assets/img/chearall.png
  4. BIN
      src/assets/img/cheardelete.png
  5. BIN
      src/assets/img/delete.png
  6. BIN
      src/assets/img/download1.png
  7. BIN
      src/assets/img/drop-down.png
  8. BIN
      src/assets/img/gobottop.png
  9. BIN
      src/assets/img/newProductDetail/cart.png
  10. BIN
      src/assets/img/newProductDetail/free.png
  11. BIN
      src/assets/img/newProductDetail/inquiry.png
  12. BIN
      src/assets/img/productDetail/coa.png
  13. BIN
      src/assets/img/productDetail/msds.png
  14. BIN
      src/assets/img/table-top.png
  15. BIN
      src/assets/img/table_bott.png
  16. BIN
      src/assets/img/whitedetele.png
  17. 50 0
      src/components/SortFieldHeader.vue
  18. 3 3
      src/components/homeHeader.vue
  19. 982 0
      src/components/siteHeader.vue
  20. 1093 0
      src/components/tableList.vue
  21. 56 0
      src/router/login.js
  22. 46 1
      src/router/routerList.js
  23. 161 0
      src/view/application/index.vue
  24. 174 0
      src/view/applications/index.vue
  25. 867 0
      src/view/inquiry/index.vue
  26. 332 0
      src/view/landing/index.vue
  27. 20 0
      src/view/privacyPolicy/index.vue
  28. 311 0
      src/view/product/components/AntibodyInfo.vue
  29. 335 0
      src/view/product/components/CellLineInfo.vue
  30. 668 0
      src/view/product/components/PriceTable.vue
  31. 277 0
      src/view/product/components/ProteinInfo.vue
  32. 131 0
      src/view/product/components/RecentlyList.vue
  33. 131 0
      src/view/product/components/RelatedProduct.vue
  34. 178 0
      src/view/product/components/info.vue
  35. 148 0
      src/view/product/components/validation.vue
  36. 722 0
      src/view/product/details.vue
  37. 210 0
      src/view/product/index.vue
  38. 324 0
      src/view/register/index.vue
  39. 148 0
      src/view/registrations/index.vue

+ 1 - 1
config/index.js

@@ -11,8 +11,8 @@ module.exports = {
         assetsPublicPath: '/',
         proxyTable: {
             '/api/': {
-                  target: 'https://oneclicktest.jiinfo.cn/api/',  // 测试地址
                 // target: 'http://192.168.0.104:18182/api/',
+                target: 'https://crs.sanyoubio.com/api/',
                 changeOrigin: true,
                 secure: false,
                 pathRewrite: {

+ 5 - 9
src/App.vue

@@ -4,23 +4,19 @@
       <div class="noHome">
         <home-header></home-header>
         <div :class="$route.meta.fullScreen ? 'content' :'content_app'">
-          <router-view :key="key" />
+          <keep-alive include="AntigenPreparation">
+            <router-view/>
+          </keep-alive>
         </div>
         <footerbox></footerbox>
       </div>
-      <!-- <div
-        class="home_b"
-        v-if="$route.name == 'home'"
-      >
-        <router-view :key="key" />
-      </div> -->
-      <!-- <div class="fixed-message" @click="dialogVisible = true">
+      <div class="fixed-message" @click="dialogVisible = true">
         <img src="@/assets/img/messageFixed.png" alt="">
         <div class="fixed-message-text">
           Contact with<br/>
           our experts
         </div>
-      </div> -->
+      </div>
     </div>
     <!-- loading -->
     <div class="loading" v-show="loading">

BIN
src/assets/img/chearall.png


BIN
src/assets/img/cheardelete.png


BIN
src/assets/img/delete.png


BIN
src/assets/img/download1.png


BIN
src/assets/img/drop-down.png


BIN
src/assets/img/gobottop.png


BIN
src/assets/img/newProductDetail/cart.png


BIN
src/assets/img/newProductDetail/free.png


BIN
src/assets/img/newProductDetail/inquiry.png


BIN
src/assets/img/productDetail/coa.png


BIN
src/assets/img/productDetail/msds.png


BIN
src/assets/img/table-top.png


BIN
src/assets/img/table_bott.png


BIN
src/assets/img/whitedetele.png


+ 50 - 0
src/components/SortFieldHeader.vue

@@ -0,0 +1,50 @@
+<template>
+    <div class="sort-field-header">
+        <i v-if="(sortField == '' && sortValue === '') || sortField !== field" class="el-icon-sort" @click="onSortFieldChange(field, 'desc')" />
+          <i v-if="sortField === field && sortValue === 'desc'" class="el-icon-sort-down" @click="onSortFieldChange(field, 'asc')" />
+          <i v-if="sortField === field && sortValue === 'asc'" class="el-icon-sort-up" @click="onSortFieldChange('', '')" />
+    </div>
+</template>
+<script>
+export default {
+  name: 'SortFieldHeader',
+  props: {
+    sortField: {
+      type: String,
+      default: ''
+    },
+    field: {
+      type: String,
+      default: ''
+    }
+  },
+  data () {
+    return {
+      sortValue: ''
+    }
+  },
+  methods: {
+    onSortFieldChange (field, value) {
+      this.sortValue = value
+      this.$emit('sort-change', {
+        field: field,
+        value: value
+      })
+    }
+  }
+}
+</script>
+<style lang="scss" scoped>
+.sort-field-header {
+    display: inline-flex;
+    .el-icon-sort {
+        cursor: pointer;
+        color: #6f6f6f;
+    }
+
+    .el-icon-sort-down, .el-icon-sort-up {
+        cursor: pointer;
+        color: #000;
+    }
+}
+</style>

+ 3 - 3
src/components/homeHeader.vue

@@ -11,18 +11,18 @@
           <el-menu :default-active="activeIndex" class="el-menu-demo" mode="horizontal" text-color="#065BA9" active-text-color="#065BA9" @select="handleSelect">
             <el-menu-item index="contact">全览图</el-menu-item>
             <el-menu-item index="contact">相关文章</el-menu-item>
-            <el-menu-item index="contact">产品详情</el-menu-item>
+            <el-menu-item index="product">产品详情</el-menu-item>
             <el-menu-item index="contact">抗体数据库</el-menu-item>
             <el-menu-item index="contact">资料下载</el-menu-item>
           </el-menu>
 
         </div>
-        <!-- <div class="header_c">
+        <div class="header_c">
           <div class="clout">
             <img class="clout_img" src="@/assets/img/slogan.png" alt="" />
             <userInfo class="user_info"></userInfo>
           </div>
-        </div> -->
+        </div>
         <div style="display:none" class="menu" @click="tapcanceltpmd">
           <img class="menu_img" src="@/assets/img/menu.png" alt="" />
         </div>

+ 982 - 0
src/components/siteHeader.vue

@@ -0,0 +1,982 @@
+<template>
+  <div class="header_app">
+
+    <home-header class="topbox_t"></home-header>
+    <div class="back-clor">
+      <div class="header_top">
+        <div class="logo" @click="$util.goRoute({ name: 'CRS-products' })">
+          <img class="logo_img" src="@/assets/img/logo.png" alt="" srcset="" />
+        </div>
+        <div class="input_box">
+          <el-autocomplete
+            clearable
+            :placeholder="$t('input.enterkeywords')"
+            v-model="keywords"
+            class="input-with-select"
+            @keyup.enter.native="changeInput"
+            style="width: 100%;"
+            :fetch-suggestions="querySearchKeyword"
+            popper-class="site-header-suggestion-select"
+            @select="changeInput"
+            :debounce="500"
+            :trigger-on-focus="false"
+            hide-loading
+          >
+            <el-select
+              class="el_select"
+              v-model="categoryType"
+              slot="prepend"
+              placeholder=""
+              popper-class="selectCls"
+              @change="changeCategory"
+            >
+              <el-option
+                v-for="item in menuList"
+                :key="item.id"
+                :label="item.name"
+                :value="item.id"
+              />
+            </el-select>
+            <div class="right" slot="append" @click="changeInput">
+              <img src="@/assets/img/search.png" alt="" class="right_img" />
+            </div>
+          </el-autocomplete>
+        </div>
+        <div class="header_c">
+          <div class="clout">
+            <!-- Antibody Drug R&D, Find Sayou Bio -->
+            <!-- {{$t('homePage.antibodyDrug')}} -->
+            <!-- <img class="clout_img" src="@/assets/img/slogan.png" alt=""> -->
+            <userInfo></userInfo>
+          </div>
+          <div class="clout_active"></div>
+        </div>
+      </div>
+    </div>
+    <!-- 菜单 -->
+    <div class="menu_box">
+      <div class="menu">
+        <el-menu
+          :default-active="activeIndex"
+          background-color="#0166b4"
+          text-color="#fff"
+          class="el-menu-demo"
+          mode="horizontal"
+          @select="handleSelect"
+        >
+          <el-menu-item index="allproducts">
+            {{ $t('menu.Products') }}
+          </el-menu-item>
+          <el-menu-item index="oneClick">
+            <div style="position: relative;">
+              oneClick<span style="position: absolute;top: -4px;">+</span>
+            </div>
+          </el-menu-item>
+          <!-- <el-menu-item index="protein">{{$t('menu.protein')}}</el-menu-item>
+          <el-menu-item index="antibody">{{$t('menu.antibody')}}</el-menu-item>
+          <el-menu-item index="cell-line">{{$t('menu.cellLine')}}</el-menu-item> -->
+          <!-- <el-menu-item index="featuredProducts">{{$t('menu.featuredProducts')}}</el-menu-item> -->
+          <el-menu-item index="customization">
+            {{ $t('menu.customization') }}
+          </el-menu-item>
+          <!-- <el-menu-item v-if="$util.localeStorage()" index="ApplyFreeSamples">
+            {{ $t('menu.FreeSamples') }}
+          </el-menu-item> -->
+          <el-menu-item index="Promotion">
+            {{ $t('menu.FreeSamples') }}
+          </el-menu-item>
+          <!-- <el-menu-item index="Literatures">
+            {{ $t('menu.literatures') }}
+          </el-menu-item> -->
+          <el-menu-item v-if="$util.localeStorage()" index="distributors">
+            {{ $t('menu.Distributors') }}
+          </el-menu-item>
+          <el-menu-item index="about">{{ $t('menu.aboutUs') }}</el-menu-item>
+        </el-menu>
+      </div>
+    </div>
+    <!-- 面包屑 -->
+    <div class="crumbs_box" v-if="activeIndex != 'productAdvice'">
+      <div class="crumbs">
+        <el-breadcrumb separator="/">
+          <!-- <el-breadcrumb-item v-for="one in bewadcrumbList" :key="one.path" :to="{ path: one.meta.pageTitle == 'Home' ? '/':one.path }">{{one.meta.pageTitle}}</el-breadcrumb-item> -->
+          <el-breadcrumb-item class="is-link_home" :to="{ path: '/' }">{{
+            $t('pageTitle.Home')
+          }}</el-breadcrumb-item>
+          <el-breadcrumb-item
+            v-for="one in bewadcrumbList"
+            :key="one.path"
+            v-if="one.meta.pageTitle !== 'Home'"
+          >
+            <a
+              :class="bewadcrumbList.length >= 2 ? 'is-link_but' : 'is-link'"
+              v-if="
+                one.meta.pageTitle == 'Search Result' || one.name == 'orderList'
+              "
+              @click="handleLink(one)"
+              >{{
+                $util.localeStorage()
+                  ? one.meta.pageTitle
+                  : one.meta.chineseTitle
+              }}</a
+            >
+            <a v-else>{{
+              $util.localeStorage() ? one.meta.pageTitle : one.meta.chineseTitle
+            }}</a>
+          </el-breadcrumb-item>
+        </el-breadcrumb>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import homeHeader from '@/components/homeHeader'
+import heaDer from '@/components/header'
+import userInfo from '@/components/userInfo'
+import sites from '@/assets/josn/search'
+export default {
+  components: {
+    homeHeader,
+    heaDer,
+    userInfo
+  },
+  name: 'siteHeader',
+  data() {
+    return {
+      // menuList: [],
+      tapshow: false,
+      keywords: '',
+      categoryType: this.$t('input.all'),
+      categoryObj: {},
+      menuList: [
+        {
+          id: 0,
+          name: this.$t('input.all'),
+          value: 'All',
+          url: 'search'
+        },
+        {
+          id: 1,
+          name: this.$t('menu.protein'),
+          value: 'protein',
+          url: 'searchProteins'
+        },
+        {
+          id: 2,
+          name: this.$t('menu.antibody'),
+          value: 'antibody',
+          url: 'searchAntibodies'
+        },
+        {
+          id: 3,
+          name: this.$t('menu.cellLine'),
+          value: 'cell-line',
+          url: 'searchCellLines'
+        }
+        // {
+        //   id: 4,
+        //   name: this.$t("input.Diagnostic"),
+        //   value: "diagnostic-reagent",
+        //   url: "searchDiagnosticReagents"
+        // }
+      ],
+      langs: this.$util.localeStorage() ? 'English' : '中文',
+      language: this.$util.localeStorage()
+    }
+  },
+  created() {},
+  computed: {
+    bewadcrumbList() {
+      // 面包屑
+      let that = this
+      if (
+        this.$route.matched.length === 2 &&
+        this.$route.matched[1].path === '/search/by-category'
+      ) {
+        this.menuList.forEach(item => {
+          if (item.value === that.$route.query.category) {
+            that.$route.matched[1].meta.pageTitle = item.name
+            that.$route.matched[1].meta.chineseTitle = item.name
+            that.$route.matched[1].meta.navActive = item.value
+          }
+        })
+      }
+      // console.log(this.$route.matched)
+      return this.$route.matched
+    },
+    activeIndex() {
+      return this.$route.name
+    }
+  },
+  mounted() {},
+  methods: {
+    handleLink(item) {
+      if (item.name === 'orderList') {
+        this.$util.goRoute({
+          name: item.name
+        })
+      } else if (
+        this.bewadcrumbList.length === 2 &&
+        this.bewadcrumbList[1].meta.navActive !== 'Product advice'
+      ) {
+        if (item.meta.navActive === 'search') {
+          this.$util.goRoute({
+            name: 'search',
+            query: {
+              keywords: this.$route.query.keywords
+            }
+          })
+        }
+      }
+    },
+    tapcancel() {
+      this.tapshow = false
+    },
+    handleSelect(key, keyPath) {
+      if (key === 'aboutUs') {
+        this.tapshow = true
+      } else if (key === 'oneClick') {
+        let _url = ''
+        if (this.$util.localeStorage()) {
+          _url = 'https://www.oneclick-plus.com?utm_source=CRS'
+        } else {
+          _url = 'https://www.oneclick-plus.cn?utm_source=CRS'
+        }
+        window.open(_url, '_blank')
+      } else {
+        this.$util.goRoute({ name: key })
+      }
+    },
+    changeCategory() {
+      // 下拉框
+      this.categoryObj = this.menuList[this.categoryType]
+      console.log(this.categoryObj)
+    },
+    postsearch() {
+      // 搜索列表
+      let that = this
+      if (this.keywords !== '') {
+        this.keywords = this.keywords.trim()
+      }
+      this.$api
+        .post('product/search', {
+          criteria: {
+            keywords: this.keywords,
+            type: this.categoryType
+          },
+          pageable: { page: 0, size: 10 }
+        })
+        .then(res => {
+          if (res.code === 0) {
+            if (res.data.content.length > 0) {
+              this.$util.goRoute({
+                path: '/search/by-category',
+                // name: this.categoryObj.url,
+                query: {
+                  keywords: this.keywords,
+                  category: this.categoryObj.value
+                }
+              })
+              console.log(res.data.content.length, '666666')
+            } else {
+              that.$util.goRoute({
+                name: 'productAdvice',
+                query: {
+                  q: this.keywords
+                }
+              })
+            }
+          }
+        })
+    },
+    searchAll() {
+      // 搜索all
+      let that = this
+      this.menuList = sites.obj
+
+      if (this.keywords !== '') {
+        this.keywords = this.keywords.trim()
+      }
+      this.$api
+        .post('product/searchAll', {
+          type: '',
+          keywords: this.keywords
+        })
+        .then(res => {
+          if (res.code === 0) {
+            if (res.data.length === 0) {
+              that.$util.goRoute({
+                name: 'productAdvice',
+                query: {
+                  q: this.keywords
+                }
+              })
+            } else {
+              // that.$util.goRoute({
+              //   name: 'search',
+              //   query: {
+              //     keywords: this.keywords
+              //   }
+              // })
+
+              this.$util.goRoute({
+                path: '/search/by-category',
+                query: {
+                  keywords: this.keywords,
+                  category: this.menuList[res.data[0].type].value
+                }
+              })
+            }
+          }
+        })
+    },
+    changeInput() {
+      // 搜索按键
+      if (this.keywords !== '') {
+        if (
+          this.categoryType == 0 ||
+          this.categoryType == this.$t('input.all')
+        ) {
+          this.searchAll()
+        } else {
+          this.postsearch()
+        }
+      }
+    },
+    querySearchKeyword(queryString, cb) {
+      if (queryString) {
+        cb([]) // 先清除下拉框选项
+        this.$api
+          .post('product/findProductCallWord', {
+            keyword: queryString.trim()
+          })
+          .then(res => {
+            if (res.code === 0) {
+              const _res = (res.data || []).map(item => {
+                return {
+                  label: item.productName,
+                  value: item.productName
+                }
+              })
+              cb(_res)
+            }
+          })
+      } else {
+        cb([])
+      }
+    }
+  }
+}
+</script>
+<style lang="scss">
+.site-header-suggestion-select {
+  .el-autocomplete-suggestion__wrap {
+    max-height: 380px;
+  }
+}
+</style>
+<style lang="scss" scoped>
+@media screen and (min-width: 751px) and (max-width: 9999px) {
+  .tophea_box {
+    display: none;
+  }
+  .el-dropdown-menu /deep/ {
+    margin-top: 6px;
+    padding: 0;
+    background: #012c53;
+    color: #fff;
+    border: none;
+    .el-dropdown-menu__item {
+      color: #fff;
+    }
+    .el-dropdown-menu__item:hover {
+      background: #00396c;
+    }
+  }
+
+  .header_app {
+    .topbox_t {
+      display: none;
+    }
+    .back-clor {
+      width: 100%;
+      background-color: #fff;
+      .header_top {
+        width: 1200px;
+        min-height: 80px;
+        margin: auto;
+        display: flex;
+        align-items: center;
+        padding: 10px 0;
+        .logo {
+          width: 96px;
+          margin-right: 56px;
+          .logo_img {
+            cursor: pointer;
+            display: block;
+            width: 100%;
+          }
+          .logo_d {
+            color: #0053a8;
+            padding-bottom: 0.625rem;
+            border-bottom: 1px solid #0053a8;
+            .logo_images {
+              width: 260px;
+            }
+          }
+        }
+        .input_box /deep/ {
+          flex: 1;
+          .input-with-select {
+            border-radius: 26px !important;
+            overflow: hidden;
+            border: 1px solid #1a75bb;
+            .el_select {
+              border: none !important;
+              width: 10rem !important;
+              background-color: #fff;
+              .el-select__caret {
+                color: #1a75bb !important;
+              }
+            }
+            .el-input-group__prepend {
+              border: none;
+              border-radius: 26px !important;
+              overflow: hidden;
+              &::after {
+                position: absolute;
+                width: 1px;
+                height: 1.2rem;
+                background-color: #cfcfcf;
+                content: '';
+                right: 0;
+                top: 50%;
+                transform: translateY(-50%);
+              }
+              .el-input__inner {
+                border: none;
+                color: #000;
+                &:focus {
+                  border: none;
+                }
+              }
+            }
+            .el-input__inner {
+              // border-left:1px solid #0053A8;
+              border: none;
+              position: relative;
+              &:focus {
+                border: none;
+              }
+            }
+            // 搜索ico
+            .el-input-group__append {
+              border: none;
+              padding: 0 0.1rem;
+              border-radius: 26px !important;
+              overflow: hidden;
+              .right {
+                width: 40px;
+                height: 40px;
+                background-color: #1a75bb;
+                border-radius: 40px;
+                display: flex;
+                align-items: center;
+                justify-content: center;
+                cursor: pointer;
+                .right_img {
+                  width: 1.6rem;
+                }
+              }
+            }
+          }
+          .clout_img {
+            display: block;
+            height: 20px;
+            position: relative;
+            margin-bottom: 4px;
+            &::before {
+              content: '';
+              position: absolute;
+              width: 100px;
+              height: 1px;
+              background-color: #000;
+              left: 0;
+              top: 50%;
+              transform: translateX(-50%);
+            }
+          }
+        }
+        .header_c {
+          position: relative;
+          margin-left: 6%;
+          .clout {
+            // font-size: 1.125rem;
+            font-family: Arial;
+            font-weight: normal;
+            color: #005bab;
+            .clout_img {
+              width: 260px;
+            }
+          }
+          .clout_active {
+            position: absolute;
+            width: 3px;
+            height: 20px;
+            background: rgba(0, 91, 171, 0.2);
+            top: 50%;
+            left: -0.8rem;
+            transform: translateY(-50%);
+          }
+        }
+      }
+    }
+    .menu_box {
+      background-color: #0166b4;
+      .menu /deep/ {
+        width: 1200px;
+        height: 3.125rem;
+        margin: auto;
+        // padding: 0.625rem 0;
+        .el-menu {
+          background-color: #0166b4;
+          border-bottom: none;
+          display: flex;
+          align-items: center;
+          justify-content: space-between;
+          .el-menu-item {
+            flex: 1;
+            text-align: center;
+            height: 3.125rem;
+            line-height: 3.125rem;
+            color: #fff;
+            border-bottom: none;
+            padding: 0 1.25rem;
+            position: relative;
+            font-size: 16px;
+            font-family: 'Arial-BoldMT', Arial;
+            font-weight: bold;
+            color: #ffffff;
+            margin: 0 10px;
+            &:hover {
+              border: none;
+              // border-bottom-color: rgba(1, 44, 83, 0.3);
+              background-color: rgba(1, 44, 83, 0.3);
+            }
+            &::before {
+              position: absolute;
+              width: 1px;
+              height: 1.25rem;
+              background-color: #fff;
+              left: -10px;
+              top: 50%;
+              transform: translateY(-50%);
+              content: '';
+            }
+            &:nth-of-type(1)::before {
+              width: 0;
+            }
+          }
+          .is-active {
+            background-color: #0166b4 !important;
+            // background-color: #012C53;
+            border-bottom: none;
+            position: relative;
+          }
+        }
+      }
+    }
+    .crumbs_box /deep/ {
+      background-color: #f7fbfc;
+      .crumbs {
+        width: 1200px;
+        margin: auto;
+        padding: 0.625rem 0;
+        .is-link_home {
+          .is-link {
+            color: #005bab !important;
+          }
+        }
+        .is-link {
+          color: #606266;
+          cursor: pointer;
+        }
+        .is-link_but {
+          // color: #606266;
+          color: #005bab !important;
+        }
+      }
+    }
+    //  弹框
+    .tap_telephone {
+      height: 50px;
+      position: fixed;
+      bottom: 70px;
+      right: 0;
+      background-color: #005bab;
+      box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.35);
+      border-radius: 8px 0px 0px 8px;
+      display: flex;
+      align-items: center;
+      padding: 0 22px 0 12px;
+      cursor: pointer;
+      z-index: 9999;
+      .telephone_img {
+        width: 24px;
+        margin-right: 8px;
+        .telephone_i {
+          width: 100%;
+        }
+      }
+      .telephone_name {
+        font-size: 20px;
+        font-family: Arial;
+        font-weight: normal;
+        color: #ffffff;
+      }
+    }
+    .taps {
+      position: fixed;
+      width: 100%;
+      // top: 0;
+      // left: 0;
+      bottom: 0;
+      right: 0;
+      // background-color: rgba(0,0,0,.5);
+      z-index: 9999;
+      .taps_s {
+        display: inline-block;
+        padding: 1.25rem 1.25rem 2rem;
+        position: absolute;
+        bottom: 3rem;
+        right: 1.4rem;
+        background-color: #f9fbfd;
+        border-radius: 0.4rem;
+        .taps_a {
+          position: relative;
+          display: inline-block;
+          padding: 1.25rem 1.25rem 2rem;
+          position: relative;
+          background-color: #f9fbfd;
+          border-radius: 0.4rem;
+          .logo {
+            display: flex;
+            align-items: center;
+            margin-bottom: 38px;
+            .logo_img {
+              width: 80px;
+            }
+            .logo_d {
+              font-size: 14px;
+              font-style: oblique;
+              font-family: 'Arial-BoldMT', Arial;
+              font-weight: bold;
+              color: #005bab;
+              margin-left: 1rem;
+              position: relative;
+              // &::after{
+              //    position: absolute;
+              //     width: 3px;
+              //     height: 1.6rem;
+              //     background: rgba(0, 91, 171, 0.2);
+              //     content: "";
+              //     left:-1rem;
+              //     top: 50%;
+              //     transform: translateY(-50%);
+              // }
+              .logo_images {
+                width: 260px;
+              }
+            }
+          }
+          .taps_d {
+            color: #000;
+            font-weight: 600;
+            font-size: 18px;
+            margin-top: 0.4rem;
+            margin-bottom: 3rem;
+          }
+          .taps_num {
+            display: flex;
+            align-items: center;
+            .num_images {
+              width: 24px;
+            }
+            .num {
+              color: #005bab;
+              margin-left: 8px;
+              font-family: Arial;
+              font-size: 14px;
+            }
+          }
+          .taps_num + .taps_num {
+            margin-top: 24px;
+          }
+          .taps_num_t {
+            cursor: pointer;
+          }
+          .cancel {
+            position: absolute;
+            top: -0.8rem;
+            right: -0.5rem;
+            cursor: pointer;
+            .cancel_images {
+              width: 1.5rem;
+            }
+          }
+          .taps_bot {
+            font-size: 14px;
+            font-family: Arial;
+            color: #313131;
+            margin-top: 22px;
+          }
+        }
+      }
+    }
+  }
+}
+
+@media screen and (min-width: 751px) and (max-width: 1200px) {
+  .header_top {
+    width: 100% !important;
+    padding: 0 20px !important;
+    .input_box /deep/ {
+      margin-left: 20px !important;
+      .el-input__inner {
+        height: 34px !important;
+      }
+      .el-input__icon {
+        line-height: 34px !important;
+      }
+      .right {
+        width: 34px !important;
+        height: 34px !important;
+      }
+    }
+    .header_c {
+      margin-left: 20px !important;
+    }
+  }
+  .crumbs {
+    width: 100% !important;
+    padding: 0 20px !important;
+    .el-breadcrumb {
+      height: 30px !important;
+      line-height: 30px !important;
+    }
+  }
+  .menu {
+    width: 100% !important;
+  }
+}
+
+@media screen and (min-width: 0px) and (max-width: 750px) {
+  .tophea_box {
+    display: block;
+  }
+  .header_app {
+    .topbox_t {
+      display: block;
+    }
+    .tap_telephone {
+      display: none;
+    }
+    .back-clor {
+      width: 100%;
+      overflow: hidden;
+      background-color: #fff;
+      .header_top {
+        width: 100%;
+        height: 0.4rem;
+        display: flex;
+        align-items: center;
+        padding: 0 0.1rem;
+        margin: 0.1rem 0;
+        .logo {
+          display: none;
+          .logo_d {
+            display: none;
+          }
+        }
+        .input_box /deep/ {
+          flex: 1;
+          .input-with-select {
+            border-radius: 26px !important;
+            overflow: hidden;
+            border: 1px solid #1a75bb;
+            .el_select {
+              border: none !important;
+              width: 1.1rem !important;
+              background-color: #fff;
+              .el-select__caret {
+                color: #1a75bb !important;
+              }
+            }
+            .el-input-group__prepend {
+              border: none;
+              border-radius: 26px !important;
+              overflow: hidden;
+              &::after {
+                position: absolute;
+                width: 1px;
+                height: 1.2rem;
+                background-color: #cfcfcf;
+                content: '';
+                right: 0;
+                top: 50%;
+                transform: translateY(-50%);
+              }
+              .el-input__inner {
+                border: none;
+                color: #000;
+                &:focus {
+                  border: none;
+                }
+              }
+            }
+            .el-input__inner {
+              // border-left:1px solid #0053A8;
+              border: none;
+              position: relative;
+              font-size: 0.14rem;
+              &:focus {
+                border: none;
+              }
+            }
+            // 搜索ico
+            .el-input-group__append {
+              border: none;
+              padding: 0rem;
+              border-radius: 26px !important;
+              overflow: hidden;
+              .right {
+                width: 0.4rem;
+                height: 0.4rem;
+                background-color: #1a75bb;
+                border-radius: 0.4rem;
+                display: flex;
+                align-items: center;
+                justify-content: center;
+                .right_img {
+                  width: 0.24rem;
+                }
+              }
+            }
+          }
+        }
+        .header_c {
+          display: none;
+        }
+      }
+    }
+    .menu_box {
+      display: none;
+    }
+    .crumbs_box /deep/ {
+      background-color: #f7fbfc;
+      .crumbs {
+        width: 100%;
+        margin: auto;
+        padding: 0.1rem;
+        .is-link_home {
+          .is-link {
+            color: #005bab !important;
+          }
+        }
+        .is-link {
+          // color: #005BAB;
+          color: #606266;
+        }
+        .is-link_but {
+          // color: #606266;
+          color: #005bab !important;
+        }
+      }
+    }
+    //  弹框
+    .taps {
+      position: fixed;
+      width: 100%;
+      top: 0;
+      left: 0;
+      bottom: 0;
+      right: 0;
+      background-color: rgba(0, 0, 0, 0.5);
+      z-index: 9999;
+      .taps_s {
+        display: inline-block;
+        padding: 0.25rem;
+        position: absolute;
+        bottom: 0;
+        right: 0;
+        background-color: #f9fbfd;
+        .taps_a {
+          position: relative;
+          display: inline-block;
+          position: relative;
+          background-color: #f9fbfd;
+          .logo {
+            display: flex;
+            align-items: center;
+            margin-bottom: 0.38rem;
+            .logo_img {
+              width: 20%;
+            }
+            .logo_d {
+              font-size: 0.12rem;
+              font-style: oblique;
+              font-family: 'Arial-BoldMT', Arial;
+              font-weight: normal;
+              color: #005bab;
+              margin-left: 0.2rem;
+              position: relative;
+              // &::after{
+              //    position: absolute;
+              //     width: 0.02rem;
+              //     height: 0.1rem;
+              //     background: rgba(0, 91, 171, 0.2);
+              //     content: "";
+              //     left:-0.1rem;
+              //     top: 50%;
+              //     transform: translateY(-50%);
+              // }
+            }
+          }
+          .taps_num {
+            display: flex;
+            align-items: center;
+            .num_images {
+              width: 0.24rem;
+            }
+            .num {
+              color: #005bab;
+              margin-left: 0.08rem;
+              font-family: Arial;
+              font-size: 0.14rem;
+            }
+          }
+          .taps_num + .taps_num {
+            margin-top: 0.2rem;
+          }
+          .cancel {
+            position: absolute;
+            top: -0.15rem;
+            right: -0.15rem;
+            cursor: pointer;
+            .cancel_images {
+              width: 0.24rem;
+            }
+          }
+          .taps_bot {
+            font-size: 0.14rem;
+            font-family: Arial;
+            color: #313131;
+            margin-top: 0.2rem;
+          }
+        }
+      }
+    }
+  }
+}
+</style>

+ 1093 - 0
src/components/tableList.vue

@@ -0,0 +1,1093 @@
+<template>
+  <div class="table_box">
+    <!-- PC端 -->
+    <div class="tableList">
+      <div class="tableList_th" style="user-select: none;">
+        <div style="width: 6%" class="th_tr_b">{{ $t("table.catalog") }}</div>
+        <div style="width: 13%;" v-if="type != 2" class="th_tr_b">
+          {{ $t("table.productName") }}
+        </div>
+        <div style="width: 13%;" v-if="type == 2" class="th_tr_b">
+          {{ $t("table.productName") }}
+        </div>
+        <div style="width: 10%;" class="th_tr_b" v-if="type == 4">
+          {{ $t("table.Specification") }}
+        </div>
+        <div
+          style="width: 8%; text-align: center;"
+          class="th_tr_b"
+          v-if="type == 2"
+        >
+          {{ $t("table.Species") }}
+          <SortFieldHeader
+            :sort-field="sortField"
+            field="species"
+            @sort-change="onSortFieldChange"
+          />
+        </div>
+        <div class="th_tr" v-if="type == 1 || type == 3">
+          {{ $t("table.Target") }}
+        </div>
+        <div
+          style="width: 9%; text-align: center;"
+          class="th_tr_b"
+          v-if="type == 2"
+        >
+          {{ $t("table.Target") }}
+        </div>
+        <!-- <div class="th_tr_b" style="width: 9%;" v-if="type == 1">{{$t('table.AAsequene')}}</div> -->
+        <div class="th_tr" v-if="type == 1">
+          {{ $t("table.Tag") }}
+          <SortFieldHeader
+            :sort-field="sortField"
+            field="tag"
+            @sort-change="onSortFieldChange"
+          />
+        </div>
+        <div style="width: 10%;" class="th_tr_b" v-if="type == 3 || type == 1">
+          {{ $t("table.Species") }}
+          <SortFieldHeader
+            :sort-field="sortField"
+            field="species"
+            @sort-change="onSortFieldChange"
+          />
+        </div>
+        <div style="width: 5%;" class="th_tr_b" v-if="type == 3">
+          {{ $t("table.CellType") }}
+        </div>
+        <div
+          style="width: 8%; text-align: center;"
+          class="th_tr_b"
+          v-if="type == 3"
+        >
+          {{ $t("table.FluorescentLabel") }}
+        </div>
+        <div class="th_tr" v-if="type == 4">{{ $t("table.Source") }}</div>
+        <div class="th_tr" v-if="type == 4">{{ $t("table.Clonality") }}</div>
+        <div
+          style="width: 12%; text-align: center;"
+          class="th_tr_b"
+          v-if="type == 4"
+        >
+          {{ $t("table.Couplingagent") }}
+        </div>
+        <div
+          style="width: 14%; text-align: center;"
+          class="th_tr_b"
+          v-if="type == 4"
+        >
+          {{ $t("table.ApplicationPmd") }}
+        </div>
+        <div
+          class="th_tr_b"
+          style="width: 9%; text-align: center;"
+          v-if="type == 2"
+        >
+          {{ $t("table.Format") }}
+        </div>
+        <!-- <div class="th_tr_b" style="width: 10%;text-align: center;" v-if="type == 1 || type == 2">
+        {{$t('table.host')}}
+        <SortFieldHeader :sort-field="sortField" field="host" @sort-change="onSortFieldChange" />
+      </div> -->
+        <div class="th_tr_b" style="width: 5%;text-align: center;">COA</div>
+        <!-- <div class="th_tr" style="width: 80px;text-align: center;">{{ $t('table.Purity') }}</div> -->
+        <!-- <div class="th_tr_b" style="width: 15%;text-align: center;">{{ $t('table.Bioactivity') }}</div> -->
+        <div class="th_tr_b" style="width: 15%;text-align: center;">
+          {{ $t("table.PurityAndBioactivity") }}
+        </div>
+        <div class="th_tr_b" style="width: 14%;text-align: center;">
+          {{ $t("table.Price") }}
+        </div>
+      </div>
+      <div class="tableList_th tableList_td" v-for="one in list" :key="one.id">
+        <div
+          style="width: 6%"
+          class="th_tr_b th_header"
+          @click="gotoproduct(one)"
+        >
+          {{ one.catalog }}
+        </div>
+        <div style="width: 13%;" v-if="type != 2" class="th_tr_b">
+          {{ one.productName }}
+        </div>
+        <div style="width: 13%;" v-if="type == 2" class="th_tr_b">
+          {{ one.productName }}
+        </div>
+        <div style="width: 10%;" class="th_tr_b" v-if="type == 4">
+          {{
+            $util.findAllCategory("Diagnostic_specification", one.specification)
+          }}
+        </div>
+        <div
+          style="width: 8%; text-align: center;"
+          class="th_tr_b"
+          v-if="type == 2"
+        >
+          {{ $util.findAllCategory("Antibody_agSpecies", one.species) }}
+        </div>
+        <div class="th_tr" v-if="type == 1 || type == 3">
+          {{ $util.targetDictionaries(one.target) }}
+        </div>
+        <div
+          style="width: 9%; text-align: center;"
+          class="th_tr_b"
+          v-if="type == 2"
+        >
+          {{ $util.targetDictionaries(one.target) }}
+        </div>
+        <!-- <div class="th_tr_b" style="width: 9%;" v-if="type == 1">{{one.aaSeqBrief}}</div> -->
+        <div class="th_tr" v-if="type == 1">
+          {{ $util.findAllCategory("Protein_tag", one.tag) }}
+        </div>
+        <div style="width: 10%;" class="th_tr_b" v-if="type == 1 || type == 3">
+          {{
+            $util.findAllCategory(
+              type == 1 ? "Protein_species" : "CellLine_species",
+              one.species
+            )
+          }}
+        </div>
+        <div style="width: 5%;" class="th_tr_b" v-if="type == 3">
+          {{ $util.findAllCategory("CellLine_subType", one.subType) }}
+        </div>
+        <div
+          style="width: 8%; text-align: center;"
+          class="th_tr_b"
+          v-if="type == 3"
+        >
+          {{
+            $util.findAllCategory("CellLine_labeling", one.fluorescenceLabeling)
+          }}
+        </div>
+        <div class="th_tr" v-if="type == 4">
+          {{ $util.findAllCategory("Diagnostic_source", one.source) }}
+        </div>
+        <div class="th_tr" v-if="type == 4">
+          {{ $util.findAllCategory("Diagnostic_clonality", one.clonality) }}
+        </div>
+        <div
+          style="width: 12%; text-align: center;"
+          class="th_tr_b"
+          v-if="type == 4"
+        >
+          {{ $util.findAllCategory("Diagnostic_coupling", one.couplingAgent) }}
+        </div>
+        <div
+          style="width: 14%; text-align: center;"
+          class="th_tr_b"
+          v-if="type == 4"
+        >
+          {{
+            $util.findAllCategory(
+              "Diagnostic_ApplicationValidated",
+              one.applicationValidated
+            )
+          }}
+        </div>
+        <div
+          class="th_tr_b"
+          style="width: 9%; text-align: center;"
+          v-if="type == 2"
+        >
+          {{ $util.findAllCategory("Antibody_format", one.format) }}
+        </div>
+        <!-- <div class="th_tr_b" style="width: 7%; text-align: center;" v-if="type == 1 || type == 2">{{$util.findAllCategory(type == 1?'Protein_host' : 'Antibody_host',one.host)}}</div> -->
+        <div
+          class="th_tr_b"
+          style="width: 5%;text-align: center;"
+          @click="clickCoa(one)"
+        >
+          <img
+            v-if="one.coaUrl"
+            src="@/assets/img/download1.png"
+            alt=""
+            class="butt_image"
+          />
+          <div v-else>N/A</div>
+        </div>
+        <!-- <div class="th_tr" style="width: 80px;text-align: center;">
+        <el-tooltip class="item-tooltip" v-if="one.purityFeature && one.purityFeature.length > 0" effect="light" placement="top">
+          <template slot="content">
+            <div class="description_pmd">
+              <el-carousel trigger="click" v-if="one.purityFeature.length > 1" indicator-position="none">
+                  <el-carousel-item v-for="(one, i) in one.purityFeature" :key="i">
+                    <div class="content-pc-box">
+                      <img :src="one" alt="" class="content-image">
+                    </div>
+                  </el-carousel-item>
+              </el-carousel>
+              <div class="content-pc-box" v-else>
+                <img :src="one.purityFeature[0]" alt="" class="content-image">
+              </div>
+          </div>
+          </template>
+          <div class="bioactivity">
+            <img src="@/assets/icon/Purity.png" alt="" class="images">
+            <div>Purity</div>
+          </div>
+        </el-tooltip>
+      </div> -->
+        <div class="th_tr_b" style="width: 15%;text-align: center;">
+          <el-tooltip
+            class="item-tooltip"
+            v-if="one.purityFeature && one.purityFeature.length > 0"
+            effect="light"
+            placement="top"
+          >
+            <template slot="content">
+              <div class="description_pmd">
+                <el-carousel
+                  trigger="click"
+                  v-if="one.purityFeature.length > 1"
+                  indicator-position="none"
+                >
+                  <el-carousel-item
+                    v-for="(one, i) in one.purityFeature"
+                    :key="i"
+                  >
+                    <div class="content-pc-box">
+                      <img :src="one" alt="" class="content-image" />
+                    </div>
+                  </el-carousel-item>
+                </el-carousel>
+                <div class="content-pc-box" v-else>
+                  <img
+                    :src="one.purityFeature[0]"
+                    alt=""
+                    class="content-image"
+                  />
+                </div>
+              </div>
+            </template>
+            <div class="bioactivity">
+              <img src="@/assets/icon/Purity.png" alt="" class="images" />
+              <div>Purity</div>
+            </div>
+          </el-tooltip>
+          <el-tooltip
+            v-if="showIcon(one.validatedFeature, 'ELISA')"
+            class="item-tooltip"
+            effect="light"
+            placement="top"
+          >
+            <template slot="content">
+              <div class="content-pc-box">
+                <img
+                  :src="showimages(one.validatedFeature, 'ELISA')"
+                  alt=""
+                  class="content-image"
+                />
+              </div>
+            </template>
+            <div class="bioactivity">
+              <img src="@/assets/icon/S-02.png" alt="" class="images" />
+              <div>ELISA</div>
+            </div>
+          </el-tooltip>
+          <el-tooltip
+            v-if="showIcon(one.validatedFeature, 'FACS')"
+            class="item-tooltip"
+            effect="light"
+            placement="top"
+          >
+            <template slot="content">
+              <div class="content-pc-box">
+                <img
+                  :src="showimages(one.validatedFeature, 'FACS')"
+                  alt=""
+                  class="content-image"
+                />
+              </div>
+            </template>
+            <div class="bioactivity">
+              <img src="@/assets/icon/S-01.png" alt="" class="images" />
+              <div>FACS</div>
+            </div>
+          </el-tooltip>
+          <el-tooltip
+            v-if="showIcon(one.validatedFeature, 'Function')"
+            class="item-tooltip"
+            effect="light"
+            placement="top"
+          >
+            <template slot="content">
+              <div class="description_pmd">
+                <el-carousel
+                  trigger="click"
+                  v-if="showimages(one.validatedFeature, 'Function').length > 1"
+                  indicator-position="none"
+                >
+                  <el-carousel-item
+                    v-for="(one, i) in showimages(
+                      one.validatedFeature,
+                      'Function'
+                    )"
+                    :key="i"
+                  >
+                    <div class="content-pc-box">
+                      <img :src="one" alt="" class="content-image" />
+                    </div>
+                  </el-carousel-item>
+                </el-carousel>
+                <div class="content-pc-box" v-else>
+                  <img
+                    :src="showimages(one.validatedFeature, 'Function')[0]"
+                    alt=""
+                    class="content-image"
+                  />
+                </div>
+              </div>
+            </template>
+            <div class="bioactivity">
+              <img src="@/assets/icon/S-04.png" alt="" class="images" />
+              <div>Function</div>
+            </div>
+          </el-tooltip>
+          <el-tooltip
+            v-if="showIcon(one.validatedFeature, 'Animal')"
+            class="item-tooltip"
+            effect="light"
+            placement="top"
+          >
+            <template slot="content">
+              <div class="content-pc-box">
+                <img
+                  :src="showimages(one.validatedFeature, 'Animal')"
+                  alt=""
+                  class="content-image"
+                />
+              </div>
+            </template>
+            <div class="bioactivity">
+              <img src="@/assets/icon/S-03.png" alt="" class="images" />
+              <div>Animal</div>
+            </div>
+          </el-tooltip>
+          <el-tooltip
+            v-if="showIcon(one.validatedFeature, 'IHC')"
+            class="item-tooltip"
+            effect="light"
+            placement="top"
+          >
+            <template slot="content">
+              <div class="description_pmd">
+                <el-carousel
+                  trigger="click"
+                  v-if="showimages(one.validatedFeature, 'IHC').length > 1"
+                  indicator-position="none"
+                >
+                  <el-carousel-item
+                    v-for="(one, i) in showimages(one.validatedFeature, 'IHC')"
+                    :key="i"
+                  >
+                    <div class="content-pc-box">
+                      <img :src="one" alt="" class="content-image" />
+                    </div>
+                  </el-carousel-item>
+                </el-carousel>
+                <div class="content-pc-box" v-else>
+                  <img
+                    :src="showimages(one.validatedFeature, 'IHC')[0]"
+                    alt=""
+                    class="content-image"
+                  />
+                </div>
+              </div>
+            </template>
+            <div class="bioactivity">
+              <img src="@/assets/icon/S-05.png" alt="" class="images" />
+              <div>IHC</div>
+            </div>
+          </el-tooltip>
+        </div>
+        <div class="th_tr_b" style="width: 14%; text-align: center;">
+          <el-select
+            v-model="one.skuDefault"
+            v-if="one.skuList && one.skuList.length > 0"
+          >
+            <el-option
+              v-for="(item, idx) in one.skuList"
+              :key="idx"
+              :value="idx"
+              :label="
+                `${item.specifications} ( ${
+                  $util.localeStorage() ? '$' : '¥'
+                }${$util.localeStorage() ? item.price : item.cnPrice})`
+              "
+            />
+          </el-select>
+          <el-link
+            type="primary"
+            @click="
+              $util.goRoute({
+                name: 'inquiry',
+                query: { catalog: one.catalog }
+              })
+            "
+            v-else
+            >{{ $t("table.Inquiry") }}</el-link
+          >
+        </div>
+      </div>
+      <div class="tableList_not" v-if="list.length == 0">
+        {{ $t("table.notable") }}
+      </div>
+    </div>
+    <!-- 移动端 -->
+    <div class="move_tableList" style="display: none;">
+      <div class="move_header">
+        <div class="th">{{ $t("table.productName") }}</div>
+        <div class="th" v-if="type == 1">{{ $t("table.Tag") }}</div>
+        <div class="th" v-if="type == 2">{{ $t("table.Format") }}</div>
+        <div class="th" v-if="type == 3">
+          {{ $t("table.FluorescentLabel") }}
+        </div>
+        <div class="th" v-if="type == 4">{{ $t("table.ApplicationPmd") }}</div>
+        <div class="hr_t">More</div>
+      </div>
+      <div class="move_td" v-for="(one, i) in list" :key="one.id">
+        <div class="td_t">
+          <div class="td can_catalog" @click="gotoproduct(one)">
+            {{ one.productName }}
+          </div>
+          <div class="td" v-if="type == 1">
+            {{ $util.findAllCategory("Protein_tag", one.tag) }}
+          </div>
+          <div class="td" v-if="type == 2">
+            {{ $util.findAllCategory("Antibody_format", one.format) }}
+          </div>
+          <div class="td" v-if="type == 3">
+            {{
+              $util.findAllCategory(
+                "CellLine_labeling",
+                one.fluorescenceLabeling
+              )
+            }}
+          </div>
+          <div class="td" v-if="type == 4">
+            {{
+              $util.findAllCategory(
+                "Diagnostic_ApplicationValidated",
+                one.applicationValidated
+              )
+            }}
+          </div>
+          <div class="hr_t">
+            <img
+              v-if="listId !== i"
+              @click="listShow(i, 1)"
+              class="more_img"
+              src="@/assets/img/table-top.png"
+              alt=""
+              srcset=""
+            />
+            <img
+              v-else
+              class="more_img"
+              @click="listShow(i, 2)"
+              src="@/assets/img/table_bott.png"
+              alt=""
+              srcset=""
+            />
+          </div>
+        </div>
+        <div class="td_show" v-if="listId == i">
+          <div class="show_t">
+            <div class="can">{{ $t("table.catalog") }}</div>
+          </div>
+          <div class="td tb_catalog can_catalog" @click="gotoproduct(one)">
+            {{ one.catalog }}
+          </div>
+        </div>
+
+        <div class="td_show" v-if="listId == i && type == 4">
+          <div class="show_t">
+            <div class="can" v-if="type == 4">
+              {{ $t("table.Specification") }}
+            </div>
+          </div>
+          <div class="td tb_catalog" v-if="type == 4">
+            {{
+              $util.findAllCategory(
+                "Diagnostic_specification",
+                one.specification
+              )
+            }}
+          </div>
+        </div>
+
+        <div class="td_show" v-if="listId == i && type == 2">
+          <div class="show_t">
+            <div class="can" v-if="type == 2">{{ $t("table.Species") }}</div>
+          </div>
+          <div class="td tb_catalog" v-if="type == 2">
+            {{ $util.findAllCategory("Antibody_agSpecies", one.species) }}
+          </div>
+        </div>
+
+        <div
+          class="td_show"
+          v-if="listId == i && (type == 1 || type == 2 || type == 3)"
+        >
+          <div class="show_t">
+            <div class="can" v-if="type == 1 || type == 2 || type == 3">
+              {{ $t("table.Target") }}
+            </div>
+          </div>
+          <div class="td tb_catalog" v-if="type == 1 || type == 2 || type == 3">
+            {{ $util.targetDictionaries(one.target) }}
+          </div>
+        </div>
+
+        <div class="td_show" v-if="listId == i && type == 1">
+          <div class="show_t">
+            <div class="can" v-if="type == 1">{{ $t("table.AAsequene") }}</div>
+          </div>
+          <div class="td tb_catalog" v-if="type == 1">{{ one.aaSeqBrief }}</div>
+        </div>
+
+        <div class="td_show" v-if="listId == i && (type == 3 || type == 1)">
+          <div class="show_t">
+            <div class="can" v-if="type == 3 || type == 1">
+              {{ $t("table.Species") }}
+            </div>
+          </div>
+          <div class="td tb_catalog" v-if="type == 1 || type == 3">
+            {{
+              $util.findAllCategory(
+                type == 1 ? "Protein_species" : "CellLine_species",
+                one.species
+              )
+            }}
+          </div>
+        </div>
+
+        <div class="td_show" v-if="listId == i && type == 3">
+          <div class="show_t">
+            <div class="can" v-if="type == 3">{{ $t("table.CellType") }}</div>
+          </div>
+          <div class="td tb_catalog" v-if="type == 3">
+            {{ $util.findAllCategory("CellLine_subType", one.subType) }}
+          </div>
+        </div>
+
+        <div class="td_show" v-if="listId == i && type == 4">
+          <div class="show_t">
+            <div class="can" v-if="type == 4">{{ $t("table.Source") }}</div>
+          </div>
+          <div class="td tb_catalog" v-if="type == 4">
+            {{ $util.findAllCategory("Diagnostic_source", one.source) }}
+          </div>
+          <!-- <div class="td tb_catalog" v-if="type == 2 || type == 4">{{$util.findAllCategory(type == 2?'Antibody_source' : 'Diagnostic_source',one.source) }}</div> -->
+        </div>
+
+        <div class="td_show" v-if="listId == i && type == 4">
+          <div class="show_t">
+            <div class="can" v-if="type == 4">{{ $t("table.Clonality") }}</div>
+          </div>
+          <div class="td tb_catalog" v-if="type == 4">
+            {{ $util.findAllCategory("Diagnostic_clonality", one.clonality) }}
+          </div>
+        </div>
+
+        <div class="td_show" v-if="listId == i && type == 4">
+          <div class="show_t">
+            <div class="can" v-if="type == 4">
+              {{ $t("table.Couplingagent") }}
+            </div>
+          </div>
+          <div class="td tb_catalog" v-if="type == 4">
+            {{
+              $util.findAllCategory("Diagnostic_coupling", one.couplingAgent)
+            }}
+          </div>
+        </div>
+        <div class="td_show" v-if="listId == i && (type == 1 || type == 2)">
+          <div class="show_t">
+            <div class="can" v-if="type == 1 || type == 2">
+              {{ $t("table.host") }}
+            </div>
+          </div>
+          <div class="td tb_catalog" v-if="type == 1 || type == 2">
+            {{
+              $util.findAllCategory(
+                type == 1 ? "Protein_host" : "Antibody_host",
+                one.host
+              )
+            }}
+          </div>
+        </div>
+        <div class="td_show" v-if="listId == i">
+          <div class="show_t">
+            <div class="can">COA</div>
+          </div>
+          <div class="td tb_catalog" @click="clickCoa(one)">
+            <img
+              v-if="one.coaUrl"
+              src="@/assets/img/download1.png"
+              alt=""
+              class="butt_image"
+            />
+            <div v-else>N/A</div>
+          </div>
+        </div>
+        <div class="td_show" v-if="listId == i">
+          <div class="show_t">
+            <div class="can">{{ $t("table.Purity") }}</div>
+          </div>
+          <div class="td tb_catalog">
+            <div class="td tb_catalog">
+              <div
+                class="bioactivity"
+                v-if="one.purityFeature && one.purityFeature.length > 0"
+              >
+                <img src="@/assets/icon/Purity.png" alt="" class="images" />
+                <div>Purity</div>
+              </div>
+            </div>
+          </div>
+        </div>
+        <div class="td_show" v-if="listId == i">
+          <div class="show_t">
+            <div class="can">{{ $t("table.Bioactivity") }}</div>
+          </div>
+          <div class="td tb_catalog">
+            <div
+              class="bioactivity"
+              v-if="showIcon(one.validatedFeature, 'ELISA')"
+            >
+              <img src="@/assets/icon/S-02.png" alt="" class="images" />
+              <div>ELISA</div>
+            </div>
+            <div
+              class="bioactivity"
+              v-if="showIcon(one.validatedFeature, 'FACS')"
+            >
+              <img src="@/assets/icon/S-01.png" alt="" class="images" />
+              <div>FACS</div>
+            </div>
+            <div
+              class="bioactivity"
+              v-if="showIcon(one.validatedFeature, 'Function')"
+            >
+              <img src="@/assets/icon/S-04.png" alt="" class="images" />
+              <div>Function</div>
+            </div>
+            <div
+              class="bioactivity"
+              v-if="showIcon(one.validatedFeature, 'Animal')"
+            >
+              <img src="@/assets/icon/S-03.png" alt="" class="images" />
+              <div>Animal</div>
+            </div>
+            <div
+              class="bioactivity"
+              v-if="showIcon(one.validatedFeature, 'IHC')"
+            >
+              <img src="@/assets/icon/S-05.png" alt="" class="images" />
+              <div>IHC</div>
+            </div>
+          </div>
+        </div>
+
+        <!-- <div class="td_show" v-if="listId == i">
+        <div class="show_t">
+          <div class="can">{{$t('table.size')}}</div>
+        </div>
+        <div class="td">{{one.size}}</div>
+        <div class="hr_t">
+          <img class="more_img" @click="tapInquiry(one)" src="@/assets/img/Inquiry.png" alt="" srcset="">
+        </div>
+      </div> -->
+      </div>
+      <div class="tableList_not" v-if="list.length == 0">
+        {{ $t("table.notable") }}
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import SortFieldHeader from "@/components/SortFieldHeader";
+
+// 表格排序默认根据产品名
+export default {
+  name: "tableList",
+  components: {
+    SortFieldHeader
+  },
+  props: {
+    list: {
+      type: Array,
+      required: true
+    },
+    type: {
+      type: [String, Number],
+      default: ""
+    }
+  },
+  data() {
+    return {
+      listId: null,
+      show: true,
+      sortField: "",
+      sortValue: ""
+    };
+  },
+  methods: {
+    onSortFieldChange(params) {
+      this.sortField = params.field;
+      this.sortValue = params.value;
+      this.$emit("my-sort-change", params);
+    },
+    // 特性图标图片显示
+    showimages(one, name) {
+      if (one) {
+        let data = one.find(item => {
+          if (item.name === name) {
+            return item;
+          }
+        });
+        if (data) {
+          return data.picUrl;
+        }
+      }
+    },
+    //  特性图标显示
+    showIcon(one, name) {
+      if (one) {
+        let data = one.find(item => {
+          if (item.name === name) {
+            return item;
+          }
+        });
+        if (data) {
+          return true;
+        } else {
+          return false;
+        }
+      } else {
+        return false;
+      }
+    },
+    // 下来COA
+    clickCoa(item) {
+      if (item.coaUrl) {
+        window.location.href = item.coaUrl;
+      }
+      // else {
+      //   this.$message.error(this.$t('taps.service'))
+      // }
+    },
+    listShow(one, num) {
+      if (num === 1) {
+        this.listId = one;
+      } else {
+        this.listId = null;
+      }
+    },
+    tapInquiry(e) {
+      this.$util.goRoute({
+        name: "inquiry",
+        query: {
+          catalog: e.catalog
+        }
+      });
+    },
+    tableRowClassName({ row, rowIndex }) {
+      if (rowIndex % 2 === 0) {
+        return "warning-row";
+      } else {
+        return "success-row";
+      }
+    },
+    gotoproduct(e) {
+      let name = this.$util.english(e.productName);
+      let title = null;
+      const _type = Number(this.type);
+      if (_type === 1) {
+        title = "protein";
+        // return this.$router.push({
+        //   path: '/protein/detail/'  + e.catalog,
+        // })
+      } else if (_type === 2) {
+        title = "antibody";
+      } else if (_type === 3) {
+        title = "cell-line";
+      } else if (_type === 4) {
+        title = "diagnostic-reagent";
+      }
+      if (this.$route.query.keywords) {
+        let datt = { keywords: this.$route.query.keywords };
+        sessionStorage.setItem("keywords", JSON.stringify(datt));
+        // this.$router.push({
+        //   path: "/products/" + title + "/" + name + "/" + e.catalog
+        //   // query: {
+        //   //   catalog: e.catalog
+        //   // }
+        // });
+      } else {
+        // this.$router.push({
+        //   path: "/products/" + title + "/" + name + "/" + e.catalog
+        //   // query: {
+        //   //   catalog: e.catalog
+        //   // }
+        // });
+      }
+      this.$router.push({
+        path: "/products/" + title + "/" + name + "/" + e.catalog
+        // query: {
+        //   catalog: e.catalog
+        // }
+      });
+    }
+  },
+  created() {}
+};
+</script>
+
+<style lang="scss" scoped>
+.table_box {
+  min-height: 530px;
+}
+.tableList /deep/ {
+  width: 100%;
+  margin-top: 1rem;
+  border: 1px solid #ebeef5;
+  .tableList_th {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    background-color: #cfe0ef;
+    min-height: 48px;
+    padding: 6px 0;
+    .th_tr {
+      flex: 1;
+      line-height: 18px;
+      margin: 0 10px;
+      font-size: 16px;
+      font-family: Arial;
+      font-weight: 600;
+      color: #005bab;
+      overflow: hidden;
+    }
+    .th_tr_b {
+      line-height: 18px;
+      margin: 0 10px;
+      font-size: 16px;
+      font-family: Arial;
+      font-weight: 600;
+      color: #005bab;
+      word-wrap: break-word;
+      word-break: normal;
+    }
+    .butt_image {
+      cursor: pointer;
+    }
+    .bioactivity {
+      display: inline-block;
+      font-size: 12px;
+    }
+    .images {
+      // margin: 10px;
+      max-width: 30px;
+      cursor: pointer;
+    }
+  }
+  .tableList_td {
+    background-color: #f0f5fa;
+    &:nth-child(odd) {
+      background-color: #f9fbfd;
+    }
+    .th_tr {
+      font-size: 14px !important;
+      font-family: Arial;
+      font-weight: 400;
+      color: #313131;
+      &:nth-of-type(1) {
+        font-size: 14px;
+        font-family: Arial;
+        color: #005bab;
+      }
+    }
+    .th_header {
+      color: #005bab !important;
+      cursor: pointer;
+    }
+    .th_tr_b {
+      font-size: 14px !important;
+      font-weight: 400;
+      color: #313131;
+      position: relative;
+      .inquiry_img {
+        position: absolute;
+        width: 24px;
+        top: 50%;
+        transform: translateY(-50%);
+        cursor: pointer;
+      }
+    }
+  }
+  .tableList_not {
+    width: 100%;
+    line-height: 60px;
+    padding: 6px 0;
+    background-color: #fff;
+    text-align: center;
+    font-size: 16px;
+    color: #909399;
+    font-family: Arial;
+  }
+}
+.description_pmd /deep/ {
+  width: 400px;
+  height: 200px;
+  .el-carousel__container {
+    height: 200px !important;
+  }
+}
+.content-pc-box {
+  width: 400px;
+  height: 200px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  .content-image {
+    width: auto;
+    height: auto;
+    max-width: 100%;
+    max-height: 100%;
+  }
+}
+/deep/ .is-light {
+  border: none !important;
+}
+
+@media screen and (min-width: 0px) and (max-width: 750px) {
+  .tableList {
+    display: none;
+  }
+  .move_tableList /deep/ {
+    display: block !important;
+    border: 1px solid #dbdbdb;
+    overflow: hidden;
+    .move_header {
+      display: flex;
+      align-items: center;
+      min-height: 48px;
+      background-color: #cfe0ef;
+      font-size: 14px;
+      font-family: Arial;
+      font-weight: bold;
+      color: #005bab;
+      .th {
+        flex: 1;
+        padding: 0 6px;
+        word-wrap: break-word;
+        word-break: normal;
+      }
+      .td {
+        flex: 1;
+        padding: 0 6px;
+      }
+      .hr_t {
+        width: 60px;
+        padding: 0 6px;
+      }
+    }
+    .move_td {
+      &:nth-child(odd) {
+        .td_t {
+          background-color: #f9fbfd;
+        }
+      }
+      .td_t {
+        display: flex;
+        align-items: center;
+        min-height: 48px;
+        background-color: #f0f5fa;
+        font-size: 14px;
+        font-family: Arial;
+        color: #313131;
+        line-height: 16px;
+        .td {
+          flex: 1;
+          padding: 6px;
+          word-wrap: break-word;
+          word-break: normal;
+        }
+        .hr_t {
+          width: 60px;
+          padding: 4px 6px;
+          .more_img {
+            width: 32px;
+          }
+        }
+      }
+      .td_show {
+        // 隐藏数据
+        display: flex;
+        align-items: center;
+        min-height: 48px;
+        background-color: #f0f5fa;
+        margin: 1px 0;
+        font-size: 14px;
+        font-family: Arial;
+        color: #313131;
+        line-height: 16px;
+        .td {
+          flex: 1;
+          padding: 2px 6px;
+        }
+        .tb_catalog {
+          color: #313131;
+          .bioactivity {
+            display: inline-block;
+            font-size: 12px;
+            text-align: center;
+            margin: 10px;
+          }
+          .images {
+            width: 30px;
+          }
+        }
+        .show_t {
+          width: 30%;
+          padding: 2px 6px;
+          background-color: #ffffff;
+          .can {
+            // min-height: 48px;
+            width: 100%;
+            // line-height: 48px;
+            padding: 0.24rem 0;
+            word-wrap: break-word;
+            word-break: normal;
+            color: #313131;
+          }
+        }
+        .hr_t {
+          width: 60px;
+          padding: 2px 6px;
+          .more_img {
+            width: 24px;
+          }
+        }
+      }
+    }
+  }
+  .tableList_not {
+    width: 100%;
+    line-height: 0.6rem;
+    height: 0.6rem;
+    // padding: 6px 0;
+    background-color: #fff;
+    text-align: center;
+    font-size: 0.16rem;
+    color: #909399;
+    font-family: Arial;
+  }
+  .can_catalog {
+    color: #005bab !important;
+  }
+}
+</style>

+ 56 - 0
src/router/login.js

@@ -0,0 +1,56 @@
+// 登录,注册,忘记密码,第三方登录绑定手机号等路由
+export default [
+  {
+    path: "/login",
+    name: "login",
+    component: () => import("@/view/landing/index"),
+    hidden: true,
+    meta: {
+      pageTitle: "Login",
+      chineseTitle: "登录",
+      navActive: "Login", // 登录
+      fullScreen: true
+    }
+  }, {
+    path: "/PasswordReset",
+    name: "PasswordReset",
+    component: () => import("@/view/applications/index"),
+    hidden: true,
+    meta: {
+      pageTitle: "Password Reset",
+      chineseTitle: "重置密码",
+      navActive: "PasswordReset" // 重置密码
+    }
+  }, {
+    path: "/register",
+    name: "register",
+    component: () => import("@/view/register/index"),
+    hidden: true,
+    meta: {
+      pageTitle: "Register",
+      chineseTitle: "注册",
+      navActive: "register" // 注册
+    }
+  },
+  {
+    path: "/application",
+    name: "application",
+    component: () => import("@/view/application/index"),
+    hidden: true,
+    meta: {
+      pageTitle: "Application",
+      chineseTitle: "密码重置申请",
+      navActive: "application" // 密码重置申请
+    }
+  }, {
+    path: "/RegisterConfirmation",
+    name: "RegisterConfirmation",
+    component: () => import("@/view/registrations/index"),
+    hidden: true,
+    meta: {
+      pageTitle: "Register Confirmation",
+      chineseTitle: "帐户激活",
+      navActive: "Register Confirmation" // 帐户激活
+    }
+  }
+]

+ 46 - 1
src/router/routerList.js

@@ -5,8 +5,9 @@
  * requireLogin:是否需要登录后才能进入
  * fullScreen: false // 是否需要满屏显示
  */
-// import login from './login.js'
+import login from './login.js'
 export default [
+  ...login,
   {
     path: "/",
     name: "home",
@@ -17,5 +18,49 @@ export default [
       requireLogin: true,
       fullScreen: true
     }
+  },
+  {
+    path: "/product",
+    name: "product",
+    component: () => import("@/view/product/index"),
+    hidden: true,
+    meta: {
+      pageTitle: "product",
+      requireLogin: true,
+      fullScreen: false
+    }
+  }, {
+    path: '/products/:id/:name/:catalog',
+    name: 'productDetail',
+    component: () => import('@/view/product/details'),
+    hidden: true,
+    meta: {
+      pageTitle: 'Product Detail',
+      chineseTitle: '产品详情',
+      navActive: 'Product detail', // 匹配路由名字 产品详情
+      fullScreen: false
+    }
+  }, {
+    path: '/inquiry',
+    name: 'inquiry',
+    component: () => import('@/view/inquiry/index'),
+    hidden: true,
+    meta: {
+      pageTitle: 'Inquiry',
+      chineseTitle: '询价',
+      navActive: 'inquiry', // 匹配路由名字 询价页
+      fullScreen: false
+    }
+  }, {
+    path: "/privacy-policy",
+    name: "privacy-policy",
+    component: () => import("@/view/privacyPolicy/index"),
+    hidden: true,
+    meta: {
+      pageTitle: "Privacy Policy",
+      chineseTitle: "隐私政策",
+      navActive: "Privacy Policy", // 匹配路由名字 隐私政策
+      fullScreen: false
+    }
   }
 ]

+ 161 - 0
src/view/application/index.vue

@@ -0,0 +1,161 @@
+<template>
+<div>
+  <div class="box">
+    <div class="toptext">{{$t('application.Password')}}</div>
+     <div class="centerbox">
+       <input class="cen_email" v-model="email" type="text" :placeholder="$t('input.email')"/>
+       <button class="cen_button" v-loading.fullscreen.lock="fullscreenLoading" @click="appli">{{$t('application.Send')}}</button>
+    </div>
+  </div>
+
+
+
+</div>
+
+</template>
+<script>
+export default {
+  components: {
+  },
+  name: 'application',
+  data () {
+    return {
+      email: "",
+      fullscreenLoading: false
+    }
+  },
+  methods: {
+    verification () {
+      if (!this.email) {
+        this.$message.error(this.$t('register.Address') + this.$t('register.Cannot'))
+        return false
+      } else if (!this.$util.isEmail(this.email)) {
+        this.$message.error(this.$t('input.email') + this.$t('message.email'))
+        return false
+      } else {
+        return true
+      }
+    },
+    appli () {
+      if (this.verification()) {
+        this.fullscreenLoading = true;
+        this.$api.post('auth/forgetPassword', {
+          email: this.email
+        }).then((res) => {
+          if (res.code == 0) {
+          this.$message({
+            message: this.$t('message.PasswordReset'),
+            type: 'success'
+          });
+          this.fullscreenLoading = false;
+        } else if (res.code == 302) {
+          this.$message.error(this.$t('register.registered'))
+          this.fullscreenLoading = false;
+        } else {
+          this.$message.error(res.msg)
+          this.fullscreenLoading = false;
+        }
+        })
+      }
+    }
+  },
+  mounted () {
+  },
+  created () {
+  }
+}
+</script>
+<style lang="scss" scoped>
+@media screen and (min-width: 751px) and (max-width: 9999px) {
+.box{
+  overflow: hidden;
+}
+.toptext{
+    margin-top: 3rem;
+    font-size: 16px;
+    color: #005bab;
+    background: #cfe0ef;
+    font-weight: 700;
+    padding: 2rem 0;
+    text-align: center;
+}
+.centerbox{
+  width: 100%;
+  box-shadow: 2px 3px 8px 0px rgba(180, 180, 180, 0.3);
+  background: #F9FBFD;
+  padding: 50px;
+  border: 1px solid #dbdbdb;
+  .cen_email{
+    width: 40%;
+    margin: 0 auto 2rem;
+    height: 40px;
+    color: #a7a7a7;
+    border: 1px solid #ccc;
+    display: block;
+    text-indent: 1rem;
+    border-radius: 4px;
+  }
+  .cen_button{
+    width: 40%;
+    margin: 0 auto;
+    height: 40px;
+    display: block;
+    background: #005bab;
+    border: none;
+    color: #ffffff;
+    border-radius: 4px;
+    font-size: 14px;
+    cursor: pointer;
+  }
+}
+
+
+}
+
+@media screen and (min-width: 0px) and (max-width: 750px) {
+.box{
+  overflow: hidden;
+}
+.toptext{
+  margin-top: 0.1rem;
+    height: 0.5rem;
+    font-size: 16px;
+    color: #005bab;
+    background: #cfe0ef;
+    line-height: 0.5rem;
+    text-indent: 0.1rem;
+    font-weight: 700;
+}
+.centerbox{
+  width: 100%;
+  box-shadow: 2px 3px 8px 0px rgba(180, 180, 180, 0.3);
+  background: #F9FBFD;
+  padding: 0.3rem;
+  border: 1px solid #dbdbdb;
+  .cen_email{
+    width: 100%;
+    margin: 0 auto 0.2rem;
+    height: 40px;
+    color: #a7a7a7;
+    border: 1px solid #ccc;
+    display: block;
+    text-indent: 0.1rem;
+    border-radius: 4px;
+  }
+  .cen_button{
+    width: 100%;
+    margin: 0 auto;
+    height: 40px;
+    display: block;
+    background: #005bab;
+    border: none;
+    color: #ffffff;
+    border-radius: 4px;
+    font-size: 14px;
+    cursor: pointer;
+  }
+}
+
+
+}
+</style>

+ 174 - 0
src/view/applications/index.vue

@@ -0,0 +1,174 @@
+<template>
+<div>
+  <div class="box">
+    <div class="toptext">{{$t('application.Reset')}}</div>
+     <div class="centerbox">
+      <el-input class="cen_email" :placeholder="$t('application.New')" v-model="password" show-password></el-input>
+      <el-input class="cen_email" :placeholder="$t('application.Confirm')" v-model="confirmPassword" show-password></el-input>
+       <button class="cen_button" v-loading.fullscreen.lock="fullscreenLoading" @click="appli">{{$t('application.Submit')}}</button>
+    </div>
+  </div>
+</div>
+
+</template>
+<script>
+export default {
+  components: {
+  },
+  name: 'applications',
+  data () {
+    return {
+      code: '',
+      email: '',
+      password: '',
+      confirmPassword: '',
+      fullscreenLoading: false
+    }
+  },
+  methods: {
+    verification () {
+      if (!this.password) {
+        this.$message.error(this.$t('register.Password') + this.$t('register.Cannot'))
+        return false
+      } else if (!this.$util.passwordValid(this.password)) {
+        this.$message.error(this.$t('register.kinds'))
+        return false
+      } else if (this.password !== this.confirmPassword) {
+        this.$message.error(this.$t('register.inconsistent'))
+        return false
+      } else {
+        return true
+      }
+    },
+    appli () {
+      if (this.verification()) {
+        var code = this.$route.query.code.split(' ')
+        // console.log(code)
+        this.fullscreenLoading = true;
+        this.$api.post('auth/resetPassword', {
+          code: code[0],
+          email: this.$route.query.email,
+          password: this.password,
+          confirmPassword: this.confirmPassword
+        }).then((res) => {
+          if (res.code == 0) {
+            this.$message({
+              message: this.$t('register.successfully'),
+              type: 'success'
+            })
+            this.fullscreenLoading = false;
+            setTimeout(()=> {
+              this.$util.goRoute({
+                name: 'login'
+              })
+            }, 1000)
+          } else if (res.code == 302) {
+            this.$message.error(this.$t('register.registered'))
+            this.fullscreenLoading = false;
+          } else if (res.code == 407) {
+            this.$message.error(this.$t('message.submitFailed'))
+            this.fullscreenLoading = false;
+          } else {
+            this.$message.error(res.msg)
+            this.fullscreenLoading = false;
+          }
+        })
+      }
+    }
+  },
+  mounted () {
+  },
+  created () {
+  }
+}
+</script>
+<style lang="scss" scoped>
+@media screen and (min-width: 751px) and (max-width: 9999px) {
+.box{
+  overflow: hidden;
+}
+.toptext{
+    margin-top: 3rem;
+    font-size: 16px;
+    color: #005bab;
+    background: #cfe0ef;
+    font-weight: 700;
+    padding: 2rem 0;
+    text-align: center;
+}
+.centerbox /deep/{
+  width: 100%;
+  box-shadow: 2px 3px 8px 0px rgba(180, 180, 180, 0.3);
+  background: #F9FBFD;
+  padding: 50px;
+  border: 1px solid #dbdbdb;
+  .cen_email{
+    width: 40%;
+    margin: 0 auto 2rem;
+    height: 40px;
+    color: #a7a7a7;
+    border: 1px solid #ccc;
+    display: block;
+    // text-indent: 1rem;
+    border-radius: 4px;
+  }
+  .cen_button{
+    width: 40%;
+    margin: 0 auto;
+    height: 40px;
+    display: block;
+    background: #005bab;
+    border: none;
+    color: #ffffff;
+    border-radius: 4px;
+    font-size: 14px;
+  }
+}
+}
+
+@media screen and (min-width: 0px) and (max-width: 750px) {
+.box{
+  overflow: hidden;
+}
+.toptext{
+  margin-top: 0.1rem;
+    height: 0.5rem;
+    font-size: 16px;
+    color: #005bab;
+    background: #cfe0ef;
+    line-height: 0.5rem;
+    text-indent: 0.1rem;
+    font-weight: 700;
+}
+.centerbox{
+  width: 100%;
+  box-shadow: 2px 3px 8px 0px rgba(180, 180, 180, 0.3);
+  background: #F9FBFD;
+  padding: 0.3rem;
+  border: 1px solid #dbdbdb;
+  .cen_email{
+    width: 100%;
+    margin: 0 auto 0.2rem;
+    height: 40px;
+    color: #a7a7a7;
+    border: 1px solid #ccc;
+    display: block;
+    // text-indent: 0.1rem;
+    border-radius: 4px;
+  }
+  .cen_button{
+    width: 100%;
+    margin: 0 auto;
+    height: 40px;
+    display: block;
+    background: #005bab;
+    border: none;
+    color: #ffffff;
+    border-radius: 4px;
+    font-size: 14px;
+  }
+}
+
+
+}
+</style>

+ 867 - 0
src/view/inquiry/index.vue

@@ -0,0 +1,867 @@
+<template>
+  <div class="box">
+    <div class="topbox">
+      {{ $t("message.ProductInquiry") }}
+    </div>
+    <div class="contentbox">
+      <div class="topcontentbox">
+        <p>
+          <!-- Tips -->
+          {{ $t("inquiry.Tips") }}
+        </p>
+        <p>
+          <!-- Please leave us a message if you have any questions about our products. We will contact you within 24 hours by email. -->
+          {{ $t("inquiry.PleaseLeave") }}
+        </p>
+      </div>
+
+      <div class="bottomcontentbox_b">
+        <p>
+          <!-- Product Information -->
+          {{ $t("inquiry.ProductInformation") }}
+        </p>
+        <div class="bottomcontentbox">
+          <el-form :inline="true">
+            <el-form-item>
+              <div class="input_box">
+                <span>
+                  <!-- Quick Add  -->
+                  {{ $t("inquiry.QuickAdd") }}:
+                </span>
+                <el-input
+                  class="catalogInput"
+                  v-model="catalog"
+                  placeholder=""
+                ></el-input>
+                <span @click="searchByCatalog">{{
+                  $t("button.addQuoteForm")
+                }}</span>
+              </div>
+            </el-form-item>
+            <el-form-item>
+              <div class="sample_info">
+                <el-form :inline="true">
+                  <el-form-item>
+                    <span style="color:#E50113">{{
+                      $t("inquiry.getFreeSampleInfo1")
+                    }}</span>
+                  </el-form-item>
+                  <el-form-item>
+                    <span style="color:#606266">{{
+                      $t("inquiry.getFreeSampleInfo2")
+                    }}</span>
+                  </el-form-item>
+                </el-form>
+              </div>
+            </el-form-item>
+          </el-form>
+          <el-table
+            :data="from.inquiryDetailList"
+            style="width: 100%; margin-bottom:2rem;"
+            :empty-text="$t('table.notable')"
+          >
+            <el-table-column
+              prop="catalog"
+              :label="$t('table.catalog')"
+              style="width:20% color:red;"
+            >
+            </el-table-column>
+            <el-table-column
+              prop="productName"
+              :label="$t('table.productName')"
+              style="width:20%"
+            >
+            </el-table-column>
+            <el-table-column
+              prop="date"
+              :label="$t('table.size')"
+              style="width:20%"
+            >
+              <template slot-scope="scope">
+                <div class="size_data">
+                  <el-input
+                    class="size_q"
+                    v-model="size"
+                    placeholder=""
+                  ></el-input>
+                  <el-select v-model="scope.row.unit" placeholder="">
+                    <el-option
+                      v-if="scope.row.unit == 'vial'"
+                      v-for="item in options"
+                      :key="item.value"
+                      :label="item.label"
+                      :value="item.value"
+                    >
+                    </el-option>
+                    <el-option
+                      v-if="scope.row.unit !== 'vial'"
+                      v-for="item in option"
+                      :key="item.value"
+                      :label="item.label"
+                      :value="item.value"
+                    >
+                    </el-option>
+                  </el-select>
+                </div>
+              </template>
+            </el-table-column>
+            <el-table-column
+              prop="date"
+              :label="$t('table.quantity')"
+              style="width:20%"
+            >
+              <template slot-scope="scope">
+                <el-input-number
+                  v-model="scope.row.quantity"
+                  @change="handleChange"
+                  :min="1"
+                  label="描述文字"
+                ></el-input-number>
+              </template>
+            </el-table-column>
+            <el-table-column :label="$t('table.delete')" style="width:20%">
+              <template slot-scope="scope">
+                <el-button type="text" size="small"
+                  ><img
+                    style="width:24px;"
+                    src="@/assets/img/delete.png"
+                    alt=""
+                    @click="deleteList(scope.$index)"
+                /></el-button>
+              </template>
+            </el-table-column>
+          </el-table>
+        </div>
+      </div>
+
+      <div class="footerbox_b">
+        <p>
+          <!-- Your Information -->
+          {{ $t("inquiry.YourInformation") }}
+        </p>
+        <div class="footerbox">
+          <div>
+            <el-input
+              class="inputbox"
+              v-model="from.name"
+              :placeholder="$t('input.fullname')"
+            ></el-input>
+            <div class="red-t">*</div>
+          </div>
+          <div>
+            <el-input
+              class="inputbox"
+              v-model="from.region"
+              :placeholder="$t('input.country')"
+            ></el-input>
+            <!-- <div class="red-t">*</div> -->
+          </div>
+          <div>
+            <el-input
+              class="inputbox"
+              v-model="from.company"
+              :placeholder="$t('input.companyInstitution')"
+            ></el-input>
+            <div class="red-t">*</div>
+          </div>
+          <div>
+            <el-input
+              class="inputbox"
+              v-model="from.email"
+              :placeholder="$t('input.email')"
+            ></el-input>
+            <div class="red-t">*</div>
+          </div>
+          <div>
+            <el-input
+              class="inputbox"
+              v-model="from.phone"
+              :placeholder="$t('input.tel')"
+            ></el-input>
+          </div>
+          <div>
+            <el-input
+              class="inputbox"
+              type="textarea"
+              :autosize="{ minRows: 4, maxRows: 6 }"
+              v-model="from.message"
+              :placeholder="$t('input.telFor')"
+            ></el-input>
+          </div>
+          <el-button class="buttonbox" type="primary" @click="postsubmit">{{
+            $t("button.submit")
+          }}</el-button>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+<script>
+export default {
+  components: {},
+  name: "inquiry",
+  data() {
+    return {
+      from: {
+        company: "",
+        email: "",
+        inquiryDetailList: [],
+        name: "",
+        phone: "",
+        region: "",
+        message: ""
+      },
+      catalog: "", // 货号
+      type: "", // 类型
+      size: 0, // 数量
+      option: [
+        {
+          value: "μg",
+          label: "μg"
+        },
+        {
+          value: "mg",
+          label: "mg"
+        },
+        {
+          value: "g",
+          label: "g"
+        }
+      ],
+      options: [
+        {
+          value: "vial",
+          label: "vial"
+        }
+      ]
+    };
+  },
+  methods: {
+    // 删除数据
+    deleteList(e) {
+      console.log(e);
+      this.from.inquiryDetailList.splice(e, 1);
+      this.$message({
+        message: this.$t("message.delete"),
+        type: "success"
+      });
+    },
+    handleChange(value) {
+      console.log(value);
+    },
+    searchByCatalog() {
+      // 货号查询
+      let that = this;
+      if (this.catalog !== "") {
+        this.$api
+          .post("product/searchByCatalog", {
+            catalog: this.catalog
+          })
+          .then(res => {
+            if (res.code == 0) {
+              if (res.data) {
+                if (res.data.type == 3) {
+                  var list = {
+                    catalog: res.data.catalog,
+                    productName: res.data.productName,
+                    quantity: 0,
+                    size: 0,
+                    unit: "vial"
+                  };
+                } else {
+                  var list = {
+                    catalog: res.data.catalog,
+                    productName: res.data.productName,
+                    quantity: 0,
+                    size: 0,
+                    unit: "μg"
+                  };
+                }
+                for (var i = 0; i < this.from.inquiryDetailList.length; i++) {
+                  if (this.from.inquiryDetailList[i].catalog == list.catalog) {
+                    this.from.inquiryDetailList[i].quantity =
+                      this.from.inquiryDetailList[i].quantity + 1;
+                    return;
+                  }
+                }
+                this.from.inquiryDetailList.push(list);
+              }
+            } else {
+              this.$message.error(res.msg);
+            }
+          });
+      }
+    },
+    postsubmit() {
+      // 提交询单
+      if (this.verification()) {
+        this.$api.post("inquiry/submit", this.from).then(res => {
+          if (res.code === 0) {
+            window.gtag && window.gtag("event", "submit_free_sample");
+            this.$message({
+              message: this.$t("message.YourInformation"),
+              type: "success"
+            });
+            (this.from = {
+              company: "",
+              email: "",
+              inquiryDetailList: [],
+              name: "",
+              phone: "",
+              region: ""
+            }),
+              (this.catalog = "");
+          } else {
+            this.$message.error(res.msg);
+          }
+        });
+      }
+    },
+    // 验证
+    verification() {
+      if (this.from.inquiryDetailList.length == 0) {
+        this.$message.error(this.$t("message.goods"));
+        return false;
+      } else if (this.from.name == "") {
+        this.$message.error(
+          this.$t("input.fullname") + this.$t("message.empty")
+        );
+        return false;
+      } else if (this.from.company == "") {
+        this.$message.error(
+          this.$t("input.companyInstitution") + this.$t("message.empty")
+        );
+        return false;
+      } else if (this.from.email == "") {
+        this.$message.error(this.$t("input.email") + this.$t("message.empty"));
+        return false;
+      } else {
+        return true;
+      }
+    }
+  },
+  mounted() {
+    this.searchByCatalog();
+  },
+  created() {
+    this.catalog = this.$route.query.catalog;
+    this.type = this.$route.query.type;
+    if (this.type == "antibody") {
+      this.size = 50;
+    } else if (this.type == "protein") {
+      this.size = 20;
+    }
+  }
+};
+</script>
+<style lang="scss" scoped>
+@media screen and (min-width: 751px) and (max-width: 9999px) {
+  .sample_info span {
+    font-size: 16px;
+  }
+  .topbox {
+    margin-bottom: 30px;
+    font-size: 20px;
+    font-family: Arial;
+    color: #313131;
+    // font-weight: 700;
+  }
+  .contentbox {
+    width: 100%;
+    overflow: hidden;
+  }
+  .topcontentbox {
+    border: 1px solid #dbdbdb;
+  }
+  .topcontentbox > p:nth-of-type(1) {
+    font-size: 18px;
+    padding: 1.5rem 2rem;
+    font-weight: 700;
+    font-family: Arial;
+    color: #005bab;
+    background: #cfe0ef;
+  }
+  .topcontentbox > p:nth-of-type(2) {
+    padding: 1.5rem 2rem 2rem 2rem;
+    font-size: 16px;
+    font-family: Arial;
+    color: #005bab;
+    word-wrap: break-word;
+    word-break: normal;
+  }
+
+  .bottomcontentbox_b /deep/ {
+    margin-top: 2rem;
+    border: 1px solid #dbdbdb;
+    // padding: 0rem 2rem;
+    .el-table__header-wrapper {
+      .cell {
+        font-size: 16px;
+        font-family: Arial;
+        font-weight: normal;
+        color: #005bab;
+      }
+    }
+    .el-table__body-wrapper {
+      tr {
+        .el-table__cell:nth-of-type(1) {
+          .cell {
+            font-size: 14px;
+            font-family: Arial;
+            color: #005bab;
+          }
+        }
+      }
+    }
+  }
+  .bottomcontentbox_b > p {
+    font-size: 18px;
+    padding: 1.5rem 2rem;
+    font-weight: 700;
+    font-family: Arial;
+    color: #005bab;
+    background: #cfe0ef;
+    margin-bottom: 1.5rem;
+  }
+  .bottomcontentbox /deep/ {
+    // margin-top: 2rem;
+    padding: 0rem 2rem;
+    overflow: hidden;
+    .el-table {
+      border: 1px solid #dfdfdf;
+    }
+    .el-table__row {
+      .el-table__cell {
+        padding: 0;
+      }
+    }
+
+    .size_data {
+      display: flex;
+      align-items: center;
+      .size_q {
+        width: 64px;
+        .el-input__inner {
+          height: 24px;
+          border: 1px solid #dfdfdf;
+          line-height: 24px;
+          padding: 0 0.3rem;
+          border-radius: 0.2rem;
+        }
+      }
+      .el-select {
+        width: 60px;
+        .el-input__inner {
+          height: 24px;
+          padding-left: 10px;
+          padding-right: 10px !important;
+        }
+        .el-input__suffix {
+          right: 0;
+        }
+        .el-input__icon {
+          line-height: 24px;
+        }
+      }
+    }
+    .el-input-number {
+      width: 50%;
+      .el-input-number__decrease {
+        width: 24px;
+        height: 24px;
+        line-height: 24px;
+        top: 7px;
+      }
+      .el-input-number__increase {
+        width: 24px;
+        height: 24px;
+        line-height: 24px;
+        top: 7px;
+      }
+      .el-input {
+        .el-input__inner {
+          height: 26px;
+          line-height: 26px;
+          padding: 0 24px;
+          border: 1px solid #dfdfdf;
+          &:focus {
+            border: 1px solid #dfdfdf;
+          }
+        }
+      }
+    }
+  }
+
+  .input_box /deep/ {
+    display: flex;
+    align-items: center;
+    & > span:nth-of-type(1) {
+      font-size: 16px;
+      float: left;
+      color: #005bab;
+      margin-top: 0.3rem;
+      margin-right: 0.5rem;
+    }
+    & > span:nth-of-type(2) {
+      padding: 0 1rem;
+      line-height: 2rem;
+      height: 2rem;
+      border: 1px solid #d3d3d3;
+      display: inline-block;
+      background: #005bab;
+      color: white;
+      border-radius: 0.2rem;
+      cursor: pointer;
+    }
+    .catalogInput {
+      width: 170px;
+      .el-input__inner {
+        height: 2rem;
+        border: 1px solid #d3d3d3;
+        float: left;
+        border-radius: 0.2rem;
+        text-indent: 0.5rem;
+        padding: 0 10px;
+      }
+    }
+  }
+
+  .footerbox_b {
+    margin-top: 2rem;
+    border: 1px solid #dbdbdb;
+    // padding: 0rem 2rem;
+    margin-bottom: 3rem;
+  }
+  .footerbox_b > p {
+    font-size: 1.4rem;
+    padding: 1.5rem 2rem;
+    font-weight: 700;
+    color: #005bab;
+    background: #cfe0ef;
+    margin-bottom: 1.5rem;
+  }
+  .footerbox {
+    padding: 0rem 2rem;
+    overflow: hidden;
+  }
+  .footerbox > div {
+    position: relative;
+    margin-bottom: 1.4rem;
+  }
+  .inputbox {
+    width: 100%;
+  }
+  .footerbox > div > .red-t {
+    font-size: 1.5rem;
+    color: #e52323;
+    position: absolute;
+    top: 40%;
+    left: -1rem;
+  }
+  .buttonbox {
+    width: 100%;
+    background: #0166b4;
+    height: 3rem;
+    padding: 0;
+    margin-bottom: 2rem;
+  }
+}
+
+@media screen and (min-width: 0px) and (max-width: 750px) {
+  .topbox {
+    margin-bottom: 0.2rem;
+    font-size: 0.18rem;
+    // font-weight: 700;
+  }
+  .contentbox {
+    width: 100%;
+    overflow: hidden;
+  }
+  .topcontentbox {
+    border: 1px solid #dbdbdb;
+  }
+  .topcontentbox > p:nth-of-type(1) {
+    font-size: 0.16rem;
+    padding: 0.14rem 0.23rem;
+    font-weight: 700;
+    color: #005bab;
+    background: #cfe0ef;
+  }
+  .topcontentbox > p:nth-of-type(2) {
+    padding: 0.14rem;
+    font-size: 0.16rem;
+    color: #005bab;
+    word-wrap: break-word;
+    word-break: normal;
+  }
+
+  .bottomcontentbox_b {
+    margin-top: 0.2rem;
+    border: 1px solid #dbdbdb;
+    // padding: 0rem 2rem;
+  }
+  .bottomcontentbox_b > p {
+    font-size: 0.16rem;
+    padding: 0.14rem 0.23rem;
+    font-weight: 700;
+    color: #005bab;
+    background: #cfe0ef;
+    margin-bottom: 0.14rem;
+  }
+  .bottomcontentbox /deep/ {
+    // margin-top: 2rem;
+    padding: 0rem 0.14rem;
+    overflow: hidden;
+    .el-table {
+      border: 1px solid #dfdfdf;
+      margin-top: 0.12rem !important ;
+      margin-bottom: 0.14rem !important ;
+      .el-table__header-wrapper {
+        width: 100%;
+        .el-table__header {
+          width: 100% !important;
+          colgroup {
+            // col{
+            //   width: 20% !important;
+            // }
+            col:nth-of-type(1) {
+              width: 17% !important;
+            }
+            col:nth-of-type(2) {
+              width: 17% !important;
+            }
+            col:nth-of-type(3) {
+              width: 28% !important;
+            }
+            col:nth-of-type(4) {
+              width: 24% !important;
+            }
+            col:nth-of-type(5) {
+              width: 14% !important;
+            }
+          }
+          thead {
+            tr {
+              width: 60px !important;
+              th {
+                width: 60px !important;
+                .cell {
+                  font-size: 12px;
+                  padding: 0 4px;
+                  font-family: Arial;
+                  font-weight: bold;
+                  color: #005bab;
+                }
+              }
+            }
+          }
+        }
+      }
+      .el-table__body-wrapper {
+        .el-table__body {
+          width: 100% !important;
+          colgroup {
+            width: 100% !important;
+            col:nth-of-type(1) {
+              width: 17% !important;
+            }
+            col:nth-of-type(2) {
+              width: 17% !important;
+            }
+            col:nth-of-type(3) {
+              width: 28% !important;
+            }
+            col:nth-of-type(4) {
+              width: 24% !important;
+            }
+            col:nth-of-type(5) {
+              width: 14% !important;
+            }
+          }
+          tbody {
+            .el-table__row {
+              .el-table__cell {
+                &:nth-of-type(1) {
+                  .cell {
+                    font-family: Arial;
+                    color: #005bab;
+                  }
+                }
+                .cell {
+                  font-size: 12px;
+                  padding: 0 4px;
+                  line-height: 0.24rem;
+                  .size_data {
+                    .size_q {
+                      width: 40% !important;
+                      max-width: 100px;
+                      .el-input__inner {
+                        width: 100% !important;
+                      }
+                    }
+                    .el-select {
+                      max-width: 100px;
+                      width: 60% !important;
+                      .el-input__inner {
+                        padding-right: 16px;
+                      }
+                      .el-input__suffix {
+                        .el-select__caret {
+                          width: 16px;
+                        }
+                      }
+                    }
+                  }
+                  .el-input-number {
+                    .el-input-number__decrease {
+                      width: 0.16rem;
+                    }
+                    .el-input-number__increase {
+                      width: 0.16rem;
+                    }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+      .el-table__empty-block {
+        width: 100% !important;
+      }
+    }
+
+    .size_data {
+      display: flex;
+      align-items: center;
+      .size_q {
+        width: 0.4rem;
+        .el-input__inner {
+          height: 0.24rem;
+          border: 1px solid #dfdfdf;
+          line-height: 0.24rem;
+          padding: 0 0.03rem;
+          width: 0.4rem;
+          // border-radius: 0.2rem;
+        }
+      }
+      .el-select {
+        width: 0.6rem;
+        .el-input__inner {
+          height: 0.24rem;
+          line-height: 0.24rem;
+          padding-left: 0.05rem;
+        }
+        .el-input__icon {
+          line-height: 0.24rem;
+        }
+      }
+    }
+    .el-input-number {
+      width: 100%;
+      .el-input-number__decrease {
+        width: 0.24rem;
+        height: 0.22rem;
+        line-height: 0.22rem;
+        top: 7px;
+      }
+      .el-input-number__increase {
+        width: 0.24rem;
+        height: 0.22rem;
+        line-height: 0.22rem;
+        top: 7px;
+      }
+      .el-input {
+        .el-input__inner {
+          height: 0.26rem;
+          line-height: 0.26rem;
+          padding: 0 0.24rem;
+          border: 1px solid #dfdfdf;
+          &:focus {
+            border: 1px solid #dfdfdf;
+          }
+        }
+      }
+    }
+  }
+
+  .input_box /deep/ {
+    display: flex;
+    align-items: center;
+    & > span:nth-of-type(1) {
+      font-size: 0.12rem;
+      float: left;
+      color: #005bab;
+      margin-right: 0.1rem;
+    }
+    & > span:nth-of-type(2) {
+      // padding: 0 1rem;
+      line-height: 0.28rem;
+      height: 0.28rem;
+      border: 1px solid #d3d3d3;
+      // float: left;
+      display: inline-block;
+      background: #005bab;
+      color: white;
+      cursor: pointer;
+      padding: 0 0.1rem;
+    }
+    .catalogInput {
+      width: 1rem;
+      .el-input__inner {
+        height: 0.28rem;
+        line-height: 0.28rem;
+        // border: none;
+        float: left;
+        padding: 0 0.1rem;
+      }
+    }
+  }
+
+  .footerbox_b {
+    margin-top: 0.2rem;
+    border: 1px solid #dbdbdb;
+    // padding: 0rem 2rem;
+  }
+  .footerbox_b > p {
+    font-size: 0.16rem;
+    padding: 0.14rem 0.23rem;
+    font-weight: 700;
+    color: #005bab;
+    background: #cfe0ef;
+  }
+  .footerbox {
+    margin-top: 0.14rem;
+    padding: 0rem 0.14rem;
+    overflow: hidden;
+  }
+  .footerbox > div {
+    position: relative;
+    margin-bottom: 0.15rem;
+    margin-left: 0.1rem;
+  }
+  .inputbox {
+    width: 100%;
+  }
+  .footerbox > div > .red-t {
+    font-size: 0.2rem;
+    color: #e52323;
+    position: absolute;
+    top: 40%;
+    left: -0.1rem;
+  }
+  .buttonbox {
+    width: 100%;
+    background: #0166b4;
+    height: 0.4rem;
+    padding: 0;
+    margin-bottom: 0.14rem;
+  }
+  .sample_info {
+    display: inline-block;
+    span {
+      font-size: 0.12rem;
+    }
+  }
+}
+</style>

+ 332 - 0
src/view/landing/index.vue

@@ -0,0 +1,332 @@
+<template>
+  <div class="boxlongin">
+    <div class="box">
+      <div class="contentbox">
+        <!-- <div class="rightcenterbox_b">
+          <p class="rightcenterbox_t">{{$t('landing.Solutions')}}</p>
+          <p class="rightcenterbox_m">{{$t('landing.providing')}}</p>
+        </div> -->
+  
+        <div class="footerbox">
+          <div class="topbox">
+            {{$t('landing.WELCOME')}}
+          </div>
+          <div class="taps_footerbox">
+            <el-input class="inputbox" v-model="username" :placeholder="$t('input.email')"></el-input>
+          </div>
+          <div class="taps_footerbox">
+            <el-input class="inputbox" v-model="password" show-password :placeholder="$t('landing.Please')"></el-input>
+          </div>
+          <div class="register_box">
+            <el-checkbox v-model="checked"></el-checkbox>
+            <span>{{$t('landing.Login')}}</span>
+          </div>
+          <el-button class="buttonbox_taps" type="primary"  v-loading.fullscreen.lock="fullscreenLoading" @click="tapUser">{{$t('landing.Sign')}}</el-button>
+          <el-button class="buttonbox_tapf" type="primary" @click="$router.push({name: 'register'})">
+            {{$t('landing.Register')}}
+          </el-button>
+          <div class="register_footer">
+            <div class="register_hen"></div>
+            <p class="register_password" @click="gotoappli">{{$t('landing.password')}}</p>
+            <div class="register_hen"></div>
+          </div>
+        </div>
+      </div>
+  
+    </div>
+  </div>
+  </template>
+  <script>
+  export default {
+    name: "landing",
+    data () {
+      return {
+        fullscreenLoading: false,
+        checked: true,
+        username: "",
+        password: "",
+        type: this.$route.query.type
+      }
+    },
+    methods: {
+      tapUser () { // 登录
+        if (!this.username) {
+          this.$message.error(this.$t('message.beEmpty'))
+          return false
+        } else if (!this.$util.isEmail(this.username)) {
+          this.$message.error(this.$t('input.email') + this.$t('message.email'))
+          return false
+        } else if (!this.password) {
+          this.$message.error(this.$t('register.Password')+this.$t('register.Cannot'))
+          return false
+        }
+        this.fullscreenLoading = true;
+        this.$api.post('auth/login', {
+          username: this.username,
+          password: this.password
+        }).then((res) => {
+          if (res.code == 0) {
+            this.fullscreenLoading = false;
+            this.$store.commit("setToken", JSON.stringify(res.data.token))
+            this.$store.commit("setUserInfo", JSON.stringify(res.data.user))
+            localStorage.setItem("token", JSON.stringify(res.data.token))
+            localStorage.setItem('user', JSON.stringify(res.data.user))
+            this.getinfo()
+            // this.getIndex()
+          } else if (res.code == 5000) {
+            this.fullscreenLoading = false;
+            this.$message(this.$t('message.passwordError'))
+          } else if (res.code == 406) {
+            this.fullscreenLoading = false;
+            this.$message(this.$t('message.notActivated'))
+          } else {
+            this.fullscreenLoading = false;
+            this.$message(res.msg)
+          }
+        })
+      },
+      gotoappli () {
+        this.$router.push({
+          name: 'application'
+        })
+      },
+      getinfo () {
+        this.$api.post('auth/info').then((res) => {
+          if (res.code == 0) {
+            localStorage.setItem('info', JSON.stringify(res.data))
+            // sessionStorage.setItem('user', JSON.stringify(res.data.user))
+            if (this.type == 1) {
+              if (!this.$util.isMobileDevice()) {
+                this.$router.back()
+              } else {
+                this.$router.push({
+                  path: "/AntigenPreparation"
+                })
+              }
+            } else {
+              this.$router.push({
+                name: 'home'
+              })
+            }
+          }
+        })
+      },
+      getIndex () { // 获取购物车数量
+        let that = this
+        let data = JSON.parse(localStorage.getItem('shoppingCart'))
+        let arry = []
+        if (data && data.length > 0) {
+          data.forEach((item) => {
+            var obj = {'checked': true, 'id': item.id, 'number': item.number, 'productCatalog': item.productCatalog, 'skuId': item.skuId}
+            arry.push(obj)
+          })
+        } else {
+          arry = null
+        }
+        this.$api.post('cart/index', {
+          cartList: arry
+        }).then((res) => {
+          if (res.code == 0) {
+            localStorage.removeItem('shoppingCart')
+            localStorage.setItem('shoppingNum', JSON.stringify(res.data.cartList.length))
+          }
+        })
+      }
+    },
+    mounted () {
+    },
+    created () {
+    }
+  }
+  </script>
+  <style lang="scss" scoped>
+  @media screen and (min-width: 751px) and (max-width: 9999px) {
+    .header_box /deep/{
+      .crumbs_box{
+        display: none;
+      }
+    }
+  .box{
+    overflow: hidden;
+    // background-image: url('~@/assets/img/responsive-home-1.png');
+    background-image: url('~@/assets/img/homeImg.jpg');
+    background-repeat: no-repeat;
+    background-size: 100% 100%;
+  }
+  .contentbox{
+    width: 1200px;
+    overflow: hidden;
+    margin: 0 auto;
+  }
+  .footerbox{
+    width: 35%;
+    float: right;
+    padding: 2.4rem 2.2rem;
+    margin-top: 7rem;
+    margin-bottom: 7rem;
+    margin-right: 6rem;
+    background: #ffffff;
+    .topbox{
+      margin-bottom: 1.8rem;
+      font-size:  1.4rem;
+      color: #005BAB;
+      font-weight: 600;
+      text-align: center;
+      }
+    .taps_footerbox{
+      margin-bottom: 1.4rem;
+      .inputbox{
+        width: 100%;
+      }
+    }
+      .buttonbox_taps{
+        width: 100%;
+        background: rgba(0, 91, 171, 0.5);
+        height: 3rem;
+        padding: 0;
+        margin-top: 1rem;
+      }
+      .buttonbox_tapf{
+        width: 100%;
+        background: #ffffff;
+        color: #005BAB !important;
+        border: 1px solid #005BAB;
+        height: 3rem;
+        padding: 0;
+        margin-top: 1rem;
+        margin-left: 0;
+        .register_a{
+          text-decoration: none;
+          color: #005BAB !important;
+        }
+      }
+      .register_footer{
+        margin-top: 1.2rem;
+        display: flex;
+        align-items: center;
+        justify-content: space-between;
+        .register_hen{
+          width: 4.8rem;
+          height: 1px;
+          background: #DBDBDB;
+        }
+        .register_password{
+          color: #6F6F6F;
+          font-size: 1rem;
+          cursor: pointer;
+        }
+      }
+    }
+  
+  .register_box{
+    margin-top: 0.6rem;
+  }
+  
+  .rightcenterbox_b{
+    margin-top: 10rem;
+    width: 45%;
+    float: left;
+    font-size: 0.16rem;
+    .rightcenterbox_t{
+      font-size: 2.6rem;
+      color: #000000;
+    }
+    .rightcenterbox_m{
+      margin-top: 1rem;
+      font-size: 1.2rem;
+      color: #000000;
+      word-wrap: break-word;
+      word-break: normal;
+    }
+  }
+  
+  }
+  
+  
+  @media screen and (min-width: 0px) and (max-width: 750px) {
+    .boxlongin{
+      height: 100%;
+      display: flex;
+      flex-direction: column;
+    }
+    .header_box /deep/{
+      .crumbs_box{
+        display: none;
+      }
+    }
+  .box{
+    flex: 1;
+    overflow: hidden;
+  }
+  .contentbox{
+    overflow: hidden;
+    margin-top: 0.2rem;
+    margin-bottom: 0.3rem;
+  }
+  .footerbox{
+    width: 90%;
+    margin: 0 auto;
+    overflow: hidden;
+    background: #ffffff;
+    .topbox{
+      margin-bottom: 0.24rem;
+      font-size:  0.2rem;
+      color: #005BAB;
+      font-weight: 600;
+      text-align: center;
+      }
+    .taps_footerbox{
+      margin-bottom: 0.22rem;
+      .inputbox{
+        width: 100%;
+      }
+    }
+      .buttonbox_taps{
+        width: 100%;
+        background: rgba(0, 91, 171, 0.5);
+        height: 0.36rem;
+        padding: 0;
+        margin-top: 0.23rem;
+        font-size: 0.16rem;
+      }
+      .buttonbox_tapf{
+        width: 100%;
+        background: #ffffff;
+        color: #005BAB;
+        border: 1px solid #005BAB;
+        height: 0.36rem;
+        padding: 0;
+        margin-top: 0.12rem;
+        margin-left: 0;
+        font-size: 0.16rem;
+        .register_a{
+          text-decoration: none;
+          color: #005BAB;
+        }
+      }
+      .register_footer{
+        margin-top: 0.16rem;
+        display: flex;
+        align-items: center;
+        justify-content: space-between;
+        .register_hen{
+          width: 0.56rem;
+          height: 1px;
+          background: #DBDBDB;
+        }
+        .register_password{
+          color: #6F6F6F;
+          font-size: 0.12rem;
+          cursor: pointer;
+        }
+      }
+    }
+  
+  
+  .rightcenterbox_b{
+    display: none;
+  }
+  
+  }
+  </style>
+  

File diff suppressed because it is too large
+ 20 - 0
src/view/privacyPolicy/index.vue


+ 311 - 0
src/view/product/components/AntibodyInfo.vue

@@ -0,0 +1,311 @@
+<template>
+  <div>
+    <div class="detail-table pc" :class="{ env_en: !!$util.localeStorage() }">
+      <div class="table_th">
+        <div class="table_td">{{ $t("newProduct.target") }}</div>
+        <div class="table_td">
+          {{ $util.targetDictionaries(list.target) }}
+        </div>
+        <div class="table_td">{{ $t("newProduct.catalog") }}</div>
+        <div class="table_td">{{ list.catalog }}</div>
+      </div>
+      <div class="table_th">
+        <div class="table_td">{{ $t("newProduct.targetAccession") }}</div>
+        <div class="table_td">{{ list.source }}</div>
+        <div class="table_td">{{ $t("newProduct.concentration") }}</div>
+        <div class="table_td">{{ list.concentration }}</div>
+      </div>
+      <div class="table_th">
+        <div class="table_td">{{ $t("newProduct.clonality") }}</div>
+        <div class="table_td">{{ list.clonality }}</div>
+        <div class="table_td">{{ $t("newProduct.format") }}</div>
+        <div class="table_td">
+          {{ $util.findAllCategory("Antibody_format", list.format) }}
+        </div>
+      </div>
+      <div class="table_th">
+        <div class="table_td">{{ $t("newProduct.reactivity") }}</div>
+        <div class="table_td">{{ list.reactivity }}</div>
+        <div class="table_td">{{ $t("newProduct.molecularWeight") }}</div>
+        <div class="table_td">{{ list.molecularWeight }}</div>
+      </div>
+      <div class="table_th">
+        <div class="table_td">{{ $t("newProduct.application") }}</div>
+        <div class="table_td">
+          {{ $util.findAllCategory("Antibody_feature", list.feature) }}
+        </div>
+        <div class="table_td">{{ $t("newProduct.endotoxin") }}</div>
+        <div class="table_td">
+          <!-- {{ list.endotoxin }} -->
+          <0.001 EU/μg
+        </div>
+      </div>
+      <div class="table_th">
+        <div class="table_td">{{ $t("newProduct.formulation") }}</div>
+        <div class="table_td">{{ list.formulation }}</div>
+        <div class="table_td">{{ $t("newProduct.conjugation") }}</div>
+        <div class="table_td">{{ list.conjugation }}</div>
+      </div>
+      <div class="table_th">
+        <div class="table_td">{{ $t("newProduct.reconstitution") }}</div>
+        <div class="table_td">{{ list.reconstitution }}</div>
+        <div class="table_td">{{ $t("newProduct.host") }}</div>
+        <div class="table_td">
+          {{ $util.findAllCategory("Antibody_host", list.host) }}
+        </div>
+      </div>
+      <div class="table_th">
+        <div class="table_td">{{ $t("newProduct.storage") }}</div>
+        <div class="table_td">
+          {{ list.storage }}
+        </div>
+        <div class="table_td">{{ $t("newProduct.purification") }}</div>
+        <div class="table_td">{{ list.purification }}</div>
+      </div>
+    </div>
+    <div
+      class="detail-table mobile"
+      :class="{ env_en: !!$util.localeStorage() }"
+    >
+      <div class="table_th">
+        <div class="table_td">{{ $t("newProduct.target") }}</div>
+        <div class="table_td">
+          {{ $util.targetDictionaries(list.target) }}
+        </div>
+      </div>
+      <div class="table_th">
+        <div class="table_td">{{ $t("newProduct.targetAccession") }}</div>
+        <div class="table_td">{{ list.source }}</div>
+      </div>
+      <div class="table_th">
+        <div class="table_td">{{ $t("newProduct.clonality") }}</div>
+        <div class="table_td">{{ list.clonality }}</div>
+      </div>
+      <div class="table_th">
+        <div class="table_td">{{ $t("newProduct.reactivity") }}</div>
+        <div class="table_td">{{ list.reactivity }}</div>
+      </div>
+      <div class="table_th">
+        <div class="table_td">{{ $t("newProduct.application") }}</div>
+        <div class="table_td">
+          {{ $util.findAllCategory("Antibody_feature", list.feature) }}
+        </div>
+      </div>
+      <div class="table_th">
+        <div class="table_td">{{ $t("newProduct.formulation") }}</div>
+        <div class="table_td">{{ list.formulation }}</div>
+      </div>
+      <div class="table_th">
+        <div class="table_td">{{ $t("newProduct.reconstitution") }}</div>
+        <div class="table_td">{{ list.reconstitution }}</div>
+      </div>
+      <div class="table_th">
+        <div class="table_td">{{ $t("newProduct.storage") }}</div>
+        <div class="table_td">
+          {{ list.storage }}
+        </div>
+      </div>
+      <div class="table_th">
+        <div class="table_td">{{ $t("newProduct.catalog") }}</div>
+        <div class="table_td">{{ list.catalog }}</div>
+      </div>
+      <div class="table_th">
+        <div class="table_td">{{ $t("newProduct.concentration") }}</div>
+        <div class="table_td">{{ list.concentration }}</div>
+      </div>
+      <div class="table_th">
+        <div class="table_td">{{ $t("newProduct.format") }}</div>
+        <div class="table_td">
+          {{ $util.findAllCategory("Antibody_format", list.format) }}
+        </div>
+      </div>
+      <div class="table_th">
+        <div class="table_td">{{ $t("newProduct.molecularWeight") }}</div>
+        <div class="table_td">{{ list.molecularWeight }}</div>
+      </div>
+      <div class="table_th">
+        <div class="table_td">{{ $t("newProduct.endotoxin") }}</div>
+        <div class="table_td">
+          <!-- {{ list.endotoxin }} -->
+          <0.001 EU/μg
+        </div>
+      </div>
+      <div class="table_th">
+        <div class="table_td">{{ $t("newProduct.conjugation") }}</div>
+        <div class="table_td">{{ list.conjugation }}</div>
+      </div>
+      <div class="table_th">
+        <div class="table_td">{{ $t("newProduct.host") }}</div>
+        <div class="table_td">
+          {{ $util.findAllCategory("Antibody_host", list.host) }}
+        </div>
+      </div>
+      <div class="table_th">
+        <div class="table_td">{{ $t("newProduct.purification") }}</div>
+        <div class="table_td">{{ list.purification }}</div>
+      </div>
+    </div>
+  </div>
+</template>
+<script>
+export default {
+  name: "info",
+  props: {
+    list: {
+      type: Object,
+      required: true
+    }
+  },
+  data() {
+    return {};
+  },
+  methods: {},
+  mounted() {},
+  created() {}
+};
+</script>
+<style lang="scss" scoped>
+@media screen and (min-width: 751px) and (max-width: 9999px) {
+  .pc {
+    display: block !important;
+
+    &.env_en {
+      .table_th {
+        .table_td {
+          &:nth-child(1) {
+            width: 141px !important;
+          }
+          &:nth-child(3) {
+            width: 181px !important;
+          }
+        }
+      }
+    }
+  }
+
+  .mobile {
+    display: none !important;
+  }
+
+  .detail-table {
+    width: 100%;
+    margin-bottom: 1rem;
+    overflow-x: auto;
+    border-top: 1px solid #0166b4;
+    color: #6f6f6f;
+    font-size: 14px;
+    border-bottom: 1px solid #d6eaff;
+
+    .table_th {
+      width: 100%;
+      // height: 36px;
+      display: flex;
+      // align-items: center;
+      justify-content: space-between;
+      // border-bottom: 1px solid #d6eaff;
+
+      &:nth-child(even) {
+        background-color: #f4faff;
+      }
+
+      .table_td {
+        // height: 36px;
+        line-height: 24px;
+        // text-indent: 12px;
+        padding: 10px;
+
+        &:nth-child(1) {
+          width: 100px;
+          &::after {
+            content: ":";
+          }
+        }
+        &:nth-child(2) {
+          flex: 3;
+          color: #313131;
+        }
+        &:nth-child(3) {
+          width: 110px;
+          &::after {
+            content: ":";
+          }
+        }
+        &:nth-child(4) {
+          flex: 1;
+          color: #313131;
+        }
+
+        &:not(:last-child) {
+          border-right: 1px solid #d6eaff;
+        }
+      }
+    }
+  }
+}
+
+@media screen and (min-width: 0px) and (max-width: 750px) {
+  .pc {
+    display: none !important;
+  }
+
+  .mobile {
+    display: flex !important;
+
+    &.env_en {
+      .table_th {
+        .table_td {
+          &:nth-child(1) {
+            width: 181px !important;
+          }
+        }
+      }
+    }
+  }
+
+  .detail-table {
+    margin-top: 0.4rem;
+    width: 100%;
+    border-top: 1px solid #0166b4;
+    color: #6f6f6f;
+    font-size: 14px;
+    border-bottom: 1px solid #d6eaff;
+    display: flex;
+    flex-direction: column;
+
+    .table_th {
+      width: 100%;
+      // height: 36px;
+      display: flex;
+      // align-items: center;
+      justify-content: space-between;
+      // border-bottom: 1px solid #d6eaff;
+
+      &:nth-child(even) {
+        background-color: #f4faff;
+      }
+
+      .table_td {
+        // height: 36px;
+        line-height: 24px;
+        // text-indent: 12px;
+        padding: 10px;
+
+        &:nth-child(1) {
+          width: 105px;
+          &::after {
+            content: ":";
+          }
+        }
+        &:nth-child(2) {
+          flex: 3;
+          color: #313131;
+        }
+
+        &:not(:last-child) {
+          border-right: 1px solid #d6eaff;
+        }
+      }
+    }
+  }
+}
+</style>

+ 335 - 0
src/view/product/components/CellLineInfo.vue

@@ -0,0 +1,335 @@
+<template>
+  <div>
+    <div class="detail-table pc" :class="{ env_en: !!$util.localeStorage() }">
+      <div class="table_th">
+        <div class="table_td">{{ $t("newProduct.target") }}</div>
+        <div class="table_td">
+          {{ $util.targetDictionaries(list.target) }}
+        </div>
+        <div class="table_td">{{ $t("table.Species") }}</div>
+        <div class="table_td">
+          {{ $util.findAllCategory("CellLine_species", list.species) }}
+        </div>
+      </div>
+      <div class="table_th">
+        <div class="table_td">{{ $t("newProduct.catalog") }}</div>
+        <div class="table_td">{{ list.catalog }}</div>
+        <div class="table_td">{{ $t("table.CellType") }}</div>
+        <div class="table_td">
+          {{ $util.findAllCategory("CellLine_subType", list.subType) }}
+        </div>
+      </div>
+      <div class="table_th">
+        <div class="table_td">{{ $t("newProduct.productFormat") }}</div>
+        <div class="table_td">{{ list.productFormat }}</div>
+        <!-- <div class="table_td">{{ $t("newProduct.lotNo") }}</div>
+        <div class="table_td">{{ list.lotNo }}??</div> -->
+        <div class="table_td">{{ $t("newProduct.biosafety") }}</div>
+        <div class="table_td">
+          <!-- {{ list.biosafety }} -->
+          BSL-1
+        </div>
+      </div>
+      <div class="table_th">
+        <!-- <div class="table_td">{{ $t("newProduct.productFormat") }}</div>
+        <div class="table_td">{{ list.productFormat }}</div> -->
+        <div class="table_td">{{ $t("newProduct.cultureMedium") }}</div>
+        <div class="table_td">{{ list.medium }}</div>
+        <div class="table_td">{{ $t("newProduct.morphology") }}</div>
+        <div class="table_td">{{ list.morphology }}</div>
+      </div>
+
+      <div class="table_th">
+        <div class="table_td">{{ $t("newProduct.storage") }}</div>
+        <div class="table_td">{{ list.storage }}</div>
+        <div class="table_td">{{ $t("newProduct.growthProperties") }}</div>
+        <div class="table_td">
+          {{ list.growth }}
+        </div>
+      </div>
+      <div class="table_th">
+        <div class="table_td">{{ $t("newProduct.cellsPerVial") }}</div>
+        <!-- <div class="table_td">{{ list.cellsPerVial }}</div> -->
+        <div class="table_td">Approximately 5E6 cells/vial</div>
+        <div class="table_td">{{ $t("table.FluorescentLabel") }}</div>
+        <div class="table_td">
+          {{
+            $util.findAllCategory(
+              "CellLine_labeling",
+              list.fluorescenceLabeling
+            )
+          }}
+        </div>
+      </div>
+      <div class="table_th">
+        <div class="table_td">{{ $t("newProduct.cryopreservation") }}</div>
+        <div class="table_td">{{ list.cryopreservation }}</div>
+        <div class="table_td">{{ $t("newProduct.mycoplasma") }}</div>
+        <!-- <div class="table_td">{{ list.mycoplasma }}</div> -->
+        <div class="table_td">Negative</div>
+      </div>
+      <div class="table_th">
+        <!-- <div class="table_td">{{ $t("newProduct.cultureMedium") }}</div>
+        <div class="table_td">{{ list.medium }}</div> -->
+        <!-- <div class="table_td">{{ $t("newProduct.biosafety") }}</div>
+        <div class="table_td">{{ list.biosafety }}</div> -->
+        <!-- <div class="table_td none_after"></div>
+        <div class="table_td"></div> -->
+      </div>
+    </div>
+    <div
+      class="detail-table mobile"
+      :class="{ env_en: !!$util.localeStorage() }"
+    >
+      <!-- <div class="table_th">
+        <div class="table_td">{{ $t("table.productName") }}</div>
+        <div class="table_td">{{ list.productName }}</div>
+      </div> -->
+      <div class="table_th">
+        <div class="table_td">{{ $t("newProduct.catalog") }}</div>
+        <div class="table_td">{{ list.catalog }}</div>
+      </div>
+      <div class="table_th">
+        <div class="table_td">{{ $t("newProduct.target") }}</div>
+        <div class="table_td">
+          {{ $util.targetDictionaries(list.target) }}
+        </div>
+      </div>
+      <div class="table_th">
+        <div class="table_td">{{ $t("newProduct.productFormat") }}</div>
+        <div class="table_td">{{ list.productFormat }}</div>
+      </div>
+      <div class="table_th">
+        <div class="table_td">{{ $t("newProduct.storage") }}</div>
+        <div class="table_td">{{ list.storage }}</div>
+      </div>
+      <div class="table_th">
+        <div class="table_td">{{ $t("newProduct.cellsPerVial") }}</div>
+        <!-- <div class="table_td">{{ list.cellsPerVial }}</div> -->
+        <div class="table_td">Approximately 5E6 cells/vial</div>
+      </div>
+      <div class="table_th">
+        <div class="table_td">{{ $t("newProduct.cryopreservation") }}</div>
+        <div class="table_td">{{ list.cryopreservation }}</div>
+      </div>
+      <div class="table_th">
+        <div class="table_td">{{ $t("newProduct.cultureMedium") }}</div>
+        <div class="table_td">{{ list.medium }}</div>
+      </div>
+      <div class="table_th">
+        <div class="table_td">{{ $t("table.Species") }}</div>
+        <div class="table_td">
+          {{ $util.findAllCategory("CellLine_species", list.species) }}
+        </div>
+      </div>
+      <div class="table_th">
+        <!-- <div class="table_td">{{ $t("newProduct.lotNo") }}</div>
+        <div class="table_td">{{ list.lotNo }}??</div> -->
+        <div class="table_td">{{ $t("newProduct.biosafety") }}</div>
+        <div class="table_td">{{ list.biosafety }}</div>
+      </div>
+      <div class="table_th">
+        <div class="table_td">{{ $t("table.CellType") }}</div>
+        <div class="table_td">
+          {{ $util.findAllCategory("CellLine_subType", list.subType) }}
+        </div>
+      </div>
+      <div class="table_th">
+        <div class="table_td">{{ $t("newProduct.morphology") }}</div>
+        <div class="table_td">{{ list.morphology }}</div>
+      </div>
+      <div class="table_th">
+        <div class="table_td">{{ $t("newProduct.growthProperties") }}</div>
+        <div class="table_td">
+          {{ list.growth }}
+        </div>
+      </div>
+      <div class="table_th">
+        <div class="table_td">{{ $t("table.FluorescentLabel") }}</div>
+        <div class="table_td">
+          {{
+            $util.findAllCategory(
+              "CellLine_labeling",
+              list.fluorescenceLabeling
+            )
+          }}
+        </div>
+      </div>
+      <div class="table_th">
+        <div class="table_td">{{ $t("newProduct.mycoplasma") }}</div>
+        <!-- <div class="table_td">{{ list.mycoplasma }}</div> -->
+        <div class="table_td">Negative</div>
+      </div>
+      <!-- <div class="table_th">
+        <div class="table_td">{{ $t("newProduct.biosafety") }}</div>
+        <div class="table_td">{{ list.biosafety }}</div>
+      </div> -->
+    </div>
+  </div>
+</template>
+<script>
+export default {
+  name: "info",
+  props: {
+    list: {
+      type: Object,
+      required: true
+    }
+  },
+  data() {
+    return {};
+  },
+  methods: {},
+  mounted() {},
+  created() {}
+};
+</script>
+<style lang="scss" scoped>
+@media screen and (min-width: 751px) and (max-width: 9999px) {
+  .pc {
+    display: block !important;
+
+    &.env_en {
+      .table_th {
+        .table_td {
+          &:nth-child(1) {
+            width: 142px !important;
+          }
+          &:nth-child(3) {
+            width: 148px !important;
+          }
+        }
+      }
+    }
+  }
+
+  .mobile {
+    display: none !important;
+  }
+
+  .detail-table {
+    width: 100%;
+    margin-bottom: 1rem;
+    overflow-x: auto;
+    border-top: 1px solid #0166b4;
+    color: #6f6f6f;
+    font-size: 14px;
+    border-bottom: 1px solid #d6eaff;
+
+    .table_th {
+      width: 100%;
+      // height: 36px;
+      display: flex;
+      // align-items: center;
+      justify-content: space-between;
+      // border-bottom: 1px solid #d6eaff;
+
+      &:nth-child(even) {
+        background-color: #f4faff;
+      }
+
+      .table_td {
+        // height: 36px;
+        line-height: 24px;
+        // text-indent: 12px;
+        padding: 10px;
+
+        &.none_after::after {
+          content: "" !important;
+        }
+
+        &:nth-child(1) {
+          width: 109px;
+          &::after {
+            content: ":";
+          }
+        }
+        &:nth-child(2) {
+          flex: 3;
+          color: #313131;
+        }
+        &:nth-child(3) {
+          width: 119px;
+          &::after {
+            content: ":";
+          }
+        }
+        &:nth-child(4) {
+          flex: 1;
+          color: #313131;
+        }
+
+        &:not(:last-child) {
+          border-right: 1px solid #d6eaff;
+        }
+      }
+    }
+  }
+}
+
+@media screen and (min-width: 0px) and (max-width: 750px) {
+  .pc {
+    display: none !important;
+  }
+
+  .mobile {
+    display: flex !important;
+
+    &.env_en {
+      .table_th {
+        .table_td {
+          &:nth-child(1) {
+            width: 148px !important;
+          }
+        }
+      }
+    }
+  }
+
+  .detail-table {
+    margin-top: 0.4rem;
+    width: 100%;
+    border-top: 1px solid #0166b4;
+    color: #6f6f6f;
+    font-size: 14px;
+    border-bottom: 1px solid #d6eaff;
+    display: flex;
+    flex-direction: column;
+
+    .table_th {
+      width: 100%;
+      // height: 36px;
+      display: flex;
+      // align-items: center;
+      justify-content: space-between;
+      // border-bottom: 1px solid #d6eaff;
+
+      &:nth-child(even) {
+        background-color: #f4faff;
+      }
+
+      .table_td {
+        // height: 36px;
+        line-height: 24px;
+        // text-indent: 12px;
+        padding: 10px;
+
+        &:nth-child(1) {
+          width: 119px;
+          &::after {
+            content: ":";
+          }
+        }
+        &:nth-child(2) {
+          flex: 3;
+          color: #313131;
+        }
+
+        &:not(:last-child) {
+          border-right: 1px solid #d6eaff;
+        }
+      }
+    }
+  }
+}
+</style>

+ 668 - 0
src/view/product/components/PriceTable.vue

@@ -0,0 +1,668 @@
+<template>
+  <div class="size-price">
+    <div class="size-price-table">
+      <div class="table_th header">
+        <template v-if="skuList.length == 0">
+          <div class="th">{{ $t("bottomBar.Size") }}</div>
+          <div class="th">{{ $t("bottomBar.Stock") }}</div>
+        </template>
+        <template v-else>
+          <div class="th">{{ $t("bottomBar.Size") }}</div>
+          <div class="th">
+            {{ $t("bottomBar.Price") }}({{ $t("bottomBar.money") }})
+          </div>
+          <div class="th">{{ $t("bottomBar.Quantity") }}</div>
+        </template>
+      </div>
+      <div class="table_th table_t" v-for="one in skuList" :key="one.id">
+        <div class="td">{{ one.specifications }}</div>
+        <div class="td td_h" v-if="$util.localeStorage()">
+          {{ one.price }}
+        </div>
+        <div class="td td_h" v-if="!$util.localeStorage()">
+          {{ one.cnPrice }}
+        </div>
+        <!-- <div class="td">{{one.number}}</div> -->
+        <div class="td">
+          <el-input-number
+            v-model="one.num"
+            :min="0"
+            :max="10"
+            label=""
+            @change="changeNum"
+          />
+        </div>
+      </div>
+      <div class="table_th table_t" v-if="totalNum > 10">
+        <div class="td">{{ $t("table.packaging") }}</div>
+        <div class="td td_b" @click="
+              $util.goRoute({
+                name: 'inquiry',
+                query: { catalog: catalog }
+              })
+            ">
+          {{ $t("table.inquiry") }}
+        </div>
+        <div class="td"></div>
+      </div>
+      <template v-if="skuList.length == 0">
+        <template v-if="list.type === 3">
+          <div class="table_th table_t">
+            <div class="td">5E6 cells/vial</div>
+            <div class="td">
+              <el-link type="primary" @click="tapInquiry">
+                {{ $t("table.Inquiry") }}
+              </el-link>
+            </div>
+          </div>
+        </template>
+        <template v-else>
+          <div class="table_th table_t">
+            <div class="td">100 μg</div>
+            <div class="td">
+              <el-link type="primary" @click="tapInquiry">
+                {{ $t("table.Inquiry") }}
+              </el-link>
+            </div>
+          </div>
+          <div class="table_th table_t">
+            <div class="td">1 mg</div>
+            <div class="td">
+              <el-link type="primary" @click="tapInquiry">
+                {{ $t("table.Inquiry") }}
+              </el-link>
+            </div>
+          </div>
+        </template>
+      </template>
+    </div>
+
+    <div class="price-button">
+      <template v-if="skuList.length == 0">
+        <div @click="tapInquiry" class="buttom_box">
+          <div class="price-btn-text">{{ $t("table.Inquiry") }}</div>
+          <div class="price-btn-img">
+            <img
+              class="btn-img"
+              src="@/assets/img/newProductDetail/inquiry.png"
+            />
+          </div>
+        </div>
+      </template>
+      <template v-else>
+        <div
+          @click="tapShoppingCart"
+          class="buttom_box"
+          style="max-width: 200px;"
+        >
+          <div class="price-btn-text">{{ $t("button.Cart") }}</div>
+          <div class="price-btn-img">
+            <img class="btn-img" src="@/assets/img/newProductDetail/cart.png" />
+          </div>
+        </div>
+        <div
+          v-if="showFreeSampleBtn(list)"
+          style="max-width: 200px;background: rgb(229, 1, 19);"
+          @click="tapInquiry"
+          class="buttom_box"
+        >
+          <div class="price-btn-text">{{ $t("button.Bulk") }}</div>
+          <div class="price-btn-img free">
+            <img class="btn-img" src="@/assets/img/newProductDetail/free.png" />
+          </div>
+        </div>
+      </template>
+    </div>
+  </div>
+</template>
+<script>
+import Bus from "@/js/bus";
+import axios from "axios";
+
+export default {
+  name: "PriceTable",
+  props: {
+    list: {
+      type: Object,
+      required: true
+    },
+    skuList: {
+      type: Array,
+      required: true
+    }
+  },
+  data() {
+    return {
+      changeNumList: [],
+      totalNum: '',
+      catalog: this.$route.params.catalog
+    };
+  },
+  created() {
+    // this.changeGetSampleStock()
+  },
+  mounted() {
+    if (this.$route.params.id == "antibody") {
+      this.changeGetSampleStock()
+    }
+  },
+  methods: {
+    changeGetSampleStock() {
+      // this.$api.post("sample/getSampleStock", {
+      //   catalog: this.catalog
+      // }).then(res => {
+      //   if (res.code === 0) {
+      //     this.totalNum = res.data.totalNum
+      //   } else {
+      //     this.$message(res.msg);
+      //   }
+      // });
+      // let formdata = new FormData();
+      // formdata.append("catalog", this.catalog);
+      let formdata = {
+        catalog: this.catalog
+      }
+      this.postAxios(formdata)
+        .then(res => {
+          console.log(res);
+          if (res.data.code === 0) {
+            this.totalNum = res.data.data.totalNum
+            // console.log(this.totalNum, '==============');
+          } else {
+            this.$message(res.msg);
+          }
+        })
+        .catch(() => {});
+    },
+    // 大包装
+    postAxios(formdata) {
+      return new Promise((resolve, reject) => {
+        axios({
+          method: "post",
+          url: "https://erp.sanyoubio.com/sys/sample/getSampleStock",
+          data: formdata,
+          xhrFields: {
+            withCredentials: true
+          },
+          headers: {
+            "lang": localStorage.getItem('internationalization') || 'en',
+            "Content-Type": "application/json"
+          }
+        })
+          .then(response => {
+            resolve(response);
+          })
+          .catch(() => {
+            reject();
+          });
+      });
+    },
+    showFreeSampleBtn(list) {
+      const category = Number(list.category); // 二级分类是VLP 3560 则不显示免费获取样品按钮
+      const catalog = list.catalog; // X开头的货号以及ABY开头的货号,不显示免费获取样品按钮
+
+      return (
+        list.type !== 3 &&
+        category !== 3560 &&
+        !catalog.startsWith("X") &&
+        !catalog.startsWith("ABY")
+      );
+    },
+    changeNum() {
+      // 计数器
+      let that = this;
+      that.changeNumList = [];
+      for (var i = 0; i < that.skuList.length; i++) {
+        if (that.skuList[i].num > 0) {
+          let datas = {
+            skuId: that.skuList[i].id,
+            cnDiscountPrice: that.skuList[i].cnDiscountPrice,
+            productCatalog: that.skuList[i].catalog,
+            productName: that.skuList[i].productName,
+            size: that.skuList[i].specifications,
+            number: that.skuList[i].num,
+            discountPrice: that.skuList[i].discountPrice,
+            price: that.skuList[i].price,
+            checked: true,
+            id: that.list.id,
+            cnPrice: that.skuList[i].cnPrice
+          };
+          this.changeNumList.push(datas);
+        }
+      }
+    },
+    tapShoppingCart() {
+      // 购物车
+      let that = this;
+      //   var obj = []
+      var cartList = [];
+      if (this.skuList.length > 0) {
+        if (this.changeNumList.length === 0) {
+          this.$message.error(this.$t("button.Article"));
+        } else {
+          if (JSON.parse(localStorage.getItem("token"))) {
+            that.skuList.forEach(item => {
+              if (item.num > 0) {
+                var data = {
+                  checked: true,
+                  id: that.list.id,
+                  number: item.num,
+                  productCatalog: item.catalog,
+                  skuId: item.id
+                };
+                cartList.push(data);
+              }
+            });
+            this.$api
+              .post("cart/batchAdd", {
+                cartList: cartList
+              })
+              .then(res => {
+                if (res.code === 0) {
+                  this.getIndex();
+                  this.$message({
+                    message: this.$t("button.successfully"),
+                    type: "success"
+                  });
+                  // localStorage.setItem('cartTap', '1')
+                  this.resetPriceTable();
+                } else {
+                  this.$message(res.msg);
+                }
+              });
+          } else {
+            this.localList();
+          }
+        }
+      }
+    },
+    resetPriceTable() {
+      this.changeNumList = [];
+      this.skuList.forEach(item => {
+        item.num = 0;
+      });
+    },
+    localList() {
+      // 本地存储
+      var shoppingCart = null;
+      var arrObj = null; // 选中数量
+      var list = []; // 新增数据
+      arrObj = JSON.parse(JSON.stringify(this.changeNumList));
+      shoppingCart = JSON.parse(localStorage.getItem("shoppingCart")) || []; // 获取购物车数据
+      if (shoppingCart.length > 0) {
+        for (var i = 0; i < this.changeNumList.length; i++) {
+          for (var j = 0; j < shoppingCart.length; j++) {
+            if (
+              Number(this.changeNumList[i].skuId) ===
+              Number(shoppingCart[j].skuId)
+            ) {
+              this.$set(arrObj[i], "checked", false);
+              shoppingCart[j].number =
+                Number(this.changeNumList[i].number) +
+                Number(shoppingCart[j].number);
+            }
+          }
+        }
+      } else {
+        localStorage.setItem(
+          "shoppingCart",
+          JSON.stringify(this.changeNumList)
+        );
+        localStorage.setItem(
+          "shoppingNum",
+          JSON.stringify(this.changeNumList.length)
+        );
+        this.elementByValue();
+        this.$message({
+          message: this.$t("button.successfully"),
+          type: "success"
+        });
+        this.resetPriceTable();
+        return;
+      }
+      for (var n = 0; n < arrObj.length; n++) {
+        if (arrObj[n].checked) {
+          list.push(arrObj[n]);
+        }
+      }
+      this.$message({
+        message: this.$t("button.successfully"),
+        type: "success"
+      });
+      var arr = shoppingCart.concat(list);
+      localStorage.setItem("shoppingCart", JSON.stringify(arr));
+      localStorage.setItem("shoppingNum", JSON.stringify(arr.length));
+      // localStorage.setItem('cartTap', '1')
+      this.elementByValue();
+
+      this.resetPriceTable();
+    },
+    getIndex() {
+      // 获取购物车数量
+      this.$api
+        .post("cart/index", {
+          cartList: null
+        })
+        .then(res => {
+          if (res.code === 0) {
+            localStorage.removeItem("shoppingCart");
+            localStorage.setItem(
+              "shoppingNum",
+              JSON.stringify(res.data.cartList.length)
+            );
+            this.elementByValue();
+          }
+        });
+    },
+    elementByValue() {
+      // localStorage.setItem('cartTap', 1)
+      Bus.$emit("onmycar", "1");
+      // console.log('---------888888-')
+      // this.num = this.num + 1
+      // this.$store.commit('settapscart', this.num)
+      // console.log('----77777-----888888-')
+    },
+    tapInquiry() {
+      this.$util.goRoute({
+        name: "inquiry",
+        query: {
+          catalog: this.list.catalog
+        }
+      });
+    }
+  }
+};
+</script>
+<style lang="scss" scoped>
+@media screen and (min-width: 751px) and (max-width: 9999px) {
+  .size-price {
+    .size-price-table {
+      width: 100%;
+      margin-bottom: 1rem;
+      // height: 180px;
+      // min-height: 9rem;
+      overflow-y: auto;
+      -ms-overflow-style: none;
+      overflow: -moz-scrollbars-none;
+      &::-webkit-scrollbar {
+        width: 0 !important;
+      }
+      .table_th {
+        width: 100%;
+        height: 36px;
+        background-color: #f4faff;
+        display: flex;
+        align-items: center;
+        justify-content: space-between;
+
+        &.header {
+          font-weight: bold;
+        }
+
+        .th {
+          flex: 1;
+          font-size: 14px;
+          color: #313131;
+          padding-left: 18px;
+        }
+        .td /deep/ {
+          flex: 1;
+          font-size: 14px;
+          color: #313131;
+          padding-left: 18px;
+
+          .el-input-number {
+            width: 80%;
+            margin: auto;
+            line-height: 28px;
+            .el-input-number__decrease {
+              width: 30px;
+            }
+            .el-input-number__increase {
+              width: 30px;
+            }
+            .el-input {
+              width: 100%;
+              .el-input__inner {
+                width: 100%;
+                height: 30px;
+                font-size: 14px;
+                line-height: 30px;
+                padding: 0 30px !important;
+                color: #313131;
+              }
+            }
+          }
+          .el-select {
+            width: 50px;
+            .el-input__inner {
+              height: 20px;
+              line-height: 20px;
+              padding: 0 20px 0 10px;
+            }
+            .el-input__suffix {
+              right: 0;
+              .el-select__caret {
+                line-height: 20px;
+              }
+            }
+          }
+        }
+        .td_h {
+          color: #ea1f1f;
+        }
+        .td_b{
+          color: #0166b4;
+          cursor: pointer;
+        }
+      }
+      .table_t {
+        margin-top: 10px;
+        background-color: #fff;
+      }
+      .no_table {
+        width: 100%;
+        line-height: 60px;
+        padding: 6px 0;
+        background-color: #fff;
+        text-align: center;
+        font-size: 16px;
+        color: #909399;
+        font-family: Arial;
+      }
+    }
+
+    .price-button {
+      display: flex;
+      align-content: center;
+      justify-content: center;
+      gap: 17px;
+      margin-bottom: 24px;
+      margin-top: 20px;
+      margin-left: 18px;
+      margin-right: 18px;
+
+      .buttom_box {
+        flex: 1;
+        height: 40px;
+        color: #fff;
+        font-size: 14px;
+        line-height: 40px;
+        background: #0166b4;
+        text-align: center;
+        cursor: pointer;
+        display: flex;
+        align-items: center;
+        justify-content: space-between;
+
+        .price-btn-text {
+          flex: 1;
+          display: flex;
+          justify-content: center;
+          align-items: center;
+          overflow: hidden;
+          text-overflow: ellipsis;
+          white-space: nowrap;
+          font-weight: bold;
+        }
+
+        .price-btn-img {
+          display: flex;
+          border-left: 1px solid #1a78c0;
+
+          &.free {
+            border-left: 2px solid #eb5965;
+          }
+          .btn-img {
+            margin: 11px 9px;
+            width: 18px;
+          }
+        }
+      }
+    }
+  }
+}
+
+@media screen and (min-width: 0px) and (max-width: 750px) {
+  .size-price {
+    .size-price-table {
+      width: 100%;
+      overflow-y: auto;
+      -ms-overflow-style: none;
+      overflow: -moz-scrollbars-none;
+      &::-webkit-scrollbar {
+        width: 0 !important;
+      }
+      .table_th {
+        width: 100%;
+        height: 36px;
+        background-color: #f4faff;
+        display: flex;
+        align-items: center;
+        justify-content: space-between;
+
+        &.header {
+          font-weight: bold;
+        }
+
+        .th {
+          flex: 1;
+          font-size: 14px;
+          color: #313131;
+          padding-left: 0.15rem;
+        }
+        .td /deep/ {
+          flex: 1;
+          font-size: 14px;
+          color: #313131;
+          padding-left: 0.15rem;
+
+          .el-input-number {
+            width: 80%;
+            margin: auto;
+            line-height: 28px;
+            .el-input-number__decrease {
+              width: 30px;
+            }
+            .el-input-number__increase {
+              width: 30px;
+            }
+            .el-input {
+              width: 100%;
+              .el-input__inner {
+                width: 100%;
+                height: 30px;
+                font-size: 14px;
+                line-height: 30px;
+                padding: 0 30px !important;
+                color: #313131;
+              }
+            }
+          }
+          .el-select {
+            width: 50px;
+            .el-input__inner {
+              height: 20px;
+              line-height: 20px;
+              padding: 0 20px 0 10px;
+            }
+            .el-input__suffix {
+              right: 0;
+              .el-select__caret {
+                line-height: 20px;
+              }
+            }
+          }
+        }
+        .td_h {
+          color: #ea1f1f;
+        }
+        .td_b{
+          color: #0166b4;
+          cursor: pointer;
+        }
+      }
+      .table_t {
+        margin-top: 10px;
+        background-color: #fff;
+      }
+      .no_table {
+        width: 100%;
+        line-height: 60px;
+        padding: 6px 0;
+        background-color: #fff;
+        text-align: center;
+        font-size: 16px;
+        color: #909399;
+        font-family: Arial;
+      }
+    }
+
+    .price-button {
+      display: flex;
+      align-content: center;
+      justify-content: center;
+      gap: 0.15rem;
+      margin: 0.2rem 0.15rem;
+
+      .buttom_box {
+        flex: 1;
+        height: 40px;
+        color: #fff;
+        font-size: 14px;
+        line-height: 40px;
+        background: #0166b4;
+        text-align: center;
+        cursor: pointer;
+        display: flex;
+        align-items: center;
+        justify-content: space-between;
+
+        .price-btn-text {
+          flex: 1;
+          display: flex;
+          justify-content: center;
+          align-items: center;
+          overflow: hidden;
+          text-overflow: ellipsis;
+          white-space: nowrap;
+          font-weight: bold;
+        }
+
+        .price-btn-img {
+          display: flex;
+          border-left: 1px solid #1a78c0;
+
+          &.free {
+            border-left: 2px solid #eb5965;
+          }
+          .btn-img {
+            margin: 11px 9px;
+            width: 18px;
+          }
+        }
+      }
+    }
+  }
+}
+</style>

+ 277 - 0
src/view/product/components/ProteinInfo.vue

@@ -0,0 +1,277 @@
+<template>
+  <div>
+    <div class="detail-table pc" :class="{ env_en: !!$util.localeStorage() }">
+      <div class="table_th">
+        <div class="table_td">{{ $t("newProduct.target") }}</div>
+        <div class="table_td">
+          {{ $util.targetDictionaries(list.target) }}
+        </div>
+        <div class="table_td">{{ $t("newProduct.catalog") }}</div>
+        <div class="table_td">{{ list.catalog }}</div>
+      </div>
+      <div class="table_th">
+        <div class="table_td">{{ $t("newProduct.targetAccession") }}</div>
+        <div class="table_td">{{ list.accession }}</div>
+        <div class="table_td">{{ $t("newProduct.concentration") }}</div>
+        <div class="table_td">{{ list.concentration }}</div>
+      </div>
+      <div class="table_th">
+        <div class="table_td">{{ $t("table.Species") }}</div>
+        <div class="table_td">
+          {{ $util.findAllCategory("Protein_species", list.species) }}
+        </div>
+        <div class="table_td">{{ $t("newProduct.molecularWeight") }}</div>
+        <div class="table_td">
+          {{ list.molecularWeight }}
+        </div>
+      </div>
+      <div class="table_th">
+        <div class="table_td">{{ $t("table.AASeqBrief") }}</div>
+        <div class="table_td">{{ list.aaSeqBrief }}</div>
+        <div class="table_td">{{ $t("newProduct.endotoxin") }}</div>
+        <div class="table_td">
+          <!-- {{ list.endotoxin }} -->
+          <0.001 EU/μg
+        </div>
+      </div>
+      <div class="table_th">
+        <div class="table_td">{{ $t("newProduct.formulation") }}</div>
+        <div class="table_td">{{ list.formulation }}</div>
+        <div class="table_td">{{ $t("newProduct.conjugation") }}</div>
+        <div class="table_td">{{ list.conjugation }}</div>
+      </div>
+      <div class="table_th">
+        <div class="table_td">{{ $t("newProduct.storage") }}</div>
+        <div class="table_td">{{ list.storage }}</div>
+        <div class="table_td">{{ $t("newProduct.host") }}</div>
+        <div class="table_td">
+          {{ $util.findAllCategory("Protein_host", list.host) }}
+        </div>
+      </div>
+    </div>
+    <div
+      class="detail-table mobile"
+      :class="{ env_en: !!$util.localeStorage() }"
+    >
+      <div class="table_th">
+        <div class="table_td">{{ $t("newProduct.target") }}</div>
+        <div class="table_td">
+          {{ $util.targetDictionaries(list.target) }}
+        </div>
+      </div>
+      <div class="table_th">
+        <div class="table_td">{{ $t("newProduct.targetAccession") }}</div>
+        <div class="table_td">{{ list.accession }}</div>
+      </div>
+      <div class="table_th">
+        <div class="table_td">{{ $t("table.Species") }}</div>
+        <div class="table_td">
+          {{ $util.findAllCategory("Protein_species", list.species) }}
+        </div>
+      </div>
+      <div class="table_th">
+        <div class="table_td">{{ $t("table.AASeqBrief") }}</div>
+        <div class="table_td">{{ list.aaSeqBrief }}</div>
+      </div>
+      <div class="table_th">
+        <div class="table_td">{{ $t("newProduct.formulation") }}</div>
+        <div class="table_td">{{ list.formulation }}</div>
+      </div>
+      <div class="table_th">
+        <div class="table_td">{{ $t("newProduct.storage") }}</div>
+        <div class="table_td">{{ list.storage }}</div>
+      </div>
+      <div class="table_th">
+        <div class="table_td">{{ $t("newProduct.catalog") }}</div>
+        <div class="table_td">{{ list.catalog }}</div>
+      </div>
+      <div class="table_th">
+        <div class="table_td">{{ $t("newProduct.concentration") }}</div>
+        <div class="table_td">{{ list.concentration }}</div>
+      </div>
+      <div class="table_th">
+        <div class="table_td">{{ $t("newProduct.molecularWeight") }}</div>
+        <div class="table_td">{{ list.molecularWeight }}</div>
+      </div>
+      <div class="table_th">
+        <div class="table_td">{{ $t("newProduct.endotoxin") }}</div>
+        <div class="table_td">
+          <!-- {{ list.endotoxin }} -->
+          <0.001 EU/μg
+        </div>
+      </div>
+      <div class="table_th">
+        <div class="table_td">{{ $t("newProduct.conjugation") }}</div>
+        <div class="table_td">{{ list.conjugation }}</div>
+      </div>
+      <div class="table_th">
+        <div class="table_td">{{ $t("newProduct.host") }}</div>
+        <div class="table_td">
+          {{ $util.findAllCategory("Antibody_host", list.host) }}
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+<script>
+export default {
+  name: "info",
+  props: {
+    list: {
+      type: Object,
+      required: true
+    }
+  },
+  data() {
+    return {};
+  },
+  methods: {},
+  mounted() {},
+  created() {}
+};
+</script>
+<style lang="scss" scoped>
+@media screen and (min-width: 751px) and (max-width: 9999px) {
+  .pc {
+    display: block !important;
+
+    &.env_en {
+      .table_th {
+        .table_td {
+          &:nth-child(1) {
+            width: 141px !important;
+          }
+          &:nth-child(3) {
+            width: 181px !important;
+          }
+        }
+      }
+    }
+  }
+
+  .mobile {
+    display: none !important;
+  }
+
+  .detail-table {
+    width: 100%;
+    margin-bottom: 1rem;
+    overflow-x: auto;
+    border-top: 1px solid #0166b4;
+    color: #6f6f6f;
+    font-size: 14px;
+    border-bottom: 1px solid #d6eaff;
+
+    .table_th {
+      width: 100%;
+      // height: 36px;
+      display: flex;
+      // align-items: center;
+      justify-content: space-between;
+      // border-bottom: 1px solid #d6eaff;
+
+      &:nth-child(even) {
+        background-color: #f4faff;
+      }
+
+      .table_td {
+        // height: 36px;
+        line-height: 24px;
+        // text-indent: 12px;
+        padding: 10px;
+
+        &:nth-child(1) {
+          width: 133px;
+          &::after {
+            content: ":";
+          }
+        }
+        &:nth-child(2) {
+          flex: 3;
+          color: #313131;
+        }
+        &:nth-child(3) {
+          width: 105px;
+          &::after {
+            content: ":";
+          }
+        }
+        &:nth-child(4) {
+          flex: 1;
+          color: #313131;
+        }
+
+        &:not(:last-child) {
+          border-right: 1px solid #d6eaff;
+        }
+      }
+    }
+  }
+}
+
+@media screen and (min-width: 0px) and (max-width: 750px) {
+  .pc {
+    display: none !important;
+  }
+
+  .mobile {
+    display: flex !important;
+
+    &.env_en {
+      .table_th {
+        .table_td {
+          &:nth-child(1) {
+            width: 181px !important;
+          }
+        }
+      }
+    }
+  }
+
+  .detail-table {
+    margin-top: 0.4rem;
+    width: 100%;
+    border-top: 1px solid #0166b4;
+    color: #6f6f6f;
+    font-size: 14px;
+    border-bottom: 1px solid #d6eaff;
+    display: flex;
+    flex-direction: column;
+
+    .table_th {
+      width: 100%;
+      // height: 36px;
+      display: flex;
+      // align-items: center;
+      justify-content: space-between;
+      // border-bottom: 1px solid #d6eaff;
+
+      &:nth-child(even) {
+        background-color: #f4faff;
+      }
+
+      .table_td {
+        // height: 36px;
+        line-height: 24px;
+        // text-indent: 12px;
+        padding: 10px;
+
+        &:nth-child(1) {
+          width: 133px;
+          &::after {
+            content: ":";
+          }
+        }
+        &:nth-child(2) {
+          flex: 3;
+          color: #313131;
+        }
+
+        &:not(:last-child) {
+          border-right: 1px solid #d6eaff;
+        }
+      }
+    }
+  }
+}
+</style>

+ 131 - 0
src/view/product/components/RecentlyList.vue

@@ -0,0 +1,131 @@
+<template>
+  <div class="rightcenterbox">
+    <div class="box-title">{{ $t("inquiry.RecentlyViewed") }}</div>
+    <div class="rightcenterbox_text">
+      <div
+        class="topage"
+        v-for="one in recentlyList.slice(0, 5)"
+        :key="one.id"
+        @click="tapRoduct(one)"
+      >
+        <div class="list_name">{{ one.catalog }} / {{ one.product }}</div>
+        <i class="el-icon-arrow-right"></i>
+      </div>
+    </div>
+  </div>
+</template>
+<script>
+export default {
+  name: "RecentlyList",
+  props: {
+    recentlyList: {
+      type: Array,
+      required: true
+    }
+  },
+  methods: {
+    tapRoduct(e) {
+      // 浏览记录
+      let name = this.$util.english(e.product);
+      this.$router.push({
+        path:
+          "/products/" + this.$route.params.id + "/" + name + "/" + e.catalog
+        // query: {
+        //   catalog: e.catalog
+        // }
+      });
+    }
+  }
+};
+</script>
+<style lang="scss" scoped>
+@media screen and (min-width: 751px) and (max-width: 9999px) {
+  .rightcenterbox:not(:nth-child(1)) {
+    margin-top: 2rem;
+  }
+
+  .rightcenterbox_text {
+    font-size: 1rem !important;
+  }
+}
+
+@media screen and (min-width: 0px) and (max-width: 750px) {
+  .rightcenterbox_text {
+    font-size: 0.16rem !important;
+  }
+
+  .rightcenterbox > div:nth-of-type(2) {
+    padding: 0.1rem 0.2rem !important;
+  }
+
+  .rightcenterbox:not(:nth-child(1)) {
+    margin-top: 0.4rem;
+  }
+}
+
+.rightcenterbox {
+  width: 100%;
+
+  .box-title {
+    font-size: 14px;
+    height: 36px;
+    line-height: 36px;
+    background-color: #f4faff;
+    font-weight: bold;
+    text-indent: 16px;
+  }
+}
+.rightcenterbox > div:nth-of-type(2) {
+  font-size: 0.16rem;
+  padding: 1rem;
+  font-size: 16px;
+}
+.rightcenterbox_text /deep/ {
+  .topage {
+    display: block;
+    height: 42px;
+    line-height: 42px;
+    font-size: 16px;
+    color: #6f6f6f;
+    padding-left: 12px;
+    margin-left: -12px;
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    cursor: pointer;
+    &:hover {
+      background: rgba(0, 91, 171, 0.11);
+      border-radius: 2px;
+      border: 1px solid #005bab;
+      color: #005bab;
+      .el-icon-arrow-right {
+        color: #005bab;
+      }
+    }
+    .list_name {
+      font-size: 14px;
+      white-space: nowrap;
+      overflow: hidden;
+      text-overflow: ellipsis;
+    }
+  }
+  .el-icon-arrow-right {
+    height: 42px;
+    line-height: 42px;
+    margin-right: 10px;
+    color: #0166b4;
+  }
+}
+.rightcenterbox > div:nth-of-type(2) > p:nth-of-type(1) {
+  margin-top: 0;
+}
+.rightcenterbox > div > p {
+  word-wrap: break-word;
+  word-break: normal;
+  cursor: pointer;
+  a {
+    color: #6f6f6f;
+    text-decoration: none;
+  }
+}
+</style>

+ 131 - 0
src/view/product/components/RelatedProduct.vue

@@ -0,0 +1,131 @@
+<template>
+  <div class="rightcenterbox">
+    <div class="box-title">{{ $t("button.RelatedProducts") }}</div>
+    <div class="rightcenterbox_text">
+      <div
+        class="topage"
+        v-for="one in relatedProductlist.slice(0, 5)"
+        :key="one.id"
+        @click="tapRoduct(one)"
+      >
+        <div class="list_name">{{ one.catalog }} / {{ one.productName }}</div>
+        <i class="el-icon-arrow-right"></i>
+      </div>
+    </div>
+  </div>
+</template>
+<script>
+export default {
+  name: "RelatedProduct",
+  props: {
+    relatedProductlist: {
+      type: Array,
+      required: true
+    }
+  },
+  methods: {
+    tapRoduct(e) {
+      // 浏览记录
+      let name = this.$util.english(e.productName);
+      this.$router.push({
+        path:
+          "/products/" + this.$route.params.id + "/" + name + "/" + e.catalog
+        // query: {
+        //   catalog: e.catalog
+        // }
+      });
+    }
+  }
+};
+</script>
+<style lang="scss" scoped>
+@media screen and (min-width: 751px) and (max-width: 9999px) {
+  .rightcenterbox:not(:nth-child(1)) {
+    margin-top: 2rem;
+  }
+
+  .rightcenterbox_text {
+    font-size: 1rem !important;
+  }
+}
+
+@media screen and (min-width: 0px) and (max-width: 750px) {
+  .rightcenterbox_text {
+    font-size: 0.16rem !important;
+  }
+
+  .rightcenterbox > div:nth-of-type(2) {
+    padding: 0.1rem 0.24rem !important;
+  }
+
+  .rightcenterbox:not(:nth-child(1)) {
+    margin-top: 0.4rem;
+  }
+}
+
+.rightcenterbox {
+  width: 100%;
+
+  .box-title {
+    font-size: 14px;
+    height: 36px;
+    line-height: 36px;
+    background-color: #f4faff;
+    font-weight: bold;
+    text-indent: 16px;
+  }
+}
+.rightcenterbox > div:nth-of-type(2) {
+  font-size: 0.16rem;
+  padding: 1rem;
+  font-size: 16px;
+}
+.rightcenterbox_text /deep/ {
+  .topage {
+    display: block;
+    height: 42px;
+    line-height: 42px;
+    font-size: 16px;
+    color: #6f6f6f;
+    padding-left: 12px;
+    margin-left: -12px;
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    cursor: pointer;
+    &:hover {
+      background: rgba(0, 91, 171, 0.11);
+      border-radius: 2px;
+      border: 1px solid #005bab;
+      color: #005bab;
+      .el-icon-arrow-right {
+        color: #005bab;
+      }
+    }
+    .list_name {
+      font-size: 14px;
+      white-space: nowrap;
+      overflow: hidden;
+      text-overflow: ellipsis;
+    }
+  }
+  .el-icon-arrow-right {
+    height: 42px;
+    line-height: 42px;
+    margin-right: 10px;
+    color: #0166b4;
+  }
+}
+.rightcenterbox > div:nth-of-type(2) > p:nth-of-type(1) {
+  margin-top: 0;
+}
+.rightcenterbox > div > p {
+  word-wrap: break-word;
+  word-break: normal;
+  cursor: pointer;
+  a {
+    color: #6f6f6f;
+    text-decoration: none;
+  }
+}
+</style>

+ 178 - 0
src/view/product/components/info.vue

@@ -0,0 +1,178 @@
+<template>
+  <div>
+    <protein-info :list="list" v-if="list.type === 1" />
+    <antibody-info :list="list" v-else-if="list.type === 2" />
+    <cell-line-info :list="list" v-else-if="list.type === 3" />
+  </div>
+</template>
+<script>
+import ProteinInfo from "./ProteinInfo.vue";
+import AntibodyInfo from "./AntibodyInfo.vue";
+import CellLineInfo from "./CellLineInfo.vue";
+
+export default {
+  name: "info",
+  components: {
+    ProteinInfo,
+    AntibodyInfo,
+    CellLineInfo
+  },
+  props: {
+    list: {
+      type: Object,
+      required: true
+    }
+  },
+  data() {
+    return {};
+  },
+  methods: {},
+  mounted() {},
+  created() {}
+};
+</script>
+<style lang="scss" scoped>
+@media screen and (min-width: 751px) and (max-width: 9999px) {
+  .pc {
+    display: block !important;
+
+    &.env_en {
+      .table_th {
+        .table_td {
+          &:nth-child(1) {
+            width: 141px !important;
+          }
+          &:nth-child(3) {
+            width: 181px !important;
+          }
+        }
+      }
+    }
+  }
+
+  .mobile {
+    display: none !important;
+  }
+
+  .detail-table {
+    width: 100%;
+    margin-bottom: 1rem;
+    overflow-x: auto;
+    border-top: 1px solid #0166b4;
+    color: #6f6f6f;
+    font-size: 14px;
+    border-bottom: 1px solid #d6eaff;
+
+    .table_th {
+      width: 100%;
+      // height: 36px;
+      display: flex;
+      // align-items: center;
+      justify-content: space-between;
+      // border-bottom: 1px solid #d6eaff;
+
+      &:nth-child(even) {
+        background-color: #f4faff;
+      }
+
+      .table_td {
+        // height: 36px;
+        line-height: 24px;
+        // text-indent: 12px;
+        padding: 10px;
+
+        &:nth-child(1) {
+          width: 100px;
+          &::after {
+            content: ":";
+          }
+        }
+        &:nth-child(2) {
+          flex: 3;
+          color: #313131;
+        }
+        &:nth-child(3) {
+          width: 110px;
+          &::after {
+            content: ":";
+          }
+        }
+        &:nth-child(4) {
+          flex: 1;
+          color: #313131;
+        }
+
+        &:not(:last-child) {
+          border-right: 1px solid #d6eaff;
+        }
+      }
+    }
+  }
+}
+
+@media screen and (min-width: 0px) and (max-width: 750px) {
+  .pc {
+    display: none !important;
+  }
+
+  .mobile {
+    display: flex !important;
+
+    &.env_en {
+      .table_th {
+        .table_td {
+          &:nth-child(1) {
+            width: 181px !important;
+          }
+        }
+      }
+    }
+  }
+
+  .detail-table {
+    margin-top: 0.4rem;
+    width: 100%;
+    border-top: 1px solid #0166b4;
+    color: #6f6f6f;
+    font-size: 14px;
+    border-bottom: 1px solid #d6eaff;
+    display: flex;
+    flex-direction: column;
+
+    .table_th {
+      width: 100%;
+      // height: 36px;
+      display: flex;
+      // align-items: center;
+      justify-content: space-between;
+      // border-bottom: 1px solid #d6eaff;
+
+      &:nth-child(even) {
+        background-color: #f4faff;
+      }
+
+      .table_td {
+        // height: 36px;
+        line-height: 24px;
+        // text-indent: 12px;
+        padding: 10px;
+
+        &:nth-child(1) {
+          width: 105px;
+          &::after {
+            content: ":";
+          }
+        }
+        &:nth-child(2) {
+          flex: 3;
+          color: #313131;
+        }
+
+        &:not(:last-child) {
+          border-right: 1px solid #d6eaff;
+        }
+      }
+    }
+  }
+}
+</style>

+ 148 - 0
src/view/product/components/validation.vue

@@ -0,0 +1,148 @@
+<template>
+  <div>
+    <div class="data-title">{{ $t("newProduct.productData") }}</div>
+    <div class="image-list" v-if="!!list">
+      <div
+        class="image-list-item"
+        v-for="item in list.productValidatedEnList"
+        :key="item.id"
+      >
+        <div class="title">{{ formatTitle(item.title) }}</div>
+        <div class="img-box">
+          <div
+            class="img-box-item"
+            :style="{ backgroundImage: 'url(' + item.pictureUrl + ')' }"
+          />
+        </div>
+        <div class="desc">{{ item.description }}</div>
+      </div>
+    </div>
+  </div>
+</template>
+<script>
+export default {
+  name: "info",
+  props: {
+    list: {
+      type: Object,
+      required: true
+    }
+  },
+  data() {
+    return {};
+  },
+  methods: {
+    formatTitle(title) {
+      if (!!title && !!title.split) {
+        return title.split(":").join(": ");
+      }
+
+      return title;
+    }
+  },
+  mounted() {},
+  created() {}
+};
+</script>
+<style lang="scss" scoped>
+@media screen and (min-width: 751px) and (max-width: 9999px) {
+  .data-title {
+    font-size: 16px;
+    margin-top: 30px;
+    padding-bottom: 15px;
+  }
+
+  .image-list {
+    .image-list-item {
+      .img-box {
+        height: 250px;
+
+        .img-box-item {
+          width: calc(100% - 32px);
+          height: calc(100% - 32px);
+          margin: 16px;
+        }
+      }
+    }
+  }
+}
+
+@media screen and (min-width: 0px) and (max-width: 750px) {
+  .data-title {
+    font-size: 0.14rem;
+    font-weight: 600;
+    margin-top: 0.4rem;
+    padding-bottom: 0.1rem;
+  }
+
+  .image-list {
+    flex-direction: column;
+
+    .image-list-item {
+      flex: 1;
+
+      .img-box {
+        height: 2rem;
+        .img-box-item {
+          width: calc(100% - 12px);
+          height: calc(100% - 12px);
+          margin: 6px;
+        }
+      }
+    }
+  }
+}
+
+.data-title {
+  // font-size: 18px;
+  font-weight: bold;
+  // height: 40px;
+  // line-height: 40px;
+  border-bottom: 1px solid #0166b4;
+  color: #313131;
+}
+
+.image-list {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 4%;
+
+  .image-list-item {
+    flex: 0 0 48%;
+    overflow: hidden;
+
+    .title {
+      font-weight: bold;
+      font-size: 14px;
+      color: #313131;
+      margin-top: 30px;
+      margin-bottom: 8px;
+      overflow: hidden;
+      white-space: nowrap;
+      text-overflow: ellipsis;
+    }
+
+    .img-box {
+      border: 1px solid #d6eaff;
+      // height: 250px;
+
+      .img-box-item {
+        // width: calc(100% - 32px);
+        // height: calc(100% - 32px);
+        // margin: 16px;
+        background-repeat: no-repeat;
+        background-size: contain;
+        background-position: center;
+      }
+    }
+
+    .desc {
+      font-weight: 400;
+      font-size: 14px;
+      color: #6f6f6f;
+      line-height: 18px;
+      margin-top: 14px;
+    }
+  }
+}
+</style>

+ 722 - 0
src/view/product/details.vue

@@ -0,0 +1,722 @@
+<template>
+  <div>
+    <div class="pc-page">
+      <div class="box">
+        <div class="topbox">
+          <div style="display: flex;align-items: center;">
+            <div style="flex:1;font-weight: bold;">
+              {{ list.productName }}
+            </div>
+            <div
+              style="display: flex;align-items: center;margin-left: 20px;gap: 10px;flex:1;"
+            >
+              <div @click="clickCoa">
+                <img
+                  src="@/assets/img/productDetail/coa.png"
+                  style="width: 43px;height: 47px;cursor: pointer;"
+                  alt=""
+                  class="butt_image"
+                />
+              </div>
+              <div @click="clickMsds">
+                <img
+                  src="@/assets/img/productDetail/msds.png"
+                  style="width: 43px;height: 47px;cursor: pointer;"
+                  alt=""
+                  class="butt_image"
+                />
+              </div>
+            </div>
+          </div>
+        </div>
+        <div class="contentbox">
+          <info :list="list" v-loading="getProductDetaiLoading" />
+          <validation :list="list" v-loading="getProductDetaiLoading" />
+        </div>
+        <div class="rightbox">
+          <price-table
+            class="common-border"
+            :list="list"
+            :sku-list="skuList"
+            v-loading="getProductDetaiLoading"
+          />
+          <!-- 最近访问 -->
+          <recently-list
+            v-if="recentlyList.length > 0"
+            class="common-border"
+            :recentlyList="recentlyList"
+          />
+          <!-- <div
+            class="rightcenterbox common-border"
+            v-if="recentlyList.length > 0"
+          >
+            <div class="box-title">{{ $t("inquiry.RecentlyViewed") }}</div>
+            <div class="rightcenterbox_text">
+              <div
+                class="topage"
+                v-for="one in recentlyList.slice(0, 5)"
+                :key="one.id"
+                @click="tapRoduct(one)"
+              >
+                <div class="list_name">
+                  {{ one.catalog }} / {{ one.product }}
+                </div>
+                <i class="el-icon-arrow-right"></i>
+              </div>
+            </div>
+          </div> -->
+          <!-- 相关产品 -->
+          <related-product
+            class="common-border"
+            v-if="relatedProductlist.length > 0"
+            :relatedProductlist="relatedProductlist"
+          />
+          <!-- <div
+            class="rightcenterbox common-border"
+            v-if="relatedProductlist.length > 0"
+          >
+            <div class="box-title">{{ $t("button.RelatedProducts") }}</div>
+            <div class="rightcenterbox_text">
+              <div
+                class="topage"
+                v-for="one in relatedProductlist.slice(0, 5)"
+                :key="one.id"
+                @click="tapRoduct(one)"
+              >
+                <div class="list_name">
+                  {{ one.catalog }} / {{ one.productName }}
+                </div>
+                <i class="el-icon-arrow-right"></i>
+              </div>
+            </div>
+          </div> -->
+        </div>
+      </div>
+    </div>
+    <div class="mobile-page">
+      <div class="box">
+        <div class="topbox">
+          <div class="product-title">
+            {{ list.productName }}
+          </div>
+          <div class="img-group">
+            <div @click="clickCoa">
+              <img
+                src="@/assets/img/productDetail/coa.png"
+                style="width: 43px;height: 47px;cursor: pointer;"
+                alt=""
+                class="butt_image"
+              />
+            </div>
+            <div @click="clickMsds">
+              <img
+                src="@/assets/img/productDetail/msds.png"
+                style="width: 43px;height: 47px;cursor: pointer;"
+                alt=""
+                class="butt_image"
+              />
+            </div>
+          </div>
+        </div>
+      </div>
+      <price-table
+        class="common-border"
+        :list="list"
+        :sku-list="skuList"
+        v-loading="getProductDetaiLoading"
+      />
+      <info :list="list" v-loading="getProductDetaiLoading" />
+      <validation :list="list" v-loading="getProductDetaiLoading" />
+      <!-- 最近访问 -->
+      <recently-list
+        v-if="recentlyList.length > 0"
+        class="common-border"
+        :recentlyList="recentlyList"
+      />
+      <!-- 相关产品 -->
+      <related-product
+        class="common-border"
+        v-if="relatedProductlist.length > 0"
+        :relatedProductlist="relatedProductlist"
+      />
+    </div>
+  </div>
+</template>
+<script>
+import Bus from "@/js/bus";
+import sites from "@/assets/josn/search";
+import axios from "axios";
+import info from "./components/info.vue";
+import validation from "./components/validation.vue";
+import PriceTable from "./components/PriceTable";
+import RecentlyList from "./components/RecentlyList";
+import RelatedProduct from "./components/RelatedProduct";
+
+export default {
+  components: {
+    info,
+    validation,
+    PriceTable,
+    RecentlyList,
+    RelatedProduct
+  },
+  name: "product",
+  data() {
+    return {
+      type: "",
+      tapoption: 1,
+      list: {},
+      skuList: [], // 价格
+      options: [
+        {
+          value: 0,
+          label: 0
+        },
+        {
+          value: 1,
+          label: 1
+        },
+        {
+          value: 2,
+          label: 2
+        },
+        {
+          value: 3,
+          label: 3
+        },
+        {
+          value: 4,
+          label: 4
+        },
+        {
+          value: 5,
+          label: 5
+        },
+        {
+          value: 6,
+          label: 6
+        },
+        {
+          value: 7,
+          label: 7
+        },
+        {
+          value: 8,
+          label: 8
+        },
+        {
+          value: 9,
+          label: 9
+        },
+        {
+          value: 10,
+          label: 10
+        }
+      ],
+      recentlyList: [],
+      relatedProductlist: [],
+      swiperOption: {
+        // loop: true,
+        slidesPerView: 2,
+        slidesPerGroup: 2,
+        // 设置点击箭头
+        navigation: {
+          nextEl: ".swiper-button-next",
+          prevEl: ".swiper-button-prev"
+        }
+      },
+      menuList: {},
+      changeNumList: [],
+      pageable: {
+        // 文献
+        page: 0,
+        size: 10
+      },
+      literature: false,
+      busShow: false,
+      num: 1,
+      msdsUrl: ""
+    };
+  },
+  computed: {
+    swiper() {
+      return this.$refs.mySwiper.swiper;
+    }
+  },
+  methods: {
+    clickCoa() {
+      if (this.list.coaUrl) {
+        window.location.href = this.list.coaUrl;
+      } else {
+        this.$message.error(this.$t("taps.service"));
+      }
+    },
+    clickMsds() {
+      // this.$message({
+      //   message: this.$t('message.MDSD'),
+      //   type: 'warning'
+      // });
+
+      this.$alert(this.$t('message.MDSD'), {
+        confirmButtonText: this.$t('button.determine'),
+        customClass: "tankuang",
+        callback: action => {
+        }
+      });
+      
+      // if (this.list.msdsUrl) {
+      //   window.location.href = this.list.msdsUrl;
+      // } else {
+      //   if (this.msdsUrl) {
+      //     window.location.href = this.msdsUrl;
+      //   } else {
+      //     axios
+      //       .post("https://crs.sanyoubio.com/api/product/msds", {
+      //         catalog: this.$route.params.catalog
+      //       })
+      //       .then(res => {
+      //         if (res.data.data) {
+      //           // console.log(res)
+      //           this.msdsUrl = res.data.data;
+      //           window.location.href = res.data.data;
+      //         } else {
+      //           this.$message.error(this.$t("taps.service"));
+      //         }
+      //       });
+      //   }
+      // }
+    },
+    datasheet() {
+      window.open(
+        "https://crs.sanyoubio.com/ds/SYD100_Mix_and_Go_Competent_Cells_DH5α_COA221011.pdf" +
+          "?response-content-type=application/pdf"
+      );
+    },
+    goMsds() {
+      window.open(
+        "https://crs.sanyoubio.com/ds/SYD100_Mix_and_Go_Competent_Cells_DH5α_MSDS.pdf"
+      );
+    },
+    changeNum() {
+      // 计数器
+      let that = this;
+      that.changeNumList = [];
+      for (var i = 0; i < that.skuList.length; i++) {
+        if (that.skuList[i].num > 0) {
+          let datas = {
+            skuId: that.skuList[i].id,
+            cnDiscountPrice: that.skuList[i].cnDiscountPrice,
+            productCatalog: that.skuList[i].catalog,
+            productName: that.skuList[i].productName,
+            size: that.skuList[i].specifications,
+            number: that.skuList[i].num,
+            discountPrice: that.skuList[i].discountPrice,
+            price: that.skuList[i].price,
+            checked: true,
+            id: that.list.id,
+            cnPrice: that.skuList[i].cnPrice
+          };
+          this.changeNumList.push(datas);
+        }
+      }
+    },
+    tapShoppingCart() {
+      // 购物车
+      let that = this;
+      //   var obj = []
+      var cartList = [];
+      if (this.skuList.length > 0) {
+        if (this.changeNumList.length === 0) {
+          this.$message.error(this.$t("button.Article"));
+        } else {
+          if (JSON.parse(localStorage.getItem("token"))) {
+            that.skuList.forEach(item => {
+              if (item.num > 0) {
+                var data = {
+                  checked: true,
+                  id: that.list.id,
+                  number: item.num,
+                  productCatalog: item.catalog,
+                  skuId: item.id
+                };
+                cartList.push(data);
+              }
+            });
+            this.$api
+              .post("cart/batchAdd", {
+                cartList: cartList
+              })
+              .then(res => {
+                if (res.code === 0) {
+                  this.getIndex();
+                  this.$message({
+                    message: this.$t("button.successfully"),
+                    type: "success"
+                  });
+                  // localStorage.setItem('cartTap', '1')
+                } else {
+                  this.$message(res.msg);
+                }
+              });
+          } else {
+            this.localList();
+          }
+        }
+      }
+    },
+    localList() {
+      // 本地存储
+      var shoppingCart = null;
+      var arrObj = null; // 选中数量
+      var list = []; // 新增数据
+      arrObj = JSON.parse(JSON.stringify(this.changeNumList));
+      shoppingCart = JSON.parse(localStorage.getItem("shoppingCart")) || []; // 获取购物车数据
+      if (shoppingCart.length > 0) {
+        for (var i = 0; i < this.changeNumList.length; i++) {
+          for (var j = 0; j < shoppingCart.length; j++) {
+            if (
+              Number(this.changeNumList[i].skuId) ===
+              Number(shoppingCart[j].skuId)
+            ) {
+              this.$set(arrObj[i], "checked", false);
+              shoppingCart[j].number =
+                Number(this.changeNumList[i].number) +
+                Number(shoppingCart[j].number);
+            }
+          }
+        }
+      } else {
+        localStorage.setItem(
+          "shoppingCart",
+          JSON.stringify(this.changeNumList)
+        );
+        localStorage.setItem(
+          "shoppingNum",
+          JSON.stringify(this.changeNumList.length)
+        );
+        this.elementByValue();
+        this.$message({
+          message: this.$t("button.successfully"),
+          type: "success"
+        });
+        return;
+      }
+      for (var n = 0; n < arrObj.length; n++) {
+        if (arrObj[n].checked) {
+          list.push(arrObj[n]);
+        }
+      }
+      this.$message({
+        message: this.$t("button.successfully"),
+        type: "success"
+      });
+      var arr = shoppingCart.concat(list);
+      localStorage.setItem("shoppingCart", JSON.stringify(arr));
+      localStorage.setItem("shoppingNum", JSON.stringify(arr.length));
+      // localStorage.setItem('cartTap', '1')
+      this.elementByValue();
+    },
+    getIndex() {
+      // 获取购物车数量
+      this.$api
+        .post("cart/index", {
+          cartList: null
+        })
+        .then(res => {
+          if (res.code === 0) {
+            localStorage.removeItem("shoppingCart");
+            localStorage.setItem(
+              "shoppingNum",
+              JSON.stringify(res.data.cartList.length)
+            );
+            this.elementByValue();
+          }
+        });
+    },
+    postLIstanbul() {
+      let that = this;
+      that.getProductDetaiLoading = true;
+      this.$api
+        .post("product/getProductDetail", {
+          catalog: this.$route.params.catalog
+          // catalog: this.$route.query.catalog
+        })
+        .then(res => {
+          if (res.code === 0) {
+            this.$store.commit("setProductName", res.data.productName);
+            this.list = res.data;
+            that.skuList = res.data.skuList || [];
+            that.skuList.forEach((item, index) => {
+              this.$set(that.skuList[index], "num", 0);
+            });
+            this.getList(); // 文献
+            this.postpageRelatedProduct();
+          }
+          that.getProductDetaiLoading = false;
+        })
+        .catch(() => {
+          that.getProductDetaiLoading = false;
+        });
+    },
+    getrecentlyList() {
+      // 最近浏览
+      this.$api.post("product/recentlyList").then(res => {
+        if (res.code === 0) {
+          this.recentlyList = res.data.content;
+        }
+      });
+    },
+    postpageRelatedProduct() {
+      this.$api
+        .post("product/pageRelatedProduct", {
+          criteria: {
+            catalog: this.list.catalog,
+            type: this.list.type,
+            targetId: this.list.target,
+            category: this.list.category
+          },
+          pageable: this.pageable
+        })
+        .then(res => {
+          if (res.code === 0) {
+            this.relatedProductlist = res.data.content;
+          }
+        });
+    },
+    goBack() {
+      console.log(sites.obj[this.list.type].url);
+      let kes = JSON.parse(sessionStorage.getItem("keywords"));
+      this.$router.replace({
+        path: "/search/by-category",
+        // name: sites.obj[this.list.type].url,
+        query: {
+          keywords: kes.keywords,
+          category: sites.obj[this.list.type].value
+        }
+      });
+      sessionStorage.removeItem("keywords");
+    },
+    getList() {
+      // 文献
+      this.$api
+        .post("citations/list", {
+          criteria: {
+            catalog: this.list.catalog
+          },
+          pageable: this.pageable
+        })
+        .then(res => {
+          if (res.code === 0) {
+            if (res.data.content && res.data.content.length > 0) {
+              this.literature = true;
+            } else {
+              this.literature = false;
+            }
+          }
+        });
+    },
+    elementByValue() {
+      // localStorage.setItem('cartTap', 1)
+      Bus.$emit("onmycar", "1");
+      // console.log('---------888888-')
+      // this.num = this.num + 1
+      // this.$store.commit('settapscart', this.num)
+      // console.log('----77777-----888888-')
+    }
+  },
+  mounted() {
+    // 浏览器返回
+    if (sessionStorage.getItem("keywords")) {
+      if (window.history && window.history.pushState) {
+        // 向历史记录中插入了当前页
+        history.pushState(null, null, document.URL);
+        window.addEventListener("popstate", this.goBack, false);
+      }
+    }
+  },
+  destroyed() {
+    window.removeEventListener("popstate", this.goBack, false);
+  },
+  created() {
+    this.postLIstanbul();
+    this.getrecentlyList();
+  }
+};
+</script>
+<style lang="scss" scoped>
+.common-border {
+  border-top: 1px solid #0166b4;
+  border-left: 1px solid #d6eaff;
+  border-right: 1px solid #d6eaff;
+  border-bottom: 1px solid #d6eaff;
+}
+
+@media screen and (min-width: 751px) and (max-width: 9999px) {
+  .pc-page {
+    display: block;
+  }
+
+  .mobile-page {
+    display: none;
+  }
+
+  .box {
+    overflow: hidden;
+    margin-bottom: 3rem;
+  }
+
+  .topbox {
+    margin-bottom: 26px;
+    margin-top: 30px;
+    font-size: 20px;
+    color: #313131;
+    // font-weight: 700;
+  }
+  .contentbox {
+    width: 66%;
+    float: left;
+  }
+
+  .rightbox {
+    width: 32%;
+    float: right;
+  }
+
+  .rightcenterbox:not(:nth-child(1)) {
+    margin-top: 2rem;
+  }
+
+  .rightcenterbox {
+    width: 100%;
+
+    .box-title {
+      font-size: 14px;
+      height: 36px;
+      line-height: 36px;
+      background-color: #f4faff;
+      font-weight: bold;
+      text-indent: 16px;
+    }
+  }
+  // .rightcenterbox > div:nth-of-type(1) {
+  //   height: 3rem;
+  //   font-size: 18px;
+  //   font-weight: 700;
+  //   color: #313131;
+  //   background: #f5f5f5;
+  //   line-height: 3rem;
+  //   text-indent: 1rem;
+  // }
+  .rightcenterbox > div:nth-of-type(2) {
+    font-size: 0.16rem;
+    padding: 1rem;
+    font-size: 16px;
+  }
+  .rightcenterbox_text /deep/ {
+    font-size: 1rem !important;
+    .topage {
+      display: block;
+      height: 42px;
+      line-height: 42px;
+      font-size: 16px;
+      color: #6f6f6f;
+      padding-left: 12px;
+      margin-left: -12px;
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      cursor: pointer;
+      &:hover {
+        background: rgba(0, 91, 171, 0.11);
+        border-radius: 2px;
+        border: 1px solid #005bab;
+        color: #005bab;
+        .el-icon-arrow-right {
+          color: #005bab;
+        }
+      }
+      .list_name {
+        font-size: 14px;
+        white-space: nowrap;
+        overflow: hidden;
+        text-overflow: ellipsis;
+      }
+    }
+    .el-icon-arrow-right {
+      height: 42px;
+      line-height: 42px;
+      margin-right: 10px;
+    }
+  }
+  .rightcenterbox > div:nth-of-type(2) > p:nth-of-type(1) {
+    margin-top: 0;
+  }
+  // .rightcenterbox>div:nth-of-type(2)>p{
+  //   margin-top: 1rem;
+  //   color: #6f6f6f;
+  // }
+  .rightcenterbox > div > p {
+    word-wrap: break-word;
+    word-break: normal;
+    cursor: pointer;
+    a {
+      color: #6f6f6f;
+      text-decoration: none;
+    }
+  }
+  .rightbox_ds {
+    line-height: 24px;
+    color: #6f6f6f;
+  }
+  .rightcenterbox > div:nth-of-type(2) > .rightbox_b {
+    color: #005bab;
+    // font-weight: 600;
+    margin-top: 10px;
+  }
+}
+
+@media screen and (min-width: 0px) and (max-width: 750px) {
+  .pc-page {
+    display: none;
+  }
+
+  .mobile-page {
+    display: block;
+  }
+
+  .box {
+    overflow: hidden;
+    margin-bottom: 0.1rem;
+
+    .topbox {
+      margin-bottom: 0.2rem;
+      font-size: 0.18rem;
+      color: #313131;
+      font-weight: 600;
+
+      .img-group {
+        display: flex;
+        margin-top: 0.2rem;
+        gap: 0.1rem;
+      }
+    }
+    .contentbox {
+      width: 100%;
+      overflow: hidden;
+    }
+  }
+
+  .not_list {
+    height: 100%;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    .block_img {
+      width: 80%;
+    }
+  }
+  .tankuang, .el-message-box{
+    width: 80% !important;
+  }
+}
+</style>

+ 210 - 0
src/view/product/index.vue

@@ -0,0 +1,210 @@
+<template>
+  <div class="antibody_box" ref="tablePar">
+    <table-list
+      v-loading="tableLoading"
+      :list="list"
+      type="2"
+      @my-sort-change="onSortFieldChange"
+    />
+    <!-- 加载更多 -->
+    <div
+      class="load_b"
+      v-if="list.length > 0 && pageable.page + 1 !== moreParams.totalPages"
+      @click="loadList"
+    >
+      <i v-if="loadShow" class="el-icon-loading"></i>
+      <span class="load">{{ $t("table.load") }}</span>
+    </div>
+  </div>
+</template>
+<script>
+import tableList from "@/components/tableList";
+
+let timer = null;
+export default {
+  components: {
+    tableList
+  },
+  name: "antibody",
+  data() {
+    return {
+      criteria: {
+        type: 2,
+        species: "",
+        // source: '',
+        format: "",
+        host: "",
+        category: this.$route.query.id || "",
+        sortKey: undefined,
+        sortValue: undefined
+      },
+      pageable: {
+        page: 0,
+        size: 10
+      },
+      list: [],
+      tableLoading: false,
+      loadShow: false,
+      moreParams: {},
+      resultObj: {}
+    };
+  },
+  methods: {
+    onSortFieldChange(params) {
+      this.criteria.sortKey = params.field || undefined;
+      this.criteria.sortValue = params.value || undefined;
+      this.pageable.page = 0;
+      this.postlist();
+    },
+    // 加载更多
+    loadList() {
+      this.loadShow = true;
+      this.pageable.page++;
+      this.postlist();
+    },
+    // 获取列表
+    postlist() {
+      let that = this;
+      that.tableLoading = true;
+      this.$api
+        .post("product/listByCategory", {
+          criteria: this.criteria,
+          pageable: this.pageable
+        })
+        .then(res => {
+          if (res.code === 0) {
+            const resDataContent = (res.data.content || []).map(item => {
+              return {
+                ...item,
+                skuDefault: item.skuList && item.skuList.length > 0 ? 0 : ""
+              };
+            });
+            if (that.pageable.page === 0) {
+              this.list = resDataContent;
+            } else {
+              this.list = this.list.concat(resDataContent);
+              console.log(this.list);
+            }
+            this.moreParams = res.data.more_params;
+            this.loadShow = false;
+          }
+
+          that.tableLoading = false;
+        })
+        .catch(() => {
+          that.tableLoading = false;
+        });
+    },
+    // 判断滚动条位置
+    handleScroll() {
+      if (timer) {
+        clearTimeout(timer);
+      }
+      timer = setTimeout(() => {
+        var scrollTop =
+          window.pageYOffset ||
+          document.documentElement.scrollTop ||
+          document.body.scrollTop;
+        var windowHeight =
+          window.innerHeight ||
+          document.documentElement.clientHeight ||
+          document.body.clientHeight;
+        var scrollHeight =
+          document.documentElement.scrollHeight || document.body.scrollHeight;
+        if (
+          this.pageable.page + 1 == this.moreParams.totalPages ||
+          this.list.length < 10
+        ) {
+          clearTimeout(timer);
+          window.removeEventListener("scroll", this.handleScroll);
+          return;
+        }
+        if (scrollTop + windowHeight >= scrollHeight && !this.loadShow) {
+          // console.log('触底了')
+          this.loadShow = true;
+          this.pageable.page++;
+          this.postlist();
+        }
+      }, 300);
+    }
+  },
+  mounted() {
+    this.postlist();
+    // 监听滚动
+    window.addEventListener("scroll", this.handleScroll);
+  },
+  created() {
+    // this.getList()
+  },
+  beforeDestroy() {
+    // 移除监听
+    window.removeEventListener("scroll", this.handleScroll);
+  }
+};
+</script>
+<style lang="scss" scoped>
+.antibody_box {
+  display: block !important;
+  .clout_box {
+    margin-bottom: 2rem;
+    .title {
+      word-wrap: break-word;
+      word-break: normal;
+      width: 100%;
+      background: #f3f3f3;
+      padding: 1.5rem 2rem;
+      font-size: 16px;
+      font-family: Arial;
+      color: #313131;
+    }
+  }
+}
+.load_b {
+  margin: 1.2rem 0;
+  font-size: 14px;
+  font-family: Arial;
+  color: #005bab;
+  text-align: center;
+  cursor: pointer;
+  .el-icon-loading {
+    font-size: 24px;
+  }
+  .load {
+    display: block;
+    line-height: 32px;
+  }
+}
+.menu_box /deep/ {
+  // 菜单
+  border: 1px solid #dbdbdb;
+  margin-bottom: 2rem;
+  .menu_b {
+    .list {
+      border: none;
+    }
+  }
+}
+@media screen and (min-width: 751px) and (max-width: 9999px) {
+  .menu_box_pmd {
+    display: none;
+  }
+}
+@media screen and (min-width: 0px) and (max-width: 750px) {
+  .antibody_box {
+    .clout_box {
+      margin-bottom: 20px;
+      .title {
+        padding: 10px !important;
+      }
+    }
+  }
+  .load_b {
+    margin: 20px 0;
+  }
+  .menu_box /deep/ {
+    // 菜单
+    border: none;
+    margin-bottom: 0;
+  }
+}
+</style>

+ 324 - 0
src/view/register/index.vue

@@ -0,0 +1,324 @@
+<template>
+  <div class="box">
+    <div class="footerbox">
+      <div class="topbox">
+        {{$t('register.WELCOME')}}
+      </div>
+            <div class="taps_footerbox">
+              <el-input class="inputbox" v-model="from.email" :placeholder="$t('register.Address')"></el-input>
+              <div class="red-t">*</div>
+            </div>
+            <div class="taps_footerbox">
+              <el-input class="inputbox" v-model="from.password" show-password :placeholder="$t('register.Password')"></el-input>
+              <div class="red-t">*</div>
+            </div>
+            <div class="taps_footerbox">
+              <el-input class="inputbox" v-model="from.confirmPassword" show-password :placeholder="$t('register.Confirm')"></el-input>
+              <div class="red-t">*</div>
+            </div>
+            <div class="taps_footerbox">
+              <el-input class="inputbox" v-model="from.name" :placeholder="$t('register.Fullname')"></el-input>
+              <!-- <div class="red-t">*</div> -->
+            </div>
+            <div class="taps_footerbox">
+              <el-input class="inputbox" v-model="from.company" :placeholder="$t('register.Company')"></el-input>
+              <!-- <div class="red-t">*</div> -->
+            </div>
+            <div class="taps_footerbox">
+              <el-select v-model="from.country" :placeholder="$t('register.Country')">
+                <el-option
+                  v-for="item in regionList"
+                  :key="item.en"
+                  :label="item.en"
+                  :value="item.en">
+                </el-option>
+              </el-select>
+            </div>
+            <div class="taps_footerbox">
+              <el-select v-model="from.accountType" :placeholder="$t('register.Account')">
+                <el-option
+                  v-for="item in accountTypeList"
+                  :key="item.name"
+                  :label="item.name"
+                  :value="item.name">
+                </el-option>
+              </el-select>
+            </div>
+            <el-button class="buttonbox_taps" type="primary" v-loading.fullscreen.lock="fullscreenLoading" @click="postRegister">{{$t('register.Agree')}}</el-button>
+          </div>
+   <div class="rightbox">
+     <div class="rightcenterbox">
+       <div class="rightcenterbox_f">
+         <!-- Contact Us -->
+         {{$t('button.contactUs')}}
+        </div>
+       <div class="rightcenterbox_b">
+         <p>{{$t('bottomBar.Tel')}} {{$t('taps.Telnum')}}</p>
+         <p>{{$t('bottomBar.Email')}} {{$t('taps.Emailnum')}}</p>
+       </div>
+     </div>
+   </div>
+  </div>
+</template>
+<script>
+import region from '@/js/region'
+export default {
+  components: {
+  },
+  name: 'register',
+  data () {
+    return {
+      fullscreenLoading: false,
+      langShow: this.$util.localeStorage(),
+      checked: true,
+      checkedp: true,
+      regionList: [],
+      from: {
+        accountType: '',
+        company: '',
+        confirmPassword: '',
+        country: '',
+        email: '',
+        name: '',
+        password: '',
+        country: ''
+      },
+      accountTypeList: [{
+        name: 'Industry',
+        nameCn: '工业客户'
+      }, {
+        name: 'Academic',
+        nameCn: '科研客户'
+      }, {
+        name: 'Distributor',
+        nameCn: '经销商'
+      }]
+    }
+  },
+  methods: {
+    postRegister () { // 注册
+      if (this.verification()) {
+        this.fullscreenLoading = true;
+        this.$api.post('auth/register', this.from).then((res) => {
+          if (res.code == 0) {
+            this.fullscreenLoading = false;
+            this.$message({
+              message: this.$t('message.registration'),
+              type: 'success'
+            })
+            this.$router.push({
+              name: 'registration'
+            })
+          } else if (res.code == 226) {
+            this.$message(this.$t('message.alreadyExists'))
+            this.fullscreenLoading = false;
+          } else if (res.code == 407) {
+            this.$message(this.$t('message.hasFailed'))
+            this.fullscreenLoading = false;
+          } else {
+            this.$message(res.msg)
+            this.fullscreenLoading = false;
+          }
+        })
+        
+      }
+    },
+    verification () {
+      // if (!this.from.email) {
+      //   this.$message.error(this.$t('register.Address') + this.$t('register.Cannot'))
+      //   return false
+      // } else if (!this.$util.isEmail(this.from.email)) {
+      //   this.$message.error(this.$t('input.email') + this.$t('message.email'))
+      //   return false
+      // } else if (!this.from.password) {
+      //   this.$message.error(this.$t('register.Password') + this.$t('register.Cannot'))
+      //   return false
+      // } else if (!this.$util.passwordValid(this.from.password)) {
+      //   this.$message.error(this.$t('register.kinds'))
+      //   return false
+      // } else if (this.from.password !== this.from.confirmPassword) {
+      //   this.$message.error(this.$t('register.inconsistent'))
+      //   return false
+      // } else if (!this.from.name) {
+      //   this.$message.error(this.$t('register.Fullname') + this.$t('register.Cannot'))
+      //   return false
+      // } else if (!this.from.company) {
+      //   this.$message.error(this.$t('register.Company') + this.$t('register.Cannot'))
+      //   return false
+      // } else if (!this.from.country) {
+      //   this.$message.error(this.$t('register.Country') + this.$t('register.Cannot'))
+      //   return false
+      // } else if (!this.from.accountType) {
+      //   this.$message.error(this.$t('register.Account') + this.$t('register.Cannot'))
+      //   return false
+      // } else {
+      //   return true
+      // }
+
+      if (!this.from.email) {
+        this.$message.error(this.$t('register.Address') + this.$t('register.Cannot'))
+        return false
+      } else if (!this.$util.isEmail(this.from.email)) {
+        this.$message.error(this.$t('input.email') + this.$t('message.email'))
+        return false
+      } else if (!this.from.password) {
+        this.$message.error(this.$t('register.Password') + this.$t('register.Cannot'))
+        return false
+      } else if (!this.$util.passwordValid(this.from.password)) {
+        this.$message.error(this.$t('register.kinds'))
+        return false
+      } else if (this.from.password !== this.from.confirmPassword) {
+        this.$message.error(this.$t('register.inconsistent'))
+        return false
+      } else {
+        return true
+      }
+    }
+  },
+  mounted () {
+  },
+  created () {
+    this.regionList = region
+  }
+}
+</script>
+<style lang="scss" scoped>
+@media screen and (min-width: 751px) and (max-width: 9999px) {
+.box{
+  overflow: hidden;
+  margin-bottom: 3rem;
+}
+
+.footerbox{
+  width: 40%;
+  float: left;
+  margin-left: 2rem;
+  margin-top: 1.8rem;
+  margin-right: 8rem;
+  .topbox{
+    margin-bottom: 1.8rem;
+    font-size:  1.4rem;
+    color: #005BAB;
+    font-weight: 600;
+    text-align: center;
+    }
+  .taps_footerbox /deep/{
+    position: relative;
+    margin-bottom: 0.8rem;
+    .el-select{
+      width: 100%;
+    }
+    .inputbox{
+      width: 100%;
+    }
+    .red-t{
+      font-size: 1.5rem;
+      color: #E52323;
+      position: absolute;
+      top: 40%;
+      left: -1rem;
+    }
+  }
+    .buttonbox_taps{
+      font-size: 16px;
+      width: 100%;
+      background: #0166b4;
+      height: 3rem;
+      padding: 0;
+      margin-top: 1rem;
+    }
+  }
+
+.register_box{
+  margin-top: 0.6rem;
+}
+
+.rightbox{
+  width: 30%;
+  float: left;
+  .rightcenterbox{
+  width: 100%;
+  margin-top: 5.2rem;
+  border: 1px solid #DBDBDB;
+  .rightcenterbox_f{
+    height: 3rem;
+    font-size: 1.2rem;
+    font-weight: 700;
+    color: #313131;
+    background: #F5F5F5;
+    line-height: 3rem;
+    text-indent: 1rem;
+  }
+  .rightcenterbox_b{
+    font-size: 1rem;
+    padding: 1rem;
+  }
+  }
+}
+
+.rightcenterbox_b>p:nth-of-type(1){
+  margin-top: 0;
+}
+.rightcenterbox_b>p{
+  margin-top: 1rem;
+  color: #6f6f6f;
+}
+}
+
+@media screen and (min-width: 0px) and (max-width: 750px) {
+.box{
+  overflow: hidden;
+  // margin-bottom: 3rem;
+}
+
+.footerbox{
+  width: 90%;
+  margin: 0 auto;
+  // overflow: hidden;
+  background: #ffffff;
+  .topbox{
+    margin-bottom: 0.24rem;
+    font-size:  0.2rem;
+    color: #005BAB;
+    font-weight: 600;
+    text-align: center;
+    }
+  .taps_footerbox /deep/{
+    position: relative;
+    margin-bottom: 0.16rem;
+    .el-select{
+      width: 100%;
+    }
+    .inputbox{
+      width: 100%;
+    }
+    .red-t{
+      font-size: 0.2rem;
+      color: #E52323;
+      position: absolute;
+      top: 50%;
+      transform: translateY(-50%);
+      left: -0.1rem;
+    }
+  }
+    .buttonbox_taps{
+      font-size: 0.16rem;
+      width: 100%;
+      background: #0166b4;
+      height: 0.42rem;
+      padding: 0;
+      margin-top: 0.2rem;
+    }
+  }
+
+.register_box{
+  margin-top: 0.1rem;
+}
+
+.rightbox{
+  display: none;
+}
+
+}
+
+</style>

+ 148 - 0
src/view/registrations/index.vue

@@ -0,0 +1,148 @@
+<template>
+<div>
+  <div class="box">
+    <div class="toptext">Account Confirmation</div>
+     <div class="centerbox">
+      <p class="contact_text" v-if="textShow == 1"> {{$route.query.email}} This account has already been activated!</p>
+      <p class="contact_text" v-if="textShow == 2"> Mailbox does not exist!</p>
+      <p class="contact_text" v-if="textShow == 3"> Already activated do not activate again!</p>
+      <p class="contact_text" v-if="textShow == 4"> Link failure, re register!</p>
+      <p class="contact_text" v-if="textShow == 5">Register fail.</p>
+    </div>
+  </div>
+
+  <!-- <div class="box" v-if="!$util.localeStorage()">
+  <div class="toptext">帐户激活</div>
+   <div class="centerbox">
+      <p class="contact_text" v-if="textShow == 1">{{$route.query.email}} 此帐户已激活!</p>
+      <p class="contact_text" v-if="textShow == 2">邮箱不存在!</p>
+      <p class="contact_text" v-if="textShow == 3">已经激活不要重复激活!</p>
+      <p class="contact_text" v-if="textShow == 4">链接失效,重新注册!</p>
+      <p class="contact_text" v-if="textShow == 5">注册失败</p>
+   </div>
+  </div> -->
+
+</div>
+
+</template>
+<script>
+export default {
+  components: {
+  },
+  name: 'registrations',
+  data () {
+    return {
+      textShow: 1
+    }
+  },
+  methods: {
+    getActive () {
+      const loading = this.$loading({
+        lock: true,
+        text: 'Loading',
+        spinner: 'el-icon-loading',
+        background: 'rgba(0, 0, 0, 0.7)'
+      });
+      this.$api.post('auth/active', {
+        code: this.$route.query.code,
+        email: this.$route.query.email
+      }).then((res) => {
+        if (res.code == 0) {
+          this.textShow = 1
+          setTimeout(()=> {
+            this.$util.goRoute({
+              name: 'login'
+            })
+          }, 5000)
+        } else if (res.code == 302) {
+          this.textShow = 2
+        } else if (res.code == 226) {
+          this.textShow = 3
+        } else if (res.code == 307) {
+          this.textShow = 4
+        } else if (res.code == 5000 && res.msg == '账号已激活') {
+          this.textShow = 1
+          setTimeout(()=> {
+            this.$util.goRoute({
+              name: 'login'
+            })
+          }, 5000)
+        } else {
+          this.textShow = 5
+        }
+      })
+      loading.close();
+    }
+  },
+  mounted () {
+  },
+  created () {
+    this.getActive()
+  }
+}
+</script>
+<style lang="scss" scoped>
+@media screen and (min-width: 751px) and (max-width: 9999px) {
+.box{
+  overflow: hidden;
+}
+.toptext{
+  margin-top: 3rem;
+    height: 3rem;
+    font-size: 16px;
+    color: #005bab;
+    background: #cfe0ef;
+    line-height: 3rem;
+    text-indent: 1rem;
+    font-weight: 700;
+}
+.centerbox{
+  width: 100%;
+  box-shadow: 2px 3px 8px 0px rgba(180, 180, 180, 0.3);
+  background: #F9FBFD;
+  padding: 50px;
+  border: 1px solid #dbdbdb;
+  .contact_text{
+    text-align: center;
+    font-size: 20px;
+    font-weight: 600;
+    word-wrap: break-word;
+    word-break: normal;
+  }
+}
+
+
+}
+
+@media screen and (min-width: 0px) and (max-width: 750px) {
+.box{
+  overflow: hidden;
+}
+.toptext{
+  margin-top: 0.1rem;
+    height: 0.5rem;
+    font-size: 16px;
+    color: #005bab;
+    background: #cfe0ef;
+    line-height: 0.5rem;
+    text-indent: 0.1rem;
+    font-weight: 700;
+}
+.centerbox{
+  width: 100%;
+  box-shadow: 2px 3px 8px 0px rgba(180, 180, 180, 0.3);
+  background: #F9FBFD;
+  padding: 50px;
+  border: 1px solid #dbdbdb;
+  .contact_text{
+    text-align: center;
+    font-size: 20px;
+    font-weight: 600;
+    word-wrap: break-word;
+    word-break: normal;
+  }
+}
+
+
+}
+</style>

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